@intelex-ia/sdk 0.1.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 ADDED
@@ -0,0 +1,207 @@
1
+ # `@intelex-ia/sdk`
2
+
3
+ SDK pra consumir a **Content API IntelexIA** em sites headless (Next.js, Astro etc.). Multiplataforma Fase 2b.
4
+
5
+ > **O que você ganha:** `getArticles` / `getArticleBySlug` tipados, um `<ArticleJsonLd>` pra injetar o schema JSON-LD, e um `articleToMetadata` pra plugar no `generateMetadata` do Next.js App Router. Zero dependências (usa `fetch` global).
6
+
7
+ ## Instalação
8
+
9
+ ```bash
10
+ pnpm add @intelex-ia/sdk
11
+ # ou
12
+ npm install @intelex-ia/sdk
13
+ ```
14
+
15
+ > **Enquanto não publicamos no npm**, instale via tarball/git URL (peça pro time IntelexIA).
16
+
17
+ ## Configuração
18
+
19
+ 1. No painel da IntelexIA, **cadastre o site como "Headless (código)"** (vai pedir só domain + opcional revalidate URL/secret).
20
+ 2. Abra o site na lista → seção **"Tokens de API (Content API)"** → **Gerar token**. Você recebe `itx_…` (mostrado uma única vez).
21
+ 3. Coloque o token em `.env.local`:
22
+
23
+ ```bash
24
+ INTELEXIA_TOKEN=itx_seu_token_aqui
25
+ INTELEXIA_API_URL=https://api.innovarticles.intelexia.com.br # opcional, é o default
26
+ ```
27
+
28
+ ## Uso (Next.js App Router)
29
+
30
+ ### Cliente — `lib/intelexia.ts`
31
+
32
+ ```ts
33
+ import { createClient } from "@intelex-ia/sdk";
34
+
35
+ export const intelexia = createClient({
36
+ token: process.env.INTELEXIA_TOKEN!,
37
+ // ISR: revalida a cada 60s (ou use webhook revalidate pra invalidar
38
+ // sob demanda — ver mais abaixo).
39
+ init: { next: { revalidate: 60, tags: ["intelexia-articles"] } },
40
+ });
41
+ ```
42
+
43
+ ### Listagem — `app/blog/page.tsx` (Server Component)
44
+
45
+ ```tsx
46
+ import { intelexia } from "@/lib/intelexia";
47
+ import Link from "next/link";
48
+
49
+ export default async function BlogIndex() {
50
+ const { items } = await intelexia.getArticles({ limit: 20 });
51
+ return (
52
+ <main>
53
+ <h1>Blog</h1>
54
+ <ul>
55
+ {items.map((a) => (
56
+ <li key={a.id}>
57
+ <Link href={`/blog/${a.slug}`}>{a.title}</Link>
58
+ {a.publishedAt && (
59
+ <time>{new Date(a.publishedAt).toLocaleDateString("pt-BR")}</time>
60
+ )}
61
+ </li>
62
+ ))}
63
+ </ul>
64
+ </main>
65
+ );
66
+ }
67
+ ```
68
+
69
+ ### Post — `app/blog/[slug]/page.tsx` (com SEO completo)
70
+
71
+ ```tsx
72
+ import { intelexia } from "@/lib/intelexia";
73
+ import { ArticleJsonLd, articleToMetadata } from "@intelex-ia/sdk/react";
74
+ import { IntelexiaApiError } from "@intelex-ia/sdk";
75
+ import { notFound } from "next/navigation";
76
+
77
+ async function fetchArticle(slug: string) {
78
+ try {
79
+ return await intelexia.getArticleBySlug(slug);
80
+ } catch (err) {
81
+ if (err instanceof IntelexiaApiError && err.status === 404) notFound();
82
+ throw err;
83
+ }
84
+ }
85
+
86
+ export async function generateMetadata({
87
+ params,
88
+ }: {
89
+ params: Promise<{ slug: string }>;
90
+ }) {
91
+ const { slug } = await params;
92
+ const { article } = await fetchArticle(slug);
93
+ return articleToMetadata(article); // → title, description, OG, Twitter, keywords
94
+ }
95
+
96
+ export default async function PostPage({
97
+ params,
98
+ }: {
99
+ params: Promise<{ slug: string }>;
100
+ }) {
101
+ const { slug } = await params;
102
+ const { article } = await fetchArticle(slug);
103
+ return (
104
+ <article>
105
+ {/* Schema JSON-LD (Article/Breadcrumb/FAQ/HowTo/Org/Person) */}
106
+ <ArticleJsonLd article={article} />
107
+
108
+ <h1>{article.title}</h1>
109
+ {article.featuredImageUrl && (
110
+ <img src={article.featuredImageUrl} alt={article.title ?? ""} />
111
+ )}
112
+ <div
113
+ dangerouslySetInnerHTML={{ __html: article.contentHtml ?? "" }}
114
+ />
115
+ </article>
116
+ );
117
+ }
118
+ ```
119
+
120
+ ### Webhook de revalidate — `app/api/revalidate/route.ts`
121
+
122
+ Quando um artigo publica no painel, o worker IntelexIA faz um `POST` no seu endpoint de revalidate (configurado no cadastro do site). Implemente assim:
123
+
124
+ ```ts
125
+ import { NextResponse } from "next/server";
126
+ import { revalidatePath, revalidateTag } from "next/cache";
127
+
128
+ export async function POST(req: Request) {
129
+ // Autentica com o secret cadastrado no painel (header X ou body)
130
+ const headerSecret = req.headers.get("x-revalidate-secret");
131
+ const body = (await req.json().catch(() => ({}))) as {
132
+ secret?: string;
133
+ slug?: string | null;
134
+ domain?: string;
135
+ };
136
+ const got = headerSecret ?? body.secret ?? "";
137
+ if (!process.env.INTELEXIA_REVALIDATE_SECRET || got !== process.env.INTELEXIA_REVALIDATE_SECRET) {
138
+ return NextResponse.json({ ok: false, error: "unauthorized" }, { status: 401 });
139
+ }
140
+
141
+ // Revalida a página do post (se veio slug) e o índice do blog.
142
+ if (body.slug) revalidatePath(`/blog/${body.slug}`);
143
+ revalidatePath("/blog");
144
+ revalidateTag("intelexia-articles");
145
+
146
+ return NextResponse.json({ ok: true, revalidated: { slug: body.slug ?? null } });
147
+ }
148
+ ```
149
+
150
+ E no `.env.local`:
151
+
152
+ ```bash
153
+ INTELEXIA_REVALIDATE_SECRET=cole-o-mesmo-segredo-do-painel
154
+ ```
155
+
156
+ > O worker envia o secret tanto em `x-revalidate-secret` quanto no body (`{ secret, slug, domain }`), tem timeout de 15s e é **fire-and-forget** (se o seu endpoint falhar, o artigo continua publicado e a ISR atualiza pelo `revalidate: 60`).
157
+
158
+ ## API
159
+
160
+ ### `createClient(config)`
161
+
162
+ | Opção | Tipo | Default |
163
+ | -------- | -------------------- | ------------------------------------------------- |
164
+ | `token` | `string` (obrig.) | — |
165
+ | `apiUrl` | `string` | `https://api.innovarticles.intelexia.com.br` |
166
+ | `fetch` | `typeof fetch` | `globalThis.fetch` |
167
+ | `init` | `RequestInit` | `undefined` (passe `{ next: { revalidate: N } }`) |
168
+
169
+ ### `client.getArticles({ limit?, offset?, init? })`
170
+
171
+ Resposta: `{ ok, mode, lifecycle, count, items: ArticleListItem[] }`.
172
+
173
+ ### `client.getArticleBySlug(slug, { init? })`
174
+
175
+ Resposta: `{ ok, mode, lifecycle, article: Article }`. **404 → joga `IntelexiaApiError`** (use `try/catch` + `notFound()`).
176
+
177
+ ### `mode: "full" | "plain"`
178
+
179
+ - **`full`** (sites `active`/`paused`): inclui schema JSON-LD, metaTitle/Description, keyword(s), interlinking interno no `contentHtml`.
180
+ - **`plain`** (site `cancelled`): só conteúdo cru — schema/meta/keywords vêm `null`, interlinking removido. O `ArticleJsonLd` e o `articleToMetadata` lidam graciosamente (omitem o que não tem).
181
+
182
+ A decisão é **server-side e não-negociável** — o cliente não escolhe o modo.
183
+
184
+ ### Helpers `/react`
185
+
186
+ - `<ArticleJsonLd article={article} />` — renderiza `<script type="application/ld+json">` com o `schemaJson`. No-op se ausente.
187
+ - `articleToMetadata(article)` → objeto compatível com o `Metadata` do Next.js App Router (title, description, keywords, openGraph, twitter, customMetaTags como `other`).
188
+
189
+ ## Erros
190
+
191
+ ```ts
192
+ import { IntelexiaApiError } from "@intelex-ia/sdk";
193
+
194
+ try {
195
+ await intelexia.getArticleBySlug("post-inexistente");
196
+ } catch (err) {
197
+ if (err instanceof IntelexiaApiError) {
198
+ console.error(err.status, err.message); // 404, "Artigo não encontrado."
199
+ }
200
+ }
201
+ ```
202
+
203
+ ## Compatibilidade
204
+
205
+ - Node 18+ (fetch nativo), Edge Runtime, Browser.
206
+ - React 18+ (peer dep opcional — só pros helpers `/react`).
207
+ - TypeScript: tipos publicados no `dist`.
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Cliente HTTP do `@intelex-ia/sdk`. Zero dependências (usa fetch global).
3
+ * Compatível com Next.js App Router (Server Components): aceita `init`
4
+ * customizado (ex.: `{ next: { revalidate: 60 } }` pra ISR).
5
+ */
6
+ import type { Article, ArticleListItem, Lifecycle, Mode } from "./types.js";
7
+ /** Configuração do cliente. */
8
+ export interface ClientConfig {
9
+ /**
10
+ * URL base da API IntelexIA. Default:
11
+ * `https://api.innovarticles.intelexia.com.br`.
12
+ */
13
+ apiUrl?: string;
14
+ /**
15
+ * Token `itx_…` gerado no painel (Sites → seção "Tokens de API"). É
16
+ * SITE-SCOPED: cada token só lê os artigos do site dono.
17
+ */
18
+ token: string;
19
+ /**
20
+ * Função de fetch (opcional). Default: `globalThis.fetch`. Útil pra
21
+ * injetar mock em testes ou um fetch wrappado.
22
+ */
23
+ fetch?: typeof fetch;
24
+ /**
25
+ * `RequestInit` aplicado em TODA chamada. Use pra:
26
+ * - Next.js App Router: `{ next: { revalidate: 60, tags: ["articles"] } }`
27
+ * - Astro: `{ cache: "force-cache" }`
28
+ * - Cancelar via AbortSignal global, etc.
29
+ */
30
+ init?: RequestInit;
31
+ }
32
+ /** Resposta de GET /v1/articles. */
33
+ export interface ArticlesListResponse {
34
+ ok: true;
35
+ mode: Mode;
36
+ lifecycle: Lifecycle;
37
+ count: number;
38
+ items: ArticleListItem[];
39
+ }
40
+ /** Resposta de GET /v1/articles/:slug. */
41
+ export interface ArticleResponse {
42
+ ok: true;
43
+ mode: Mode;
44
+ lifecycle: Lifecycle;
45
+ article: Article;
46
+ }
47
+ /** Erro HTTP da Content API com status + mensagem. */
48
+ export declare class IntelexiaApiError extends Error {
49
+ readonly status: number;
50
+ readonly path?: string | undefined;
51
+ constructor(status: number, message: string, path?: string | undefined);
52
+ }
53
+ /**
54
+ * Cria uma instância do cliente. O retorno tem os métodos `getArticles` e
55
+ * `getArticleBySlug`. Idempotente — pode ser instanciado uma vez por process
56
+ * (Node/Edge) e reusado.
57
+ */
58
+ export declare function createClient(config: ClientConfig): {
59
+ /**
60
+ * Lista os artigos publicados do site (mais recentes primeiro).
61
+ * Em sites cancelados, retorna a versão "plain" (sem metaTitle/Description).
62
+ *
63
+ * @example
64
+ * const { items } = await client.getArticles({ limit: 10 });
65
+ */
66
+ getArticles(opts?: {
67
+ limit?: number;
68
+ offset?: number;
69
+ /** Override do `init` desta chamada específica. */
70
+ init?: RequestInit;
71
+ }): Promise<ArticlesListResponse>;
72
+ /**
73
+ * Busca um artigo publicado pelo slug. 404 vira `IntelexiaApiError`.
74
+ * Em sites cancelados, retorna a versão "plain" (sem schema/meta/keywords).
75
+ *
76
+ * @example
77
+ * try {
78
+ * const { article, mode } = await client.getArticleBySlug("meu-post");
79
+ * } catch (err) {
80
+ * if (err instanceof IntelexiaApiError && err.status === 404) notFound();
81
+ * }
82
+ */
83
+ getArticleBySlug(slug: string, opts?: {
84
+ init?: RequestInit;
85
+ }): Promise<ArticleResponse>;
86
+ };
87
+ /** Tipo do retorno de `createClient` (útil pra passar adiante). */
88
+ export type IntelexiaClient = ReturnType<typeof createClient>;
89
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,SAAS,EACT,IAAI,EACL,MAAM,YAAY,CAAC;AAEpB,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,oCAAoC;AACpC,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,sDAAsD;AACtD,qBAAa,iBAAkB,SAAQ,KAAK;aAExB,MAAM,EAAE,MAAM;aAEd,IAAI,CAAC,EAAE,MAAM;gBAFb,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AAID;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY;IAwC7C;;;;;;OAMG;uBACsB;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,mDAAmD;QACnD,IAAI,CAAC,EAAE,WAAW,CAAC;KACpB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAWjC;;;;;;;;;;OAUG;2BAEK,MAAM,SACL;QAAE,IAAI,CAAC,EAAE,WAAW,CAAA;KAAE,GAC5B,OAAO,CAAC,eAAe,CAAC;EAK9B;AAED,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
package/dist/client.js ADDED
@@ -0,0 +1,87 @@
1
+ /** Erro HTTP da Content API com status + mensagem. */
2
+ export class IntelexiaApiError extends Error {
3
+ status;
4
+ path;
5
+ constructor(status, message, path) {
6
+ super(`[IntelexiaApi ${status}${path ? ` ${path}` : ""}] ${message}`);
7
+ this.status = status;
8
+ this.path = path;
9
+ this.name = "IntelexiaApiError";
10
+ }
11
+ }
12
+ const DEFAULT_API_URL = "https://api.innovarticles.intelexia.com.br";
13
+ /**
14
+ * Cria uma instância do cliente. O retorno tem os métodos `getArticles` e
15
+ * `getArticleBySlug`. Idempotente — pode ser instanciado uma vez por process
16
+ * (Node/Edge) e reusado.
17
+ */
18
+ export function createClient(config) {
19
+ if (!config.token || !config.token.startsWith("itx_")) {
20
+ throw new Error("[@intelex-ia/sdk] token inválido — esperado um token `itx_…` gerado no painel.");
21
+ }
22
+ const fetchFn = config.fetch ?? globalThis.fetch;
23
+ if (typeof fetchFn !== "function") {
24
+ throw new Error("[@intelex-ia/sdk] fetch não encontrado — passe `config.fetch` ou rode em ambiente com fetch global (Node 18+, Edge, browser).");
25
+ }
26
+ const apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\/+$/, "");
27
+ async function request(path, init) {
28
+ const url = `${apiUrl}${path}`;
29
+ const res = await fetchFn(url, {
30
+ ...config.init,
31
+ ...init,
32
+ headers: {
33
+ Authorization: `Bearer ${config.token}`,
34
+ Accept: "application/json",
35
+ ...config.init?.headers,
36
+ ...init?.headers,
37
+ },
38
+ });
39
+ if (!res.ok) {
40
+ let msg = res.statusText || `HTTP ${res.status}`;
41
+ try {
42
+ const body = (await res.json());
43
+ if (body?.error)
44
+ msg = body.error;
45
+ }
46
+ catch {
47
+ // ignore parse errors — usa msg padrão
48
+ }
49
+ throw new IntelexiaApiError(res.status, msg, path);
50
+ }
51
+ return (await res.json());
52
+ }
53
+ return {
54
+ /**
55
+ * Lista os artigos publicados do site (mais recentes primeiro).
56
+ * Em sites cancelados, retorna a versão "plain" (sem metaTitle/Description).
57
+ *
58
+ * @example
59
+ * const { items } = await client.getArticles({ limit: 10 });
60
+ */
61
+ async getArticles(opts) {
62
+ const params = new URLSearchParams();
63
+ if (opts?.limit != null)
64
+ params.set("limit", String(opts.limit));
65
+ if (opts?.offset != null)
66
+ params.set("offset", String(opts.offset));
67
+ const qs = params.toString();
68
+ return request(`/v1/articles${qs ? `?${qs}` : ""}`, opts?.init);
69
+ },
70
+ /**
71
+ * Busca um artigo publicado pelo slug. 404 vira `IntelexiaApiError`.
72
+ * Em sites cancelados, retorna a versão "plain" (sem schema/meta/keywords).
73
+ *
74
+ * @example
75
+ * try {
76
+ * const { article, mode } = await client.getArticleBySlug("meu-post");
77
+ * } catch (err) {
78
+ * if (err instanceof IntelexiaApiError && err.status === 404) notFound();
79
+ * }
80
+ */
81
+ async getArticleBySlug(slug, opts) {
82
+ const safeSlug = encodeURIComponent(slug);
83
+ return request(`/v1/articles/${safeSlug}`, opts?.init);
84
+ },
85
+ };
86
+ }
87
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Entry pública do `@intelex-ia/sdk` — core (sem React).
3
+ *
4
+ * Pra os helpers React (ArticleJsonLd, articleToMetadata), importe de
5
+ * `@intelex-ia/sdk/react`.
6
+ */
7
+ export { createClient, IntelexiaApiError, type ClientConfig, type ArticlesListResponse, type ArticleResponse, type IntelexiaClient, } from "./client.js";
8
+ export type { Lifecycle, Mode, Article, ArticleListItem, CustomMetaTag, ErrorResponse, } from "./types.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,SAAS,EACT,IAAI,EACJ,OAAO,EACP,eAAe,EACf,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Entry pública do `@intelex-ia/sdk` — core (sem React).
3
+ *
4
+ * Pra os helpers React (ArticleJsonLd, articleToMetadata), importe de
5
+ * `@intelex-ia/sdk/react`.
6
+ */
7
+ export { createClient, IntelexiaApiError, } from "./client.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,YAAY,EACZ,iBAAiB,GAKlB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Helpers React do `@intelex-ia/sdk`. Import:
3
+ *
4
+ * import { ArticleJsonLd, articleToMetadata } from "@intelex-ia/sdk/react";
5
+ *
6
+ * Compatível com Next.js App Router (Server Components) e qualquer
7
+ * framework React 18+.
8
+ */
9
+ import type { ReactElement } from "react";
10
+ import type { CustomMetaTag } from "./types.js";
11
+ /** Subset mínimo de Article necessário pro `<ArticleJsonLd>`. */
12
+ interface ArticleSchemaInput {
13
+ schemaJson?: unknown | null;
14
+ }
15
+ /**
16
+ * Renderiza um `<script type="application/ld+json">` com o schema JSON-LD do
17
+ * artigo. Pode ser colocado em qualquer lugar do `<body>` — o Google lê tanto
18
+ * no `<head>` quanto no body, mas no body é mais compatível com o React do
19
+ * Next.js App Router (que prefere a Metadata API pro `<head>`).
20
+ *
21
+ * No-op (retorna null) quando `article.schemaJson` é null/undefined — útil pra
22
+ * sites cancelados (modo "plain"), que não recebem schema.
23
+ *
24
+ * @example
25
+ * // app/blog/[slug]/page.tsx
26
+ * import { ArticleJsonLd } from "@intelex-ia/sdk/react";
27
+ * export default async function Page({ params }) {
28
+ * const { article } = await client.getArticleBySlug(params.slug);
29
+ * return (
30
+ * <>
31
+ * <ArticleJsonLd article={article} />
32
+ * <article dangerouslySetInnerHTML={{ __html: article.contentHtml ?? "" }} />
33
+ * </>
34
+ * );
35
+ * }
36
+ */
37
+ export declare function ArticleJsonLd({ article, }: {
38
+ article: ArticleSchemaInput;
39
+ }): ReactElement | null;
40
+ /** Subset mínimo de Article necessário pro `articleToMetadata`. */
41
+ interface ArticleMetadataInput {
42
+ title?: string | null;
43
+ metaTitle?: string | null;
44
+ metaDescription?: string | null;
45
+ featuredImageUrl?: string | null;
46
+ keyword?: string | null;
47
+ keywordSynonyms?: string[] | null;
48
+ customMetaTags?: CustomMetaTag[] | null;
49
+ }
50
+ /**
51
+ * Resultado do `articleToMetadata`. Compatível com o tipo `Metadata` do
52
+ * Next.js App Router (mas não importa de "next" — mantém o SDK
53
+ * framework-agnostic). Sites Astro/Remix também podem usar como referência.
54
+ */
55
+ export interface ArticleMetadata {
56
+ title?: string;
57
+ description?: string;
58
+ keywords?: string[];
59
+ openGraph?: {
60
+ title?: string;
61
+ description?: string;
62
+ images?: {
63
+ url: string;
64
+ }[];
65
+ };
66
+ twitter?: {
67
+ card: "summary_large_image";
68
+ title?: string;
69
+ description?: string;
70
+ images?: string[];
71
+ };
72
+ other?: Record<string, string>;
73
+ }
74
+ /**
75
+ * Converte um Article do SDK em um objeto de metadata compatível com o
76
+ * `Metadata` do Next.js App Router. Use em `generateMetadata`:
77
+ *
78
+ * // app/blog/[slug]/page.tsx
79
+ * import { articleToMetadata } from "@intelex-ia/sdk/react";
80
+ * export async function generateMetadata({ params }) {
81
+ * const { article } = await client.getArticleBySlug(params.slug);
82
+ * return articleToMetadata(article);
83
+ * }
84
+ *
85
+ * Cobre title/description, keywords, OG (title/description/image) e Twitter
86
+ * (summary_large_image). `customMetaTags` (OG/Twitter custom configurados no
87
+ * painel) entram em `other` como `name=value` ou `property=value`.
88
+ */
89
+ export declare function articleToMetadata(article: ArticleMetadataInput): ArticleMetadata;
90
+ export type { Article, CustomMetaTag } from "./types.js";
91
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAW,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzD,iEAAiE;AACjE,UAAU,kBAAkB;IAC1B,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,GACR,EAAE;IACD,OAAO,EAAE,kBAAkB,CAAC;CAC7B,GAAG,YAAY,GAAG,IAAI,CAYtB;AAED,mEAAmE;AACnE,UAAU,oBAAoB;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,cAAc,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;CACzC;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC5B,CAAC;IACF,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,qBAAqB,CAAC;QAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,oBAAoB,GAC5B,eAAe,CAiCjB;AAGD,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/react.js ADDED
@@ -0,0 +1,84 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Renderiza um `<script type="application/ld+json">` com o schema JSON-LD do
4
+ * artigo. Pode ser colocado em qualquer lugar do `<body>` — o Google lê tanto
5
+ * no `<head>` quanto no body, mas no body é mais compatível com o React do
6
+ * Next.js App Router (que prefere a Metadata API pro `<head>`).
7
+ *
8
+ * No-op (retorna null) quando `article.schemaJson` é null/undefined — útil pra
9
+ * sites cancelados (modo "plain"), que não recebem schema.
10
+ *
11
+ * @example
12
+ * // app/blog/[slug]/page.tsx
13
+ * import { ArticleJsonLd } from "@intelex-ia/sdk/react";
14
+ * export default async function Page({ params }) {
15
+ * const { article } = await client.getArticleBySlug(params.slug);
16
+ * return (
17
+ * <>
18
+ * <ArticleJsonLd article={article} />
19
+ * <article dangerouslySetInnerHTML={{ __html: article.contentHtml ?? "" }} />
20
+ * </>
21
+ * );
22
+ * }
23
+ */
24
+ export function ArticleJsonLd({ article, }) {
25
+ if (!article.schemaJson)
26
+ return null;
27
+ return (_jsx("script", { type: "application/ld+json",
28
+ // JSON.stringify garante escaping de aspas/HTML — não tem XSS aqui
29
+ // (schema vem do nosso banco, controlado).
30
+ dangerouslySetInnerHTML: {
31
+ __html: JSON.stringify(article.schemaJson),
32
+ } }));
33
+ }
34
+ /**
35
+ * Converte um Article do SDK em um objeto de metadata compatível com o
36
+ * `Metadata` do Next.js App Router. Use em `generateMetadata`:
37
+ *
38
+ * // app/blog/[slug]/page.tsx
39
+ * import { articleToMetadata } from "@intelex-ia/sdk/react";
40
+ * export async function generateMetadata({ params }) {
41
+ * const { article } = await client.getArticleBySlug(params.slug);
42
+ * return articleToMetadata(article);
43
+ * }
44
+ *
45
+ * Cobre title/description, keywords, OG (title/description/image) e Twitter
46
+ * (summary_large_image). `customMetaTags` (OG/Twitter custom configurados no
47
+ * painel) entram em `other` como `name=value` ou `property=value`.
48
+ */
49
+ export function articleToMetadata(article) {
50
+ const title = article.metaTitle ?? article.title ?? undefined;
51
+ const description = article.metaDescription ?? undefined;
52
+ const image = article.featuredImageUrl ?? undefined;
53
+ const keywords = [
54
+ ...(article.keyword ? [article.keyword] : []),
55
+ ...(article.keywordSynonyms ?? []),
56
+ ].filter(Boolean);
57
+ const other = {};
58
+ for (const tag of article.customMetaTags ?? []) {
59
+ if (tag?.content == null)
60
+ continue;
61
+ if (tag.property)
62
+ other[tag.property] = tag.content;
63
+ else if (tag.name)
64
+ other[tag.name] = tag.content;
65
+ }
66
+ return {
67
+ ...(title ? { title } : {}),
68
+ ...(description ? { description } : {}),
69
+ ...(keywords.length > 0 ? { keywords } : {}),
70
+ openGraph: {
71
+ ...(title ? { title } : {}),
72
+ ...(description ? { description } : {}),
73
+ ...(image ? { images: [{ url: image }] } : {}),
74
+ },
75
+ twitter: {
76
+ card: "summary_large_image",
77
+ ...(title ? { title } : {}),
78
+ ...(description ? { description } : {}),
79
+ ...(image ? { images: [image] } : {}),
80
+ },
81
+ ...(Object.keys(other).length > 0 ? { other } : {}),
82
+ };
83
+ }
84
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Tipos públicos do `@intelex-ia/sdk`. Espelham o shape REAL da Content API /v1
3
+ * (ver apps/api/src/routes/content-api.ts). Mantém compatibilidade futura:
4
+ * campos opcionais ficam `?:` pra não quebrar quando a API evolui.
5
+ */
6
+ /** Ciclo de vida comercial do site — define se a inteligência é servida. */
7
+ export type Lifecycle = "active" | "paused" | "cancelled";
8
+ /**
9
+ * Modo da resposta:
10
+ * - "full": site `active`/`paused` → inclui inteligência (schema, meta SEO,
11
+ * keywords, interlinking dentro do contentHtml).
12
+ * - "plain": site `cancelled` → só conteúdo cru (sem schema/meta/keywords;
13
+ * interlinking interno removido do HTML).
14
+ */
15
+ export type Mode = "full" | "plain";
16
+ /** Custom meta tag (OG/Twitter custom configurado globalmente no painel). */
17
+ export interface CustomMetaTag {
18
+ name?: string | null;
19
+ property?: string | null;
20
+ content: string;
21
+ }
22
+ /**
23
+ * Item de listagem (GET /v1/articles). Campos comuns. Em modo "full" inclui
24
+ * também `metaTitle`/`metaDescription`; em "plain" eles vêm ausentes.
25
+ */
26
+ export interface ArticleListItem {
27
+ id: string;
28
+ slug: string | null;
29
+ title: string | null;
30
+ featuredImageUrl: string | null;
31
+ words: number;
32
+ publishedAt: string | null;
33
+ /** Só presente em modo "full". */
34
+ metaTitle?: string | null;
35
+ /** Só presente em modo "full". */
36
+ metaDescription?: string | null;
37
+ }
38
+ /**
39
+ * Artigo completo (GET /v1/articles/:slug). Tipo unificado — em modo "plain"
40
+ * os campos de inteligência (schemaJson, metaTitle, keyword, etc.) vêm
41
+ * ausentes/null porque o plain-serializer os omite. Use o `mode` da resposta
42
+ * pra saber qual versão você recebeu.
43
+ */
44
+ export interface Article {
45
+ id: string;
46
+ title: string | null;
47
+ slug: string | null;
48
+ /** Em "full" inclui interlinking; em "plain" o interlinking é removido. */
49
+ contentHtml: string | null;
50
+ featuredImageUrl: string | null;
51
+ ctaImage1Url?: string | null;
52
+ ctaImage1Title?: string | null;
53
+ ctaImage1Subtitle?: string | null;
54
+ ctaImage2Url?: string | null;
55
+ ctaImage2Title?: string | null;
56
+ ctaImage2Subtitle?: string | null;
57
+ ctaImage3Url?: string | null;
58
+ ctaImage3Title?: string | null;
59
+ ctaImage3Subtitle?: string | null;
60
+ categoryIds?: number[] | null;
61
+ primaryCategoryId?: number | null;
62
+ tagNames?: string[] | null;
63
+ words?: number | null;
64
+ metaTitle?: string | null;
65
+ metaDescription?: string | null;
66
+ keyword?: string | null;
67
+ keywordSynonyms?: string[] | null;
68
+ additionalKeywords?: string[] | null;
69
+ /** JSON-LD @graph (Article/WebPage/Breadcrumb/FAQ/HowTo/Org/Person). */
70
+ schemaJson?: unknown | null;
71
+ /** Meta tags custom (OG/Twitter customizados no painel). */
72
+ customMetaTags?: CustomMetaTag[] | null;
73
+ seoScore?: number | null;
74
+ publishedAt?: string | null;
75
+ }
76
+ /** Resposta de erro padrão (HTTP 4xx/5xx). */
77
+ export interface ErrorResponse {
78
+ ok: false;
79
+ error: string;
80
+ }
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpC,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kCAAkC;IAClC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACrC,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B,4DAA4D;IAC5D,cAAc,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Tipos públicos do `@intelex-ia/sdk`. Espelham o shape REAL da Content API /v1
3
+ * (ver apps/api/src/routes/content-api.ts). Mantém compatibilidade futura:
4
+ * campos opcionais ficam `?:` pra não quebrar quando a API evolui.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@intelex-ia/sdk",
3
+ "version": "0.1.0",
4
+ "description": "SDK pra consumir a Content API da IntelexIA em sites headless (Next.js, Astro, etc.). Multiplataforma Fase 2b.",
5
+ "license": "MIT",
6
+ "author": "intelex-ia",
7
+ "homepage": "https://github.com/intelex-ia/combo_automatico/tree/main/packages/sdk",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/intelex-ia/combo_automatico.git",
11
+ "directory": "packages/sdk"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/intelex-ia/combo_automatico/issues"
15
+ },
16
+ "keywords": [
17
+ "intelexia",
18
+ "content-api",
19
+ "headless",
20
+ "cms",
21
+ "next",
22
+ "nextjs",
23
+ "react",
24
+ "sdk"
25
+ ],
26
+ "type": "module",
27
+ "main": "./dist/index.js",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "./react": {
36
+ "types": "./dist/react.d.ts",
37
+ "default": "./dist/react.js"
38
+ }
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "README.md"
43
+ ],
44
+ "scripts": {
45
+ "build": "tsc",
46
+ "typecheck": "tsc --noEmit"
47
+ },
48
+ "peerDependencies": {
49
+ "react": ">=18"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "react": {
53
+ "optional": true
54
+ }
55
+ },
56
+ "devDependencies": {
57
+ "@types/react": "^18.3.12",
58
+ "typescript": "^5.6.3"
59
+ },
60
+ "publishConfig": {
61
+ "access": "public",
62
+ "provenance": true
63
+ }
64
+ }