Compare commits
20 commits
master
...
remove-web
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f2d42607c | ||
|
|
98491c9a52 | ||
|
|
45aa7dc37c | ||
|
|
b6572a5d13 | ||
|
|
9c1c812ea1 | ||
|
|
f2873075d3 | ||
|
|
9b9c06c703 | ||
|
|
9cf33a9632 | ||
|
|
8c13525177 | ||
|
|
0e6cc54ed9 | ||
|
|
7b1700ba3f | ||
|
|
adb2b0a940 | ||
|
|
b4126aa82b | ||
|
|
28596667fb | ||
|
|
f265e2a1fe | ||
|
|
529e8e7dea | ||
|
|
0a40fef084 | ||
|
|
7af65c1eee | ||
|
|
348bf8398c | ||
|
|
cd5d094c25 |
76
.eslintrc
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
{ "extends": ["eslint-config-airbnb", "prettier"],
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"node": true,
|
||||||
|
"jest": true
|
||||||
|
},
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"rules": {
|
||||||
|
"camelcase": 0,
|
||||||
|
"strict": 0,
|
||||||
|
"react/no-multi-comp": 0,
|
||||||
|
"import/default": 0,
|
||||||
|
"import/no-duplicates": 0,
|
||||||
|
"import/named": 0,
|
||||||
|
"import/namespace": 0,
|
||||||
|
"import/no-unresolved": 0,
|
||||||
|
"import/no-named-as-default": 2,
|
||||||
|
"import/prefer-default-export": 0,
|
||||||
|
"comma-dangle": 0, // not sure why airbnb turned this on. gross!
|
||||||
|
"indent": [2, 2, {"SwitchCase": 1}],
|
||||||
|
"no-console": 0,
|
||||||
|
"no-alert": 0,
|
||||||
|
"no-shadow": 2,
|
||||||
|
"arrow-body-style": 0,
|
||||||
|
"react/prop-types": 0,
|
||||||
|
"react/jsx-filename-extension": 0,
|
||||||
|
"react/prefer-stateless-function": 0,
|
||||||
|
"jsx-a11y/anchor-is-valid": 0,
|
||||||
|
"jsx-a11y/tabindex-no-positive": 0,
|
||||||
|
"no-mixed-operators": 0,
|
||||||
|
"no-plusplus": 0,
|
||||||
|
"no-underscore-dangle": 0,
|
||||||
|
"prettier/prettier": "error",
|
||||||
|
"jsx-a11y/no-autofocus": 0,
|
||||||
|
"jsx-a11y/label-has-for": 0,
|
||||||
|
"prefer-destructuring": 0,
|
||||||
|
"react-hooks/rules-of-hooks": "error",
|
||||||
|
"react-hooks/exhaustive-deps": "warn",
|
||||||
|
"react/jsx-wrap-multilines": ["error", {"declaration": false, "assignment": false}],
|
||||||
|
"react/jsx-one-expression-per-line": 0,
|
||||||
|
"@typescript-eslint/no-unused-vars": 1,
|
||||||
|
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*_test.ts"]}],
|
||||||
|
"lines-between-class-members": 0,
|
||||||
|
"react/jsx-fragments": 0,
|
||||||
|
"jsx-a11y/label-has-associated-control": 0,
|
||||||
|
"no-empty": 0,
|
||||||
|
"import/extensions": 0,
|
||||||
|
"react/require-default-props": 0,
|
||||||
|
"react/default-props-match-prop-types": 0
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"react", "react-hooks", "import", "prettier", "@typescript-eslint"
|
||||||
|
],
|
||||||
|
"globals": {
|
||||||
|
"__DEVELOPMENT__": true,
|
||||||
|
"__PRODUCTION__": true,
|
||||||
|
"__DISABLE_SSR__": true,
|
||||||
|
"__DEVTOOLS__": true,
|
||||||
|
"__DOMAIN__": true,
|
||||||
|
"__BASE_URL__": true,
|
||||||
|
"__BASE_NAME__": true,
|
||||||
|
"__STRIPE_PUBLIC_KEY__": true,
|
||||||
|
"__ROOT_URL__": true,
|
||||||
|
"__CDN_URL__": true,
|
||||||
|
"__STANDALONE__": true,
|
||||||
|
"socket": true,
|
||||||
|
"webpackIsomorphicTools": true,
|
||||||
|
"StripeCheckout": true,
|
||||||
|
|
||||||
|
"browser": true,
|
||||||
|
"chrome": true,
|
||||||
|
__WEB_URL__: true,
|
||||||
|
__API_ENDPOINT__: true,
|
||||||
|
__VERSION__: true
|
||||||
|
}
|
||||||
|
}
|
||||||
34
.github/workflows/ci.yml
vendored
|
|
@ -1,34 +0,0 @@
|
||||||
name: CI
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: actions/setup-go@v6
|
|
||||||
with:
|
|
||||||
go-version: '>=1.25.0'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
make install
|
|
||||||
|
|
||||||
- name: Test cli
|
|
||||||
run: |
|
|
||||||
make test-cli
|
|
||||||
|
|
||||||
- name: Test app
|
|
||||||
run: |
|
|
||||||
make test-api
|
|
||||||
|
|
||||||
- name: Test e2e
|
|
||||||
run: |
|
|
||||||
make test-e2e
|
|
||||||
77
.github/workflows/release-cli.yml
vendored
|
|
@ -1,77 +0,0 @@
|
||||||
name: Release CLI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'cli-v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: actions/setup-go@v6
|
|
||||||
with:
|
|
||||||
go-version: '>=1.25.0'
|
|
||||||
|
|
||||||
- name: Extract version from tag
|
|
||||||
id: version
|
|
||||||
run: |
|
|
||||||
TAG=${GITHUB_REF#refs/tags/cli-v}
|
|
||||||
echo "version=$TAG" >> $GITHUB_OUTPUT
|
|
||||||
echo "Releasing version: $TAG"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: make install
|
|
||||||
|
|
||||||
- name: Run CLI tests
|
|
||||||
run: make test-cli
|
|
||||||
|
|
||||||
- name: Run E2E tests
|
|
||||||
run: make test-e2e
|
|
||||||
|
|
||||||
- name: Build CLI
|
|
||||||
run: make version=${{ steps.version.outputs.version }} build-cli
|
|
||||||
|
|
||||||
- name: Generate changelog
|
|
||||||
run: |
|
|
||||||
VERSION="${{ steps.version.outputs.version }}"
|
|
||||||
TAG="cli-v${VERSION}"
|
|
||||||
|
|
||||||
# Find previous CLI tag
|
|
||||||
PREV_TAG=$(git tag --sort=-version:refname | grep "^cli-" | grep -v "^${TAG}$" | head -n 1)
|
|
||||||
|
|
||||||
if [ -z "$PREV_TAG" ]; then
|
|
||||||
echo "Error: No previous CLI tag found"
|
|
||||||
echo "This appears to be the first release."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
./scripts/generate-changelog.sh cli "$TAG" "$PREV_TAG" > /tmp/changelog.txt
|
|
||||||
cat /tmp/changelog.txt
|
|
||||||
|
|
||||||
- name: Create GitHub release
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
run: |
|
|
||||||
VERSION="${{ steps.version.outputs.version }}"
|
|
||||||
TAG="cli-v${VERSION}"
|
|
||||||
|
|
||||||
# Determine if prerelease (version not matching major.minor.patch)
|
|
||||||
FLAGS=""
|
|
||||||
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
||||||
FLAGS="--prerelease"
|
|
||||||
fi
|
|
||||||
|
|
||||||
gh release create "$TAG" \
|
|
||||||
build/cli/*.tar.gz \
|
|
||||||
build/cli/*_checksums.txt \
|
|
||||||
$FLAGS \
|
|
||||||
--title="$TAG" \
|
|
||||||
--notes-file=/tmp/changelog.txt \
|
|
||||||
--draft
|
|
||||||
109
.github/workflows/release-server.yml
vendored
|
|
@ -1,109 +0,0 @@
|
||||||
name: Release Server
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'server-v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: actions/setup-go@v6
|
|
||||||
with:
|
|
||||||
go-version: '>=1.25.0'
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '20'
|
|
||||||
|
|
||||||
- name: Extract version from tag
|
|
||||||
id: version
|
|
||||||
run: |
|
|
||||||
TAG=${GITHUB_REF#refs/tags/server-v}
|
|
||||||
echo "version=$TAG" >> $GITHUB_OUTPUT
|
|
||||||
echo "Releasing version: $TAG"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: make install
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: make test
|
|
||||||
|
|
||||||
- name: Build server
|
|
||||||
run: make version=${{ steps.version.outputs.version }} build-server
|
|
||||||
|
|
||||||
- name: Generate changelog
|
|
||||||
run: |
|
|
||||||
VERSION="${{ steps.version.outputs.version }}"
|
|
||||||
TAG="server-v${VERSION}"
|
|
||||||
|
|
||||||
# Find previous server tag
|
|
||||||
PREV_TAG=$(git tag --sort=-version:refname | grep "^server-" | grep -v "^${TAG}$" | head -n 1)
|
|
||||||
|
|
||||||
if [ -z "$PREV_TAG" ]; then
|
|
||||||
echo "Error: No previous server tag found"
|
|
||||||
echo "This appears to be the first release."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
./scripts/generate-changelog.sh server "$TAG" "$PREV_TAG" > /tmp/changelog.txt
|
|
||||||
cat /tmp/changelog.txt
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v3
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Prepare Docker build context
|
|
||||||
run: |
|
|
||||||
VERSION="${{ steps.version.outputs.version }}"
|
|
||||||
cp build/server/dnote_server_${VERSION}_linux_amd64.tar.gz host/docker/
|
|
||||||
cp build/server/dnote_server_${VERSION}_linux_arm64.tar.gz host/docker/
|
|
||||||
cp build/server/dnote_server_${VERSION}_linux_arm.tar.gz host/docker/
|
|
||||||
cp build/server/dnote_server_${VERSION}_linux_386.tar.gz host/docker/
|
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: ./host/docker
|
|
||||||
push: true
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/386
|
|
||||||
tags: |
|
|
||||||
dnote/dnote:${{ steps.version.outputs.version }}
|
|
||||||
dnote/dnote:latest
|
|
||||||
build-args: |
|
|
||||||
version=${{ steps.version.outputs.version }}
|
|
||||||
|
|
||||||
- name: Create GitHub release
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
run: |
|
|
||||||
VERSION="${{ steps.version.outputs.version }}"
|
|
||||||
TAG="server-v${VERSION}"
|
|
||||||
|
|
||||||
# Determine if prerelease (version not matching major.minor.patch)
|
|
||||||
FLAGS=""
|
|
||||||
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
||||||
FLAGS="--prerelease"
|
|
||||||
fi
|
|
||||||
|
|
||||||
gh release create "$TAG" \
|
|
||||||
build/server/*.tar.gz \
|
|
||||||
build/server/*_checksums.txt \
|
|
||||||
$FLAGS \
|
|
||||||
--title="$TAG" \
|
|
||||||
--notes-file=/tmp/changelog.txt \
|
|
||||||
--draft
|
|
||||||
4
.gitignore
vendored
|
|
@ -3,7 +3,3 @@
|
||||||
.vagrant
|
.vagrant
|
||||||
*.log
|
*.log
|
||||||
node_modules
|
node_modules
|
||||||
/test
|
|
||||||
tmp
|
|
||||||
*.db
|
|
||||||
/server
|
|
||||||
|
|
|
||||||
6
.prettierrc
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
}
|
||||||
|
|
||||||
32
.travis.yml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
language: go
|
||||||
|
dist: xenial
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.13
|
||||||
|
|
||||||
|
env:
|
||||||
|
- NODE_VERSION=10.15.0
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get update
|
||||||
|
- sudo apt-get --yes remove postgresql\*
|
||||||
|
- sudo apt-get install -y postgresql-11 postgresql-client-11
|
||||||
|
- sudo cp /etc/postgresql/{9.6,11}/main/pg_hba.conf
|
||||||
|
- sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/11/main/postgresql.conf
|
||||||
|
- sudo service postgresql restart 11
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- nvm install "$NODE_VERSION"
|
||||||
|
- nvm use "$NODE_VERSION"
|
||||||
|
- node --version
|
||||||
|
- psql -c "CREATE DATABASE dnote_test;" -U postgres
|
||||||
|
|
||||||
|
install:
|
||||||
|
- make install
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make lint
|
||||||
|
- make test-cli
|
||||||
|
- make test-api
|
||||||
|
- make test-web
|
||||||
|
- make test-jslib
|
||||||
270
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
# CHANAGELOG
|
||||||
|
|
||||||
|
All notable changes to the projects under this repository will be documented in this file.
|
||||||
|
|
||||||
|
* [Server](#server)
|
||||||
|
* [CLI](#cli)
|
||||||
|
* [Browser Extensions](#browser-extensions)
|
||||||
|
|
||||||
|
## Server
|
||||||
|
|
||||||
|
The following log documents the history of the server project.
|
||||||
|
|
||||||
|
### Unreleased
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
### 1.0.4 2020-05-23
|
||||||
|
|
||||||
|
#### Removed
|
||||||
|
|
||||||
|
- Simplify the bundle by removing unnecessary payment logic
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix timestamp in the note content view
|
||||||
|
- Invalidate existing sessions when password is changed
|
||||||
|
|
||||||
|
### 1.0.3 2020-05-03
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix timeline grouping notes by added time rather than updated time.
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Sort notes by last activity to make it easier to see the most recently accessed information.
|
||||||
|
|
||||||
|
### 1.0.2 2020-05-03
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
* Support arm64.
|
||||||
|
|
||||||
|
### 1.0.1 - 2020-03-29
|
||||||
|
|
||||||
|
- Fix fresh install running migrations against tables that no longer exists.
|
||||||
|
|
||||||
|
### 1.0.0 - 2020-03-22
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix unsubscribe link from the inactive reminder (#433)
|
||||||
|
|
||||||
|
#### Removed
|
||||||
|
|
||||||
|
- Remove the deprecated features related to digests and repetition rules (#432)
|
||||||
|
- Remove the migration for the deprecated, encrypted Dnote (#433)
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Please set `OnPremise` environment to `true` in order to automatically use the Pro version.
|
||||||
|
|
||||||
|
### 0.5.0 - 2020-02-06
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- **Deprecated** the digest and digest emails (#397)
|
||||||
|
- **Deprecated** the repetition rules (#397)
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix refocusing to the end of the textarea input (#405)
|
||||||
|
|
||||||
|
### 0.4.0 - 2020-01-09
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- A web-based digest (#380)
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Send inactive reminders with a correct email type (#385)
|
||||||
|
- Wrap words in note content (#389)
|
||||||
|
|
||||||
|
### 0.3.4 - 2019-12-24
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Remind when the knowledge base stops growing (#375)
|
||||||
|
- Alert when a password is changed (#375)
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Implement syntax highlighting for code blocks ($377)
|
||||||
|
|
||||||
|
### 0.3.3 - 2019-12-17
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Send welcome email with login instructions upon reigstering (#352)
|
||||||
|
- Add an option to disable registration (#365)
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Send emails from the domain that hosts the application for on premise installations (#355)
|
||||||
|
- For on premise installations, automatically upgrade user accounts (#361)
|
||||||
|
|
||||||
|
### 0.3.2 - 2019-11-20
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix server crash upon landing on a note page (#324).
|
||||||
|
- Allow to synchronize a large number of records (#321)
|
||||||
|
|
||||||
|
### 0.3.1 - 2019-11-12
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix static files not being embedded in the binary. (#309)
|
||||||
|
- Fix mobile menu not covering the whole screen. (#308)
|
||||||
|
|
||||||
|
### 0.3.0 - 2019-11-12
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Share notes (#300)
|
||||||
|
- Allow to recover from a missed repetition processing (#305)
|
||||||
|
|
||||||
|
### 0.2.1 - 2019-11-04
|
||||||
|
|
||||||
|
#### Upgrade Guide
|
||||||
|
|
||||||
|
* Please define the follwoing new environment variables:
|
||||||
|
|
||||||
|
- `WebURL`: the URL to your Dnote server, without the trailing slash. (e.g. `https://my-server.com`) (Please see #290)
|
||||||
|
- `SmtpPort`: the SMTP port. (e.g. `465`) optional - required *if you want to configure email*
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Display version number in the settings (#293)
|
||||||
|
- Allow unsecure database connection in production (#276)
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Allow to customize the app URL in the emails (#290)
|
||||||
|
- Allow to customize the SMTP port (#292)
|
||||||
|
|
||||||
|
### 0.2.0 - 2019-10-28
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Specify spaced repetition rule (#280)
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Treat a linebreak as a new line in the preview (#261)
|
||||||
|
- Allow to have multiple editor states for adding and editing notes (#260)
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix jumping focus on editor (#265)
|
||||||
|
|
||||||
|
### 0.1.1 - 2019-09-30
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix asset loading (#257)
|
||||||
|
|
||||||
|
|
||||||
|
### 0.1.0 - 2019-09-30
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Full-text search (#254)
|
||||||
|
- Password recovery (#254)
|
||||||
|
- Embedded notes in the digest emails (#254)
|
||||||
|
|
||||||
|
#### Removed
|
||||||
|
|
||||||
|
- **Breaking Change**: End-to-end encryption was removed. Existing users need to go to `/classic` and follow the automated migration steps. (#254)
|
||||||
|
- **Breaking Change**: `v1` and `v2` API endpoints were removed, and `v3` API was added as a replacement.
|
||||||
|
|
||||||
|
#### Migration guide
|
||||||
|
|
||||||
|
- In your application, navigate to `/classic` and follow the automated migration steps.
|
||||||
|
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
|
The following log documentes the history of the CLI project
|
||||||
|
|
||||||
|
### Unreleased
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
### 0.12.0 - 2020-01-03
|
||||||
|
|
||||||
|
#### Upgrade guide
|
||||||
|
|
||||||
|
* **On Linux or macOS** Please move your Dnote files to new directories based on the XDG base directory specfication. **On Windows**, no action is required.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Move the database file
|
||||||
|
mv ~/.dnote/dnote.db ~/.local/share/dnote/dnote.db
|
||||||
|
|
||||||
|
# Move the config file
|
||||||
|
mv ~/.dnote/dnoterc ~/.config/dnote/dnoterc
|
||||||
|
|
||||||
|
# Delete ~/.dnote. (it is safe to delete DNOTE_TMPCONTENT.md files, if they exist.)
|
||||||
|
rm -rf ~/.dnote
|
||||||
|
```
|
||||||
|
|
||||||
|
If `~/.dnote` directory exists, dnote will continue to use that directory for backward compatibility until the next major release.
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Add `--content-only` flag to print the note content only (#528)
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Use XDG base directory on Linux and macOS (#527)
|
||||||
|
|
||||||
|
### 0.11.1 - 2020-04-25
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fix upgrade URL (#453)
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Display hostname of the self-hosted instance while logging in (#454)
|
||||||
|
- Display helpful error if endpoint is misconfigured (#455)
|
||||||
|
|
||||||
|
### 0.11.0 - 2020-02-05
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Allow to pass credentials through flags while logging in (#403)
|
||||||
|
|
||||||
|
### 0.10.0 - 2019-09-30
|
||||||
|
|
||||||
|
#### Removed
|
||||||
|
|
||||||
|
- **Breaking Change**: End-to-end encryption was removed. Previous versions will no longer be able to interact with the web API, because `v1` and `v2` endpoints were replaced by a new `v3` endpoint to remove encryption.
|
||||||
|
|
||||||
|
#### Migration guide
|
||||||
|
|
||||||
|
- If you are using Dnote Pro, change the value of `apiEndpoint` in `~/.dnote/dnoterc` to `https://api.getdnote.com`.
|
||||||
|
|
||||||
|
## Browser Extensions
|
||||||
|
|
||||||
|
The following log documentes the history of the browser extensions project
|
||||||
|
|
||||||
|
### [Unreleased]
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
### 2.0.0 - 2019-10-29
|
||||||
|
|
||||||
|
- Allow to customize API and web URLs (#285)
|
||||||
|
|
||||||
|
### 1.1.1 - 2019-10-02
|
||||||
|
|
||||||
|
- Fix failing requests (#263)
|
||||||
|
|
||||||
|
### 1.1.0 - 2019-09-30
|
||||||
|
|
||||||
|
#### Removed
|
||||||
|
|
||||||
|
- **Breaking Change**: End-to-end encryption was removed. Previous versions will no longer be able to interact with the web API, because `v1` and `v2` endpoints were replaced by a new `v3` endpoint to remove encryption.
|
||||||
|
|
@ -8,61 +8,95 @@ Dnote is an open source project.
|
||||||
|
|
||||||
## Setting up
|
## Setting up
|
||||||
|
|
||||||
The CLI and server are single single binary files with SQLite embedded - no databases to install, no containers to run, no VMs required.
|
Dnote uses [Vagrant](https://github.com/hashicorp/vagrant) to provision a consistent development environment.
|
||||||
|
|
||||||
**Prerequisites**
|
*Prerequisites*
|
||||||
|
|
||||||
* Go 1.25+ ([Download](https://go.dev/dl/))
|
* Vagrant ([Download](https://www.vagrantup.com/downloads.html))
|
||||||
* Node.js 18+ ([Download](https://nodejs.org/) - only needed for building frontend assets)
|
* VirtualBox ([Download](https://www.virtualbox.org/))
|
||||||
|
|
||||||
**Quick Start**
|
Run the following command from the project root. It starts the virtual machine and bootstraps the project.
|
||||||
|
|
||||||
1. Clone the repository
|
```
|
||||||
2. Install dependencies:
|
vagrant up
|
||||||
```bash
|
```
|
||||||
make install
|
|
||||||
```
|
|
||||||
3. Start developing! Run tests:
|
|
||||||
```bash
|
|
||||||
make test
|
|
||||||
```
|
|
||||||
Or start the dev server:
|
|
||||||
```bash
|
|
||||||
make dev-server
|
|
||||||
```
|
|
||||||
|
|
||||||
That's it. You're ready to contribute.
|
*Workflow*
|
||||||
|
|
||||||
|
* You can make changes to the source code from the host machine.
|
||||||
|
* Any commands need to be run inside the virtual machine. You can connect to it by running `vagrant ssh`.
|
||||||
|
* If you want to run tests in a WATCH mode, please do so from the host machine. We cannot watch file changes due to the limitation of file system used in a virtual machine.
|
||||||
|
|
||||||
## Server
|
## Server
|
||||||
|
|
||||||
```bash
|
The server consists of the frontend web application and a web server.
|
||||||
# Start dev server (runs on localhost:3001)
|
|
||||||
make dev-server
|
|
||||||
|
|
||||||
# Run tests
|
### Development
|
||||||
|
|
||||||
|
* Run `make dev-server` to start a local server.
|
||||||
|
* You can access the server on `localhost:3000` on your machine.
|
||||||
|
|
||||||
|
### Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run tests for the frontend web application
|
||||||
|
make test-web
|
||||||
|
|
||||||
|
# Run in watch mode
|
||||||
|
WATCH=true make test-web
|
||||||
|
|
||||||
|
# Run tests for API
|
||||||
make test-api
|
make test-api
|
||||||
|
|
||||||
# Run tests in watch mode
|
# Run in watch mode
|
||||||
WATCH=true make test-api
|
WATCH=true make test-api
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Command Line Interface
|
## Command Line Interface
|
||||||
|
|
||||||
```bash
|
### Build
|
||||||
# Run tests
|
|
||||||
make test-cli
|
|
||||||
|
|
||||||
# Build dev version (places in your PATH)
|
You can build either a development version or a production version:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Build a development version for your platform and place it in your `PATH`.
|
||||||
make debug=true build-cli
|
make debug=true build-cli
|
||||||
|
|
||||||
# Build production version for all platforms
|
# Build a production version for all platforms
|
||||||
make version=v0.1.0 build-cli
|
make version=v0.1.0 build-cli
|
||||||
|
|
||||||
# Build for a specific platform
|
# Build a production version for a specific platform
|
||||||
# Note: You cannot cross-compile using this method because Dnote uses CGO
|
# Note: You cannot cross-compile using this method because Dnote uses CGO
|
||||||
# and requires the OS specific headers.
|
# and requires the OS specific headers.
|
||||||
GOOS=[insert OS] GOARCH=[insert arch] make version=v0.1.0 build-cli
|
GOOS=[insert OS] GOARCH=[insert arch] make version=v0.1.0 build-cli
|
||||||
|
```
|
||||||
|
|
||||||
# Debug mode
|
### Test
|
||||||
|
|
||||||
|
* Run all tests for the command line interface:
|
||||||
|
|
||||||
|
```
|
||||||
|
make test-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debug
|
||||||
|
|
||||||
|
Run Dnote with `DNOTE_DEBUG=1` to print debugging statements. For instance:
|
||||||
|
|
||||||
|
```
|
||||||
DNOTE_DEBUG=1 dnote sync
|
DNOTE_DEBUG=1 dnote sync
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Release
|
||||||
|
|
||||||
|
* Run `make version=v0.1.0 release-cli` to achieve the following:
|
||||||
|
* Build for all target platforms, create a git tag, push all tags to the repository
|
||||||
|
* Create a release on GitHub and [Dnote Homebrew tap](https://github.com/dnote/homebrew-dnote).
|
||||||
|
|
||||||
|
**Note**
|
||||||
|
|
||||||
|
- If a release is not stable,
|
||||||
|
- disable the homebrew release by commenting out relevant code in the release script.
|
||||||
|
- mark release as pre-release on GitHub release
|
||||||
|
|
||||||
|
|
|
||||||
209
LICENSE
|
|
@ -1,203 +1,8 @@
|
||||||
|
Source code in this repository is variously licensed under the GNU Affero General Public
|
||||||
|
License v3.0 (GNU AGPLv3), and GNU General Public License v3.0 (GNU GPLv3). A copy of each
|
||||||
|
license can be found in the licenses directory. The Source code for the cli is licensed under
|
||||||
|
GNU GPLv3. The source code for the server and the web is licensed under GNU AGPLv3. Unless
|
||||||
|
otherwise noted, source code in a given file is licensed under the GNU AGPLv3.
|
||||||
|
|
||||||
Apache License
|
Unless otherwise noted at the beginning of the file, the copyright belongs to
|
||||||
Version 2.0, January 2004
|
Monomax Software Pty Ltd.
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
|
|
|
||||||
152
Makefile
|
|
@ -1,5 +1,6 @@
|
||||||
|
PACKR2 := $(shell command -v packr2 2> /dev/null)
|
||||||
NPM := $(shell command -v npm 2> /dev/null)
|
NPM := $(shell command -v npm 2> /dev/null)
|
||||||
GH := $(shell command -v gh 2> /dev/null)
|
HUB := $(shell command -v hub 2> /dev/null)
|
||||||
|
|
||||||
currentDir = $(shell pwd)
|
currentDir = $(shell pwd)
|
||||||
serverOutputDir = ${currentDir}/build/server
|
serverOutputDir = ${currentDir}/build/server
|
||||||
|
|
@ -11,6 +12,11 @@ install: install-go install-js
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
|
|
||||||
install-go:
|
install-go:
|
||||||
|
ifndef PACKR2
|
||||||
|
@echo "==> installing packr2"
|
||||||
|
@go get -u github.com/gobuffalo/packr/v2/packr2
|
||||||
|
endif
|
||||||
|
|
||||||
@echo "==> installing go dependencies"
|
@echo "==> installing go dependencies"
|
||||||
@go mod download
|
@go mod download
|
||||||
.PHONY: install-go
|
.PHONY: install-go
|
||||||
|
|
@ -23,17 +29,35 @@ endif
|
||||||
@echo "==> installing js dependencies"
|
@echo "==> installing js dependencies"
|
||||||
|
|
||||||
ifeq ($(CI), true)
|
ifeq ($(CI), true)
|
||||||
@(cd ${currentDir}/pkg/server/assets && npm ci --cache $(NPM_CACHE_DIR) --prefer-offline --unsafe-perm=true)
|
@(cd ${currentDir} && npm ci --cache $(NPM_CACHE_DIR) --prefer-offline --unsafe-perm=true)
|
||||||
|
@(cd ${currentDir}/web && npm ci --cache $(NPM_CACHE_DIR) --prefer-offline --unsafe-perm=true)
|
||||||
|
@(cd ${currentDir}/browser && npm ci --cache $(NPM_CACHE_DIR) --prefer-offline --unsafe-perm=true)
|
||||||
|
@(cd ${currentDir}/jslib && npm ci --cache $(NPM_CACHE_DIR) --prefer-offline --unsafe-perm=true)
|
||||||
else
|
else
|
||||||
@(cd ${currentDir}/pkg/server/assets && npm install)
|
@(cd ${currentDir} && npm install)
|
||||||
|
@(cd ${currentDir}/web && npm install)
|
||||||
|
@(cd ${currentDir}/browser && npm install)
|
||||||
|
@(cd ${currentDir}/jslib && npm install)
|
||||||
endif
|
endif
|
||||||
.PHONY: install-js
|
.PHONY: install-js
|
||||||
|
|
||||||
|
lint:
|
||||||
|
@(cd ${currentDir}/web && npm run lint)
|
||||||
|
@(cd ${currentDir}/jslib && npm run lint)
|
||||||
|
@(cd ${currentDir}/browser && npm run lint)
|
||||||
|
.PHONY: lint
|
||||||
|
|
||||||
|
lint-fix:
|
||||||
|
@(cd ${currentDir}/web && npm run lint:fix)
|
||||||
|
@(cd ${currentDir}/jslib && npm run lint:fix)
|
||||||
|
@(cd ${currentDir}/browser && npm run lint:fix)
|
||||||
|
.PHONY: lint
|
||||||
|
|
||||||
## test
|
## test
|
||||||
test: test-cli test-api test-e2e
|
test: test-cli test-api test-web test-jslib
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
test-cli: generate-cli-schema
|
test-cli:
|
||||||
@echo "==> running CLI test"
|
@echo "==> running CLI test"
|
||||||
@(${currentDir}/scripts/cli/test.sh)
|
@(${currentDir}/scripts/cli/test.sh)
|
||||||
.PHONY: test-cli
|
.PHONY: test-cli
|
||||||
|
|
@ -43,47 +67,57 @@ test-api:
|
||||||
@(${currentDir}/scripts/server/test-local.sh)
|
@(${currentDir}/scripts/server/test-local.sh)
|
||||||
.PHONY: test-api
|
.PHONY: test-api
|
||||||
|
|
||||||
test-e2e:
|
test-web:
|
||||||
@echo "==> running E2E test"
|
@echo "==> running web test"
|
||||||
@(${currentDir}/scripts/e2e/test.sh)
|
|
||||||
.PHONY: test-e2e
|
ifeq ($(WATCH), true)
|
||||||
|
@(cd ${currentDir}/web && npm run test:watch)
|
||||||
|
else
|
||||||
|
@(cd ${currentDir}/web && npm run test)
|
||||||
|
endif
|
||||||
|
.PHONY: test-web
|
||||||
|
|
||||||
|
test-jslib:
|
||||||
|
@echo "==> running jslib test"
|
||||||
|
|
||||||
|
ifeq ($(WATCH), true)
|
||||||
|
@(cd ${currentDir}/jslib && npm run test:watch)
|
||||||
|
else
|
||||||
|
@(cd ${currentDir}/jslib && npm run test)
|
||||||
|
endif
|
||||||
|
.PHONY: test-jslib
|
||||||
|
|
||||||
|
test-selfhost:
|
||||||
|
@echo "==> running a smoke test for self-hosting"
|
||||||
|
|
||||||
|
@${currentDir}/host/smoketest/run_test.sh ${tarballPath}
|
||||||
|
.PHONY: test-jslib
|
||||||
|
|
||||||
# development
|
# development
|
||||||
dev-server:
|
dev-server:
|
||||||
@echo "==> running dev environment"
|
@echo "==> running dev environment"
|
||||||
@VERSION=master ${currentDir}/scripts/server/dev.sh
|
@VERSION=master ${currentDir}/scripts/web/dev.sh
|
||||||
.PHONY: dev-server
|
.PHONY: dev-server
|
||||||
|
|
||||||
build-server:
|
## build
|
||||||
|
build-web:
|
||||||
|
ifndef version
|
||||||
|
$(error version is required. Usage: make version=0.1.0 build-web)
|
||||||
|
endif
|
||||||
|
@echo "==> building web"
|
||||||
|
@VERSION=${version} ${currentDir}/scripts/web/build-prod.sh
|
||||||
|
.PHONY: build-web
|
||||||
|
|
||||||
|
build-server: build-web
|
||||||
ifndef version
|
ifndef version
|
||||||
$(error version is required. Usage: make version=0.1.0 build-server)
|
$(error version is required. Usage: make version=0.1.0 build-server)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@echo "==> building server assets"
|
|
||||||
@(cd "${currentDir}/pkg/server/assets/" && ./styles/build.sh)
|
|
||||||
@(cd "${currentDir}/pkg/server/assets/" && ./js/build.sh)
|
|
||||||
|
|
||||||
@echo "==> building server"
|
@echo "==> building server"
|
||||||
@${currentDir}/scripts/server/build.sh $(version)
|
@${currentDir}/scripts/server/build.sh $(version)
|
||||||
.PHONY: build-server
|
.PHONY: build-server
|
||||||
|
|
||||||
build-server-docker: build-server
|
build-cli:
|
||||||
ifndef version
|
|
||||||
$(error version is required. Usage: make version=0.1.0 [platform=linux/amd64] build-server-docker)
|
|
||||||
endif
|
|
||||||
|
|
||||||
@echo "==> building Docker image"
|
|
||||||
@(cd ${currentDir}/host/docker && ./build.sh $(version) $(platform))
|
|
||||||
.PHONY: build-server-docker
|
|
||||||
|
|
||||||
generate-cli-schema:
|
|
||||||
@echo "==> generating CLI database schema"
|
|
||||||
@mkdir -p pkg/cli/database
|
|
||||||
@touch pkg/cli/database/schema.sql
|
|
||||||
@go run -tags fts5 ./pkg/cli/database/schema
|
|
||||||
.PHONY: generate-cli-schema
|
|
||||||
|
|
||||||
build-cli: generate-cli-schema
|
|
||||||
ifeq ($(debug), true)
|
ifeq ($(debug), true)
|
||||||
@echo "==> building cli in dev mode"
|
@echo "==> building cli in dev mode"
|
||||||
@${currentDir}/scripts/cli/dev.sh
|
@${currentDir}/scripts/cli/dev.sh
|
||||||
|
|
@ -98,7 +132,61 @@ endif
|
||||||
endif
|
endif
|
||||||
.PHONY: build-cli
|
.PHONY: build-cli
|
||||||
|
|
||||||
|
## release
|
||||||
|
release-cli: clean build-cli
|
||||||
|
ifndef version
|
||||||
|
$(error version is required. Usage: make version=0.1.0 release-cli)
|
||||||
|
endif
|
||||||
|
ifndef HUB
|
||||||
|
$(error please install hub)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if [ ! -d ${cliHomebrewDir} ]; then \
|
||||||
|
@echo "homebrew-dnote not found locally. did you clone it?"; \
|
||||||
|
@exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
@echo "==> releasing cli"
|
||||||
|
@${currentDir}/scripts/release.sh cli $(version) ${cliOutputDir}
|
||||||
|
|
||||||
|
@echo "===> releading on Homebrew"
|
||||||
|
@(cd "${cliHomebrewDir}" && \
|
||||||
|
./release.sh "$(version)" "${cliOutputDir}/dnote_$(version)_darwin_amd64.tar.gz")
|
||||||
|
.PHONY: release-cli
|
||||||
|
|
||||||
|
release-server:
|
||||||
|
ifndef version
|
||||||
|
$(error version is required. Usage: make version=0.1.0 release-server)
|
||||||
|
endif
|
||||||
|
ifndef HUB
|
||||||
|
$(error please install hub)
|
||||||
|
endif
|
||||||
|
|
||||||
|
@echo "==> releasing server"
|
||||||
|
@${currentDir}/scripts/release.sh server $(version) ${serverOutputDir}
|
||||||
|
|
||||||
|
@echo "==> building and releasing docker image"
|
||||||
|
@(cd ${currentDir}/host/docker && ./build.sh $(version))
|
||||||
|
@(cd ${currentDir}/host/docker && ./release.sh $(version))
|
||||||
|
.PHONY: release-server
|
||||||
|
|
||||||
|
# migrations
|
||||||
|
create-migration:
|
||||||
|
ifndef filename
|
||||||
|
$(error filename is required. Usage: make filename=your-filename create-migration)
|
||||||
|
endif
|
||||||
|
|
||||||
|
@(cd ${currentDir}/pkg/server/database && ./scripts/create-migration.sh $(filename))
|
||||||
|
.PHONY: create-migration
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@git clean -f
|
@git clean -f
|
||||||
@rm -rf build
|
@rm -rf build
|
||||||
|
@rm -rf web/public
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
|
clean-dep:
|
||||||
|
@rm -rf ${currentDir}/web/node_modules
|
||||||
|
@rm -rf ${currentDir}/jslib/node_modules
|
||||||
|
@rm -rf ${currentDir}/browser/node_modules
|
||||||
|
.PHONY: clean-dep
|
||||||
|
|
|
||||||
62
README.md
|
|
@ -1,64 +1,40 @@
|
||||||

|

|
||||||
=========================
|
=========================
|
||||||
|
|
||||||

|
[](https://travis-ci.org/dnote/dnote)
|
||||||
|
|
||||||
Dnote is a simple command line notebook. Single binary, no dependencies. Since 2017.
|
Dnote is a simple command line notebook for programmers.
|
||||||
|
|
||||||
Your notes are stored in **one SQLite file** - portable, searchable, and completely under your control. Optional sync between devices via a self-hosted server with REST API access.
|
It **keeps you focused** by providing a way of effortlessly capturing and retrieving information **without leaving your terminal**. It also offers a seamless **multi-device sync** and a **web interface**.
|
||||||
|
|
||||||
```sh
|

|
||||||
# Add a note (or omit -c to launch your editor)
|
|
||||||
dnote add linux -c "Check disk usage with df -h"
|
|
||||||
|
|
||||||
# View notes in a book
|
|
||||||
dnote view linux
|
|
||||||
|
|
||||||
# Full-text search
|
|
||||||
dnote find "disk usage"
|
|
||||||
|
|
||||||
# Sync notes
|
|
||||||
dnote sync
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
On macOS, you can install using Homebrew:
|
||||||
# Linux, macOS, FreeBSD, Windows
|
|
||||||
curl -s https://www.getdnote.com/install | sh
|
|
||||||
|
|
||||||
# macOS with Homebrew
|
```sh
|
||||||
|
brew tap dnote/dnote
|
||||||
brew install dnote
|
brew install dnote
|
||||||
```
|
```
|
||||||
|
|
||||||
Or [download binary](https://github.com/dnote/dnote/releases).
|
On Linux or macOS, you can use the installation script:
|
||||||
|
|
||||||
## Server (Optional)
|
curl -s https://www.getdnote.com/install | sh
|
||||||
|
|
||||||
Server is a binary with SQLite embedded. No database setup is required.
|
Otherwise, you can download the binary for your platform manually from the [releases page](https://github.com/dnote/dnote/releases).
|
||||||
|
|
||||||
If using docker, create a compose.yml:
|
## Server
|
||||||
|
|
||||||
```yaml
|
The quickest way to experience the Dnote server is to use [Dnote Cloud](https://app.getdnote.com).
|
||||||
services:
|
|
||||||
dnote:
|
|
||||||
image: dnote/dnote:latest
|
|
||||||
container_name: dnote
|
|
||||||
ports:
|
|
||||||
- 3001:3001
|
|
||||||
volumes:
|
|
||||||
- ./dnote_data:/data
|
|
||||||
restart: unless-stopped
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run:
|
Or you can install it on your server by [using Docker](https://github.com/dnote/dnote/blob/master/host/docker/README.md), or [using a binary](https://github.com/dnote/dnote/blob/master/SELF_HOSTING.md).
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
Or see the [guide](https://www.getdnote.com/docs/server/manual) for binary installation.
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
See the [Dnote doc](https://www.getdnote.com/docs).
|
Please see [Dnote wiki](https://github.com/dnote/dnote/wiki) for the documentation.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Homepage](https://www.getdnote.com)
|
||||||
|
- [I Wrote Down Everything I Learned While Programming for a Month](https://www.getdnote.com/blog/writing-everything-i-learn-coding-for-a-month/)
|
||||||
|
|
|
||||||
202
SELF_HOSTING.md
|
|
@ -1,43 +1,183 @@
|
||||||
# Self-Hosting Dnote Server
|
# Installing Dnote Server
|
||||||
|
|
||||||
Please see the [doc](https://www.getdnote.com/docs/server) for more.
|
This guide documents the steps for installing the Dnote server on your own machine. If you prefer Docker, please see [the Docker guide](https://github.com/dnote/dnote/blob/master/host/docker/README.md).
|
||||||
|
|
||||||
## Docker Installation
|
## Overview
|
||||||
|
|
||||||
1. Install [Docker](https://docs.docker.com/install/).
|
Dnote server comes as a single binary file that you can simply download and run. It uses Postgres as the database.
|
||||||
2. Install Docker [Compose plugin](https://docs.docker.com/compose/install/linux/).
|
|
||||||
3. Create a `compose.yml` file with the following content:
|
|
||||||
|
|
||||||
```yaml
|
## Installation
|
||||||
services:
|
|
||||||
dnote:
|
|
||||||
image: dnote/dnote:latest
|
|
||||||
container_name: dnote
|
|
||||||
ports:
|
|
||||||
- 3001:3001
|
|
||||||
volumes:
|
|
||||||
- ./dnote_data:/data
|
|
||||||
restart: unless-stopped
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Run the following to download the image and start the container
|
1. Install Postgres 11+.
|
||||||
|
2. Create a `dnote` database by running `createdb dnote`
|
||||||
```
|
3. Download the official Dnote server release from the [release page](https://github.com/dnote/dnote/releases).
|
||||||
docker compose up -d
|
4. Extract the archive and move the `dnote-server` executable to `/usr/local/bin`.
|
||||||
```
|
|
||||||
|
|
||||||
Visit http://localhost:3001 in your browser to see Dnote running.
|
|
||||||
|
|
||||||
## Manual Installation
|
|
||||||
|
|
||||||
Download from [releases](https://github.com/dnote/dnote/releases), extract, and run:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
tar -xzf dnote-server-$version-$os.tar.gz
|
tar -xzf dnote-server-$version-$os.tar.gz
|
||||||
mv ./dnote-server /usr/local/bin
|
mv ./dnote-server /usr/local/bin
|
||||||
dnote-server start --baseUrl=https://your.server
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You're up and running. Database: `~/.local/share/dnote/server.db` (customize with `--dbPath`). Run `dnote-server start --help` for options.
|
4. Run Dnote
|
||||||
|
|
||||||
Set `apiEndpoint: https://your.server/api` in `~/.config/dnote/dnoterc` to connect your CLI to the server.
|
```bash
|
||||||
|
GO_ENV=PRODUCTION \
|
||||||
|
OnPremise=true \
|
||||||
|
DBHost=localhost \
|
||||||
|
DBPort=5432 \
|
||||||
|
DBName=dnote \
|
||||||
|
DBUser=$user \
|
||||||
|
DBPassword=$password \
|
||||||
|
WebURL=$webURL \
|
||||||
|
SmtpHost=$SmtpHost \
|
||||||
|
SmtpPort=$SmtpPort \
|
||||||
|
SmtpUsername=$SmtpUsername \
|
||||||
|
SmtpPassword=$SmtpPassword \
|
||||||
|
DisableRegistration=false
|
||||||
|
dnote-server start
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `$user`, `$password` with the credentials of the Postgres user that owns the `dnote` database.
|
||||||
|
|
||||||
|
Replace `$webURL` with the full URL to your server, without a trailing slash (e.g. `https://your.server`).
|
||||||
|
|
||||||
|
Replace `$SmtpHost`, `SmtpPort`, `$SmtpUsername`, `$SmtpPassword` with actual values, if you would like to receive spaced repetition through email.
|
||||||
|
|
||||||
|
Replace `DisableRegistration` to `true` if you would like to disable user registrations.
|
||||||
|
|
||||||
|
By default, dnote server will run on the port 3000.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
By now, Dnote is fully functional in your machine. The API, frontend app, and the background tasks are all in the single binary. Let's take a few more steps to configure Dnote.
|
||||||
|
|
||||||
|
### Configure Nginx
|
||||||
|
|
||||||
|
To make it accessible from the Internet, you need to configure Nginx.
|
||||||
|
|
||||||
|
1. Install nginx.
|
||||||
|
2. Create a new file in `/etc/nginx/sites-enabled/dnote` with the following contents:
|
||||||
|
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
server_name my-dnote-server.com;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Replace `my-dnote-server.com` with the URL for your server.
|
||||||
|
4. Reload the nginx configuration by running the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo service nginx reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure Apache2
|
||||||
|
|
||||||
|
1. Install Apache2 and install/enable mod_proxy.
|
||||||
|
2. Create a new file in `/etc/apache2/sites-available/dnote.conf` with the following contents:
|
||||||
|
|
||||||
|
```
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName notes.example.com
|
||||||
|
|
||||||
|
ProxyRequests Off
|
||||||
|
ProxyPreserveHost On
|
||||||
|
ProxyPass / http://127.0.0.1:3000/ keepalive=On
|
||||||
|
ProxyPassReverse / http://127.0.0.1:3000/
|
||||||
|
RequestHeader set X-Forwarded-HTTPS "0"
|
||||||
|
</VirtualHost>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Enable the dnote site and restart the Apache2 service by running the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
a2ensite dnote
|
||||||
|
sudo service apache2 restart
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can access the Dnote frontend application on `/`, and the API on `/api`.
|
||||||
|
|
||||||
|
### Configure TLS by using LetsEncrypt
|
||||||
|
|
||||||
|
It is recommended to use HTTPS. Obtain a certificate using LetsEncrypt and configure TLS in Nginx.
|
||||||
|
|
||||||
|
In the future versions of the Dnote Server, HTTPS will be required at all times.
|
||||||
|
|
||||||
|
### Run Dnote As a Daemon
|
||||||
|
|
||||||
|
We can use `systemd` to run Dnote in the background as a Daemon, and automatically start it on system reboot.
|
||||||
|
|
||||||
|
1. Create a new file at `/etc/systemd/system/dnote.service` with the following content:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=Starts the dnote server
|
||||||
|
Requires=network.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=$user
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3
|
||||||
|
WorkingDirectory=/home/$user
|
||||||
|
ExecStart=/usr/local/bin/dnote-server start
|
||||||
|
Environment=GO_ENV=PRODUCTION
|
||||||
|
Environment=OnPremise=true
|
||||||
|
Environment=DBHost=localhost
|
||||||
|
Environment=DBPort=5432
|
||||||
|
Environment=DBName=dnote
|
||||||
|
Environment=DBUser=$DBUser
|
||||||
|
Environment=DBPassword=$DBPassword
|
||||||
|
Environment=DBSkipSSL=true
|
||||||
|
Environment=WebURL=$WebURL
|
||||||
|
Environment=SmtpHost=
|
||||||
|
Environment=SmtpPort=
|
||||||
|
Environment=SmtpUsername=
|
||||||
|
Environment=SmtpPassword=
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `$user`, `$WebURL`, `$DBUser`, and `$DBPassword` with the actual values.
|
||||||
|
|
||||||
|
Optionally, if you would like to send spaced repetitions throught email, populate `SmtpHost`, `SmtpPort`, `SmtpUsername`, and `SmtpPassword`.
|
||||||
|
|
||||||
|
2. Reload the change by running `sudo systemctl daemon-reload`.
|
||||||
|
3. Enable the Daemon by running `sudo systemctl enable dnote`.`
|
||||||
|
4. Start the Daemon by running `sudo systemctl start dnote`
|
||||||
|
|
||||||
|
### Configure clients
|
||||||
|
|
||||||
|
Let's configure Dnote clients to connect to the self-hosted web API endpoint.
|
||||||
|
|
||||||
|
#### CLI
|
||||||
|
|
||||||
|
We need to modify the configuration file for the CLI. It should have been generated at `~/.dnote/dnoterc` upon running the CLI for the first time.
|
||||||
|
|
||||||
|
The following is an example configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
editor: nvim
|
||||||
|
apiEndpoint: https://api.getdnote.com
|
||||||
|
```
|
||||||
|
|
||||||
|
Simply change the value for `apiEndpoint` to a full URL to the self-hosted instance, followed by '/api', and save the configuration file.
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
editor: nvim
|
||||||
|
apiEndpoint: my-dnote-server.com/api
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Browser extension
|
||||||
|
|
||||||
|
Navigate into the 'Settings' tab and set the values for 'API URL', and 'Web URL'.
|
||||||
|
|
|
||||||
20
Vagrantfile
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- mode: ruby -*-
|
||||||
|
|
||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
config.vm.box = "ubuntu/bionic64"
|
||||||
|
config.vm.synced_folder '.', '/go/src/github.com/dnote/dnote'
|
||||||
|
config.vm.network "forwarded_port", guest: 3000, host: 3000
|
||||||
|
config.vm.network "forwarded_port", guest: 8080, host: 8080
|
||||||
|
config.vm.network "forwarded_port", guest: 5432, host: 5433
|
||||||
|
|
||||||
|
config.vm.provision 'shell', path: './scripts/vagrant/install_utils.sh'
|
||||||
|
config.vm.provision 'shell', path: './scripts/vagrant/install_go.sh', privileged: false
|
||||||
|
config.vm.provision 'shell', path: './scripts/vagrant/install_node.sh', privileged: false
|
||||||
|
config.vm.provision 'shell', path: './scripts/vagrant/install_postgres.sh', privileged: false
|
||||||
|
config.vm.provision 'shell', path: './scripts/vagrant/bootstrap.sh', privileged: false
|
||||||
|
|
||||||
|
config.vm.provider "virtualbox" do |v|
|
||||||
|
v.memory = 4000
|
||||||
|
v.cpus = 2
|
||||||
|
end
|
||||||
|
end
|
||||||
BIN
assets/cli.gif
Normal file
|
After Width: | Height: | Size: 245 KiB |
BIN
assets/devices.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
5
browser/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
/dist
|
||||||
|
/package
|
||||||
|
/node_modules
|
||||||
|
.DS_Store
|
||||||
|
extension.tar.gz
|
||||||
18
browser/CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
Use the following commands to set up, build, and release.
|
||||||
|
|
||||||
|
## Set up
|
||||||
|
|
||||||
|
* `npm install` to install dependencies.
|
||||||
|
|
||||||
|
## Developing locally
|
||||||
|
|
||||||
|
* `npm run watch:firefox`
|
||||||
|
* `npm run watch:chrome`
|
||||||
|
|
||||||
|
## Releasing
|
||||||
|
|
||||||
|
* Set a new version in `package.json`
|
||||||
|
* Run `./scripts/build_prod.sh`
|
||||||
|
* A gulp task `manifest` will copy the version from `package.json` to `manifest.json`
|
||||||
18
browser/NOTE_TO_REVIEWER.md
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Note to reviewer
|
||||||
|
|
||||||
|
This document contains instructions about how to reproduce the final build of this extension.
|
||||||
|
|
||||||
|
All releases are tagged and pushed to [the GitHub repository](https://github.com/dnote/dnote).
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
To reproduce the obfuscated code for Firefox, please follow the steps below.
|
||||||
|
|
||||||
|
1. Run `npm install` to install dependencies
|
||||||
|
2. Run `./scripts/build_prod.sh` to build for Firefox and Chrome.
|
||||||
|
|
||||||
|
The obfuscated code will be under `/dist/firefox` and `/dist/chrome`.
|
||||||
|
|
||||||
|
## Further questions
|
||||||
|
|
||||||
|
Please contact sung@dnote.io
|
||||||
28
browser/README.md
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Dnote Browser Extension
|
||||||
|
|
||||||
|
Dnote browser extension for Chrome and Firefox. Capture new information without opening a new tab or leaving your browser.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Install the extension
|
||||||
|
|
||||||
|
* Firefox - https://addons.mozilla.org/addon/dnote
|
||||||
|
* Chrome - https://chrome.google.com/webstore/detail/dnote/mcfbfmihbijfaambfbbfcdcfibcjcahi
|
||||||
|
|
||||||
|
2. Login with your API key from https://dnote.io
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
We learn many things while reading technical articles, or browsing StackOverflow. Unless we write them down we forget most of them exponentially.
|
||||||
|
|
||||||
|
This extension integrates seamlessly with [Dnote CLI](https://github.com/dnote/dnote/cli) and requires [Dnote Cloud](https://www.getdnote.com/pricing) account.
|
||||||
|
|
||||||
|
## Hotkeys
|
||||||
|
|
||||||
|
Write new notes without even moving your hands to the mouse.
|
||||||
|
|
||||||
|
* **Ctrl + d** - Open the extension (**Ctrl + Shift + v** on Firefox on Linux).
|
||||||
|
* **Shift + Enter** - Save the current note
|
||||||
|
* **b** - Open the saved note in the browser
|
||||||
BIN
browser/assets/demo.gif
Normal file
|
After Width: | Height: | Size: 519 KiB |
100
browser/gulpfile.js
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const gulp = require('gulp');
|
||||||
|
const del = require('del');
|
||||||
|
const replace = require('gulp-replace');
|
||||||
|
const gulpif = require('gulp-if');
|
||||||
|
const imagemin = require('gulp-imagemin');
|
||||||
|
const livereload = require('gulp-livereload');
|
||||||
|
const zip = require('gulp-zip');
|
||||||
|
|
||||||
|
const target = process.env.TARGET;
|
||||||
|
|
||||||
|
gulp.task('manifest', () => {
|
||||||
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
|
return gulp
|
||||||
|
.src(`manifests/${target}/manifest.json`)
|
||||||
|
.pipe(replace('__VERSION__', pkg.version))
|
||||||
|
.pipe(gulp.dest(`dist/${target}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('styles', () => {
|
||||||
|
return gulp.src('src/styles/*.css').pipe(gulp.dest(`dist/${target}/styles`));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task(
|
||||||
|
'html',
|
||||||
|
gulp.series('styles', () => {
|
||||||
|
return gulp.src('src/*.html').pipe(gulp.dest(`dist/${target}`));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('images', () => {
|
||||||
|
return gulp
|
||||||
|
.src('src/images/**/*')
|
||||||
|
.pipe(
|
||||||
|
gulpif(
|
||||||
|
gulpif.isFile,
|
||||||
|
imagemin({
|
||||||
|
progressive: true,
|
||||||
|
interlaced: true,
|
||||||
|
svgoPlugins: [{ cleanupIDs: false }]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.pipe(gulp.dest(`dist/${target}/images`));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task(
|
||||||
|
'clean',
|
||||||
|
del.bind(null, ['.tmp', `dist/${target}`, `package/${target}`])
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task(
|
||||||
|
'watch',
|
||||||
|
gulp.series('manifest', 'html', 'styles', 'images', () => {
|
||||||
|
livereload.listen();
|
||||||
|
|
||||||
|
gulp
|
||||||
|
.watch([
|
||||||
|
'src/*.html',
|
||||||
|
'src/scripts/**/*',
|
||||||
|
'src/images/**/*',
|
||||||
|
'src/styles/**/*'
|
||||||
|
])
|
||||||
|
.on('change', livereload.reload);
|
||||||
|
|
||||||
|
gulp.watch('src/*.html', gulp.parallel('html'));
|
||||||
|
gulp.watch('manifests/**/*.json', gulp.parallel('manifest'));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('package', function() {
|
||||||
|
const manifest = require(`./dist/${target}/manifest.json`);
|
||||||
|
|
||||||
|
return gulp
|
||||||
|
.src(`dist/${target}/**`)
|
||||||
|
.pipe(zip('dnote-' + manifest.version + '.zip'))
|
||||||
|
.pipe(gulp.dest(`package/${target}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('build', gulp.series('manifest', gulp.parallel('html', 'images')));
|
||||||
|
|
||||||
|
gulp.task('default', gulp.series('clean', 'build'));
|
||||||
31
browser/manifests/chrome/manifest.json
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "Dnote",
|
||||||
|
"version": "__VERSION__",
|
||||||
|
"description": "Capture your microlessons without leaving the browser.",
|
||||||
|
"icons": {
|
||||||
|
"16": "images/iconx16.png",
|
||||||
|
"48": "images/iconx48.png",
|
||||||
|
"128": "images/iconx128.png"
|
||||||
|
},
|
||||||
|
"manifest_version": 2,
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "images/iconx16.png",
|
||||||
|
"32": "images/iconx32.png"
|
||||||
|
},
|
||||||
|
"default_popup": "popup.html"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"content_scripts": [],
|
||||||
|
"permissions": ["storage"],
|
||||||
|
"commands": {
|
||||||
|
"_execute_browser_action": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Ctrl+D",
|
||||||
|
"mac": "MacCtrl+D"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
browser/manifests/firefox/manifest.json
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"name": "Dnote",
|
||||||
|
"version": "__VERSION__",
|
||||||
|
"description": "Capture your microlessons without leaving the browser.",
|
||||||
|
"applications": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "sung@dnote.io",
|
||||||
|
"strict_min_version": "42.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"16": "images/iconx16.png",
|
||||||
|
"48": "images/iconx48.png",
|
||||||
|
"128": "images/iconx128.png"
|
||||||
|
},
|
||||||
|
"manifest_version": 2,
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "images/iconx16.png",
|
||||||
|
"32": "images/iconx32.png"
|
||||||
|
},
|
||||||
|
"default_popup": "popup.html"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"content_scripts": [],
|
||||||
|
"permissions": ["storage"],
|
||||||
|
"commands": {
|
||||||
|
"_execute_browser_action": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Ctrl+D",
|
||||||
|
"linux": "Ctrl+Shift+V",
|
||||||
|
"mac": "MacCtrl+D"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11193
browser/package-lock.json
generated
Normal file
50
browser/package.json
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"name": "dnote-extension",
|
||||||
|
"repository": "https://github.com/dnote/dnote",
|
||||||
|
"description": "Dnote browser extension for Chrome and Firefox",
|
||||||
|
"scripts": {
|
||||||
|
"clean": "TARGET=firefox gulp clean && TARGET=chrome gulp clean",
|
||||||
|
"build:chrome": "TARGET=chrome NODE_ENV=production concurrently webpack \"gulp build\"",
|
||||||
|
"build:firefox": "TARGET=firefox NODE_ENV=production concurrently webpack \"gulp build\"",
|
||||||
|
"package:chrome": "TARGET=chrome NODE_ENV=production gulp package",
|
||||||
|
"package:firefox": "TARGET=firefox NODE_ENV=production gulp package",
|
||||||
|
"watch:chrome": "TARGET=chrome NODE_ENV=development concurrently \"webpack --watch\" \"gulp watch\" ",
|
||||||
|
"watch:firefox": "TARGET=firefox NODE_ENV=development concurrently \"webpack --watch\" \"gulp watch\" ",
|
||||||
|
"lint": "../node_modules/.bin/eslint ./src --ext .ts,.tsx,.js",
|
||||||
|
"lint:fix": "../node_modules/.bin/eslint ./src --fix --ext .ts,.tsx,.js"
|
||||||
|
},
|
||||||
|
"author": "Monomax Software Pty Ltd",
|
||||||
|
"license": "GPL-3.0-or-later",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"classnames": "^2.2.5",
|
||||||
|
"lodash": "^4.17.20",
|
||||||
|
"qs": "^6.9.4",
|
||||||
|
"react": "^16.12.0",
|
||||||
|
"react-dom": "^16.12.0",
|
||||||
|
"react-redux": "^7.2.1",
|
||||||
|
"react-select": "^3.1.0",
|
||||||
|
"redux": "^4.0.4",
|
||||||
|
"redux-logger": "^3.0.6",
|
||||||
|
"redux-thunk": "^2.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.11.4",
|
||||||
|
"@babel/preset-env": "^7.11.0",
|
||||||
|
"@types/react": "^16.9.46",
|
||||||
|
"@types/react-dom": "^16.9.8",
|
||||||
|
"concurrently": "^5.3.0",
|
||||||
|
"del": "^5.0.0",
|
||||||
|
"gulp": "^4.0.0",
|
||||||
|
"gulp-if": "^3.0.0",
|
||||||
|
"gulp-imagemin": "^6.2.0",
|
||||||
|
"gulp-livereload": "^4.0.2",
|
||||||
|
"gulp-replace": "^1.0.0",
|
||||||
|
"gulp-zip": "^5.0.2",
|
||||||
|
"prettier": "^1.19.1",
|
||||||
|
"ts-loader": "^6.2.2",
|
||||||
|
"typescript": "^3.9.7",
|
||||||
|
"webpack": "^4.44.1",
|
||||||
|
"webpack-cli": "^3.3.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
14
browser/scripts/build_prod.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# build_prod.sh builds distributable archive for the addon
|
||||||
|
# remember to bump version in package.json
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
# clean
|
||||||
|
npm run clean
|
||||||
|
|
||||||
|
# chrome
|
||||||
|
npm run build:chrome
|
||||||
|
npm run package:chrome
|
||||||
|
# firefox
|
||||||
|
npm run build:firefox
|
||||||
|
npm run package:firefox
|
||||||
3
browser/scripts/zip.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
tar --exclude='./node_modules' --exclude='./package' --exclude='./dist' -zcvf extension.tar.gz * .eslintrc
|
||||||
21
browser/src/browser.d.ts
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// browser.d.ts
|
||||||
|
declare let browser: any;
|
||||||
|
declare let chrome: any;
|
||||||
25
browser/src/global.d.ts
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// global.d.ts
|
||||||
|
|
||||||
|
// defined by webpack-define-plugin
|
||||||
|
declare let __API_ENDPOINT__: string;
|
||||||
|
declare let __STANDALONE__: string;
|
||||||
|
declare let __WEB_URL__: string;
|
||||||
|
declare let __VERSION__: string;
|
||||||
1
browser/src/images/close.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 100 100" id="Layer_1" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><polygon fill="#010101" points="77.6,21.1 49.6,49.2 21.5,21.1 19.6,23 47.6,51.1 19.6,79.2 21.5,81.1 49.6,53 77.6,81.1 79.6,79.2 51.5,51.1 79.6,23 "/></svg>
|
||||||
|
After Width: | Height: | Size: 468 B |
1
browser/src/images/hamberger-menu.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'><svg enable-background="new 0 0 24 24" id="Layer_1" version="1.0" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><line fill="none" stroke="#000000" stroke-miterlimit="10" stroke-width="2" x1="2" x2="22" y1="12" y2="12"/><line fill="none" stroke="#000000" stroke-miterlimit="10" stroke-width="2" x1="2" x2="22" y1="6" y2="6"/><line fill="none" stroke="#000000" stroke-miterlimit="10" stroke-width="2" x1="2" x2="22" y1="18" y2="18"/></svg>
|
||||||
|
After Width: | Height: | Size: 641 B |
BIN
browser/src/images/iconx128.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
browser/src/images/iconx16.png
Normal file
|
After Width: | Height: | Size: 327 B |
BIN
browser/src/images/iconx32.png
Normal file
|
After Width: | Height: | Size: 517 B |
BIN
browser/src/images/iconx48.png
Normal file
|
After Width: | Height: | Size: 631 B |
BIN
browser/src/images/iconx96.png
Normal file
|
After Width: | Height: | Size: 1 KiB |
BIN
browser/src/images/logo-circle.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
15
browser/src/popup.html
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Dnote browser extension</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link href="styles/popup.css" rel="stylesheet" />
|
||||||
|
<link href="styles/select.css" rel="stylesheet" />
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body class="pending">
|
||||||
|
<div id="app"></div>
|
||||||
|
|
||||||
|
<script src="scripts/popup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
118
browser/src/scripts/components/App.tsx
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import initServices from '../utils/services';
|
||||||
|
import { logout } from '../store/auth/actions';
|
||||||
|
import { AuthState } from '../store/auth/types';
|
||||||
|
import { useSelector, useDispatch } from '../store/hooks';
|
||||||
|
import Header from './Header';
|
||||||
|
import Home from './Home';
|
||||||
|
import Menu from './Menu';
|
||||||
|
import Success from './Success';
|
||||||
|
import Settings from './Settings';
|
||||||
|
import Composer from './Composer';
|
||||||
|
|
||||||
|
interface Props {}
|
||||||
|
|
||||||
|
function renderRoutes(path: string, isLoggedIn: boolean) {
|
||||||
|
switch (path) {
|
||||||
|
case '/success':
|
||||||
|
return <Success />;
|
||||||
|
case '/': {
|
||||||
|
if (isLoggedIn) {
|
||||||
|
return <Composer />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Home />;
|
||||||
|
}
|
||||||
|
case '/settings': {
|
||||||
|
return <Settings />;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return <div>Not found</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// useCheckSessionValid ensures that the current session is valid
|
||||||
|
function useCheckSessionValid(auth: AuthState) {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// if session is expired, clear it
|
||||||
|
const now = Math.round(new Date().getTime() / 1000);
|
||||||
|
if (auth.sessionKey && auth.sessionKeyExpiry < now) {
|
||||||
|
dispatch(logout());
|
||||||
|
}
|
||||||
|
}, [dispatch, auth.sessionKey, auth.sessionKeyExpiry]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const App: React.FunctionComponent<Props> = () => {
|
||||||
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||||
|
const [errMsg, setErrMsg] = useState('');
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { path, auth, settings } = useSelector(state => ({
|
||||||
|
path: state.location.path,
|
||||||
|
auth: state.auth,
|
||||||
|
settings: state.settings
|
||||||
|
}));
|
||||||
|
|
||||||
|
useCheckSessionValid(auth);
|
||||||
|
|
||||||
|
const isLoggedIn = Boolean(auth.sessionKey);
|
||||||
|
const toggleMenu = () => {
|
||||||
|
setIsMenuOpen(!isMenuOpen);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLogout = async (done?: Function) => {
|
||||||
|
try {
|
||||||
|
await initServices(settings.apiUrl).users.signout();
|
||||||
|
dispatch(logout());
|
||||||
|
|
||||||
|
if (done) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setErrMsg(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<Header toggleMenu={toggleMenu} isShowingMenu={isMenuOpen} />
|
||||||
|
|
||||||
|
{isMenuOpen && (
|
||||||
|
<Menu
|
||||||
|
toggleMenu={toggleMenu}
|
||||||
|
loggedIn={isLoggedIn}
|
||||||
|
onLogout={handleLogout}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<main>
|
||||||
|
{errMsg && <div className="alert error">{errMsg}</div>}
|
||||||
|
|
||||||
|
{renderRoutes(path, isLoggedIn)}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
46
browser/src/scripts/components/BookIcon.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const Icon = ({ fill, width, height, className }) => {
|
||||||
|
const h = `${height}px`;
|
||||||
|
const w = `${width}px`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
height={h}
|
||||||
|
width={w}
|
||||||
|
fill={fill}
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<g transform="translate(240 0)">
|
||||||
|
<path d="M-211,4v26h-24c-1.104,0-2-0.895-2-2s0.896-2,2-2h22V0h-22c-2.209,0-4,1.791-4,4v24c0,2.209,1.791,4,4,4h26V4H-211z M-235,8V2h20v22h-20V8z M-219,6h-12V4h12V6z M-223,10h-8V8h8V10z M-227,14h-4v-2h4V14z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Icon.defaultProps = {
|
||||||
|
fill: '#000',
|
||||||
|
width: 32,
|
||||||
|
height: 32
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Icon;
|
||||||
117
browser/src/scripts/components/BookSelector.tsx
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import CreatableSelect from 'react-select/creatable';
|
||||||
|
import cloneDeep from 'lodash/cloneDeep';
|
||||||
|
import { useSelector, useDispatch } from '../store/hooks';
|
||||||
|
import { updateBook, resetBook } from '../store/composer/actions';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
selectorRef: React.Dispatch<any>;
|
||||||
|
onAfterChange: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function useCurrentOptions(options) {
|
||||||
|
const currentValue = useSelector(state => state.composer.bookUUID);
|
||||||
|
|
||||||
|
for (let i = 0; i < options.length; i++) {
|
||||||
|
const option = options[i];
|
||||||
|
|
||||||
|
if (option.value === currentValue) {
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function useOptions() {
|
||||||
|
const { books, composer } = useSelector(state => ({
|
||||||
|
books: state.books,
|
||||||
|
composer: state.composer
|
||||||
|
}));
|
||||||
|
|
||||||
|
const opts = books.items.map(book => ({
|
||||||
|
label: book.label,
|
||||||
|
value: book.uuid
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (composer.bookLabel !== '' && composer.bookUUID === '') {
|
||||||
|
opts.push({
|
||||||
|
label: composer.bookLabel,
|
||||||
|
value: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// clone the array so as not to mutate Redux state manually
|
||||||
|
// e.g. react-select mutates options prop internally upon adding a new option
|
||||||
|
return cloneDeep(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
const BookSelector: React.FunctionComponent<Props> = ({
|
||||||
|
selectorRef,
|
||||||
|
onAfterChange
|
||||||
|
}) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { books } = useSelector(state => ({
|
||||||
|
books: state.books
|
||||||
|
}));
|
||||||
|
const options = useOptions();
|
||||||
|
const currentOption = useCurrentOptions(options);
|
||||||
|
|
||||||
|
let placeholder: string;
|
||||||
|
if (books.isFetched) {
|
||||||
|
placeholder = 'Choose a book';
|
||||||
|
} else {
|
||||||
|
placeholder = 'Loading books...';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CreatableSelect
|
||||||
|
ref={el => {
|
||||||
|
selectorRef(el);
|
||||||
|
}}
|
||||||
|
multi={false}
|
||||||
|
isClearable
|
||||||
|
placeholder={placeholder}
|
||||||
|
options={options}
|
||||||
|
value={currentOption}
|
||||||
|
onChange={(option, meta) => {
|
||||||
|
if (meta.action === 'clear') {
|
||||||
|
dispatch(resetBook());
|
||||||
|
} else {
|
||||||
|
let uuid: string;
|
||||||
|
if (meta.action === 'create-option') {
|
||||||
|
uuid = '';
|
||||||
|
} else {
|
||||||
|
uuid = option.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(updateBook({ uuid, label: option.label }));
|
||||||
|
}
|
||||||
|
|
||||||
|
onAfterChange();
|
||||||
|
}}
|
||||||
|
formatCreateLabel={label => `Add a new book ${label}`}
|
||||||
|
isDisabled={!books.isFetched}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BookSelector;
|
||||||
29
browser/src/scripts/components/CloseIcon.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<svg height="20" viewBox="0 0 48 48" width="20">
|
||||||
|
<path
|
||||||
|
fill="#ffffff"
|
||||||
|
d="M38 12.83l-2.83-2.83-11.17 11.17-11.17-11.17-2.83 2.83 11.17 11.17-11.17 11.17 2.83 2.83 11.17-11.17 11.17 11.17 2.83-2.83-11.17-11.17z"
|
||||||
|
/>
|
||||||
|
<path fill="none" d="M0 0h48v48h-48z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
239
browser/src/scripts/components/Composer.tsx
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
import { KEYCODE_ENTER } from 'jslib/helpers/keyboard';
|
||||||
|
import initServices from '../utils/services';
|
||||||
|
import BookSelector from './BookSelector';
|
||||||
|
import Flash from './Flash';
|
||||||
|
import { useSelector, useDispatch } from '../store/hooks';
|
||||||
|
import { updateContent, resetComposer } from '../store/composer/actions';
|
||||||
|
import { fetchBooks } from '../store/books/actions';
|
||||||
|
import { navigate } from '../store/location/actions';
|
||||||
|
|
||||||
|
interface Props {}
|
||||||
|
|
||||||
|
// focusBookSelectorInput focuses on the input element of the book selector.
|
||||||
|
// It needs to traverse the tree returned by the ref API of the 'react-select' library,
|
||||||
|
// and to guard against possible breaking changes, if the path does not exist, it noops.
|
||||||
|
function focusBookSelectorInput(bookSelectorRef) {
|
||||||
|
return (
|
||||||
|
bookSelectorRef.select &&
|
||||||
|
bookSelectorRef.select.select &&
|
||||||
|
bookSelectorRef.select.select.inputRef &&
|
||||||
|
bookSelectorRef.select.select.inputRef.focus()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function useFetchData() {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const { books } = useSelector(state => ({
|
||||||
|
books: state.books
|
||||||
|
}));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!books.isFetched) {
|
||||||
|
dispatch(fetchBooks());
|
||||||
|
}
|
||||||
|
}, [dispatch, books.isFetched]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function useInitFocus(contentRef, bookSelectorRef) {
|
||||||
|
const { composer, books } = useSelector(state => ({
|
||||||
|
composer: state.composer,
|
||||||
|
books: state.books
|
||||||
|
}));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!books.isFetched) {
|
||||||
|
return () => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bookSelectorRef && contentRef) {
|
||||||
|
if (composer.bookLabel === '') {
|
||||||
|
focusBookSelectorInput(bookSelectorRef);
|
||||||
|
} else {
|
||||||
|
contentRef.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => null;
|
||||||
|
}, [contentRef, bookSelectorRef, books.isFetched, composer.bookLabel]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Composer: React.FunctionComponent<Props> = () => {
|
||||||
|
useFetchData();
|
||||||
|
const [contentFocused, setContentFocused] = useState(false);
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
|
const [errMsg, setErrMsg] = useState('');
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const [contentRef, setContentEl] = useState(null);
|
||||||
|
const [bookSelectorRef, setBookSelectorEl] = useState(null);
|
||||||
|
|
||||||
|
const { composer, settings, auth } = useSelector(state => ({
|
||||||
|
composer: state.composer,
|
||||||
|
settings: state.settings,
|
||||||
|
auth: state.auth
|
||||||
|
}));
|
||||||
|
|
||||||
|
const handleSubmit = useCallback(
|
||||||
|
async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const services = initServices(settings.apiUrl);
|
||||||
|
|
||||||
|
setSubmitting(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let bookUUID;
|
||||||
|
if (composer.bookUUID === '') {
|
||||||
|
const resp = await services.books.create(
|
||||||
|
{
|
||||||
|
name: composer.bookLabel
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${auth.sessionKey}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
bookUUID = resp.book.uuid;
|
||||||
|
} else {
|
||||||
|
bookUUID = composer.bookUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await services.notes.create(
|
||||||
|
{
|
||||||
|
book_uuid: bookUUID,
|
||||||
|
content: composer.content
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${auth.sessionKey}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// clear the composer state
|
||||||
|
setErrMsg('');
|
||||||
|
setSubmitting(false);
|
||||||
|
|
||||||
|
dispatch(resetComposer());
|
||||||
|
|
||||||
|
// navigate
|
||||||
|
dispatch(
|
||||||
|
navigate('/success', {
|
||||||
|
bookName: composer.bookLabel,
|
||||||
|
noteUUID: resp.result.uuid
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
setErrMsg(err.message);
|
||||||
|
setSubmitting(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
settings.apiUrl,
|
||||||
|
composer.bookUUID,
|
||||||
|
composer.content,
|
||||||
|
composer.bookLabel,
|
||||||
|
auth.sessionKey,
|
||||||
|
dispatch
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleSubmitShortcut = e => {
|
||||||
|
// Shift + Enter
|
||||||
|
if (e.shiftKey && e.keyCode === KEYCODE_ENTER) {
|
||||||
|
handleSubmit(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('keydown', handleSubmitShortcut);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', handleSubmitShortcut);
|
||||||
|
};
|
||||||
|
}, [composer, handleSubmit]);
|
||||||
|
|
||||||
|
let submitBtnText: string;
|
||||||
|
if (submitting) {
|
||||||
|
submitBtnText = 'Saving...';
|
||||||
|
} else {
|
||||||
|
submitBtnText = 'Save';
|
||||||
|
}
|
||||||
|
|
||||||
|
useInitFocus(contentRef, bookSelectorRef);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="composer">
|
||||||
|
<Flash kind="error" when={errMsg !== ''} message={errMsg} />
|
||||||
|
|
||||||
|
<form onSubmit={handleSubmit} className="form">
|
||||||
|
<BookSelector
|
||||||
|
selectorRef={setBookSelectorEl}
|
||||||
|
onAfterChange={() => {
|
||||||
|
contentRef.focus();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="content-container">
|
||||||
|
<textarea
|
||||||
|
className="content"
|
||||||
|
placeholder="What did you learn?"
|
||||||
|
onChange={e => {
|
||||||
|
const val = e.target.value;
|
||||||
|
|
||||||
|
dispatch(updateContent(val));
|
||||||
|
}}
|
||||||
|
value={composer.content}
|
||||||
|
ref={el => {
|
||||||
|
setContentEl(el);
|
||||||
|
}}
|
||||||
|
onFocus={() => {
|
||||||
|
setContentFocused(true);
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
setContentFocused(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={classnames('shortcut-hint', { shown: contentFocused })}
|
||||||
|
>
|
||||||
|
Shift + Enter to save
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="submit"
|
||||||
|
value={submitBtnText}
|
||||||
|
className="submit-button"
|
||||||
|
disabled={submitting}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Composer;
|
||||||
37
browser/src/scripts/components/Flash.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
type Kind = 'error' | 'info';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
message: string;
|
||||||
|
when: boolean;
|
||||||
|
kind: Kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Flash: React.FunctionComponent<Props> = ({ message, when, kind }) => {
|
||||||
|
if (when) {
|
||||||
|
return <div className={`alert alert-${kind}`}>{message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Flash;
|
||||||
54
browser/src/scripts/components/Header.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import Link from './Link';
|
||||||
|
import MenuToggleIcon from './MenuToggleIcon';
|
||||||
|
import CloseIcon from './CloseIcon';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
toggleMenu: () => void;
|
||||||
|
isShowingMenu: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Header: React.FunctionComponent<Props> = ({
|
||||||
|
toggleMenu,
|
||||||
|
isShowingMenu
|
||||||
|
}) => (
|
||||||
|
<header className="header">
|
||||||
|
<Link to="/" className="logo-link" tabIndex={-1}>
|
||||||
|
<img src="images/logo-circle.png" alt="dnote" className="logo" />
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="#toggle"
|
||||||
|
className="menu-toggle"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
toggleMenu();
|
||||||
|
}}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
{isShowingMenu ? <CloseIcon /> : <MenuToggleIcon />}
|
||||||
|
</a>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Header;
|
||||||
108
browser/src/scripts/components/Home.tsx
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
import { login } from '../store/auth/actions';
|
||||||
|
import { useDispatch } from '../store/hooks';
|
||||||
|
import Flash from '../components/Flash';
|
||||||
|
|
||||||
|
interface Props {}
|
||||||
|
|
||||||
|
const Home: React.FunctionComponent<Props> = () => {
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
const [password, setPassword] = useState('');
|
||||||
|
const [errMsg, setErrMsg] = useState('');
|
||||||
|
const [loggingIn, setLoggingIn] = useState(false);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const handleLogin = async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
setErrMsg('');
|
||||||
|
setLoggingIn(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await dispatch(login({ email, password }));
|
||||||
|
} catch (err) {
|
||||||
|
console.log('error while logging in', err);
|
||||||
|
|
||||||
|
setErrMsg(e.message);
|
||||||
|
setLoggingIn(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="home page">
|
||||||
|
<h1 className="heading">Welcome to Dnote</h1>
|
||||||
|
|
||||||
|
<p className="lead">A simple personal knowledge base</p>
|
||||||
|
|
||||||
|
<Flash kind="error" when={errMsg !== ''} message={errMsg} />
|
||||||
|
|
||||||
|
<form id="login-form" onSubmit={handleLogin}>
|
||||||
|
<label htmlFor="email-input">Email</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="your@email.com"
|
||||||
|
className="input login-input"
|
||||||
|
id="email-input"
|
||||||
|
value={email}
|
||||||
|
onChange={e => {
|
||||||
|
setEmail(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label htmlFor="password-input">Password</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
placeholder="●●●●●●●●"
|
||||||
|
className="input login-input"
|
||||||
|
id="password-input"
|
||||||
|
value={password}
|
||||||
|
onChange={e => {
|
||||||
|
setPassword(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="button button-first button-small login-btn"
|
||||||
|
disabled={loggingIn}
|
||||||
|
>
|
||||||
|
{loggingIn ? 'Signing in...' : 'Sign in'}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div className="actions">
|
||||||
|
Don't have an account?{' '}
|
||||||
|
<a
|
||||||
|
href="https://app.getdnote.com/join"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="signup"
|
||||||
|
>
|
||||||
|
Sign Up
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Home;
|
||||||
60
browser/src/scripts/components/Link.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable react/jsx-props-no-spreading */
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { useDispatch } from '../store/hooks';
|
||||||
|
import { navigate } from '../store/location/actions';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
to: string;
|
||||||
|
className: string;
|
||||||
|
tabIndex?: number;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link: React.FunctionComponent<Props> = ({
|
||||||
|
to,
|
||||||
|
children,
|
||||||
|
onClick,
|
||||||
|
...restProps
|
||||||
|
}) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={`${to}`}
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
dispatch(navigate(to));
|
||||||
|
|
||||||
|
if (onClick) {
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Link;
|
||||||
63
browser/src/scripts/components/Menu.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { Fragment } from 'react';
|
||||||
|
|
||||||
|
import Link from './Link';
|
||||||
|
|
||||||
|
export default ({ toggleMenu, loggedIn, onLogout }) => (
|
||||||
|
<Fragment>
|
||||||
|
<ul className="menu">
|
||||||
|
<li>
|
||||||
|
<Link to="/" onClick={toggleMenu} className="menu-link">
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link to="/settings" onClick={toggleMenu} className="menu-link">
|
||||||
|
Settings
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{loggedIn && (
|
||||||
|
<li>
|
||||||
|
<form
|
||||||
|
onSubmit={e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
onLogout(toggleMenu);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="submit"
|
||||||
|
value="Logout"
|
||||||
|
className="menu-link logout-button"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="menu-overlay"
|
||||||
|
onClick={toggleMenu}
|
||||||
|
onKeyDown={() => {}}
|
||||||
|
role="none"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
61
browser/src/scripts/components/MenuToggleIcon.tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<svg
|
||||||
|
enableBackground="new 0 0 24 24"
|
||||||
|
id="Layer_1"
|
||||||
|
version="1.0"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
>
|
||||||
|
<line
|
||||||
|
fill="none"
|
||||||
|
stroke="#ffffff"
|
||||||
|
strokeMiterlimit="10"
|
||||||
|
strokeWidth="2"
|
||||||
|
x1="2"
|
||||||
|
x2="22"
|
||||||
|
y1="12"
|
||||||
|
y2="12"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
fill="none"
|
||||||
|
stroke="#ffffff"
|
||||||
|
strokeMiterlimit="10"
|
||||||
|
strokeWidth="2"
|
||||||
|
x1="2"
|
||||||
|
x2="22"
|
||||||
|
y1="6"
|
||||||
|
y2="6"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
fill="none"
|
||||||
|
stroke="#ffffff"
|
||||||
|
strokeMiterlimit="10"
|
||||||
|
strokeWidth="2"
|
||||||
|
x1="2"
|
||||||
|
x2="22"
|
||||||
|
y1="18"
|
||||||
|
y2="18"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
156
browser/src/scripts/components/Settings.tsx
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
import Flash from './Flash';
|
||||||
|
import { updateSettings, resetSettings } from '../store/settings/actions';
|
||||||
|
import { useDispatch, useSelector, useStore } from '../store/hooks';
|
||||||
|
|
||||||
|
interface Props {}
|
||||||
|
|
||||||
|
// isValidURL checks if the given string is a valid URL
|
||||||
|
function isValidURL(url: string): boolean {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
return a.host && a.host !== window.location.host;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateFormState validates the given form state. If any input is
|
||||||
|
// invalid, it throws an error.
|
||||||
|
function validateFormState({ apiUrl, webUrl }) {
|
||||||
|
if (!isValidURL(apiUrl)) {
|
||||||
|
throw new Error('Invalid URL for the API URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isValidURL(webUrl)) {
|
||||||
|
throw new Error('Invalid URL for the web URL');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Settings: React.FunctionComponent<Props> = () => {
|
||||||
|
const { settings } = useSelector(state => ({
|
||||||
|
settings: state.settings
|
||||||
|
}));
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
|
const [apiUrl, setAPIUrl] = useState(settings.apiUrl);
|
||||||
|
const [webUrl, setWebUrl] = useState(settings.webUrl);
|
||||||
|
const [errMsg, setErrMsg] = useState('');
|
||||||
|
const [successMsg, setSuccessMsg] = useState('');
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
function handleRestore() {
|
||||||
|
dispatch(resetSettings());
|
||||||
|
setSuccessMsg('Restored the default settings');
|
||||||
|
|
||||||
|
const { settings: settingsState } = store.getState();
|
||||||
|
|
||||||
|
setAPIUrl(settingsState.apiUrl);
|
||||||
|
setWebUrl(settingsState.webUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
setSuccessMsg('');
|
||||||
|
setErrMsg('');
|
||||||
|
|
||||||
|
try {
|
||||||
|
validateFormState({ apiUrl, webUrl });
|
||||||
|
} catch (err) {
|
||||||
|
setErrMsg(err.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(
|
||||||
|
updateSettings({
|
||||||
|
apiUrl,
|
||||||
|
webUrl
|
||||||
|
})
|
||||||
|
);
|
||||||
|
setSuccessMsg('Succesfully updated the settings.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Flash kind="error" when={errMsg !== ''} message={errMsg} />
|
||||||
|
<Flash kind="info" when={successMsg !== ''} message={successMsg} />
|
||||||
|
|
||||||
|
<div className="settings page">
|
||||||
|
<h1 className="heading">Settings</h1>
|
||||||
|
|
||||||
|
<p className="lead">Customize your Dnote extension</p>
|
||||||
|
|
||||||
|
<form id="settings-form" onSubmit={handleSubmit}>
|
||||||
|
<div className="input-row">
|
||||||
|
<label htmlFor="api-url-input" className="label">
|
||||||
|
API URL
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="api-url"
|
||||||
|
placeholder="https://api.getdnote.com"
|
||||||
|
className="input"
|
||||||
|
id="api-url-input"
|
||||||
|
value={apiUrl}
|
||||||
|
onChange={e => {
|
||||||
|
setAPIUrl(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="input-row">
|
||||||
|
<label htmlFor="web-url-input" className="label">
|
||||||
|
Web URL
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="web-url"
|
||||||
|
placeholder="https://app.getdnote.com"
|
||||||
|
className="input"
|
||||||
|
id="web-url-input"
|
||||||
|
value={webUrl}
|
||||||
|
onChange={e => {
|
||||||
|
setWebUrl(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="actions">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="button button-first button-small button-stretch"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleRestore}
|
||||||
|
className="restore button-no-ui"
|
||||||
|
>
|
||||||
|
Restore default
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Settings;
|
||||||
105
browser/src/scripts/components/Success.tsx
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useEffect, useState, Fragment } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
KEYCODE_ENTER,
|
||||||
|
KEYCODE_ESC,
|
||||||
|
KEYCODE_LOWERCASE_B
|
||||||
|
} from 'jslib/helpers/keyboard';
|
||||||
|
import Flash from './Flash';
|
||||||
|
import ext from '../utils/ext';
|
||||||
|
import BookIcon from './BookIcon';
|
||||||
|
import { navigate } from '../store/location/actions';
|
||||||
|
import { useSelector, useDispatch } from '../store/hooks';
|
||||||
|
|
||||||
|
const Success: React.FunctionComponent = () => {
|
||||||
|
const [errorMsg, setErrorMsg] = useState('');
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { location, settings } = useSelector(state => ({
|
||||||
|
location: state.location,
|
||||||
|
settings: state.settings
|
||||||
|
}));
|
||||||
|
|
||||||
|
const { bookName, noteUUID } = location.state;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeydown = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (e.keyCode === KEYCODE_ENTER) {
|
||||||
|
dispatch(navigate('/'));
|
||||||
|
} else if (e.keyCode === KEYCODE_ESC) {
|
||||||
|
window.close();
|
||||||
|
} else if (e.keyCode === KEYCODE_LOWERCASE_B) {
|
||||||
|
const url = `${settings.webUrl}/notes/${noteUUID}`;
|
||||||
|
|
||||||
|
ext.tabs
|
||||||
|
.create({ url })
|
||||||
|
.then(() => {
|
||||||
|
window.close();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
setErrorMsg(err.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('keydown', handleKeydown);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', handleKeydown);
|
||||||
|
};
|
||||||
|
}, [dispatch, noteUUID, settings.webUrl]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Flash kind="error" when={errorMsg !== ''} message={errorMsg} />
|
||||||
|
|
||||||
|
<div className="success-page">
|
||||||
|
<div>
|
||||||
|
<BookIcon width={20} height={20} className="book-icon" />
|
||||||
|
|
||||||
|
<h1 className="heading">
|
||||||
|
Saved to
|
||||||
|
{bookName}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul className="key-list">
|
||||||
|
<li className="key-item">
|
||||||
|
<kbd className="key">Enter</kbd>{' '}
|
||||||
|
<div className="key-desc">Go back</div>
|
||||||
|
</li>
|
||||||
|
<li className="key-item">
|
||||||
|
<kbd className="key">b</kbd>{' '}
|
||||||
|
<div className="key-desc">Open in browser</div>
|
||||||
|
</li>
|
||||||
|
<li className="key-item">
|
||||||
|
<kbd className="key">ESC</kbd>
|
||||||
|
<div className="key-desc">Close</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Success;
|
||||||
65
browser/src/scripts/popup.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
|
import { debounce } from 'jslib/helpers/perf';
|
||||||
|
import configureStore from './store';
|
||||||
|
import { loadState, saveState } from './utils/storage';
|
||||||
|
import App from './components/App';
|
||||||
|
import ext from './utils/ext';
|
||||||
|
|
||||||
|
const appContainer = document.getElementById('app');
|
||||||
|
|
||||||
|
loadState(items => {
|
||||||
|
if (ext.runtime.lastError) {
|
||||||
|
appContainer.innerText = `Failed to retrieve previous app state ${ext.runtime.lastError.message}`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let initialState;
|
||||||
|
const prevState = items.state;
|
||||||
|
if (prevState) {
|
||||||
|
// rehydrate
|
||||||
|
initialState = prevState;
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = configureStore(initialState);
|
||||||
|
|
||||||
|
store.subscribe(
|
||||||
|
debounce(() => {
|
||||||
|
const state = store.getState();
|
||||||
|
|
||||||
|
saveState(state);
|
||||||
|
}, 100)
|
||||||
|
);
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<App />
|
||||||
|
</Provider>,
|
||||||
|
appContainer,
|
||||||
|
() => {
|
||||||
|
// On Chrome, popup window size is kept at minimum if app render is delayed
|
||||||
|
// Therefore add minimum dimension to body until app is rendered
|
||||||
|
document.getElementsByTagName('body')[0].className = '';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
46
browser/src/scripts/store/auth/actions.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { LOGIN, LOGOUT, LogoutAction } from './types';
|
||||||
|
import { ThunkAction } from '../types';
|
||||||
|
import initServices from '../../utils/services';
|
||||||
|
|
||||||
|
export function login({ email, password }): ThunkAction<void> {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const { settings } = getState();
|
||||||
|
const { apiUrl } = settings;
|
||||||
|
|
||||||
|
return initServices(apiUrl)
|
||||||
|
.users.signin({ email, password })
|
||||||
|
.then(resp => {
|
||||||
|
dispatch({
|
||||||
|
type: LOGIN,
|
||||||
|
data: {
|
||||||
|
sessionKey: resp.key,
|
||||||
|
sessionKeyExpiry: resp.expiresAt
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logout(): LogoutAction {
|
||||||
|
return {
|
||||||
|
type: LOGOUT
|
||||||
|
};
|
||||||
|
}
|
||||||
45
browser/src/scripts/store/auth/reducers.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { LOGIN, LOGOUT, AuthState, AuthActionType } from './types';
|
||||||
|
|
||||||
|
const initialState: AuthState = {
|
||||||
|
sessionKey: '',
|
||||||
|
sessionKeyExpiry: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (
|
||||||
|
state = initialState,
|
||||||
|
action: AuthActionType
|
||||||
|
): AuthState {
|
||||||
|
switch (action.type) {
|
||||||
|
case LOGIN: {
|
||||||
|
const { sessionKey, sessionKeyExpiry } = action.data;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
sessionKey,
|
||||||
|
sessionKeyExpiry
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case LOGOUT:
|
||||||
|
return initialState;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
browser/src/scripts/store/auth/types.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface AuthState {
|
||||||
|
sessionKey: string;
|
||||||
|
sessionKeyExpiry: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LOGIN = 'auth/LOGIN';
|
||||||
|
export const LOGOUT = 'auth/LOGOUT';
|
||||||
|
|
||||||
|
export interface LoginAction {
|
||||||
|
type: typeof LOGIN;
|
||||||
|
data: {
|
||||||
|
sessionKey: string;
|
||||||
|
sessionKeyExpiry: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LogoutAction {
|
||||||
|
type: typeof LOGOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AuthActionType = LogoutAction | LoginAction;
|
||||||
78
browser/src/scripts/store/books/actions.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import initServices from '../../utils/services';
|
||||||
|
|
||||||
|
import {
|
||||||
|
START_FETCHING,
|
||||||
|
RECEIVE,
|
||||||
|
RECEIVE_ERROR,
|
||||||
|
StartFetchingAction,
|
||||||
|
ReceiveAction,
|
||||||
|
ReceiveErrorAction
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
function startFetchingBooks(): StartFetchingAction {
|
||||||
|
return {
|
||||||
|
type: START_FETCHING
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function receiveBooks(books): ReceiveAction {
|
||||||
|
return {
|
||||||
|
type: RECEIVE,
|
||||||
|
data: {
|
||||||
|
books
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function receiveBooksError(error: string): ReceiveErrorAction {
|
||||||
|
return {
|
||||||
|
type: RECEIVE_ERROR,
|
||||||
|
data: {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchBooks() {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
dispatch(startFetchingBooks());
|
||||||
|
|
||||||
|
const { settings, auth } = getState();
|
||||||
|
const services = initServices(settings.apiUrl);
|
||||||
|
|
||||||
|
services.books
|
||||||
|
.fetch(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${auth.sessionKey}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(books => {
|
||||||
|
dispatch(receiveBooks(books));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('error fetching books', err);
|
||||||
|
dispatch(receiveBooksError(err));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
66
browser/src/scripts/store/books/reducers.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
START_FETCHING,
|
||||||
|
RECEIVE,
|
||||||
|
RECEIVE_ERROR,
|
||||||
|
BooksState,
|
||||||
|
BooksActionType
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
items: [],
|
||||||
|
isFetching: false,
|
||||||
|
isFetched: false,
|
||||||
|
error: null
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (
|
||||||
|
state = initialState,
|
||||||
|
action: BooksActionType
|
||||||
|
): BooksState {
|
||||||
|
switch (action.type) {
|
||||||
|
case START_FETCHING:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isFetching: true,
|
||||||
|
isFetched: false
|
||||||
|
};
|
||||||
|
case RECEIVE: {
|
||||||
|
const { books } = action.data;
|
||||||
|
|
||||||
|
// get uuids of deleted books and that of a currently selected book
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isFetching: false,
|
||||||
|
isFetched: true,
|
||||||
|
items: [...state.items, ...books]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case RECEIVE_ERROR:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isFetching: false,
|
||||||
|
isFetched: true,
|
||||||
|
error: action.data.error
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
53
browser/src/scripts/store/books/types.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type BookData = any;
|
||||||
|
|
||||||
|
export interface BooksState {
|
||||||
|
items: BookData[];
|
||||||
|
isFetching: boolean;
|
||||||
|
isFetched: boolean;
|
||||||
|
error: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const START_FETCHING = 'books/START_FETCHING';
|
||||||
|
export const RECEIVE = 'books/RECEIVE';
|
||||||
|
export const RECEIVE_ERROR = 'books/RECEIVE_ERROR';
|
||||||
|
|
||||||
|
export interface StartFetchingAction {
|
||||||
|
type: typeof START_FETCHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReceiveAction {
|
||||||
|
type: typeof RECEIVE;
|
||||||
|
data: {
|
||||||
|
books: BookData[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReceiveErrorAction {
|
||||||
|
type: typeof RECEIVE_ERROR;
|
||||||
|
data: {
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BooksActionType =
|
||||||
|
| StartFetchingAction
|
||||||
|
| ReceiveAction
|
||||||
|
| ReceiveErrorAction;
|
||||||
65
browser/src/scripts/store/composer/actions.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
UPDATE_CONTENT,
|
||||||
|
UPDATE_BOOK,
|
||||||
|
RESET,
|
||||||
|
RESET_BOOK,
|
||||||
|
UpdateContentAction,
|
||||||
|
UpdateBookAction,
|
||||||
|
ResetBookAction,
|
||||||
|
ResetAction
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
export function updateContent(content: string): UpdateContentAction {
|
||||||
|
return {
|
||||||
|
type: UPDATE_CONTENT,
|
||||||
|
data: { content }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateBookActionParam {
|
||||||
|
uuid: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateBook({
|
||||||
|
uuid,
|
||||||
|
label
|
||||||
|
}: UpdateBookActionParam): UpdateBookAction {
|
||||||
|
return {
|
||||||
|
type: UPDATE_BOOK,
|
||||||
|
data: {
|
||||||
|
uuid,
|
||||||
|
label
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetBook(): ResetBookAction {
|
||||||
|
return {
|
||||||
|
type: RESET_BOOK
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetComposer(): ResetAction {
|
||||||
|
return {
|
||||||
|
type: RESET
|
||||||
|
};
|
||||||
|
}
|
||||||
65
browser/src/scripts/store/composer/reducers.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
UPDATE_CONTENT,
|
||||||
|
UPDATE_BOOK,
|
||||||
|
RESET,
|
||||||
|
RESET_BOOK,
|
||||||
|
ComposerActionType,
|
||||||
|
ComposerState
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
const initialState: ComposerState = {
|
||||||
|
content: '',
|
||||||
|
bookUUID: '',
|
||||||
|
bookLabel: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (
|
||||||
|
state = initialState,
|
||||||
|
action: ComposerActionType
|
||||||
|
): ComposerState {
|
||||||
|
switch (action.type) {
|
||||||
|
case UPDATE_CONTENT: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
content: action.data.content
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case UPDATE_BOOK: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
bookUUID: action.data.uuid,
|
||||||
|
bookLabel: action.data.label
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case RESET_BOOK: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
bookUUID: '',
|
||||||
|
bookLabel: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case RESET: {
|
||||||
|
return initialState;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
57
browser/src/scripts/store/composer/types.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface ComposerState {
|
||||||
|
content: string;
|
||||||
|
bookUUID: string;
|
||||||
|
bookLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const UPDATE_CONTENT = 'composer/UPDATE_CONTENT';
|
||||||
|
export const UPDATE_BOOK = 'composer/UPDATE_BOOK';
|
||||||
|
export const RESET = 'composer/RESET';
|
||||||
|
export const RESET_BOOK = 'composer/RESET_BOOK';
|
||||||
|
|
||||||
|
export interface UpdateContentAction {
|
||||||
|
type: typeof UPDATE_CONTENT;
|
||||||
|
data: {
|
||||||
|
content: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateBookAction {
|
||||||
|
type: typeof UPDATE_BOOK;
|
||||||
|
data: {
|
||||||
|
uuid: string;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResetAction {
|
||||||
|
type: typeof RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResetBookAction {
|
||||||
|
type: typeof RESET_BOOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ComposerActionType =
|
||||||
|
| UpdateContentAction
|
||||||
|
| UpdateBookAction
|
||||||
|
| ResetAction
|
||||||
|
| ResetBookAction;
|
||||||
43
browser/src/scripts/store/hooks.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Store, Action } from 'redux';
|
||||||
|
import {
|
||||||
|
useDispatch as useReduxDispatch,
|
||||||
|
useStore as useReduxStore,
|
||||||
|
useSelector as useReduxSelector
|
||||||
|
} from 'react-redux';
|
||||||
|
import { ThunkDispatch } from 'redux-thunk';
|
||||||
|
|
||||||
|
import { AppState } from './types';
|
||||||
|
|
||||||
|
type ReduxDispatch = ThunkDispatch<AppState, any, Action>;
|
||||||
|
|
||||||
|
export function useDispatch(): ReduxDispatch {
|
||||||
|
return useReduxDispatch<ReduxDispatch>();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useStore(): Store<AppState> {
|
||||||
|
return useReduxStore<AppState>();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSelector<TSelected>(
|
||||||
|
selector: (state: AppState) => TSelected
|
||||||
|
) {
|
||||||
|
return useReduxSelector<AppState, TSelected>(selector);
|
||||||
|
}
|
||||||
70
browser/src/scripts/store/index.ts
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { combineReducers, createStore, applyMiddleware, compose } from 'redux';
|
||||||
|
import thunkMiddleware from 'redux-thunk';
|
||||||
|
import createLogger from 'redux-logger';
|
||||||
|
|
||||||
|
import location from './location/reducers';
|
||||||
|
import settings from './settings/reducers';
|
||||||
|
import books from './books/reducers';
|
||||||
|
import composer from './composer/reducers';
|
||||||
|
import auth from './auth/reducers';
|
||||||
|
import { AppState } from './types';
|
||||||
|
import config from '../utils/config';
|
||||||
|
|
||||||
|
const rootReducer = combineReducers({
|
||||||
|
auth,
|
||||||
|
location,
|
||||||
|
settings,
|
||||||
|
books,
|
||||||
|
composer
|
||||||
|
});
|
||||||
|
|
||||||
|
// initState returns a new state with any missing values populated
|
||||||
|
// if a state is given.
|
||||||
|
function initState(s: AppState | undefined): AppState {
|
||||||
|
if (s === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { settings: settingsState } = s;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...s,
|
||||||
|
settings: {
|
||||||
|
...settingsState,
|
||||||
|
apiUrl: settingsState.apiUrl || config.defaultApiEndpoint,
|
||||||
|
webUrl: settingsState.webUrl || config.defaultWebUrl
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// configureStore returns a new store that contains the appliation state
|
||||||
|
export default function configureStore(state: AppState | undefined) {
|
||||||
|
const typedWindow = window as any;
|
||||||
|
|
||||||
|
const composeEnhancers =
|
||||||
|
typedWindow.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||||
|
|
||||||
|
return createStore(
|
||||||
|
rootReducer,
|
||||||
|
initState(state),
|
||||||
|
composeEnhancers(applyMiddleware(createLogger, thunkMiddleware))
|
||||||
|
);
|
||||||
|
}
|
||||||
26
browser/src/scripts/store/location/actions.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NAVIGATE, NavigateAction } from './types';
|
||||||
|
|
||||||
|
export function navigate(path: string, state?): NavigateAction {
|
||||||
|
return {
|
||||||
|
type: NAVIGATE,
|
||||||
|
data: { path, state }
|
||||||
|
};
|
||||||
|
}
|
||||||
40
browser/src/scripts/store/location/reducers.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NAVIGATE, LocationState, LocationActionType } from './types';
|
||||||
|
|
||||||
|
const initialState: LocationState = {
|
||||||
|
path: '/',
|
||||||
|
state: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (
|
||||||
|
state = initialState,
|
||||||
|
action: LocationActionType
|
||||||
|
): LocationState {
|
||||||
|
switch (action.type) {
|
||||||
|
case NAVIGATE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
path: action.data.path,
|
||||||
|
state: action.data.state || {}
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
browser/src/scripts/store/location/types.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface LocationState {
|
||||||
|
path: string;
|
||||||
|
state: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NAVIGATE = 'location/NAVIGATE';
|
||||||
|
|
||||||
|
export interface NavigateAction {
|
||||||
|
type: typeof NAVIGATE;
|
||||||
|
data: {
|
||||||
|
path: string;
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LocationActionType = NavigateAction;
|
||||||
32
browser/src/scripts/store/settings/actions.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { UPDATE, RESET, UpdateAction, ResetAction } from './types';
|
||||||
|
|
||||||
|
export function updateSettings(settings): UpdateAction {
|
||||||
|
return {
|
||||||
|
type: UPDATE,
|
||||||
|
data: { settings }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetSettings(): ResetAction {
|
||||||
|
return {
|
||||||
|
type: RESET
|
||||||
|
};
|
||||||
|
}
|
||||||
42
browser/src/scripts/store/settings/reducers.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { UPDATE, RESET, SettingsState, SettingsActionType } from './types';
|
||||||
|
import config from '../../utils/config';
|
||||||
|
|
||||||
|
const initialState: SettingsState = {
|
||||||
|
apiUrl: config.defaultApiEndpoint,
|
||||||
|
webUrl: config.defaultWebUrl
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (
|
||||||
|
state = initialState,
|
||||||
|
action: SettingsActionType
|
||||||
|
): SettingsState {
|
||||||
|
switch (action.type) {
|
||||||
|
case UPDATE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...action.data.settings
|
||||||
|
};
|
||||||
|
case RESET:
|
||||||
|
return initialState;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
browser/src/scripts/store/settings/types.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface SettingsState {
|
||||||
|
apiUrl: string;
|
||||||
|
webUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const UPDATE = 'settings/UPDATE';
|
||||||
|
export const RESET = 'settings/RESET';
|
||||||
|
|
||||||
|
export interface UpdateAction {
|
||||||
|
type: typeof UPDATE;
|
||||||
|
data: {
|
||||||
|
settings: Partial<SettingsState>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResetAction {
|
||||||
|
type: typeof RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SettingsActionType = UpdateAction | ResetAction;
|
||||||
43
browser/src/scripts/store/types.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { ThunkAction as ReduxThunkAction } from 'redux-thunk';
|
||||||
|
|
||||||
|
import { AuthState } from './auth/types';
|
||||||
|
import { ComposerState } from './composer/types';
|
||||||
|
import { LocationState } from './location/types';
|
||||||
|
import { SettingsState } from './settings/types';
|
||||||
|
import { BooksState } from './books/types';
|
||||||
|
|
||||||
|
// AppState represents the application state
|
||||||
|
export interface AppState {
|
||||||
|
auth: AuthState;
|
||||||
|
composer: ComposerState;
|
||||||
|
location: LocationState;
|
||||||
|
settings: SettingsState;
|
||||||
|
books: BooksState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ThunkAction is a thunk action type
|
||||||
|
export type ThunkAction<T = void> = ReduxThunkAction<
|
||||||
|
Promise<T>,
|
||||||
|
AppState,
|
||||||
|
void,
|
||||||
|
Action
|
||||||
|
>;
|
||||||
23
browser/src/scripts/utils/config.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
defaultWebUrl: __WEB_URL__,
|
||||||
|
defaultApiEndpoint: __API_ENDPOINT__,
|
||||||
|
version: __VERSION__
|
||||||
|
};
|
||||||
55
browser/src/scripts/utils/ext.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// module ext provides a cross-browser interface to access extension APIs
|
||||||
|
// by using WebExtensions API if available, and using Chrome as a fallback.
|
||||||
|
const ext: any = {};
|
||||||
|
|
||||||
|
const apis = ['tabs', 'storage', 'runtime'];
|
||||||
|
|
||||||
|
for (let i = 0; i < apis.length; i++) {
|
||||||
|
const api = apis[i];
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (browser[api]) {
|
||||||
|
ext[api] = browser[api];
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (chrome[api] && !ext[api]) {
|
||||||
|
ext[api] = chrome[api];
|
||||||
|
|
||||||
|
// Standardize the signature to conform to WebExtensions API
|
||||||
|
if (api === 'tabs') {
|
||||||
|
const fn = ext[api].create;
|
||||||
|
|
||||||
|
// Promisify chrome.tabs.create
|
||||||
|
ext[api].create = obj => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
fn(obj, tab => {
|
||||||
|
resolve(tab);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ext;
|
||||||
64
browser/src/scripts/utils/fetch.js
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import qs from 'qs';
|
||||||
|
|
||||||
|
function checkStatus(response) {
|
||||||
|
if (response.status >= 200 && response.status < 300) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
return response.text().then(body => {
|
||||||
|
const error = new Error(body);
|
||||||
|
error.response = response;
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseJSON(response) {
|
||||||
|
if (response.headers.get('Content-Type') === 'application/json') {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
function request(url, options) {
|
||||||
|
return fetch(url, options).then(checkStatus).then(parseJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function post(url, data, options = {}) {
|
||||||
|
return request(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(url, options = {}) {
|
||||||
|
let endpoint = url;
|
||||||
|
|
||||||
|
if (options.params) {
|
||||||
|
endpoint = `${endpoint}?${qs.stringify(options.params)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return request(endpoint, {
|
||||||
|
method: 'GET',
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
27
browser/src/scripts/utils/services.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import init from 'jslib/services';
|
||||||
|
|
||||||
|
const initServices = (baseUrl: string) =>
|
||||||
|
init({
|
||||||
|
baseUrl,
|
||||||
|
pathPrefix: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
export default initServices;
|
||||||
63
browser/src/scripts/utils/storage.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ext from './ext';
|
||||||
|
|
||||||
|
const stateKey = 'state';
|
||||||
|
|
||||||
|
// filterState filters the given state to be suitable for reuse upon next app
|
||||||
|
// load
|
||||||
|
function filterState(state) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
location: {
|
||||||
|
...state.location,
|
||||||
|
path: '/'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseStorageItem(item) {
|
||||||
|
if (!item) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// saveState writes the given state to storage
|
||||||
|
export function saveState(state) {
|
||||||
|
const filtered = filterState(state);
|
||||||
|
const serialized = JSON.stringify(filtered);
|
||||||
|
|
||||||
|
ext.storage.local.set({ [stateKey]: serialized }, () => {
|
||||||
|
console.log('synced state');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadState loads and parses serialized state stored in ext.storage
|
||||||
|
export function loadState(done) {
|
||||||
|
ext.storage.local.get('state', items => {
|
||||||
|
const parsed = {
|
||||||
|
...items,
|
||||||
|
state: parseStorageItem(items.state)
|
||||||
|
};
|
||||||
|
|
||||||
|
return done(parsed);
|
||||||
|
});
|
||||||
|
}
|
||||||
431
browser/src/styles/popup.css
Normal file
|
|
@ -0,0 +1,431 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* container width: 345px */
|
||||||
|
|
||||||
|
/* global */
|
||||||
|
html {
|
||||||
|
font-size: 62.5%;
|
||||||
|
/* 1.0 rem = 10px */
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
body.pending {
|
||||||
|
height: 257px;
|
||||||
|
width: 345px;
|
||||||
|
}
|
||||||
|
main.blur {
|
||||||
|
opacity: 0.15;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 345px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: .375rem .75rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #495057;
|
||||||
|
background-color: #fff;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: .25rem;
|
||||||
|
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.login-input {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.message {
|
||||||
|
color: #2cae2c;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
padding: 10px 9px;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
.alert-info {
|
||||||
|
color: #0c5460;
|
||||||
|
background-color: #bee5eb;
|
||||||
|
border-color: #f5c6cb;
|
||||||
|
}
|
||||||
|
.alert-error {
|
||||||
|
color: #721c24;
|
||||||
|
background-color: #f8d7da;
|
||||||
|
border-color: #f5c6cb;
|
||||||
|
}
|
||||||
|
kbd {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 3px 5px;
|
||||||
|
font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||||
|
line-height: 10px;
|
||||||
|
color: #444d56;
|
||||||
|
vertical-align: middle;
|
||||||
|
background-color: #fafbfc;
|
||||||
|
border: solid 1px #d1d5da;
|
||||||
|
border-bottom-color: #c6cbd1;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: inset 0 -1px 0 #c6cbd1;
|
||||||
|
}
|
||||||
|
.menu {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: white;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
z-index: 1;
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
box-shadow: 0px 3px 2px 0px #cacaca;
|
||||||
|
}
|
||||||
|
.menu .logout-button {
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.menu-link {
|
||||||
|
display: block;
|
||||||
|
padding: 10px 13px;
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
/* override chrome default */
|
||||||
|
font: inherit !important;
|
||||||
|
}
|
||||||
|
.menu-link:hover {
|
||||||
|
background: #f7f7f7;
|
||||||
|
}
|
||||||
|
.menu-link:not(:hover) {
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
.menu-overlay {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
top: 44px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
opacity: 0.8;
|
||||||
|
background: #f7f7f7;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background-color: #272a35;
|
||||||
|
height: 44px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.header .logo {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
.header .logo-link {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
.header .menu-toggle {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
font-size: 2.2rem;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.lead {
|
||||||
|
color: #575757;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.page {
|
||||||
|
padding: 16px 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* home */
|
||||||
|
.home {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.home #login-form {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.home #login-form label {
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.home .login-btn {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.home .actions {
|
||||||
|
margin-top: 18px;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
.home .actions a {
|
||||||
|
color: gray;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.home .actions .signup:visited {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* settings */
|
||||||
|
.settings #settings-form {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.settings .input-row ~ .input-row {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.settings .label {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.settings .actions {
|
||||||
|
margin-top: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.settings .restore {
|
||||||
|
margin-top: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
color: gray;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* composer */
|
||||||
|
.composer .form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.composer .content-container {
|
||||||
|
position: relative;
|
||||||
|
height: 148px;
|
||||||
|
}
|
||||||
|
.composer .content {
|
||||||
|
border: none;
|
||||||
|
resize: none;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 11px 11px 18px 11px;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #e2e2e2;
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
.composer .content::placeholder {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
.composer .content:focus {
|
||||||
|
box-shadow: inset 0px 0px 3px #c0c0c0;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.composer .shortcut-hint {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 3px;
|
||||||
|
right: 7px;
|
||||||
|
color: gray;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.composer .shortcut-hint:not(.shown) {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.composer .submit-button {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #272a35;
|
||||||
|
border-radius: 0;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
user-select: none;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 11px 18px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 6px 0;
|
||||||
|
border-radius: 0;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.composer .submit-button:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #323642;
|
||||||
|
box-shadow: 0px 0px 4px 2px #cacaca;
|
||||||
|
}
|
||||||
|
.composer .book-value {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.composer .book-value .book-icon {
|
||||||
|
margin-right: 9px;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
.composer .book-option {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
padding: 5px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
.success-page {
|
||||||
|
text-align: center;
|
||||||
|
padding: 21px 0;
|
||||||
|
}
|
||||||
|
.success-page .key-list {
|
||||||
|
display: inline-block;
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.success-page .key-item {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.success-page .key-item:not(:first-child) {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.success-page .key-desc {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
margin-left: 9px;
|
||||||
|
}
|
||||||
|
.success-page .book-icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.success-page .heading {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 2.2rem;
|
||||||
|
margin-left: 13px;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buttons */
|
||||||
|
.button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
user-select: none;
|
||||||
|
border-width: 2px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: transparent;
|
||||||
|
border-image: initial;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 11px 18px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:icon {
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-first {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #333745;
|
||||||
|
}
|
||||||
|
.button-first:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #252833;
|
||||||
|
box-shadow: 0px 0px 4px 2px #cacaca;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-first-outline {
|
||||||
|
background: transparent;
|
||||||
|
border-color: #333745;
|
||||||
|
color: #333744;
|
||||||
|
}
|
||||||
|
.button-first-outline:hover {
|
||||||
|
color: #333744;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-second {
|
||||||
|
background: white;
|
||||||
|
color: #343a40;
|
||||||
|
}
|
||||||
|
.button-second:hover {
|
||||||
|
color: #343a40;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-third {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #4577cc;
|
||||||
|
}
|
||||||
|
.button-third:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #245fc5;
|
||||||
|
box-shadow: 0px 0px 4px 2px #cacaca;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-outline {
|
||||||
|
color: #0366d6;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 2px solid #0366d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button ~ .button {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-small {
|
||||||
|
padding: 5px 14px;
|
||||||
|
}
|
||||||
|
.button-stretch {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.button-no-ui {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
453
browser/src/styles/select.css
Normal file
|
|
@ -0,0 +1,453 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Select
|
||||||
|
* ============
|
||||||
|
* Created by Jed Watson and Joss Mackison for KeystoneJS, http://www.keystonejs.com/
|
||||||
|
* https://twitter.com/jedwatson https://twitter.com/jossmackison https://twitter.com/keystonejs
|
||||||
|
* MIT License: https://github.com/JedWatson/react-select
|
||||||
|
*/
|
||||||
|
.Select {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.Select input::-webkit-contacts-auto-fill-button,
|
||||||
|
.Select input::-webkit-credentials-auto-fill-button {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.Select input::-ms-clear {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.Select input::-ms-reveal {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.Select,
|
||||||
|
.Select div,
|
||||||
|
.Select input,
|
||||||
|
.Select span {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.Select.is-disabled .Select-arrow-zone {
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.35;
|
||||||
|
}
|
||||||
|
.Select.is-disabled > .Select-control {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
.Select.is-disabled > .Select-control:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.Select.is-open > .Select-control {
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
background: #fff;
|
||||||
|
border-color: #b3b3b3 #ccc #d9d9d9;
|
||||||
|
}
|
||||||
|
.Select.is-open > .Select-control .Select-arrow {
|
||||||
|
top: -2px;
|
||||||
|
border-color: transparent transparent #999;
|
||||||
|
border-width: 0 5px 5px;
|
||||||
|
}
|
||||||
|
.Select.is-searchable.is-open > .Select-control {
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
.Select.is-searchable.is-focused:not(.is-open) > .Select-control {
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
.Select.is-focused > .Select-control {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.Select.is-focused:not(.is-open) > .Select-control {
|
||||||
|
border-color: #007eff;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
|
||||||
|
0 0 0 3px rgba(0, 126, 255, 0.1);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.Select.has-value.is-clearable.Select--single > .Select-control .Select-value {
|
||||||
|
padding-right: 42px;
|
||||||
|
}
|
||||||
|
.Select.has-value.Select--single
|
||||||
|
> .Select-control .Select-value .Select-value-label,
|
||||||
|
.Select.has-value.is-pseudo-focused.Select--single
|
||||||
|
> .Select-control .Select-value .Select-value-label {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.Select.has-value.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label,
|
||||||
|
.Select.has-value.is-pseudo-focused.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label {
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.Select.has-value.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label:hover,
|
||||||
|
.Select.has-value.is-pseudo-focused.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label:hover,
|
||||||
|
.Select.has-value.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label:focus,
|
||||||
|
.Select.has-value.is-pseudo-focused.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label:focus {
|
||||||
|
color: #007eff;
|
||||||
|
outline: none;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.Select.has-value.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label:focus,
|
||||||
|
.Select.has-value.is-pseudo-focused.Select--single
|
||||||
|
> .Select-control .Select-value a.Select-value-label:focus {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.Select.has-value.is-pseudo-focused .Select-input {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.Select.is-open .Select-arrow,
|
||||||
|
.Select .Select-arrow-zone:hover > .Select-arrow {
|
||||||
|
border-top-color: #666;
|
||||||
|
}
|
||||||
|
.Select.Select--rtl {
|
||||||
|
direction: rtl;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.Select-control {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
cursor: default;
|
||||||
|
display: table;
|
||||||
|
border: 1px solid #e2e2e2;
|
||||||
|
border-top: 0;
|
||||||
|
height: 36px;
|
||||||
|
outline: none;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.Select-control:hover {
|
||||||
|
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.Select-control .Select-input:focus {
|
||||||
|
outline: none;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.Select-placeholder,
|
||||||
|
.Select--single > .Select-control .Select-value {
|
||||||
|
bottom: 0;
|
||||||
|
color: #aaa;
|
||||||
|
left: 0;
|
||||||
|
line-height: 34px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.Select-input {
|
||||||
|
height: 34px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.Select-input > input {
|
||||||
|
width: 100%;
|
||||||
|
background: none transparent;
|
||||||
|
border: 0 none;
|
||||||
|
box-shadow: none;
|
||||||
|
cursor: default;
|
||||||
|
display: inline-block;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
margin: 0;
|
||||||
|
outline: none;
|
||||||
|
line-height: 17px;
|
||||||
|
/* For IE 8 compatibility */
|
||||||
|
padding: 8px 0 12px;
|
||||||
|
/* For IE 8 compatibility */
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
.is-focused .Select-input > input {
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
.has-value.is-pseudo-focused .Select-input {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.Select-control:not(.is-searchable) > .Select-input {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.Select-loading-zone {
|
||||||
|
cursor: pointer;
|
||||||
|
display: table-cell;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
.Select-loading {
|
||||||
|
-webkit-animation: Select-animation-spin 400ms infinite linear;
|
||||||
|
-o-animation: Select-animation-spin 400ms infinite linear;
|
||||||
|
animation: Select-animation-spin 400ms infinite linear;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-right-color: #333;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.Select-clear-zone {
|
||||||
|
-webkit-animation: Select-animation-fadeIn 200ms;
|
||||||
|
-o-animation: Select-animation-fadeIn 200ms;
|
||||||
|
animation: Select-animation-fadeIn 200ms;
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
display: table-cell;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 17px;
|
||||||
|
}
|
||||||
|
.Select-clear-zone:hover {
|
||||||
|
color: #d0021b;
|
||||||
|
}
|
||||||
|
.Select-clear {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-clear-zone {
|
||||||
|
width: 17px;
|
||||||
|
}
|
||||||
|
.Select-arrow-zone {
|
||||||
|
cursor: pointer;
|
||||||
|
display: table-cell;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 25px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
.Select--rtl .Select-arrow-zone {
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
.Select-arrow {
|
||||||
|
border-color: #999 transparent transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 5px 2.5px;
|
||||||
|
display: inline-block;
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.Select-control > *:last-child {
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-multi-value-wrapper {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.Select .Select-aria-only {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
height: 1px;
|
||||||
|
width: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
overflow: hidden;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
@-webkit-keyframes Select-animation-fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes Select-animation-fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.Select-menu-outer {
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-top-color: #e6e6e6;
|
||||||
|
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: -1px;
|
||||||
|
max-height: 200px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 100%;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
.Select-menu {
|
||||||
|
max-height: 150px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.Select-option {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #666666;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
.Select-option:last-child {
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
.Select-option.is-selected {
|
||||||
|
background-color: #f5faff;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
background-color: rgba(0, 126, 255, 0.04);
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.Select-option.is-focused {
|
||||||
|
background-color: #ebf5ff;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
background-color: rgba(0, 126, 255, 0.08);
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.Select-option.is-disabled {
|
||||||
|
color: #cccccc;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.Select-noresults {
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #999999;
|
||||||
|
cursor: default;
|
||||||
|
display: block;
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-input {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 10px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.Select--multi.Select--rtl .Select-input {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.Select--multi.has-value .Select-input {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-value {
|
||||||
|
background-color: #ebf5ff;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
background-color: rgba(0, 126, 255, 0.08);
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid #c2e0ff;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
border: 1px solid rgba(0, 126, 255, 0.24);
|
||||||
|
color: #007eff;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.9em;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-value-icon,
|
||||||
|
.Select--multi .Select-value-label {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-value-label {
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
cursor: default;
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
.Select--multi a.Select-value-label {
|
||||||
|
color: #007eff;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.Select--multi a.Select-value-label:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-value-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
border-top-left-radius: 2px;
|
||||||
|
border-right: 1px solid #c2e0ff;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
border-right: 1px solid rgba(0, 126, 255, 0.24);
|
||||||
|
padding: 1px 5px 3px;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-value-icon:hover,
|
||||||
|
.Select--multi .Select-value-icon:focus {
|
||||||
|
background-color: #d8eafd;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
background-color: rgba(0, 113, 230, 0.08);
|
||||||
|
color: #0071e6;
|
||||||
|
}
|
||||||
|
.Select--multi .Select-value-icon:active {
|
||||||
|
background-color: #c2e0ff;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
background-color: rgba(0, 126, 255, 0.24);
|
||||||
|
}
|
||||||
|
.Select--multi.Select--rtl .Select-value {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
.Select--multi.Select--rtl .Select-value-icon {
|
||||||
|
border-right: none;
|
||||||
|
border-left: 1px solid #c2e0ff;
|
||||||
|
/* Fallback color for IE 8 */
|
||||||
|
border-left: 1px solid rgba(0, 126, 255, 0.24);
|
||||||
|
}
|
||||||
|
.Select--multi.is-disabled .Select-value {
|
||||||
|
background-color: #fcfcfc;
|
||||||
|
border: 1px solid #e3e3e3;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.Select--multi.is-disabled .Select-value-icon {
|
||||||
|
cursor: not-allowed;
|
||||||
|
border-right: 1px solid #e3e3e3;
|
||||||
|
}
|
||||||
|
.Select--multi.is-disabled .Select-value-icon:hover,
|
||||||
|
.Select--multi.is-disabled .Select-value-icon:focus,
|
||||||
|
.Select--multi.is-disabled .Select-value-icon:active {
|
||||||
|
background-color: #fcfcfc;
|
||||||
|
}
|
||||||
|
@keyframes Select-animation-spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(1turn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes Select-animation-spin {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(1turn);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
browser/tsconfig.json
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"sourceMap": true,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"target": "es6",
|
||||||
|
"jsx": "react",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"jslib/*": [
|
||||||
|
"../jslib/src/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
browser/webpack.config.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
|
||||||
|
*
|
||||||
|
* This file is part of Dnote.
|
||||||
|
*
|
||||||
|
* Dnote is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Dnote is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const packageJson = require('./package.json');
|
||||||
|
|
||||||
|
const ENV = process.env.NODE_ENV;
|
||||||
|
const TARGET = process.env.TARGET;
|
||||||
|
const isProduction = ENV === 'production';
|
||||||
|
|
||||||
|
console.log(`Running webpack in ${ENV} mode`);
|
||||||
|
|
||||||
|
const webUrl = isProduction
|
||||||
|
? 'https://app.getdnote.com'
|
||||||
|
: 'http://127.0.0.1:3000';
|
||||||
|
const apiUrl = isProduction
|
||||||
|
? 'https://api.getdnote.com'
|
||||||
|
: 'http://127.0.0.1:5000';
|
||||||
|
|
||||||
|
const plugins = [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
__API_ENDPOINT__: JSON.stringify(apiUrl),
|
||||||
|
__WEB_URL__: JSON.stringify(webUrl),
|
||||||
|
__VERSION__: JSON.stringify(packageJson.version)
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
const moduleRules = [
|
||||||
|
{
|
||||||
|
test: /\.ts(x?)$/,
|
||||||
|
exclude: /node_modules|_test\.ts(x)$/,
|
||||||
|
loaders: ['ts-loader'],
|
||||||
|
exclude: path.resolve(__dirname, 'node_modules')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = env => {
|
||||||
|
return {
|
||||||
|
// run in production mode because of Content Security Policy error encountered
|
||||||
|
// when running a JavaScript bundle produced in a development mode
|
||||||
|
mode: 'production',
|
||||||
|
entry: { popup: ['./src/scripts/popup.tsx'] },
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
path: path.resolve(__dirname, 'dist', TARGET, 'scripts')
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.tsx', '.js'],
|
||||||
|
alias: {
|
||||||
|
jslib: path.join(__dirname, '../jslib/src')
|
||||||
|
},
|
||||||
|
modules: [path.resolve('node_modules')]
|
||||||
|
},
|
||||||
|
module: { rules: moduleRules },
|
||||||
|
plugins: plugins,
|
||||||
|
optimization: {
|
||||||
|
minimize: isProduction
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
64
go.mod
|
|
@ -1,43 +1,43 @@
|
||||||
module github.com/dnote/dnote
|
module github.com/dnote/dnote
|
||||||
|
|
||||||
go 1.25
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/PuerkitoBio/goquery v1.6.0 // indirect
|
||||||
|
github.com/andybalholm/cascadia v1.2.0 // indirect
|
||||||
|
github.com/aymerick/douceur v0.2.0
|
||||||
github.com/dnote/actions v0.2.0
|
github.com/dnote/actions v0.2.0
|
||||||
github.com/fatih/color v1.18.0
|
github.com/dnote/color v1.7.0
|
||||||
github.com/google/go-cmp v0.7.0
|
github.com/gobuffalo/packr/v2 v2.8.1
|
||||||
|
github.com/google/go-cmp v0.5.4
|
||||||
github.com/google/go-github v17.0.0+incompatible
|
github.com/google/go-github v17.0.0+incompatible
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.1.3
|
||||||
github.com/gorilla/csrf v1.7.3
|
github.com/gorilla/csrf v1.6.2
|
||||||
github.com/gorilla/mux v1.8.1
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/gorilla/schema v1.4.1
|
github.com/gorilla/schema v1.2.0
|
||||||
github.com/mattn/go-sqlite3 v1.14.32
|
github.com/jinzhu/gorm v1.9.16
|
||||||
|
github.com/joho/godotenv v1.3.0
|
||||||
|
github.com/karrick/godirwalk v1.16.1 // indirect
|
||||||
|
github.com/lib/pq v1.9.0
|
||||||
|
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6
|
||||||
|
github.com/nadproject/nad v0.0.0-20200124233812-f1a4e763ee2f
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/radovskyb/watcher v1.0.7
|
github.com/radovskyb/watcher v1.0.7
|
||||||
github.com/sergi/go-diff v1.3.1
|
github.com/robfig/cron v1.2.0
|
||||||
github.com/spf13/cobra v1.10.1
|
github.com/rogpeppe/go-internal v1.6.2 // indirect
|
||||||
golang.org/x/crypto v0.45.0
|
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351
|
||||||
golang.org/x/time v0.13.0
|
github.com/sergi/go-diff v1.1.0
|
||||||
|
github.com/sirupsen/logrus v1.7.0 // indirect
|
||||||
|
github.com/spf13/cobra v1.1.1
|
||||||
|
github.com/yuin/goldmark v1.4.0
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||||
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014 // indirect
|
||||||
|
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
|
||||||
|
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gorm.io/driver/sqlite v1.6.0
|
|
||||||
gorm.io/gorm v1.30.0
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
|
||||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.10 // indirect
|
|
||||||
github.com/stretchr/testify v1.8.1 // indirect
|
|
||||||
golang.org/x/sys v0.38.0 // indirect
|
|
||||||
golang.org/x/term v0.37.0 // indirect
|
|
||||||
golang.org/x/text v0.31.0 // indirect
|
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
717
go.sum
|
|
@ -1,103 +1,674 @@
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||||
|
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||||
|
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||||
|
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||||
|
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||||
|
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||||
|
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||||
|
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||||
|
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||||
|
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||||
|
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||||
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
||||||
|
github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE=
|
||||||
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
|
github.com/PuerkitoBio/goquery v1.6.0 h1:j7taAbelrdcsOlGeMenZxc2AWXD5fieT1/znArdnx94=
|
||||||
|
github.com/PuerkitoBio/goquery v1.6.0/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||||
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
|
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
|
github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE=
|
||||||
|
github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY=
|
||||||
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
|
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||||
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
|
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
|
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/dnote/actions v0.2.0 h1:P1ut2/QRKwfAzIIB374vN9A4IanU94C/payEocvngYo=
|
github.com/dnote/actions v0.2.0 h1:P1ut2/QRKwfAzIIB374vN9A4IanU94C/payEocvngYo=
|
||||||
github.com/dnote/actions v0.2.0/go.mod h1:bBIassLhppVQdbC3iaE92SHBpM1HOVe+xZoAlj9ROxw=
|
github.com/dnote/actions v0.2.0/go.mod h1:bBIassLhppVQdbC3iaE92SHBpM1HOVe+xZoAlj9ROxw=
|
||||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
github.com/dnote/color v1.7.0 h1:8/QGLQKSU8/zcWQaHbMyC1hJRkKO/Uu9M89sH76ecHE=
|
||||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
github.com/dnote/color v1.7.0/go.mod h1:75UcP/TH7CNvjQ5pwDumkUS3vkPdGggy7/3fT8MlxHM=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||||
|
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||||
|
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||||
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||||
|
github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w=
|
||||||
|
github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
|
||||||
|
github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
|
||||||
|
github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc=
|
||||||
|
github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
|
||||||
|
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
|
||||||
|
github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=
|
||||||
|
github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=
|
||||||
|
github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=
|
||||||
|
github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.8.1 h1:tkQpju6i3EtMXJ9uoF5GT6kB+LMTimDWD8Xvbz6zDVA=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.8.1/go.mod h1:c/PLlOuTU+p3SybaJATW3H6lX/iK7xEz5OeMf+NnJpg=
|
||||||
|
github.com/godror/godror v0.13.3/go.mod h1:2ouUT4kdhUBk7TAkHWD4SN0CdI0pgEQbo8FVHhbSKWg=
|
||||||
|
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||||
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||||
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/gorilla/csrf v1.7.3 h1:BHWt6FTLZAb2HtWT5KDBf6qgpZzvtbp9QWDRKZMXJC0=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/gorilla/csrf v1.7.3/go.mod h1:F1Fj3KG23WYHE6gozCmBAezKookxbIvUJT+121wTuLk=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
github.com/google/uuid v1.1.3 h1:twObb+9XcuH5B9V1TBCvvvZoO6iEdILi2a76PYn5rJI=
|
||||||
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
|
github.com/google/uuid v1.1.3/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/gorilla/csrf v1.6.2 h1:QqQ/OWwuFp4jMKgBFAzJVW3FMULdyUW7JoM4pEWuqKg=
|
||||||
|
github.com/gorilla/csrf v1.6.2/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
|
||||||
|
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||||
|
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||||
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||||
|
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||||
|
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||||
|
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||||
|
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
|
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
|
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||||
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
|
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||||
|
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||||
|
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
|
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||||
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
|
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||||
|
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||||
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
|
github.com/jinzhu/gorm v1.9.9/go.mod h1:Kh6hTsSGffh4ui079FHrR5Gg+5D0hgihqDcsDN2BBJY=
|
||||||
|
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
|
||||||
|
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/justincampbell/bigduration v0.0.0-20160531141349-e45bf03c0666/go.mod h1:xqGOmDZzLOG7+q/CgsbXv10g4tgPsbjhmAxyaTJMvis=
|
||||||
|
github.com/justincampbell/timeago v0.0.0-20160528003754-027f40306f1d/go.mod h1:U7FWcK1jzZJnYuSnxP6efX3ZoHbK1CEpD0ThYyGNPNI=
|
||||||
|
github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||||
|
github.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
||||||
|
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
|
||||||
|
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
||||||
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
|
||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||||
github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs=
|
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||||
github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
|
||||||
|
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
|
||||||
|
github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
|
||||||
|
github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
|
||||||
|
github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
|
||||||
|
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||||
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||||
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-oci8 v0.0.7/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
|
||||||
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
|
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||||
|
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||||
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
|
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
github.com/nadproject/color v1.7.0/go.mod h1:p2KusS2iX8Q7ncpngDmtva/kZmiad9Hv5MFS4SLuCZQ=
|
||||||
|
github.com/nadproject/nad v0.0.0-20200124233812-f1a4e763ee2f h1:Vq2SFUt+Mrle7Irf7rLOnYBegSVF3tyNbsMnDomWfH8=
|
||||||
|
github.com/nadproject/nad v0.0.0-20200124233812-f1a4e763ee2f/go.mod h1:mGl2lRU9Xo49kzVYj46FwP+pEP/Um+nIqTdCmPHtI5k=
|
||||||
|
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||||
|
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||||
|
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||||
|
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||||
|
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
|
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
|
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||||
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||||
|
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||||
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||||
|
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||||
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||||
|
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
|
github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
|
||||||
github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
|
github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
github.com/rogpeppe/go-internal v1.5.2 h1:qLvObTrvO/XRCqmkKxUlOBc48bI3efyDuAZe25QiF0w=
|
||||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
github.com/rubenv/sql-migrate v0.0.0-20190618074426-f4d34eae5a5c/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
|
||||||
|
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 h1:HXr/qUllAWv9riaI4zh2eXWKmCSDqVS/XH1MRHLKRwk=
|
||||||
|
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351/go.mod h1:DCgfY80j8GYL7MLEfvcpSFvjD0L5yZq/aZUJmhZklyg=
|
||||||
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||||
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||||
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
|
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
|
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
|
||||||
|
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
|
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||||
|
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
|
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
|
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
github.com/stripe/stripe-go v61.7.1+incompatible/go.mod h1:A1dQZmO/QypXmsL0T8axYZkSN/uA/T/A64pfKdBAMiY=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
github.com/yuin/goldmark v1.4.0 h1:OtISOGfH6sOWa1/qXqqAiOIAO6Z5J3AEAE18WAq6BiQ=
|
||||||
golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||||
|
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||||
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
|
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||||
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
|
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||||
|
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||||
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
|
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
|
||||||
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014 h1:joucsQqXmyBVxViHCPFjG3hx8JzIFSaym3l3MM/Jsdg=
|
||||||
|
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
|
||||||
|
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
|
||||||
|
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
|
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41 h1:9Di9iYgOt9ThCipBxChBVhgNipDoE5mxO84rQV7D0FE=
|
||||||
|
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||||
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
|
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||||
|
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||||
|
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||||
|
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||||
|
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
|
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||||
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20150902115704-41f357289737/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
|
gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=
|
||||||
|
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
|
||||||
|
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
|
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,20 @@
|
||||||
FROM busybox:glibc
|
FROM alpine:latest
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG tarballName
|
||||||
ARG version
|
RUN test -n "$tarballName"
|
||||||
|
|
||||||
RUN test -n "$TARGETPLATFORM" || (echo "TARGETPLATFORM is required" && exit 1)
|
# add dependency to execute a golang binary with dynamical linking.
|
||||||
RUN test -n "$version" || (echo "version is required" && exit 1)
|
RUN apk add --no-cache \
|
||||||
|
libc6-compat
|
||||||
|
|
||||||
WORKDIR /tmp/tarballs
|
WORKDIR dnote
|
||||||
|
|
||||||
# Copy all architecture tarballs
|
COPY "$tarballName" .
|
||||||
COPY dnote_server_*.tar.gz ./
|
RUN tar -xvzf "$tarballName"
|
||||||
|
|
||||||
# Select and extract the correct tarball based on target platform
|
|
||||||
RUN case "$TARGETPLATFORM" in \
|
|
||||||
"linux/amd64") ARCH="amd64" ;; \
|
|
||||||
"linux/arm64") ARCH="arm64" ;; \
|
|
||||||
"linux/arm/v7") ARCH="arm" ;; \
|
|
||||||
"linux/386") ARCH="386" ;; \
|
|
||||||
*) echo "Unsupported platform: $TARGETPLATFORM" && exit 1 ;; \
|
|
||||||
esac && \
|
|
||||||
TARBALL="dnote_server_${version}_linux_${ARCH}.tar.gz" && \
|
|
||||||
echo "Extracting $TARBALL for $TARGETPLATFORM" && \
|
|
||||||
mkdir -p /dnote && \
|
|
||||||
tar -xvzf "$TARBALL" -C /dnote
|
|
||||||
|
|
||||||
WORKDIR /dnote
|
|
||||||
|
|
||||||
# Set default database path for all processes (main server, docker exec, shells)
|
|
||||||
ENV DBPath=/data/dnote.db
|
|
||||||
|
|
||||||
COPY entrypoint.sh .
|
COPY entrypoint.sh .
|
||||||
ENTRYPOINT ["./entrypoint.sh"]
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
|
|
||||||
CMD ./dnote-server start
|
CMD ./dnote-server start
|
||||||
|
|
||||||
EXPOSE 3001
|
EXPOSE 3000
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s \
|
|
||||||
CMD wget --no-verbose --tries=1 -O /dev/null http://localhost:3001/health || exit 1
|
|
||||||
|
|
|
||||||
30
host/docker/README.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Dnote Docker Image
|
||||||
|
|
||||||
|
The official Dnote docker image.
|
||||||
|
|
||||||
|
## Installing Dnote Server Using Docker
|
||||||
|
|
||||||
|
1. Install [Docker](https://docs.docker.com/install/).
|
||||||
|
2. Install Docker [Compose](https://docs.docker.com/compose/install/).
|
||||||
|
3. Download the [docker-compose.yml](https://raw.githubusercontent.com/dnote/dnote/master/host/docker/docker-compose.yml) file by running:
|
||||||
|
|
||||||
|
```
|
||||||
|
curl https://raw.githubusercontent.com/dnote/dnote/master/host/docker/docker-compose.yml > docker-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Run the following to download the images and run the containers
|
||||||
|
|
||||||
|
```
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Visit http://localhost:3000 in your browser to see Dnote running.
|
||||||
|
|
||||||
|
Please see [the installation guide](https://github.com/dnote/dnote/blob/master/SELF_HOSTING.md) for further configuration.
|
||||||
|
|
||||||
|
## Supported platform
|
||||||
|
|
||||||
|
Currently, the official Docker image for Dnote supports Linux running AMD64 CPU architecture.
|
||||||
|
|
||||||
|
If you run ARM64, please install Dnote server by downloading a binary distribution by following [the guide](https://github.com/dnote/dnote/blob/master/SELF_HOSTING.md).
|
||||||
|
|
@ -1,85 +1,13 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Build Docker image for local testing
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# # builds for host platform (auto-detected)
|
|
||||||
# ./build.sh 1.0.0
|
|
||||||
#
|
|
||||||
# # builds arm64
|
|
||||||
# ./build.sh 1.0.0 linux/arm64
|
|
||||||
#
|
|
||||||
# # builds multiple platforms
|
|
||||||
# ./build.sh 1.0.0 "linux/amd64,linux/arm64,linux/arm/v7,linux/386"
|
|
||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
version=$1
|
version=$1
|
||||||
|
|
||||||
# Detect host platform if not specified
|
|
||||||
if [ -z "${2:-}" ]; then
|
|
||||||
HOST_ARCH=$(uname -m)
|
|
||||||
case "$HOST_ARCH" in
|
|
||||||
x86_64) platform="linux/amd64" ;;
|
|
||||||
aarch64|arm64) platform="linux/arm64" ;;
|
|
||||||
armv7l) platform="linux/arm/v7" ;;
|
|
||||||
i386|i686) platform="linux/386" ;;
|
|
||||||
*)
|
|
||||||
echo "Warning: Unsupported architecture: $HOST_ARCH, defaulting to linux/amd64"
|
|
||||||
platform="linux/amd64"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo "Auto-detected platform: $platform"
|
|
||||||
else
|
|
||||||
platform=$2
|
|
||||||
fi
|
|
||||||
|
|
||||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||||
projectDir="$dir/../.."
|
projectDir="$dir/../.."
|
||||||
|
tarballName="dnote_server_${version}_linux_amd64.tar.gz"
|
||||||
|
|
||||||
# Copy all Linux tarballs to Docker build context
|
# copy over the build artifact to the Docker build context
|
||||||
cp "$projectDir/build/server/dnote_server_${version}_linux_amd64.tar.gz" "$dir/"
|
cp "$projectDir/build/server/$tarballName" "$dir"
|
||||||
cp "$projectDir/build/server/dnote_server_${version}_linux_arm64.tar.gz" "$dir/"
|
|
||||||
cp "$projectDir/build/server/dnote_server_${version}_linux_arm.tar.gz" "$dir/"
|
|
||||||
cp "$projectDir/build/server/dnote_server_${version}_linux_386.tar.gz" "$dir/"
|
|
||||||
|
|
||||||
# Count platforms (check for comma)
|
docker build --network=host -t dnote/dnote:"$version" --build-arg tarballName="$tarballName" .
|
||||||
if [[ "$platform" == *","* ]]; then
|
|
||||||
echo "Building for multiple platforms: $platform"
|
|
||||||
|
|
||||||
# Check if multiarch builder exists, create if not
|
|
||||||
if ! docker buildx ls | grep -q "multiarch"; then
|
|
||||||
echo "Creating multiarch builder for multi-platform builds..."
|
|
||||||
docker buildx create --name multiarch --use
|
|
||||||
docker buildx inspect --bootstrap
|
|
||||||
else
|
|
||||||
echo "Using existing multiarch builder"
|
|
||||||
docker buildx use multiarch
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
docker buildx build \
|
|
||||||
--platform "$platform" \
|
|
||||||
-t dnote/dnote:"$version" \
|
|
||||||
-t dnote/dnote:latest \
|
|
||||||
--build-arg version="$version" \
|
|
||||||
"$dir"
|
|
||||||
|
|
||||||
# Switch back to default builder
|
|
||||||
docker buildx use default
|
|
||||||
else
|
|
||||||
echo "Building for single platform: $platform"
|
|
||||||
echo "Image will be loaded to local Docker daemon"
|
|
||||||
|
|
||||||
docker buildx build \
|
|
||||||
--platform "$platform" \
|
|
||||||
-t dnote/dnote:"$version" \
|
|
||||||
-t dnote/dnote:latest \
|
|
||||||
--build-arg version="$version" \
|
|
||||||
--load \
|
|
||||||
"$dir"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Build complete!"
|
|
||||||
if [[ "$platform" != *","* ]]; then
|
|
||||||
echo "Test with: docker run --rm dnote/dnote:$version ./dnote-server version"
|
|
||||||
fi
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
services:
|
|
||||||
dnote:
|
|
||||||
image: dnote/dnote:latest
|
|
||||||
container_name: dnote
|
|
||||||
ports:
|
|
||||||
- 3001:3001
|
|
||||||
volumes:
|
|
||||||
- ./dnote_data:/data
|
|
||||||
restart: unless-stopped
|
|
||||||
35
host/docker/docker-compose.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:11-alpine
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: dnote
|
||||||
|
POSTGRES_PASSWORD: dnote
|
||||||
|
POSTGRES_DB: dnote
|
||||||
|
volumes:
|
||||||
|
- ./dnote_data:/var/lib/postgresql/data
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
dnote:
|
||||||
|
image: dnote/dnote:latest
|
||||||
|
environment:
|
||||||
|
GO_ENV: PRODUCTION
|
||||||
|
DBSkipSSL: "true"
|
||||||
|
DBHost: postgres
|
||||||
|
DBPort: 5432
|
||||||
|
DBName: dnote
|
||||||
|
DBUser: dnote
|
||||||
|
DBPassword: dnote
|
||||||
|
WebURL: localhost:3000
|
||||||
|
OnPremise: "true"
|
||||||
|
SmtpHost:
|
||||||
|
SmtpPort:
|
||||||
|
SmtpUsername:
|
||||||
|
SmtpPassword:
|
||||||
|
DisableRegistration: "false"
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
restart: always
|
||||||
|
|
@ -1,6 +1,25 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Set default DBPath to /data if not specified
|
wait_for_db() {
|
||||||
export DBPath=${DBPath:-/data/dnote.db}
|
HOST=${DBHost:-postgres}
|
||||||
|
PORT=${DBPort:-5432}
|
||||||
|
echo "Waiting for the database connection..."
|
||||||
|
|
||||||
|
attempts=0
|
||||||
|
max_attempts=10
|
||||||
|
while [ $attempts -lt $max_attempts ]; do
|
||||||
|
nc -z "${HOST}" "${PORT}" 2>/dev/null && break
|
||||||
|
echo "Waiting for db at ${HOST}:${PORT}..."
|
||||||
|
sleep 5
|
||||||
|
attempts=$((attempts+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $attempts -eq $max_attempts ]; then
|
||||||
|
echo "Timed out while waiting for db at ${HOST}:${PORT}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_db
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
||||||
13
host/docker/release.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
version=$1
|
||||||
|
|
||||||
|
docker login
|
||||||
|
|
||||||
|
# tag the release
|
||||||
|
docker tag dnote/dnote:"$version" dnote/dnote:latest
|
||||||
|
|
||||||
|
# publish
|
||||||
|
docker push dnote/dnote:"$version"
|
||||||
|
docker push dnote/dnote:latest
|
||||||
1
host/smoketest/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/volume
|
||||||
1
host/smoketest/README.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
This directory contains a smoke test for running a self-hosted instance using a virtual machine.
|
||||||
9
host/smoketest/Vagrantfile
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# -*- mode: ruby -*-
|
||||||
|
|
||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
config.vm.box = "ubuntu/bionic64"
|
||||||
|
config.vm.synced_folder './volume', '/vagrant'
|
||||||
|
config.vm.network "forwarded_port", guest: 2300, host: 2300
|
||||||
|
|
||||||
|
config.vm.provision 'shell', path: './setup.sh', privileged: false
|
||||||
|
end
|
||||||
42
host/smoketest/run_test.sh
Executable file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# run_test.sh builds a fresh server image, and mounts it on a fresh
|
||||||
|
# virtual machine and runs a smoke test. If a tarball path is not provided,
|
||||||
|
# this script builds a new version and uses it.
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
# tarballPath is an absolute path to a release tarball containing the dnote server.
|
||||||
|
tarballPath=$1
|
||||||
|
|
||||||
|
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||||
|
projectDir="$dir/../.."
|
||||||
|
|
||||||
|
# build
|
||||||
|
if [ -z "$tarballPath" ]; then
|
||||||
|
pushd "$projectDir"
|
||||||
|
make version=integration_test build-server
|
||||||
|
popd
|
||||||
|
tarballPath="$projectDir/build/server/dnote_server_integration_test_linux_amd64.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd "$dir"
|
||||||
|
|
||||||
|
# start a virtual machine
|
||||||
|
volume="$dir/volume"
|
||||||
|
rm -rf "$volume"
|
||||||
|
mkdir -p "$volume"
|
||||||
|
cp "$tarballPath" "$volume"
|
||||||
|
cp "$dir/testsuite.sh" "$volume"
|
||||||
|
|
||||||
|
vagrant up
|
||||||
|
|
||||||
|
# run tests
|
||||||
|
set +e
|
||||||
|
if ! vagrant ssh -c "/vagrant/testsuite.sh"; then
|
||||||
|
echo "Test failed. Please see the output."
|
||||||
|
vagrant halt
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
set -e
|
||||||
|
|
||||||
|
vagrant halt
|
||||||
|
popd
|
||||||
17
host/smoketest/setup.sh
Executable file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
sudo apt-get install wget ca-certificates
|
||||||
|
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
||||||
|
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y postgresql-11
|
||||||
|
|
||||||
|
# set up database
|
||||||
|
sudo -u postgres createdb dnote
|
||||||
|
# allow connection from host and allow to connect without password
|
||||||
|
sudo sed -i "/port*/a listen_addresses = '*'" /etc/postgresql/11/main/postgresql.conf
|
||||||
|
sudo sed -i 's/host.*all.*.all.*md5/# &/' /etc/postgresql/11/main/pg_hba.conf
|
||||||
|
sudo sed -i "$ a host all all all trust" /etc/postgresql/11/main/pg_hba.conf
|
||||||
|
sudo service postgresql restart
|
||||||
44
host/smoketest/testsuite.sh
Executable file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# testsuite.sh runs the smoke tests for a self-hosted instance.
|
||||||
|
# It is meant to be run inside a virtual machine which has been
|
||||||
|
# set up by an entry script.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
echo 'Running a smoke test'
|
||||||
|
|
||||||
|
sudo -u postgres dropdb dnote
|
||||||
|
sudo -u postgres createdb dnote
|
||||||
|
|
||||||
|
cd /vagrant
|
||||||
|
|
||||||
|
tar -xvf dnote_server_integration_test_linux_amd64.tar.gz
|
||||||
|
|
||||||
|
GO_ENV=PRODUCTION \
|
||||||
|
DBHost=localhost \
|
||||||
|
DBPort=5432 \
|
||||||
|
DBName=dnote \
|
||||||
|
DBUser=postgres \
|
||||||
|
DBPassword="" \
|
||||||
|
WebURL=localhost:3000 \
|
||||||
|
./dnote-server -port 2300 start & sleep 3
|
||||||
|
|
||||||
|
assert_http_status() {
|
||||||
|
url=$1
|
||||||
|
expected=$2
|
||||||
|
|
||||||
|
echo "======== [TEST CASE] asserting response status code for $url ========"
|
||||||
|
|
||||||
|
got=$(curl --write-out %"{http_code}" --silent --output /dev/null "$url")
|
||||||
|
|
||||||
|
if [ "$got" != "$expected" ]; then
|
||||||
|
echo "======== ASSERTION FAILED ========"
|
||||||
|
echo "status code for $url: expected: $expected got: $got"
|
||||||
|
echo "=================================="
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_http_status http://localhost:2300 "200"
|
||||||
|
assert_http_status http://localhost:2300/api/health "200"
|
||||||
|
|
||||||
|
echo "======== [SUCCESS] TEST PASSED! ========"
|
||||||
17
install.sh
|
|
@ -68,14 +68,9 @@ uname_os() {
|
||||||
|
|
||||||
uname_arch() {
|
uname_arch() {
|
||||||
arch=$(uname -m)
|
arch=$(uname -m)
|
||||||
case $arch in
|
case $arch in
|
||||||
x86_64) arch="amd64" ;;
|
x86_64) arch="amd64" ;;
|
||||||
aarch64) arch="arm64" ;;
|
aarch64) arch="arm64" ;;
|
||||||
arm64) arch="arm64" ;;
|
|
||||||
armv7l) arch="arm" ;;
|
|
||||||
armv6l) arch="arm" ;;
|
|
||||||
armv5l) arch="arm" ;;
|
|
||||||
arm) arch="arm" ;;
|
|
||||||
x86) arch="386" ;;
|
x86) arch="386" ;;
|
||||||
i686) arch="386" ;;
|
i686) arch="386" ;;
|
||||||
i386) arch="386" ;;
|
i386) arch="386" ;;
|
||||||
|
|
@ -91,17 +86,9 @@ check_platform() {
|
||||||
|
|
||||||
found=1
|
found=1
|
||||||
case "$platform" in
|
case "$platform" in
|
||||||
# Linux
|
darwin/amd64) found=0;;
|
||||||
linux/amd64) found=0 ;;
|
linux/amd64) found=0 ;;
|
||||||
linux/arm64) found=0 ;;
|
linux/arm64) found=0 ;;
|
||||||
linux/arm) found=0 ;;
|
|
||||||
# macOS
|
|
||||||
darwin/amd64) found=0 ;;
|
|
||||||
darwin/arm64) found=0 ;;
|
|
||||||
# Windows
|
|
||||||
windows/amd64) found=0 ;;
|
|
||||||
# FreeBSD
|
|
||||||
freebsd/amd64) found=0 ;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
return $found
|
return $found
|
||||||
|
|
|
||||||
3
jslib/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
/dist
|
||||||
|
/node_modules
|
||||||
|
/coverage
|
||||||
3
jslib/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# jslib
|
||||||
|
|
||||||
|
Code shared between Dnote JavaScript projects.
|
||||||
4
jslib/jest.config.js
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
collectCoverageFrom: ['./src/**/*.ts']
|
||||||
|
};
|
||||||