From eaeb88401d07687eb3db8c273f7a4c0ed31ec153 Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Mon, 4 Jan 2021 13:07:44 +0100 Subject: Move docs into subdirectory to make mkdocs work in a subdirectory Signed-off-by: Tilman Vatteroth --- docs/content/dev/api.md | 41 ++++ docs/content/dev/documentation.md | 27 +++ docs/content/dev/getting-started.md | 56 +++++ docs/content/dev/openapi.yml | 458 ++++++++++++++++++++++++++++++++++++ docs/content/dev/ot.md | 13 + docs/content/dev/webpack.md | 37 +++ 6 files changed, 632 insertions(+) create mode 100644 docs/content/dev/api.md create mode 100644 docs/content/dev/documentation.md create mode 100644 docs/content/dev/getting-started.md create mode 100644 docs/content/dev/openapi.yml create mode 100644 docs/content/dev/ot.md create mode 100644 docs/content/dev/webpack.md (limited to 'docs/content/dev') diff --git a/docs/content/dev/api.md b/docs/content/dev/api.md new file mode 100644 index 00000000..0700ecc3 --- /dev/null +++ b/docs/content/dev/api.md @@ -0,0 +1,41 @@ +# API documentation +Several tasks of HedgeDoc can be automated through HTTP requests. +The available endpoints for this api are described in this document. +For code-autogeneration there is an OpenAPIv3-compatible description available [here](openapi.yml). + +## Notes +These endpoints create notes, return information about them or export them. +You have to replace *\* with either the alias or id of a note you want to work on. + +| Endpoint | HTTP-Method | Description | +| ---------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `/new` | `GET` | **Creates a new note.**
A random id will be assigned and the content will equal to the template (blank by default). After note creation a redirect is issued to the created note. | +| `/new` | `POST` | **Imports some markdown data into a new note.**
A random id will be assigned and the content will equal to the body of the received HTTP-request. The `Content-Type: text/markdown` header should be set on this request. | +| `/new/` | `POST` | **Imports some markdown data into a new note with a given alias.**
This endpoint equals to the above one except that the alias from the url will be assigned to the note if [FreeURL-mode](../configuration.md#users-and-privileges) is enabled. | +| `//download` or `/s//download` | `GET` | **Returns the raw markdown content of a note.** | +| `//publish` | `GET` | **Redirects to the published version of the note.** | +| `//slide` | `GET` | **Redirects to the slide-presentation of the note.**
This is only useful on notes which are designed to be slides. | +| `//info` | `GET` | **Returns metadata about the note.**
This includes the title and description of the note as well as the creation date and viewcount. The data is returned as a JSON object. | +| `//revision` | `GET` | **Returns a list of the available note revisions.**
The list is returned as a JSON object with an array of revision-id and length associations. The revision-id equals to the timestamp when the revision was saved. | +| `//revision/` | `GET` | **Returns the revision of the note with some metadata.**
The revision is returned as a JSON object with the content of the note and the authorship. | +| `//gist` | `GET` | **Creates a new GitHub Gist with the note's content.**
If [GitHub integration](../configuration.md#github-login) is configured, the user will be redirected to GitHub and a new Gist with the content of the note will be created. | + +## User / History +These endpoints return information about the current logged-in user and it's note history. If no user is logged-in, the most of this requests will fail with either a HTTP 403 or a JSON object containing `{"status":"forbidden"}`. + +| Endpoint | HTTP-Method | Description | +| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `/me` | `GET` | **Returns the profile data of the current logged-in user.**
The data is returned as a JSON object containing the user-id, the user's name and a url to the profile picture. | +| `/me/export` | `GET` | **Exports a zip-archive with all notes of the current user.** | +| `/history` | `GET` | **Returns a list of the last viewed notes.**
The list is returned as a JSON object with an array containing for each entry it's id, title, tags, last visit time and pinned status. | +| `/history` | `POST` | **Replace user's history with a new one.**
The body must be form-encoded and contain a field `history` with a JSON-encoded array like its returned from the server when exporting the history. | +| `/history` | `DELETE` | **Deletes the user's history.** | +| `/history/` | `POST` | **Toggles the pinned status in the history for a note.**
The body must be form-encoded and contain a field `pinned` that is either `true` or `false`. | +| `/history/` | `DELETE` | **Deletes a note from the user's history.** | + +## HedgeDoc-server +These endpoints return information about the running HedgeDoc instance. + +| Endpoint | HTTP-Method | Description | +| --------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `/status` | `GET` | **Returns the current status of the HedgeDoc instance.**
The data is returned as a JSON object containing the number of notes stored on the server, (distinct) online users and more. | diff --git a/docs/content/dev/documentation.md b/docs/content/dev/documentation.md new file mode 100644 index 00000000..0271792b --- /dev/null +++ b/docs/content/dev/documentation.md @@ -0,0 +1,27 @@ +# Documentation + +Our documentation is build with [mkdocs](https://www.mkdocs.org). + +## Writing + +All documentation files are found in the `docs/content` directory of the [hedgedoc/hedgedoc repo](https://github.com/hedgedoc/hedgedoc). These files are just normal markdown files with nothing special about them. + +The configuration for mkdocs lies in the `docs` folder in a file called `mkdocs.yml`. With that file the theme and menu - amoung others - can be configured. +**Please note:** Any new files need to be linked to by other files or put in the navigation or the files will be very hard to find on the documentation website. + +## Building + +To build the documentation locally you need to perform the following steps: + +0. Make sure you have python3 installed. +1. Go into the `docs` folder. +2. Install all the dependencies (E.g. with a [venv](https://docs.python.org/3/library/venv.html)) with `pip install -r requirements.txt` +3. Start the mkdocs dev server (`mkdocs serve`) or build the documentation (`mkdocs build`). + +## Deployment + +The documentation is deployed with [Messor Structor](https://github.com/traefik/structor). + +The necessary Dockerfile and version menu template and also the github action to build the whole documentation can be found in the [docs.hedgedoc.org repo](https://github.com/hedgedoc/docs.hedgedoc.org). This repo is also used to deploy the actuall website to github.io. + +Messor Structor builds and deploys the documentation by finding all branches that follow the pattern `v*`. For each branch the docs are generated separately by first installing the dependencies from `requirements.txt` and then running mkdocs. Afterwards the menu go template is used to include a version switcher in the theme. diff --git a/docs/content/dev/getting-started.md b/docs/content/dev/getting-started.md new file mode 100644 index 00000000..b7154b05 --- /dev/null +++ b/docs/content/dev/getting-started.md @@ -0,0 +1,56 @@ +# Getting started + +## Preparing for running the code + +**Notice:** *There's [specialised instructions for docker](../setup/docker.md) or [heroku](../setup/heroku.md), if you prefer running code this way!* + +1. Clone the repository with `git clone https://github.com/hedgedoc/hedgedoc.git hedgedoc-server` + (cloning is the preferred way, but you can also download and unzip a release) + +2. Enter the directory and run `bin/setup`, which will install npm dependencies + and create configs. The setup script is written in Bash, you would need bash + as a prerequisite. + +3. Setup the [config file](../configuration.md) or set up + [environment variables](../configuration.md). + +## Running the Code + +Now that everything is in place, we can start HedgeDoc: + +1. `yarn run build` will build the frontend bundle. It uses webpack to do that. +2. Run the server with `node app.js` + +## Running the Code with Auto-Reload + +The commands above are fine for production, but you're a developer and surely +you want to change things. You would need to restart both commands whenever you +change something. Luckily, you can run these commands that will automatically +rebuild the frontend or restart the server if necessary. + +The commands will stay active in your terminal, so you will need multiple tabs +to run both at the same time. + +1. Use `yarn run dev` if you want webpack to continuously rebuild the frontend + code. + +2. To auto-reload the server, the easiest method is to install [nodemon](https://www.npmjs.com/package/nodemon) + and run `nodemon --watch app.js --watch lib --watch locales app.js`. + +## Structure + +The repository contains two parts: a server (backend) and a client (frontend). +most of the server code is in `/lib` and most of the client code is in `public`. + +```text +hedgedoc-server/ +├── docs/ --- documentation +├── lib/ --- server code +├── test/ --- test suite +└── public/ --- client code + ├── css/ --- css styles + ├── docs/ --- default documents + ├── js/ --- js scripts + ├── vendor/ --- vendor includes + └── views/ --- view templates +``` diff --git a/docs/content/dev/openapi.yml b/docs/content/dev/openapi.yml new file mode 100644 index 00000000..c5de475c --- /dev/null +++ b/docs/content/dev/openapi.yml @@ -0,0 +1,458 @@ +openapi: 3.0.1 + +info: + title: HedgeDoc + description: HedgeDoc is an open source collaborative note editor. Several tasks of HedgeDoc can be automated through this API. + version: 1.7.1 + contact: + name: HedgeDoc on GitHub + url: https://github.com/hedgedoc/hedgedoc + license: + name: AGPLv3 + url: https://github.com/hedgedoc/hedgedoc/blob/master/LICENSE + +externalDocs: + url: https://github.com/hedgedoc/hedgedoc/blob/master/docs/dev/api.md + + +paths: + + /new: + get: + tags: + - note + summary: Creates a new note. + description: A random id will be assigned and the content will equal to the template (blank by default). After note creation a redirect is issued to the created note. + responses: + default: + description: Redirect to the new note + post: + tags: + - note + summary: Imports some markdown data into a new note. + description: A random id will be assigned and the content will equal to the body of the received HTTP-request. + requestBody: + required: true + description: The content of the note to be imported as markdown + content: + 'text/markdown': + example: '# Some header' + responses: + default: + description: Redirect to the imported note + + /new/{alias}: + post: + tags: + - note + summary: Imports some markdown data into a new note with a given alias. + description: 'This endpoint equals to the above one except that the alias from the url will be assigned to the note if [FreeURL-mode](../configuration-env-vars.md#users-and-privileges) is enabled.' + requestBody: + required: true + description: The content of the note to be imported as markdown + content: + 'text/markdown': + example: '# Some heading' + responses: + default: + description: Redirect to the imported note + parameters: + - + name: alias + in: path + required: true + description: The alias for the note-id under which the note will be saved + content: + 'text/plain': + example: my-note + + /{note}/download: + get: + tags: + - note + summary: Returns the raw markdown content of a note. + responses: + 200: + description: The raw markdown content of the note + content: + 'text/markdown': + example: '# Some heading' + 404: + description: Note does not exist + parameters: + - + name: note + in: path + required: true + description: The note which should be downloaded + content: + 'text/plain': + example: my-note + + /{note}/publish: + get: + tags: + - note + summary: Redirects to the published version of the note. + responses: + default: + description: Redirect to the published version of the note + 404: + description: Note does not exist + parameters: + - name: note + in: path + required: true + description: The note which should be published + content: + 'text/plain': + example: my-note + + /{note}/slide: + get: + tags: + - note + summary: Redirects to the slide-presentation of the note. + description: This is only useful on notes which are designed to be slides. + responses: + default: + description: Redirect to the slide version of the note + 404: + description: Note does not exist + parameters: + - name: note + in: path + required: true + description: The note which should be shown as slide + content: + 'text/plain': + example: my-note + + /{note}/info: + get: + tags: + - note + summary: Returns metadata about the note. + description: This includes the title and description of the note as well as the creation date and viewcount. + responses: + 200: + description: Metadata about the note + content: + 'text/json': + schema: + type: object + properties: + title: + type: string + description: The title of the note + default: Untitled + description: + type: string + description: The description of the note or the first words from the note + viewcount: + type: integer + minimum: 0 + description: How often the published version of the note was viewed + createtime: + type: string + description: The timestamp when the note was created in ISO 8601 format. + updatetime: + type: string + description: The timestamp when the note was last updated in ISO 8601 format. + 404: + description: Note does not exist + parameters: + - name: note + in: path + required: true + description: The note for which the info should be shown + content: + 'text/plain': + example: my-note + + /{note}/revision: + get: + tags: + - note + summary: Returns a list of the available note revisions. + description: The list is returned as a JSON object with an array of revision-id and length associations. The revision-id equals to the timestamp when the revision was saved. + responses: + 200: + description: Revisions of the note + content: + 'text/json': + schema: + type: object + properties: + revision: + type: array + description: Array that holds all revision-info objects + items: + type: object + properties: + time: + type: integer + description: UNIX-timestamp of when the revision was saved. Is also the revision-id. + length: + type: integer + description: Length of the document to the timepoint the revision was saved + 404: + description: Note does not exist + parameters: + - name: note + in: path + required: true + description: The note for which revisions should be shown + content: + 'text/plain': + example: my-note + + /{note}/revision/{revision-id}: + get: + tags: + - note + summary: Returns the revision of the note with some metadata. + description: The revision is returned as a JSON object with the content of the note and the authorship. + responses: + 200: + description: Revision of the note for the given timestamp + content: + 'text/json': + schema: + type: object + properties: + content: + type: string + description: The raw markdown content of the note revision + authorship: + type: array + description: Data which gives insights about who worked on the note + items: + type: integer + description: Unique user ids and additional data + patch: + type: array + description: Data which gives insight about what changed in comparison to former revisions + items: + type: string + 404: + description: Note does not exist + parameters: + - name: note + in: path + required: true + description: The note for which the revision should be shown + content: + 'text/plain': + example: my-note + - name: revision-id + in: path + required: true + description: The id (timestamp) of the revision to fetch + content: + 'text/plain': + example: 1570921051959 + + /{note}/gist: + get: + tags: + - note + summary: Creates a new GitHub Gist with the note's content. + description: 'If [GitHub integration](https://github.com/hedgedoc/hedgedoc/blob/master/docs/configuration-env-vars.md#github-login) is configured, the user will be redirected to GitHub and a new Gist with the content of the note will be created.' + responses: + default: + description: Redirect to the created gist (or the GitHub authentication before) + 404: + description: Note does not exist + parameters: + - name: note + in: path + required: true + description: The note which should be pasted to GitHub gist + content: + 'text/plain': + example: my-note + + /me: + get: + tags: + - user + summary: Returns the profile data of the current logged-in user. + description: The data is returned as a JSON object containing the user-id, the user's name and a url to the profile picture. Requires an active session of the user. + responses: + 200: + description: If the user is logged-in, the user data otherwise `{"status":"forbidden"}` + content: + 'text/json': + schema: + type: object + properties: + status: + type: string + description: ok if everything works as expected, forbidden is the user is not logged-in + id: + type: string + description: Unique id of the user + name: + type: string + description: The user's display name + photo: + type: string + description: An url to the online stored user profile photo + + /me/export: + get: + tags: + - user + summary: Exports a zip-archive with all notes of the current user. + responses: + default: + description: The zip-archive with all notes + + /history: + get: + tags: + - user + summary: Returns a list of the last viewed notes. + description: The list is returned as a JSON object with an array containing for each entry it's id, title, tags, last visit time and pinned status. + responses: + 200: + description: The list of recently viewed notes and pinned notes + content: + 'text/json': + schema: + type: object + properties: + history: + type: array + description: The array that contains history objects + items: + type: object + properties: + id: + type: string + description: The id or alias of the note + text: + type: string + description: The title of the note + time: + type: integer + description: The UNIX-timestamp when the note was last accessed by the user + tags: + type: array + description: The tags that were added by the user to the note + items: + type: string + pinned: + type: boolean + description: Whether the user has pinned this note + post: + tags: + - user + summary: Replace user's history with a new one. + description: The body must be form-encoded and contain a field `history` with a JSON-encoded array like its returned from the server when exporting the history. + requestBody: + required: true + content: + 'application/x-www-form-urlencoded': + example: 'history=[{"id":"example","text":"Untitled","time":1556275442010,"tags":[],"pinned":false}]' + responses: + 200: + description: History replaced + delete: + tags: + - user + summary: Deletes the user's history. + responses: + 200: + description: User's history deleted + + /history/{note}: + post: + tags: + - user + summary: Toggles the pinned status in the history for a note. + description: The body must be form-encoded and contain a field `pinned` that is either `true` or `false`. + requestBody: + required: true + content: + 'application/x-www-form-urlencoded': + example: 'pinned=false' + responses: + 200: + description: Pinned state toggled + parameters: + - name: note + in: path + required: true + description: The note for which the pinned state should be toggled + content: + 'text/plain': + example: my-note + delete: + tags: + - user + summary: Deletes a note from the user's history. + responses: + 200: + description: Pinned state toggled + parameters: + - name: note + in: path + required: true + description: The note for which the pinned state should be toggled + content: + 'text/plain': + example: my-note + + /status: + get: + tags: + - server + summary: Returns the current status of the HedgeDoc instance. + description: The data is returned as a JSON object containing the number of notes stored on the server, (distinct) online users and more. + responses: + 200: + description: The server info + content: + 'text/json': + schema: + type: object + properties: + onlineNotes: + type: integer + description: How many notes are edited at the moment + onlineUsers: + type: integer + description: How many users are online at the moment + distinctOnlineUsers: + type: integer + description: How many distinct users (different machines) are online at the moment + notesCount: + type: integer + description: How many notes are stored on the server + registeredUsers: + type: integer + description: How many users are registered on the server + onlineRegisteredUsers: + type: integer + description: How many of the online users are registered on the server + distinctOnlineRegisteredUsers: + type: integer + description: How many of the distinct online users are registered on the server + isConnectionBusy: + type: boolean + connectionSocketQueueLength: + type: integer + isDisconnectBusy: + type: boolean + disconnectSocketQueueLength: + type: integer + +tags: + - name: note + description: These endpoints create notes, return information about them or export them. + - name: user + description: These endpoints return information about the current logged-in user and it's note history. If no user is logged-in, the most of this requests will fail with either a HTTP 403 or a JSON object containing `{"status":"forbidden"}`. + - name: server + description: These endpoints return information about the running HedgeDoc instance. diff --git a/docs/content/dev/ot.md b/docs/content/dev/ot.md new file mode 100644 index 00000000..a1d0bebe --- /dev/null +++ b/docs/content/dev/ot.md @@ -0,0 +1,13 @@ +# Operational Transformation + +From 0.3.2, we started supporting operational transformation. +It makes concurrent editing safe and will not break up other users' operations. +Additionally, now can show other clients' selections. + +See more at [https://operational-transformation.github.io/](https://operational-transformation.github.io/) + +And even more in this 2010 article series: + +- +- +- diff --git a/docs/content/dev/webpack.md b/docs/content/dev/webpack.md new file mode 100644 index 00000000..23bbd7a1 --- /dev/null +++ b/docs/content/dev/webpack.md @@ -0,0 +1,37 @@ +# Webpack + +Webpack is a JavaScript build system for frontend code. You can find out all +about it on [the webpack website](https://webpack.js.org/). + +Here's how we're using it: + +## `webpack.common.js` +This file contains all common definitions for chunks and plugins that are needed by the whole app. + +The various entrypoints under the `entry` key define groups of files (npm packages or .css/.js files directly from this project) that need to be included together to be useful. +The `index` group for example bundles all javascript files and libraries used for the note editor. + +Entrypoints are referenced in the `plugins` section. +The `HtmlWebpackPlugin` uses templates in `public/views/includes` to include the path to the generated resources in new templates under `public/views/build`. These templates are then used by the backend to serve HTML to the browser. + +**TODO:** Document which entry points are used for what. + +## `webpack.htmlexport.js` +Separate config for the "save as html" feature. +Packs all CSS from `public/js/htmlExport.js` to `build/html.min.css`. +This file is then downloaded by client-side JS and used to create the HTML. +See `exportToHTML()` in `public/js/extra.js`. + +## `webpack.dev.js` +The development config uses both common configs, enables development mode and enables "cheap" source maps (lines only). +If you need more detailed source maps while developing, you might want to use the `source-maps` option. +See for details. + +## `webpack.prod.js` +The production config uses both common configs and enables production mode. +This automatically enables various optimizations (e.g. UglifyJS). See for details. + +For the global app config, the name of the emitted chunks is changed to include the content hash. +See on why this is a good idea. + +For the HTML export config, CSS minification is enabled. -- cgit v1.2.3