@luanxdd/meowgallery 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -63
- package/dist/client.d.ts +11 -10
- package/dist/client.js +20 -169
- package/dist/client.js.map +1 -1
- package/dist/core/transport.d.ts +9 -0
- package/dist/core/transport.js +166 -0
- package/dist/core/transport.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/models/access.d.ts +19 -0
- package/dist/models/access.js +2 -0
- package/dist/models/access.js.map +1 -0
- package/dist/models/media.d.ts +16 -0
- package/dist/models/media.js +2 -0
- package/dist/models/media.js.map +1 -0
- package/dist/models/options.d.ts +16 -0
- package/dist/models/options.js +2 -0
- package/dist/models/options.js.map +1 -0
- package/dist/models/post.d.ts +12 -0
- package/dist/models/post.js +2 -0
- package/dist/models/post.js.map +1 -0
- package/dist/node/save.d.ts +8 -0
- package/dist/node/save.js +46 -0
- package/dist/node/save.js.map +1 -0
- package/dist/node/stream.d.ts +6 -0
- package/dist/node/stream.js +16 -0
- package/dist/node/stream.js.map +1 -0
- package/dist/node.d.ts +3 -6
- package/dist/node.js +2 -36
- package/dist/node.js.map +1 -1
- package/dist/resources/access.d.ts +9 -0
- package/dist/resources/access.js +19 -0
- package/dist/resources/access.js.map +1 -0
- package/dist/resources/item.d.ts +25 -0
- package/dist/resources/item.js +50 -0
- package/dist/resources/item.js.map +1 -0
- package/dist/resources/media.d.ts +8 -0
- package/dist/resources/media.js +17 -0
- package/dist/resources/media.js.map +1 -0
- package/dist/resources/posts.d.ts +9 -0
- package/dist/resources/posts.js +14 -0
- package/dist/resources/posts.js.map +1 -0
- package/dist/resources/publication.d.ts +20 -0
- package/dist/resources/publication.js +45 -0
- package/dist/resources/publication.js.map +1 -0
- package/dist/types.d.ts +4 -56
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -1,105 +1,92 @@
|
|
|
1
|
-
# MeowGallery
|
|
1
|
+
# MeowGallery
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Publicações, imagens, vídeos e áudio em uma interface pequena e organizada.
|
|
4
|
+
TypeScript, ESM, Node.js 22+ e navegadores modernos. Sem dependências de produção.
|
|
4
5
|
|
|
5
6
|
## Instalar
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
Após publicar esta versão: `npm install @luanxdd/meowgallery@^0.4.0`.
|
|
9
|
+
Antes da publicação, instale o arquivo `luanxdd-meowgallery-0.4.0.tgz` incluído no ZIP.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
npm install ./meowgallery-sdk-0.2.0.tgz
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Obter uma publicação
|
|
11
|
+
## Uma publicação
|
|
14
12
|
|
|
15
13
|
```typescript
|
|
16
|
-
import { MeowGallery } from "@meowgallery
|
|
14
|
+
import { MeowGallery } from "@luanxdd/meowgallery";
|
|
17
15
|
|
|
18
16
|
const gallery = new MeowGallery({
|
|
19
|
-
baseUrl: "https://gallery.
|
|
17
|
+
baseUrl: "https://gallery.kairogg.com.br",
|
|
20
18
|
token: process.env.MEOWGALLERY_KEY!,
|
|
21
19
|
});
|
|
22
20
|
|
|
23
|
-
const post = await gallery.
|
|
21
|
+
const post = await gallery.posts.resolve(url);
|
|
24
22
|
|
|
25
|
-
console.log(post.author.name);
|
|
26
|
-
console.log(post.
|
|
27
|
-
|
|
28
|
-
for (const item of post.items) {
|
|
29
|
-
console.log(item.kind, item.width, item.height, item.delivery.expiresAt);
|
|
30
|
-
}
|
|
23
|
+
console.log(post.author.name, post.caption);
|
|
24
|
+
console.log(post.video?.url);
|
|
31
25
|
```
|
|
32
26
|
|
|
33
|
-
|
|
27
|
+
Reutilize uma instância por configuração de autenticação. `post.items` preserva a ordem original; `post.images` e `post.videos` selecionam tipos; `post.video` é o primeiro vídeo ou `undefined`. `post.audio` contém a faixa separada quando disponível, ou `null`.
|
|
34
28
|
|
|
35
|
-
##
|
|
29
|
+
## Pronto para bots
|
|
36
30
|
|
|
37
31
|
```typescript
|
|
38
|
-
import {
|
|
32
|
+
import { streamMedia } from "@luanxdd/meowgallery/node";
|
|
39
33
|
|
|
40
|
-
|
|
34
|
+
if (post.video) {
|
|
35
|
+
const stream = await streamMedia(post.video, {
|
|
36
|
+
signal: AbortSignal.timeout(60_000),
|
|
37
|
+
});
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
await saveMedia(gallery, item, "./publicacao.bin");
|
|
39
|
+
// Passe stream ao método de envio do framework.
|
|
44
40
|
}
|
|
45
41
|
```
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
O stream começa sem aguardar o arquivo inteiro e sem gravar em disco. O framework pode precisar preparar ou armazenar a mídia por conta própria. Consuma o stream ou encerre com `stream.destroy()`.
|
|
48
44
|
|
|
49
|
-
Para
|
|
45
|
+
Para frameworks que aceitam URL, use `post.video.url`: é o link temporário protegido, não a origem da rede social. Não acrescente a chave da API a esse link.
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
const response = await gallery.download(post.items[0]!);
|
|
53
|
-
const stream = response.body;
|
|
54
|
-
```
|
|
47
|
+
## Mídia
|
|
55
48
|
|
|
56
|
-
|
|
49
|
+
| Operação | Resultado |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| `item.url` | Link protegido |
|
|
52
|
+
| `item.expired` | Se o link já expirou |
|
|
53
|
+
| `item.open(options)` | Response com status e cabeçalhos |
|
|
54
|
+
| `item.stream(options)` | Web Stream |
|
|
55
|
+
| `item.toJSON()` | Metadados serializáveis |
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
`open` e `stream` aceitam `signal` e `range`, como `{ range: "bytes=0-1023" }`. Consuma ou cancele cada corpo. Não há Buffer completo automático.
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
contém a faixa separada, com seu próprio link temporário.
|
|
59
|
+
Para gravar explicitamente no consumidor:
|
|
62
60
|
|
|
63
61
|
```typescript
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
import { saveMedia } from "@luanxdd/meowgallery/node";
|
|
63
|
+
|
|
64
|
+
if (post.video) {
|
|
65
|
+
await saveMedia(post.video, "./video.mp4", {
|
|
66
|
+
maxBytes: 64 * 1024 * 1024,
|
|
67
|
+
});
|
|
66
68
|
}
|
|
67
69
|
```
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
e não depende de FFmpeg. Na versão 0.2.0 foram removidos `createMotion`,
|
|
71
|
-
`MotionOptions` e o campo `composition`.
|
|
71
|
+
A gravação é atômica, não sobrescreve destinos e remove arquivos parciais. Fotos e áudio permanecem separados; não há conversão para MP4. Confira `mimeType` ao escolher a extensão.
|
|
72
72
|
|
|
73
|
-
##
|
|
73
|
+
## Acesso, erros e expiração
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
const gallery = new MeowGallery({
|
|
77
|
-
baseUrl: "https://gallery.seudominio.com",
|
|
78
|
-
token: async () => auth.getAccessToken(),
|
|
79
|
-
});
|
|
80
|
-
```
|
|
75
|
+
`gallery.access.create(input)`, `list()` e `revoke(id)` exigem Owner. Bots precisam dos escopos `captures:read` e `delivery:read`. `sources:authenticated` permite usar a sessão Instagram configurada. Nunca exponha chaves de bots ou Owner no frontend.
|
|
81
76
|
|
|
82
|
-
|
|
77
|
+
OAuth aceita `token: async () => auth.getAccessToken()`; login e renovação pertencem ao provedor de identidade. A função é chamada antes de cada operação autenticada.
|
|
83
78
|
|
|
84
|
-
|
|
79
|
+
`MeowGalleryError` contém `code`, `status`, `requestId` e `retryAfter`. Operações aceitam `signal: AbortSignal.timeout(30_000)`.
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
import { MeowGalleryError } from "@meowgallery/sdk";
|
|
81
|
+
Links expiram. Resolva o post novamente para obter links novos; use `{ refresh: true }` se a origem expirar antes do link. Não há repetição automática de POST nem cache de credenciais na SDK.
|
|
88
82
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (error instanceof MeowGalleryError) {
|
|
95
|
-
console.error(error.code, error.message, error.requestId);
|
|
96
|
-
} else {
|
|
97
|
-
throw error;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
```
|
|
83
|
+
## Compatibilidade
|
|
84
|
+
|
|
85
|
+
`gallery.capture(url)` retorna dados simples. `gallery.download(item)` e os métodos antigos de credenciais permanecem disponíveis.
|
|
86
|
+
|
|
87
|
+
`gallery.posts.resolve(url)` retorna `Publication`, compatível estruturalmente com `Capture`, com itens `MediaItem`. `post.toJSON()` e `JSON.stringify(post)` produzem dados sem transporte ou token.
|
|
101
88
|
|
|
102
|
-
|
|
89
|
+
`streamMedia(gallery, item)` e `saveMedia(gallery, item, destination)` continuam funcionando.
|
|
103
90
|
|
|
104
91
|
## Desenvolvimento
|
|
105
92
|
|
|
@@ -110,4 +97,4 @@ npm test
|
|
|
110
97
|
npm pack
|
|
111
98
|
```
|
|
112
99
|
|
|
113
|
-
|
|
100
|
+
`core` contém transporte; `models`, contratos; `resources`, operações e objetos; `node`, adaptação e arquivos. Aliases internos nativos ficam em `package.json#imports`; o consumidor não precisa configurar aliases. A entrada `/node` não deve entrar em bundles de navegador.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Access } from "#resources/access";
|
|
2
|
+
import { MediaLibrary } from "#resources/media";
|
|
3
|
+
import { Posts } from "#resources/posts";
|
|
4
|
+
import type { CaptureOptions, CredentialInput, DeliveryOptions, Media, MeowGalleryOptions, RequestOptions } from "#types";
|
|
2
5
|
export declare class MeowGallery {
|
|
3
|
-
|
|
6
|
+
readonly posts: Posts;
|
|
7
|
+
readonly media: MediaLibrary;
|
|
8
|
+
readonly access: Access;
|
|
4
9
|
constructor(options: MeowGalleryOptions);
|
|
5
|
-
capture(url: string, options?:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
listCredentials(options?: RequestOptions): Promise<Credential[]>;
|
|
10
|
+
capture(url: string, options?: CaptureOptions): Promise<import("#types").Capture>;
|
|
11
|
+
download(media: Media, options?: DeliveryOptions): Promise<Response>;
|
|
12
|
+
createCredential(input: CredentialInput, options?: RequestOptions): Promise<import("#types").CreatedCredential>;
|
|
13
|
+
listCredentials(options?: RequestOptions): Promise<import("#types").Credential[]>;
|
|
10
14
|
revokeCredential(id: string, options?: RequestOptions): Promise<void>;
|
|
11
|
-
download(media: Media, options?: RequestOptions & {
|
|
12
|
-
readonly range?: string;
|
|
13
|
-
}): Promise<Response>;
|
|
14
15
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,181 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Transport } from "#core/transport";
|
|
2
|
+
import { Access } from "#resources/access";
|
|
3
|
+
import { MediaLibrary } from "#resources/media";
|
|
4
|
+
import { Posts } from "#resources/posts";
|
|
2
5
|
export class MeowGallery {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
#timeout;
|
|
6
|
+
posts;
|
|
7
|
+
media;
|
|
8
|
+
access;
|
|
7
9
|
constructor(options) {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
url.username ||
|
|
13
|
-
url.password ||
|
|
14
|
-
url.pathname !== "/" ||
|
|
15
|
-
url.search ||
|
|
16
|
-
url.hash) {
|
|
17
|
-
throw new TypeError("baseUrl deve ser uma origem HTTPS válida.");
|
|
18
|
-
}
|
|
19
|
-
this.#origin = url.origin;
|
|
20
|
-
this.#token = options.token;
|
|
21
|
-
this.#fetch = options.fetch ?? globalThis.fetch;
|
|
22
|
-
this.#timeout = options.timeoutMs ?? 35_000;
|
|
23
|
-
if (!Number.isSafeInteger(this.#timeout) ||
|
|
24
|
-
this.#timeout < 1 ||
|
|
25
|
-
this.#timeout > 300_000) {
|
|
26
|
-
throw new TypeError("timeoutMs deve estar entre 1 e 300000.");
|
|
27
|
-
}
|
|
10
|
+
const transport = new Transport(options);
|
|
11
|
+
this.media = new MediaLibrary(transport);
|
|
12
|
+
this.posts = new Posts(transport, this.media);
|
|
13
|
+
this.access = new Access(transport);
|
|
28
14
|
}
|
|
29
|
-
capture(url, options = {}) {
|
|
30
|
-
|
|
15
|
+
async capture(url, options = {}) {
|
|
16
|
+
const publication = await this.posts.resolve(url, options);
|
|
17
|
+
return publication.toJSON();
|
|
18
|
+
}
|
|
19
|
+
download(media, options = {}) {
|
|
20
|
+
return this.media.open(media, options);
|
|
31
21
|
}
|
|
32
22
|
createCredential(input, options = {}) {
|
|
33
|
-
return this
|
|
23
|
+
return this.access.create(input, options);
|
|
34
24
|
}
|
|
35
25
|
listCredentials(options = {}) {
|
|
36
|
-
return this
|
|
26
|
+
return this.access.list(options);
|
|
37
27
|
}
|
|
38
28
|
revokeCredential(id, options = {}) {
|
|
39
|
-
|
|
40
|
-
throw new TypeError("Identificador de credencial inválido.");
|
|
41
|
-
}
|
|
42
|
-
return this.#request("DELETE", `/v1/credentials/${id}`, undefined, options);
|
|
43
|
-
}
|
|
44
|
-
async download(media, options = {}) {
|
|
45
|
-
const url = new URL(media.delivery.url);
|
|
46
|
-
if (url.origin !== this.#origin ||
|
|
47
|
-
!/^\/v1\/delivery\/[A-Za-z0-9_-]+$/.test(url.pathname) ||
|
|
48
|
-
url.username ||
|
|
49
|
-
url.password ||
|
|
50
|
-
url.search ||
|
|
51
|
-
url.hash) {
|
|
52
|
-
throw new TypeError("O link de entrega não pertence a esta MeowGallery.");
|
|
53
|
-
}
|
|
54
|
-
const expires = Date.parse(media.delivery.expiresAt);
|
|
55
|
-
if (!Number.isFinite(expires) || expires <= Date.now()) {
|
|
56
|
-
throw new MeowGalleryError("O link expirou. Solicite a publicação novamente.", { code: "delivery_expired", status: 410 });
|
|
57
|
-
}
|
|
58
|
-
const headers = new Headers();
|
|
59
|
-
if (options.range) {
|
|
60
|
-
headers.set("Range", options.range);
|
|
61
|
-
}
|
|
62
|
-
const response = await this.#send(url.href, {
|
|
63
|
-
headers,
|
|
64
|
-
signal: this.#signal(options.signal, 300_000),
|
|
65
|
-
});
|
|
66
|
-
if (!response.ok) {
|
|
67
|
-
throw await this.#failure(response);
|
|
68
|
-
}
|
|
69
|
-
return response;
|
|
70
|
-
}
|
|
71
|
-
async #request(method, path, body, options) {
|
|
72
|
-
const token = typeof this.#token === "function" ? await this.#token() : this.#token;
|
|
73
|
-
if (!token || /[\r\n]/.test(token)) {
|
|
74
|
-
throw new TypeError("Token de autenticação inválido.");
|
|
75
|
-
}
|
|
76
|
-
const headers = new Headers({
|
|
77
|
-
Accept: "application/json",
|
|
78
|
-
Authorization: `Bearer ${token}`,
|
|
79
|
-
});
|
|
80
|
-
const init = {
|
|
81
|
-
method,
|
|
82
|
-
headers,
|
|
83
|
-
signal: this.#signal(options.signal, this.#timeout),
|
|
84
|
-
};
|
|
85
|
-
if (body !== undefined) {
|
|
86
|
-
headers.set("Content-Type", "application/json");
|
|
87
|
-
init.body = JSON.stringify(body);
|
|
88
|
-
}
|
|
89
|
-
const response = await this.#send(`${this.#origin}${path}`, init);
|
|
90
|
-
if (!response.ok) {
|
|
91
|
-
throw await this.#failure(response);
|
|
92
|
-
}
|
|
93
|
-
if (response.status === 204) {
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
|
-
const envelope = await this.#json(response);
|
|
97
|
-
if (!envelope || typeof envelope !== "object" || !("data" in envelope)) {
|
|
98
|
-
throw new MeowGalleryError("Resposta inesperada do serviço.", {
|
|
99
|
-
code: "invalid_response",
|
|
100
|
-
status: response.status,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
return envelope.data;
|
|
104
|
-
}
|
|
105
|
-
#signal(signal, timeout) {
|
|
106
|
-
const deadline = AbortSignal.timeout(timeout);
|
|
107
|
-
return signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
108
|
-
}
|
|
109
|
-
async #send(url, init) {
|
|
110
|
-
try {
|
|
111
|
-
return await this.#fetch(url, {
|
|
112
|
-
...init,
|
|
113
|
-
redirect: "error",
|
|
114
|
-
credentials: "omit",
|
|
115
|
-
cache: "no-store",
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
throw new MeowGalleryError(init.signal?.aborted
|
|
120
|
-
? "Solicitação cancelada ou expirada."
|
|
121
|
-
: "Não foi possível conectar à MeowGallery.", { code: init.signal?.aborted ? "request_aborted" : "network_error" });
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
async #failure(response) {
|
|
125
|
-
const body = (await this.#json(response).catch(() => null));
|
|
126
|
-
const retryHeader = response.headers.get("retry-after");
|
|
127
|
-
const retry = retryHeader === null ? NaN : Number(retryHeader);
|
|
128
|
-
return new MeowGalleryError(typeof body?.error?.message === "string"
|
|
129
|
-
? body.error.message
|
|
130
|
-
: "A solicitação não foi concluída.", {
|
|
131
|
-
code: typeof body?.error?.code === "string"
|
|
132
|
-
? body.error.code
|
|
133
|
-
: "http_error",
|
|
134
|
-
status: response.status,
|
|
135
|
-
requestId: response.headers.get("x-request-id"),
|
|
136
|
-
retryAfter: Number.isFinite(retry) && retry >= 0 ? retry : null,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
async #json(response) {
|
|
140
|
-
const reader = response.body?.getReader();
|
|
141
|
-
if (!reader) {
|
|
142
|
-
throw new MeowGalleryError("Resposta vazia do serviço.", {
|
|
143
|
-
code: "invalid_response",
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
const chunks = [];
|
|
147
|
-
let size = 0;
|
|
148
|
-
try {
|
|
149
|
-
for (;;) {
|
|
150
|
-
const { done, value } = await reader.read();
|
|
151
|
-
if (done) {
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
size += value.byteLength;
|
|
155
|
-
if (size > 1_048_576) {
|
|
156
|
-
await reader.cancel();
|
|
157
|
-
throw new Error("Response limit exceeded");
|
|
158
|
-
}
|
|
159
|
-
chunks.push(value);
|
|
160
|
-
}
|
|
161
|
-
const joined = new Uint8Array(size);
|
|
162
|
-
let offset = 0;
|
|
163
|
-
for (const chunk of chunks) {
|
|
164
|
-
joined.set(chunk, offset);
|
|
165
|
-
offset += chunk.byteLength;
|
|
166
|
-
}
|
|
167
|
-
return JSON.parse(new TextDecoder().decode(joined));
|
|
168
|
-
}
|
|
169
|
-
catch {
|
|
170
|
-
throw new MeowGalleryError("Resposta inválida ou interrompida do serviço.", {
|
|
171
|
-
code: "invalid_response",
|
|
172
|
-
status: response.status,
|
|
173
|
-
requestId: response.headers.get("x-request-id"),
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
finally {
|
|
177
|
-
reader.releaseLock();
|
|
178
|
-
}
|
|
29
|
+
return this.access.revoke(id, options);
|
|
179
30
|
}
|
|
180
31
|
}
|
|
181
32
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAUzC,MAAM,OAAO,WAAW;IACb,KAAK,CAAQ;IACb,KAAK,CAAe;IACpB,MAAM,CAAS;IAExB,YAAY,OAA2B;QACrC,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;QAEzC,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,OAAO,GAAmB,EAAE;QACrD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE3D,OAAO,WAAW,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,QAAQ,CAAC,KAAY,EAAE,OAAO,GAAoB,EAAE;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,gBAAgB,CAAC,KAAsB,EAAE,OAAO,GAAmB,EAAE;QACnE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,eAAe,CAAC,OAAO,GAAmB,EAAE;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,gBAAgB,CAAC,EAAU,EAAE,OAAO,GAAmB,EAAE;QACvD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Media, MeowGalleryOptions, RequestOptions } from "#types";
|
|
2
|
+
export declare class Transport {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(options: MeowGalleryOptions);
|
|
5
|
+
download(media: Media, options?: RequestOptions & {
|
|
6
|
+
readonly range?: string;
|
|
7
|
+
}): Promise<Response>;
|
|
8
|
+
request<T>(method: string, path: string, body: unknown, options: RequestOptions): Promise<T>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { MeowGalleryError } from "#error";
|
|
2
|
+
export class Transport {
|
|
3
|
+
#origin;
|
|
4
|
+
#token;
|
|
5
|
+
#fetch;
|
|
6
|
+
#timeout;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
const url = new URL(options.baseUrl);
|
|
9
|
+
const local = ["localhost", "127.0.0.1"].includes(url.hostname);
|
|
10
|
+
if ((url.protocol !== "https:" &&
|
|
11
|
+
!(options.allowLocalHttp && local && url.protocol === "http:")) ||
|
|
12
|
+
url.username ||
|
|
13
|
+
url.password ||
|
|
14
|
+
url.pathname !== "/" ||
|
|
15
|
+
url.search ||
|
|
16
|
+
url.hash) {
|
|
17
|
+
throw new TypeError("baseUrl deve ser uma origem HTTPS válida.");
|
|
18
|
+
}
|
|
19
|
+
this.#origin = url.origin;
|
|
20
|
+
this.#token = options.token;
|
|
21
|
+
this.#fetch = options.fetch ?? globalThis.fetch;
|
|
22
|
+
this.#timeout = options.timeoutMs ?? 35_000;
|
|
23
|
+
if (!Number.isSafeInteger(this.#timeout) ||
|
|
24
|
+
this.#timeout < 1 ||
|
|
25
|
+
this.#timeout > 300_000) {
|
|
26
|
+
throw new TypeError("timeoutMs deve estar entre 1 e 300000.");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async download(media, options = {}) {
|
|
30
|
+
const url = new URL(media.delivery.url);
|
|
31
|
+
if (url.origin !== this.#origin ||
|
|
32
|
+
!/^\/v1\/delivery\/[A-Za-z0-9_-]+$/.test(url.pathname) ||
|
|
33
|
+
url.username ||
|
|
34
|
+
url.password ||
|
|
35
|
+
url.search ||
|
|
36
|
+
url.hash) {
|
|
37
|
+
throw new TypeError("O link de entrega não pertence a esta MeowGallery.");
|
|
38
|
+
}
|
|
39
|
+
const expires = Date.parse(media.delivery.expiresAt);
|
|
40
|
+
if (!Number.isFinite(expires) || expires <= Date.now()) {
|
|
41
|
+
throw new MeowGalleryError("O link expirou. Solicite a publicação novamente.", { code: "delivery_expired", status: 410 });
|
|
42
|
+
}
|
|
43
|
+
const headers = new Headers();
|
|
44
|
+
if (options.range) {
|
|
45
|
+
headers.set("Range", options.range);
|
|
46
|
+
}
|
|
47
|
+
const response = await this.#send(url.href, {
|
|
48
|
+
headers,
|
|
49
|
+
signal: this.#signal(options.signal, 300_000),
|
|
50
|
+
});
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw await this.#failure(response);
|
|
53
|
+
}
|
|
54
|
+
return response;
|
|
55
|
+
}
|
|
56
|
+
async request(method, path, body, options) {
|
|
57
|
+
const token = typeof this.#token === "function" ? await this.#token() : this.#token;
|
|
58
|
+
if (!token || /[\r\n]/.test(token)) {
|
|
59
|
+
throw new TypeError("Token de autenticação inválido.");
|
|
60
|
+
}
|
|
61
|
+
const headers = new Headers({
|
|
62
|
+
Accept: "application/json",
|
|
63
|
+
Authorization: `Bearer ${token}`,
|
|
64
|
+
});
|
|
65
|
+
const init = {
|
|
66
|
+
method,
|
|
67
|
+
headers,
|
|
68
|
+
signal: this.#signal(options.signal, this.#timeout),
|
|
69
|
+
};
|
|
70
|
+
if (body !== undefined) {
|
|
71
|
+
headers.set("Content-Type", "application/json");
|
|
72
|
+
init.body = JSON.stringify(body);
|
|
73
|
+
}
|
|
74
|
+
const response = await this.#send(`${this.#origin}${path}`, init);
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw await this.#failure(response);
|
|
77
|
+
}
|
|
78
|
+
if (response.status === 204) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
const envelope = await this.#json(response);
|
|
82
|
+
if (!envelope || typeof envelope !== "object" || !("data" in envelope)) {
|
|
83
|
+
throw new MeowGalleryError("Resposta inesperada do serviço.", {
|
|
84
|
+
code: "invalid_response",
|
|
85
|
+
status: response.status,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return envelope.data;
|
|
89
|
+
}
|
|
90
|
+
#signal(signal, timeout) {
|
|
91
|
+
const deadline = AbortSignal.timeout(timeout);
|
|
92
|
+
return signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
93
|
+
}
|
|
94
|
+
async #send(url, init) {
|
|
95
|
+
try {
|
|
96
|
+
return await this.#fetch(url, {
|
|
97
|
+
...init,
|
|
98
|
+
redirect: "error",
|
|
99
|
+
credentials: "omit",
|
|
100
|
+
cache: "no-store",
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
throw new MeowGalleryError(init.signal?.aborted
|
|
105
|
+
? "Solicitação cancelada ou expirada."
|
|
106
|
+
: "Não foi possível conectar à MeowGallery.", { code: init.signal?.aborted ? "request_aborted" : "network_error" });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async #failure(response) {
|
|
110
|
+
const body = (await this.#json(response).catch(() => null));
|
|
111
|
+
const retryHeader = response.headers.get("retry-after");
|
|
112
|
+
const retry = retryHeader === null ? NaN : Number(retryHeader);
|
|
113
|
+
return new MeowGalleryError(typeof body?.error?.message === "string"
|
|
114
|
+
? body.error.message
|
|
115
|
+
: "A solicitação não foi concluída.", {
|
|
116
|
+
code: typeof body?.error?.code === "string"
|
|
117
|
+
? body.error.code
|
|
118
|
+
: "http_error",
|
|
119
|
+
status: response.status,
|
|
120
|
+
requestId: response.headers.get("x-request-id"),
|
|
121
|
+
retryAfter: Number.isFinite(retry) && retry >= 0 ? retry : null,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async #json(response) {
|
|
125
|
+
const reader = response.body?.getReader();
|
|
126
|
+
if (!reader) {
|
|
127
|
+
throw new MeowGalleryError("Resposta vazia do serviço.", {
|
|
128
|
+
code: "invalid_response",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const chunks = [];
|
|
132
|
+
let size = 0;
|
|
133
|
+
try {
|
|
134
|
+
for (;;) {
|
|
135
|
+
const { done, value } = await reader.read();
|
|
136
|
+
if (done) {
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
size += value.byteLength;
|
|
140
|
+
if (size > 1_048_576) {
|
|
141
|
+
await reader.cancel();
|
|
142
|
+
throw new Error("Response limit exceeded");
|
|
143
|
+
}
|
|
144
|
+
chunks.push(value);
|
|
145
|
+
}
|
|
146
|
+
const joined = new Uint8Array(size);
|
|
147
|
+
let offset = 0;
|
|
148
|
+
for (const chunk of chunks) {
|
|
149
|
+
joined.set(chunk, offset);
|
|
150
|
+
offset += chunk.byteLength;
|
|
151
|
+
}
|
|
152
|
+
return JSON.parse(new TextDecoder().decode(joined));
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
throw new MeowGalleryError("Resposta inválida ou interrompida do serviço.", {
|
|
156
|
+
code: "invalid_response",
|
|
157
|
+
status: response.status,
|
|
158
|
+
requestId: response.headers.get("x-request-id"),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
reader.releaseLock();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { MeowGallery } from "#client";
|
|
2
2
|
export { MeowGalleryError } from "#error";
|
|
3
|
-
export type
|
|
3
|
+
export type * from "#types";
|
|
4
|
+
export { Publication } from "#resources/publication";
|
|
5
|
+
export { MediaItem } from "#resources/item";
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type Scope = "captures:read" | "delivery:read" | "sources:authenticated";
|
|
2
|
+
export interface CredentialInput {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly scopes: readonly Scope[];
|
|
5
|
+
readonly requestsPerMinute: number;
|
|
6
|
+
readonly subject?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface Credential {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly scopes: readonly Scope[];
|
|
12
|
+
readonly requestsPerMinute: number;
|
|
13
|
+
readonly isAdmin: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface CreatedCredential extends Omit<CredentialInput, "subject"> {
|
|
16
|
+
readonly id: string;
|
|
17
|
+
readonly key: string | null;
|
|
18
|
+
readonly subject: string | null;
|
|
19
|
+
}
|