mirror of https://github.com/vapor/docs.git
Add dead link check CI (#679)
This commit is contained in:
parent
2b993e8527
commit
41b5c4133b
|
|
@ -33,8 +33,34 @@ pip3 install mkdocs-material
|
|||
|
||||
Run with `mkdocs serve`
|
||||
|
||||
## Testing
|
||||
|
||||
If you want to check dead links, use markdown-link-check
|
||||
|
||||
```sh
|
||||
npm install --save-dev markdown-link-check
|
||||
```
|
||||
|
||||
Run with
|
||||
|
||||
```sh
|
||||
find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check -q -c markdown-link-check-config.yml
|
||||
```
|
||||
on directly under the repository.
|
||||
|
||||
|
||||
OR
|
||||
|
||||
Run docker directly under the repository
|
||||
|
||||
```sh
|
||||
docker run -v ${PWD}:/tmp:ro --rm -i --entrypoint "sh" ghcr.io/tcort/markdown-link-check:stable "-c" "find /tmp -name \*.md -print0 | xargs -0 -n1 markdown-link-check -q -c /tmp/markdown-link-check-config.yml"
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Maintainers
|
||||
- [@0xtim](https://github.com/0xTim)
|
||||
- [@mcdappdev](https://github.com/mcdappdev)
|
||||
|
||||
See https://github.com/vapor/vapor/blob/master/.github/maintainers.md for more information.
|
||||
See https://github.com/vapor/vapor/blob/main/.github/maintainers.md for more information.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
name: Build docs and check cloudformation
|
||||
name: Build docs and check cloudformation and dead links
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
|
@ -6,7 +6,7 @@ on:
|
|||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
check:
|
||||
name: build docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
|
@ -21,4 +21,11 @@ jobs:
|
|||
- name: Setup cloudformation linter
|
||||
uses: ScottBrenner/cfn-lint-action@v2.2.1
|
||||
- name: Run cloudformation lint
|
||||
run: cfn-lint -t stack.yml
|
||||
run: cfn-lint -t stack.yml
|
||||
- name: Check dead links
|
||||
uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
with:
|
||||
folder-path: '.'
|
||||
config-file: 'markdown-link-check-config.yml'
|
||||
use-verbose-mode: 'yes'
|
||||
use-quiet-mode: 'yes'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Client
|
||||
|
||||
Vapor's client API allows you to make HTTP calls to external resources. It is built on [async-http-client](https://github.com/swift-server/async-http-client) and integrates with the [content](./content.md) API.
|
||||
Vapor's client API allows you to make HTTP calls to external resources. It is built on [async-http-client](https://github.com/swift-server/async-http-client) and integrates with the [content](content.md) API.
|
||||
|
||||
## Overview
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ There are methods for each of the HTTP verbs like `get`, `post`, and `delete`. T
|
|||
|
||||
### Content
|
||||
|
||||
Vapor's [content](./content.md) API is available for handling data in client requests and responses. To encode content, query parameters or add headers to the request, use the `beforeSend` closure.
|
||||
Vapor's [content](content.md) API is available for handling data in client requests and responses. To encode content, query parameters or add headers to the request, use the `beforeSend` closure.
|
||||
|
||||
```swift
|
||||
let response = try await req.client.post("https://httpbin.org/status/200") { req in
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Client
|
||||
|
||||
Vapor的 `Client` API 允许您使用 HTTP 调用外部资源,它基于 [async-http-client](https://github.com/swift-server/async-http-client) 构建,并集成了 [Content](./content.md) API。
|
||||
Vapor的 `Client` API 允许您使用 HTTP 调用外部资源,它基于 [async-http-client](https://github.com/swift-server/async-http-client) 构建,并集成了 [Content](content.md) API。
|
||||
|
||||
|
||||
## 概述
|
||||
|
|
@ -32,7 +32,7 @@ HTTP 的常用方法(例如 `get`, `post`, `delete`)都有便捷的调用方式
|
|||
|
||||
### Content
|
||||
|
||||
Vapor 的 [Content](./content.md) API 可用于处理客户请求和响应中的数据,如果要在请求体中添加参数或编码,请在 `beforeSend` 闭包中进行。
|
||||
Vapor 的 [Content](content.md) API 可用于处理客户请求和响应中的数据,如果要在请求体中添加参数或编码,请在 `beforeSend` 闭包中进行。
|
||||
|
||||
```swift
|
||||
let response = try await req.client.post("https://httpbin.org/status/200") { req in
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ extension HTML: AsyncResponseEncodable {
|
|||
}
|
||||
}
|
||||
```
|
||||
注意,它允许自定义“Content-Type”头,查看更多请查阅 [`HTTPHeaders` reference](https://api.vapor.codes/vapor/master/Vapor/)
|
||||
注意,它允许自定义“Content-Type”头,查看更多请查阅 [`HTTPHeaders` reference](https://api.vapor.codes/vapor/main/Vapor/)
|
||||
|
||||
接下来,你可以在你的路由中使用 `HTML` 作为 response:
|
||||
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ app.get("hello", ":name") { req -> String in
|
|||
We can be sure that `req.parameters.get` will never return `nil` here since our route path includes `:name`. However, if you are accessing route parameters in middleware or in code triggered by multiple routes, you will want to handle the possibility of `nil`.
|
||||
|
||||
!!! tip
|
||||
If you want to retrieve URL query params, e.g. `/hello/?name=foo` you need to use Vapor's Content APIs to handle URL encoded data in the URL's query string. See [`Content` reference](/content/) for more details.
|
||||
If you want to retrieve URL query params, e.g. `/hello/?name=foo` you need to use Vapor's Content APIs to handle URL encoded data in the URL's query string. See [`Content` reference](content.md) for more details.
|
||||
|
||||
`req.parameters.get` also supports casting the parameter to `LosslessStringConvertible` types automatically.
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ builder.create()
|
|||
|
||||
## MongoDB
|
||||
|
||||
Fluent MongoDB 是一个集成了 [Fluent](../fluent/overview.zh.md) 和 [MongoKitten](https://github.com/OpenKitten/MongoKitten/) 的驱动程序。它利用 Swift 的强类型特性以及 Fluent 使用与 MongoDB 数据库无关的接口。
|
||||
Fluent MongoDB 是一个集成了 [Fluent](../fluent/overview.md) 和 [MongoKitten](https://github.com/OpenKitten/MongoKitten/) 的驱动程序。它利用 Swift 的强类型特性以及 Fluent 使用与 MongoDB 数据库无关的接口。
|
||||
|
||||
MongoDB 中最常见的标识符是 ObjectId。你可以在项目中使用 `@ID(custom: .id)` 自定义标志符。
|
||||
如果需要在 SQL 中使用相同的模型,请不要使用 `ObjectId`。改为使用 `UUID`。
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ app.migrations.add(MyMigration(), to: .myDatabase)
|
|||
vapor run migrate
|
||||
```
|
||||
|
||||
你也可以[通过 Xcode 运行这个命令](../advanced/commands.zh.md#xcode)。migrate 命令将检查数据库,查看自上次运行以来是否注册了新的迁移。如果有新的迁移,运行它之前会要求确认。
|
||||
你也可以[通过 Xcode 运行这个命令](../advanced/commands.md#xcode)。migrate 命令将检查数据库,查看自上次运行以来是否注册了新的迁移。如果有新的迁移,运行它之前会要求确认。
|
||||
|
||||
### 撤销
|
||||
|
||||
|
|
@ -93,6 +93,6 @@ try await app.autoMigrate()
|
|||
|
||||
## 下一步
|
||||
|
||||
请查看[schema builder](schema.md) 和 [query builder](query.zh.md) 指南,以了解更多迁移相关的信息。
|
||||
请查看[schema builder](schema.md) 和 [query builder](query.md) 指南,以了解更多迁移相关的信息。
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ Models expose a static method `query(on:)` that returns a query builder.
|
|||
Planet.query(on: database).all()
|
||||
```
|
||||
|
||||
Learn more about querying in the [query](./query.md) section.
|
||||
Learn more about querying in the [query](query.md) section.
|
||||
|
||||
## Find
|
||||
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ Note that for this migration to work, we need to be able to reference both the r
|
|||
|
||||
## Setting Model Space
|
||||
|
||||
To define the [space for a model](/fluent/model/#database-space), pass the space to the `schema(_:space:)` when creating the table. E.g.
|
||||
To define the [space for a model](model.md#database-space), pass the space to the `schema(_:space:)` when creating the table. E.g.
|
||||
|
||||
```swift
|
||||
try await db.schema("planets", space: "mirror_universe")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Willkommen zur Dokumentation von Vapor! Vapor ist ein Web-Framework für Swift,
|
|||
|
||||
## Einstieg
|
||||
|
||||
Für die Installation, folge den Anweisungen im Abschnitt [Installation → macOS](install/macos.de.md). Nach der Installation, folge den Anweisungen [Erste Schritte → Hello, world](getting-started/hello-world.de.md) um deine erste Vapor-Anwendungen zu erstellen.
|
||||
Für die Installation, folge den Anweisungen im Abschnitt [Installation → macOS](install/macos.md). Nach der Installation, folge den Anweisungen [Erste Schritte → Hello, world](getting-started/hello-world.md) um deine erste Vapor-Anwendungen zu erstellen.
|
||||
|
||||
## Hilfen
|
||||
|
||||
|
|
|
|||
|
|
@ -54,4 +54,4 @@ vapor --help
|
|||
|
||||
ausführst. Dir sollten nun mehrere Befehl der Toolbox angezeigt werden.
|
||||
|
||||
Nach der Swift-Installation kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](/hallo-world.de.md).
|
||||
Nach der Swift-Installation kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](../getting-started/hello-world.md).
|
||||
|
|
@ -29,4 +29,4 @@ brew install vapor
|
|||
|
||||
##
|
||||
|
||||
Nach den Installationen kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](../getting-started/hello-world.de.md).
|
||||
Nach den Installationen kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](../getting-started/hello-world.md).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Custom Tags
|
||||
|
||||
You can create custom Leaf tags using the [`LeafTag`](https://api.vapor.codes/leaf-kit/latest/LeafKit/LeafSyntax/LeafTag.html) protocol.
|
||||
You can create custom Leaf tags using the [`LeafTag`](https://api.vapor.codes/leaf-kit/main/LeafKit/LeafTag) protocol.
|
||||
|
||||
To demonstrate this, let's take a look at creating a custom tag `#now` that prints the current timestamp. The tag will also support a single, optional parameter for specifying the date format.
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ This tells Vapor to use the `LeafRenderer` when you call `req.view` in your code
|
|||
Leaf has an internal cache for rendering pages. When the `Application`'s environment is set to `.development`, this cache is disabled, so that changes to templates take effect immediately. In `.production` and all other environments, the cache is enabled by default; any changes made to templates will not take effect until the application is restarted.
|
||||
|
||||
!!! warning
|
||||
For Leaf to be able to find the templates when running from Xcode, you must set the [custom working directory](/xcode/#custom-working-directory) for you Xcode workspace.
|
||||
|
||||
For Leaf to be able to find the templates when running from Xcode, you must set the [custom working directory](../getting-started/xcode.md#custom-working-directory) for you Xcode workspace.
|
||||
## Folder Structure
|
||||
|
||||
Once you have configured Leaf, you will need to ensure you have a `Views` folder to store your `.leaf` files in. By default, Leaf expects the views folder to be a `./Resources/Views` relative to your project's root.
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ let package = Package(
|
|||
|
||||
## 配置
|
||||
|
||||
将包添加到项目后,通常在 [`configure.swift`](../getting-started/folder-structure.zh.md#configureswift) 中进行配置,这样 Vapor 就可以使用它了。
|
||||
将包添加到项目后,通常在 [`configure.swift`](../getting-started/folder-structure.md#configureswift) 中进行配置,这样 Vapor 就可以使用它了。
|
||||
|
||||
```swift
|
||||
import Leaf
|
||||
|
|
@ -45,7 +45,7 @@ app.views.use(.leaf)
|
|||
Leaf 有一个用于渲染页面的内部缓存。当 `Application` 的运行环境设置为 `.development` 时,此缓存被禁用,因此对模板的更改会立即生效。在 `.production` 环境和所有的其它环境中,默认启用缓存;应用重启之前,对模板所做的任何更改都不会生效。
|
||||
|
||||
!!! 警告
|
||||
从 Xcode 运行项目时为了 Leaf 能够找到模板,你必须为你的 Xcode 工作区设置[自定义工作目录](../getting-started/xcode.zh.md#working-directory)。
|
||||
从 Xcode 运行项目时为了 Leaf 能够找到模板,你必须为你的 Xcode 工作区设置[自定义工作目录](../getting-started/xcode.md#working-directory)。
|
||||
|
||||
## 目录结构
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Leaf also supports many expressions you are familiar with in Swift.
|
|||
|
||||
## Context
|
||||
|
||||
In the example from [Getting Started](./getting-started.md), we used a `[String: String]` dictionary to pass data to Leaf. However, you can pass anything that conforms to `Encodable`. It's actually preferred to use `Encodable` structs since `[String: Any]` is not supported. This means you *can not* pass in an array, and should instead wrap it in a struct:
|
||||
In the example from [Getting Started](getting-started.md), we used a `[String: String]` dictionary to pass data to Leaf. However, you can pass anything that conforms to `Encodable`. It's actually preferred to use `Encodable` structs since `[String: Any]` is not supported. This means you *can not* pass in an array, and should instead wrap it in a struct:
|
||||
|
||||
```swift
|
||||
struct WelcomeContext: Encodable {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
Redis can act as a storage provider for caching [session data](../advanced/sessions.md#session-data) such as user credentials.
|
||||
|
||||
If a custom [`RedisSessionsDelegate`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/) isn't provided, a default will be used.
|
||||
If a custom [`RedisSessionsDelegate`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/) isn't provided, a default will be used.
|
||||
|
||||
## Default Behavior
|
||||
|
||||
### SessionID Creation
|
||||
|
||||
Unless you implement the [`makeNewID()`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeNewID()) method in [your own `RedisSessionsDelegate`](#RedisSessionsDelegate), all [`SessionID`](https://api.vapor.codes/vapor/master/Vapor/SessionID/) values will be created by doing the following:
|
||||
Unless you implement the [`makeNewID()`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeNewID()) method in [your own `RedisSessionsDelegate`](#redissessionsdelegate), all [`SessionID`](https://api.vapor.codes/vapor/main/Vapor/SessionID/) values will be created by doing the following:
|
||||
|
||||
1. Generate 32 bytes of random characters
|
||||
1. base64 encode the value
|
||||
|
|
@ -17,9 +17,9 @@ For example: `Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=`
|
|||
|
||||
### SessionData Storage
|
||||
|
||||
The default implementation of `RedisSessionsDelegate` will store [`SessionData`](https://api.vapor.codes/vapor/master/Vapor/SessionData/) as a simple JSON string value using `Codable`.
|
||||
The default implementation of `RedisSessionsDelegate` will store [`SessionData`](https://api.vapor.codes/vapor/main/Vapor/SessionData/) as a simple JSON string value using `Codable`.
|
||||
|
||||
Unless you implement the [`makeRedisKey(for:)`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeRedisKey(for:)) method in your own `RedisSessionsDelegate`, `SessionData` will be stored in Redis with a key that prefixes the `SessionID` with `vrs-` (**V**apor **R**edis **S**essions)
|
||||
Unless you implement the [`makeRedisKey(for:)`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeRedisKey(for:)) method in your own `RedisSessionsDelegate`, `SessionData` will be stored in Redis with a key that prefixes the `SessionID` with `vrs-` (**V**apor **R**edis **S**essions)
|
||||
|
||||
For example: `vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=`
|
||||
|
||||
|
|
@ -39,11 +39,11 @@ app.sessions.use(.redis(delegate: CustomRedisSessionsDelegate()))
|
|||
|
||||
## RedisSessionsDelegate
|
||||
|
||||
> API Documentation: [`RedisSessionsDelegate`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/)
|
||||
> API Documentation: [`RedisSessionsDelegate`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/)
|
||||
|
||||
An object that conforms to this protocol can be used to change how `SessionData` is stored in Redis.
|
||||
|
||||
Only two methods are required to be implemented by a type conforming to the protocol: [`redis(_:store:with:)`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:store:with:)) and [`redis(_:fetchDataFor:)`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:fetchDataFor:)).
|
||||
Only two methods are required to be implemented by a type conforming to the protocol: [`redis(_:store:with:)`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:store:with:)) and [`redis(_:fetchDataFor:)`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:fetchDataFor:)).
|
||||
|
||||
Both are required, as the way you customize writing the session data to Redis is intrinsically linked to how it is to be read from Redis.
|
||||
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ try app.jwt.signers.use(.rs256(key: .public(pem: rsaPublicKey)))
|
|||
|
||||
ECDSA is a more modern algorithm that is similar to RSA. It is considered to be more secure for a given key length than RSA[^1]. However, you should do your own research before deciding.
|
||||
|
||||
[^1]: [https://sectigostore.com/blog/ecdsa-vs-rsa-everything-you-need-to-know/](https://sectigostore.com/blog/ecdsa-vs-rsa-everything-you-need-to-know/)
|
||||
[^1]: https://sectigostore.com/blog/ecdsa-vs-rsa-everything-you-need-to-know/
|
||||
|
||||
Like RSA, you can load ECDSA keys using PEM files:
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ The Install section of the docs goes over installing dependencies.
|
|||
|
||||
## Package.swift
|
||||
|
||||
The first step to upgrading to Vapor 4 is to update your package's dependencies. Below is an example of an upgraded Package.swift file. You can also check out the updated [template Package.swift](https://github.com/vapor/template/blob/master/Package.swift).
|
||||
The first step to upgrading to Vapor 4 is to update your package's dependencies. Below is an example of an upgraded Package.swift file. You can also check out the updated [template Package.swift](https://github.com/vapor/template/blob/main/Package.swift).
|
||||
|
||||
```diff
|
||||
-// swift-tools-version:4.0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"ignorePatterns": [{ "pattern": ".*(localhost|127.0.0.1).*" }],
|
||||
"aliveStatusCodes": [403, 429, 200]
|
||||
}
|
||||
Loading…
Reference in New Issue