Skip to content
Draft
1 change: 1 addition & 0 deletions .github/translation_needed.description.leaf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Languages:
- [ ] 한국어 (Korean)
- [ ] Nederlands (Dutch)
- [ ] Polski (Polish)
- [ ] Português Brasileiro (Brazilian Portuguese)
- [ ] 简体中文 (Simplified Chinese)

Assigned to @vapor/translators - please submit a PR with the relevant updates and check the box once merged.
Expand Down
148 changes: 148 additions & 0 deletions docs/advanced/apns.pt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# APNS

A API do Apple Push Notification Service (APNS) do Vapor facilita a autenticação e o envio de notificações push para dispositivos Apple. É construída sobre o [APNSwift](https://github.com/swift-server-community/APNSwift).

## Primeiros Passos

Vamos ver como você pode começar a usar o APNS.

### Package

O primeiro passo para usar o APNS é adicionar o pacote às suas dependências.

```swift
// swift-tools-version:5.8
import PackageDescription

let package = Package(
name: "my-app",
dependencies: [
// Outras dependências...
.package(url: "https://github.com/vapor/apns.git", from: "4.0.0"),
],
targets: [
.target(name: "App", dependencies: [
// Outras dependências...
.product(name: "VaporAPNS", package: "apns")
]),
// Outros targets...
]
)
```

Se você editar o manifesto diretamente dentro do Xcode, ele automaticamente detectará as mudanças e buscará a nova dependência quando o arquivo for salvo. Caso contrário, no Terminal, execute `swift package resolve` para buscar a nova dependência.

### Configuração

O módulo APNS adiciona uma nova propriedade `apns` ao `Application`. Para enviar notificações push, você precisará definir a propriedade `configuration` com suas credenciais.

```swift
import APNS
import VaporAPNS
import APNSCore

// Configurar APNS usando autenticação JWT.
let apnsConfig = APNSClientConfiguration(
authenticationMethod: .jwt(
privateKey: try .loadFrom(string: "<#key.p8 content#>"),
keyIdentifier: "<#key identifier#>",
teamIdentifier: "<#team identifier#>"
),
environment: .development
)
app.apns.containers.use(
apnsConfig,
eventLoopGroupProvider: .shared(app.eventLoopGroup),
responseDecoder: JSONDecoder(),
requestEncoder: JSONEncoder(),
as: .default
)
```

Preencha os placeholders com suas credenciais. O exemplo acima mostra [autenticação baseada em JWT](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns) usando a chave `.p8` que você obtém do portal de desenvolvedores da Apple. Para [autenticação baseada em TLS](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns) com um certificado, use o método de autenticação `.tls`:

```swift
authenticationMethod: .tls(
privateKeyPath: <#path to private key#>,
pemPath: <#path to pem file#>,
pemPassword: <#optional pem password#>
)
```

### Envio

Uma vez que o APNS está configurado, você pode enviar notificações push usando o método `apns.send` no `Application` ou `Request`.

```swift
// Payload Codable personalizado
struct Payload: Codable {
let acme1: String
let acme2: Int
}
// Criar Alert de notificação push
let dt = "70075697aa918ebddd64efb165f5b9cb92ce095f1c4c76d995b384c623a258bb"
let payload = Payload(acme1: "hey", acme2: 2)
let alert = APNSAlertNotification(
alert: .init(
title: .raw("Olá"),
subtitle: .raw("Este é um teste do vapor/apns")
),
expiration: .immediately,
priority: .immediately,
topic: "<#my topic#>",
payload: payload
)
// Enviar a notificação
try! await req.apns.client.sendAlertNotification(
alert,
deviceToken: dt,
deadline: .distantFuture
)
```

Use `req.apns` sempre que estiver dentro de um route handler.

```swift
// Envia uma notificação push.
app.get("test-push") { req async throws -> HTTPStatus in
try await req.apns.client.send(...)
return .ok
}
```

O primeiro parâmetro aceita o alert de notificação push e o segundo parâmetro é o device token de destino.

## Alert

`APNSAlertNotification` é o metadado real do alert de notificação push a ser enviado. Mais detalhes sobre as especificidades de cada propriedade são fornecidos [aqui](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html). Eles seguem um esquema de nomenclatura um-para-um listado na documentação da Apple.

```swift
let alert = APNSAlertNotification(
alert: .init(
title: .raw("Olá"),
subtitle: .raw("Este é um teste do vapor/apns")
),
expiration: .immediately,
priority: .immediately,
topic: "<#my topic#>",
payload: payload
)
```

Este tipo pode ser passado diretamente ao método `send`.

### Dados de Notificação Personalizados

A Apple fornece aos engenheiros a capacidade de adicionar dados de payload personalizados a cada notificação. Para facilitar isso, aceitamos conformidade `Codable` no parâmetro payload em todas as APIs `send`.

```swift
// Payload Codable personalizado
struct Payload: Codable {
let acme1: String
let acme2: Int
}
```

## Mais Informações

Para mais informações sobre métodos disponíveis, veja o [README do APNSwift](https://github.com/swift-server-community/APNSwift).
129 changes: 129 additions & 0 deletions docs/advanced/commands.pt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Comandos

A API de Comandos do Vapor permite que você construa funções personalizadas de linha de comando e interaja com o terminal. É sobre ela que os comandos padrão do Vapor como `serve`, `routes` e `migrate` são construídos.

## Comandos Padrão

Você pode aprender mais sobre os comandos padrão do Vapor usando a opção `--help`.

```sh
swift run App --help
```

Você pode usar `--help` em um comando específico para ver quais argumentos e opções ele aceita.

```sh
swift run App serve --help
```

### Xcode

Você pode executar comandos no Xcode adicionando argumentos ao scheme `App`. Para fazer isso, siga estes passos:

- Escolha o scheme `App` (à direita dos botões play/stop)
- Clique em "Edit Scheme"
- Escolha o produto "App"
- Selecione a aba "Arguments"
- Adicione o nome do comando em "Arguments Passed On Launch" (ex: `serve`)

## Comandos Personalizados

Você pode criar seus próprios comandos criando tipos que conformam com `AsyncCommand`.

```swift
import Vapor

struct HelloCommand: AsyncCommand {
...
}
```

Adicionar o comando personalizado a `app.asyncCommands` o tornará disponível via `swift run`.

```swift
app.asyncCommands.use(HelloCommand(), as: "hello")
```

Para conformar com `AsyncCommand`, você deve implementar o método `run`. Isso requer declarar uma `Signature`. Você também deve fornecer um texto de ajuda padrão.

```swift
import Vapor

struct HelloCommand: AsyncCommand {
struct Signature: CommandSignature { }

var help: String {
"Diz olá"
}

func run(using context: CommandContext, signature: Signature) async throws {
context.console.print("Olá, mundo!")
}
}
```

Este exemplo simples de comando não tem argumentos ou opções, então deixe a signature vazia.

Você pode acessar o console atual através do contexto fornecido. O Console possui muitos métodos úteis para solicitar entrada do usuário, formatação de saída e mais.

```swift
let name = context.console.ask("Qual é o seu \("nome", color: .blue)?")
context.console.print("Olá, \(name) 👋")
```

Teste seu comando executando:

```sh
swift run App hello
```

### Cowsay

Veja esta recriação do famoso comando [`cowsay`](https://en.wikipedia.org/wiki/Cowsay) para um exemplo de uso de `@Argument` e `@Option`.

```swift
import Vapor

struct Cowsay: AsyncCommand {
struct Signature: CommandSignature {
@Argument(name: "message")
var message: String

@Option(name: "eyes", short: "e")
var eyes: String?

@Option(name: "tongue", short: "t")
var tongue: String?
}

var help: String {
"Gera uma imagem ASCII de uma vaca com uma mensagem."
}

func run(using context: CommandContext, signature: Signature) async throws {
let eyes = signature.eyes ?? "oo"
let tongue = signature.tongue ?? " "
let cow = #"""
< $M >
\ ^__^
\ ($E)\_______
(__)\ )\/\
$T ||----w |
|| ||
"""#.replacingOccurrences(of: "$M", with: signature.message)
.replacingOccurrences(of: "$E", with: eyes)
.replacingOccurrences(of: "$T", with: tongue)
context.console.print(cow)
}
}
```

Tente adicionar isso à sua aplicação e executar.

```swift
app.asyncCommands.use(Cowsay(), as: "cowsay")
```

```sh
swift run App cowsay sup --eyes ^^ --tongue "U "
```
97 changes: 97 additions & 0 deletions docs/advanced/files.pt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Arquivos

O Vapor oferece uma API simples para ler e escrever arquivos de forma assíncrona dentro de route handlers. Esta API é construída sobre o tipo [`NonBlockingFileIO`](https://swiftpackageindex.com/apple/swift-nio/main/documentation/nioposix/nonblockingfileio) do NIO.

## Leitura

O método principal para ler um arquivo entrega partes (chunks) a um callback handler conforme são lidas do disco. O arquivo a ser lido é especificado pelo seu caminho. Caminhos relativos procurarão no diretório de trabalho atual do processo.

```swift
// Lê um arquivo do disco de forma assíncrona.
let readComplete: EventLoopFuture<Void> = req.fileio.readFile(at: "/caminho/do/arquivo") { chunk in
print(chunk) // ByteBuffer
}

// Ou

try await req.fileio.readFile(at: "/caminho/do/arquivo") { chunk in
print(chunk) // ByteBuffer
}
// Leitura completa
```

Se estiver usando `EventLoopFuture`s, o future retornado sinalizará quando a leitura foi concluída ou quando um erro ocorreu. Se estiver usando `async`/`await`, uma vez que o `await` retornar, a leitura foi concluída. Se um erro ocorrer, ele lançará um erro.

### Stream

O método `streamFile` converte um arquivo em streaming para uma `Response`. Este método definirá headers apropriados como `ETag` e `Content-Type` automaticamente.

```swift
// Faz streaming de um arquivo como resposta HTTP de forma assíncrona.
req.fileio.streamFile(at: "/caminho/do/arquivo").map { res in
print(res) // Response
}

// Ou

let res = req.fileio.streamFile(at: "/caminho/do/arquivo")
print(res)

```

O resultado pode ser retornado diretamente pelo seu route handler.

### Collect

O método `collectFile` lê o arquivo especificado em um buffer.

```swift
// Lê o arquivo em um buffer.
req.fileio.collectFile(at: "/caminho/do/arquivo").map { buffer in
print(buffer) // ByteBuffer
}

// ou

let buffer = req.fileio.collectFile(at: "/caminho/do/arquivo")
print(buffer)
```

!!! warning "Aviso"
Este método requer que o arquivo inteiro esteja na memória de uma vez. Use leitura por chunks ou streaming para limitar o uso de memória.

## Escrita

O método `writeFile` suporta escrever um buffer em um arquivo.

```swift
// Escreve buffer em um arquivo.
req.fileio.writeFile(ByteBuffer(string: "Olá, mundo"), at: "/caminho/do/arquivo")
```

O future retornado sinalizará quando a escrita foi concluída ou quando um erro ocorreu.

## Middleware

Para mais informações sobre servir arquivos da pasta _Public_ do seu projeto automaticamente, veja [Middleware &rarr; FileMiddleware](middleware.md#file-middleware).

## Avançado

Para casos que a API do Vapor não suporta, você pode usar o tipo `NonBlockingFileIO` do NIO diretamente.

```swift
// Thread principal.
let fileHandle = try await app.fileio.openFile(
path: "/caminho/do/arquivo",
eventLoop: app.eventLoopGroup.next()
).get()
print(fileHandle)

// Em um route handler.
let fileHandle = try await req.application.fileio.openFile(
path: "/caminho/do/arquivo",
eventLoop: req.eventLoop)
print(fileHandle)
```

Para mais informações, consulte a [referência de API](https://swiftpackageindex.com/apple/swift-nio/main/documentation/nioposix/nonblockingfileio) do SwiftNIO.
Loading