@intelex-ia/sdk 0.1.0 → 0.3.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 +310 -207
- package/dist/autoria.test.d.ts +2 -0
- package/dist/autoria.test.d.ts.map +1 -0
- package/dist/autoria.test.js +85 -0
- package/dist/autoria.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/merge.d.ts +86 -0
- package/dist/merge.d.ts.map +1 -0
- package/dist/merge.js +84 -0
- package/dist/merge.js.map +1 -0
- package/dist/merge.test.d.ts +2 -0
- package/dist/merge.test.d.ts.map +1 -0
- package/dist/merge.test.js +224 -0
- package/dist/merge.test.js.map +1 -0
- package/dist/react.d.ts +58 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +97 -1
- package/dist/react.js.map +1 -1
- package/package.json +64 -64
package/dist/merge.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mergePosts()` — junta posts locais (formato do cliente) com artigos do
|
|
3
|
+
* painel IntelexIA num feed unificado. Resolve o caso real "cliente já tem
|
|
4
|
+
* 50 artigos no site e quer ADICIONAR os da IA sem perder os antigos".
|
|
5
|
+
*
|
|
6
|
+
* Função pura, zero deps, zero React. Roda em qualquer ambiente JS.
|
|
7
|
+
*
|
|
8
|
+
* @example modo "additive" (clientes existentes — caso mais comum)
|
|
9
|
+
* import { listArticles } from "@/lib/intelexia"
|
|
10
|
+
* import { mergePosts } from "@intelex-ia/sdk"
|
|
11
|
+
*
|
|
12
|
+
* const { items: remote } = await client.getArticles({ limit: 50 })
|
|
13
|
+
* const merged = mergePosts({
|
|
14
|
+
* local: localPosts,
|
|
15
|
+
* remote,
|
|
16
|
+
* mapLocal: (p) => ({
|
|
17
|
+
* slug: p.slug,
|
|
18
|
+
* title: p.title,
|
|
19
|
+
* excerpt: p.excerpt,
|
|
20
|
+
* publishedAt: p.date,
|
|
21
|
+
* category: p.category,
|
|
22
|
+
* }),
|
|
23
|
+
* })
|
|
24
|
+
* // merged: UnifiedPost[] — ordenado por data desc, slug duplicado: remoto vence
|
|
25
|
+
*/
|
|
26
|
+
import type { ArticleListItem } from "./types.js";
|
|
27
|
+
/**
|
|
28
|
+
* Shape unificado pra renderizar lista de posts independente da origem.
|
|
29
|
+
* Cliente que precisa de mais campos pode estender via TypeScript generics
|
|
30
|
+
* — por enquanto fixamos o mínimo viável pra UI (slug + meta de card).
|
|
31
|
+
*/
|
|
32
|
+
export interface UnifiedPost {
|
|
33
|
+
/** Slug pra URL. Único no feed (dedup por slug). */
|
|
34
|
+
slug: string;
|
|
35
|
+
/** Título do post. */
|
|
36
|
+
title: string;
|
|
37
|
+
/** Resumo curto (excerpt/metaDescription). Pode ser `null` se ausente. */
|
|
38
|
+
excerpt: string | null;
|
|
39
|
+
/** Data ISO 8601 (`2026-05-26T10:00:00Z` ou `2026-05-26`). */
|
|
40
|
+
publishedAt: string;
|
|
41
|
+
/** URL absoluta da imagem destacada. `null` se não tiver. */
|
|
42
|
+
featuredImageUrl: string | null;
|
|
43
|
+
/** Categoria principal (string display). `null` se não classificado. */
|
|
44
|
+
category: string | null;
|
|
45
|
+
/** De onde veio: `"local"` (cliente) ou `"remote"` (painel IntelexIA). */
|
|
46
|
+
source: "local" | "remote";
|
|
47
|
+
}
|
|
48
|
+
/** Opções de `mergePosts()`. `local` é genérico — cliente passa qualquer shape. */
|
|
49
|
+
export interface MergePostsOptions<TLocal> {
|
|
50
|
+
/** Array de posts locais (formato livre do cliente). */
|
|
51
|
+
local: readonly TLocal[];
|
|
52
|
+
/** Array de artigos vindos da Content API (via `client.getArticles()`). */
|
|
53
|
+
remote: readonly ArticleListItem[];
|
|
54
|
+
/**
|
|
55
|
+
* Mapper que converte um post local pro `UnifiedPost`. Obrigatório porque
|
|
56
|
+
* cada cliente tem um shape diferente (markdown frontmatter, CMS custom,
|
|
57
|
+
* array hardcoded, etc.). Retorne `null` pra ignorar o post (filtro).
|
|
58
|
+
*/
|
|
59
|
+
mapLocal: (post: TLocal) => Omit<UnifiedPost, "source"> | null;
|
|
60
|
+
/**
|
|
61
|
+
* Estratégia quando um slug existe nos DOIS lados:
|
|
62
|
+
* - `"remote-wins"` (default): painel substitui o local. Faz sentido pra
|
|
63
|
+
* migração gradual (cliente publica versão nova IA do post antigo).
|
|
64
|
+
* - `"local-wins"`: ignora o remoto, mantém o local.
|
|
65
|
+
* - `"throw"`: lança `MergeConflictError` (forçar resolução explícita).
|
|
66
|
+
*/
|
|
67
|
+
dedupe?: "remote-wins" | "local-wins" | "throw";
|
|
68
|
+
/**
|
|
69
|
+
* Ordenação do feed final:
|
|
70
|
+
* - `"date-desc"` (default): mais recente primeiro.
|
|
71
|
+
* - `"date-asc"`: mais antigo primeiro.
|
|
72
|
+
* - `"none"`: mantém ordem (remotos primeiro, locais depois — útil pra
|
|
73
|
+
* "destaques curados" no topo).
|
|
74
|
+
*/
|
|
75
|
+
sortBy?: "date-desc" | "date-asc" | "none";
|
|
76
|
+
}
|
|
77
|
+
/** Lançado quando `dedupe: "throw"` e há slug duplicado. */
|
|
78
|
+
export declare class MergeConflictError extends Error {
|
|
79
|
+
readonly slug: string;
|
|
80
|
+
constructor(slug: string);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Junta posts locais + remotos num único feed. Veja `MergePostsOptions`.
|
|
84
|
+
*/
|
|
85
|
+
export declare function mergePosts<TLocal>(opts: MergePostsOptions<TLocal>): UnifiedPost[];
|
|
86
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,wEAAwE;IACxE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,0EAA0E;IAC1E,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC5B;AAED,mFAAmF;AACnF,MAAM,WAAW,iBAAiB,CAAC,MAAM;IACvC,wDAAwD;IACxD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,2EAA2E;IAC3E,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IACnC;;;;OAIG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC/D;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,aAAa,GAAG,YAAY,GAAG,OAAO,CAAC;IAChD;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;CAC5C;AAED,4DAA4D;AAC5D,qBAAa,kBAAmB,SAAQ,KAAK;aACf,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAOzC;AAmBD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAC/B,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAC9B,WAAW,EAAE,CAoDf"}
|
package/dist/merge.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Lançado quando `dedupe: "throw"` e há slug duplicado. */
|
|
2
|
+
export class MergeConflictError extends Error {
|
|
3
|
+
slug;
|
|
4
|
+
constructor(slug) {
|
|
5
|
+
super(`[@intelex-ia/sdk] mergePosts: slug "${slug}" existe em local E remote. ` +
|
|
6
|
+
`Configure dedupe: "remote-wins" ou "local-wins" pra resolver.`);
|
|
7
|
+
this.slug = slug;
|
|
8
|
+
this.name = "MergeConflictError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Normaliza `ArticleListItem` (Content API) pro `UnifiedPost`. Filtra itens
|
|
13
|
+
* sem slug/title/publishedAt (não dá pra renderizar card).
|
|
14
|
+
*/
|
|
15
|
+
function remoteToUnified(item) {
|
|
16
|
+
if (!item.slug || !item.title || !item.publishedAt)
|
|
17
|
+
return null;
|
|
18
|
+
return {
|
|
19
|
+
slug: item.slug,
|
|
20
|
+
title: item.title,
|
|
21
|
+
excerpt: item.metaDescription ?? null,
|
|
22
|
+
publishedAt: item.publishedAt,
|
|
23
|
+
featuredImageUrl: item.featuredImageUrl,
|
|
24
|
+
category: null, // Content API não devolve categoria na listagem (Fase 2b inc1 — pode evoluir)
|
|
25
|
+
source: "remote",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Junta posts locais + remotos num único feed. Veja `MergePostsOptions`.
|
|
30
|
+
*/
|
|
31
|
+
export function mergePosts(opts) {
|
|
32
|
+
const dedupeMode = opts.dedupe ?? "remote-wins";
|
|
33
|
+
const sortMode = opts.sortBy ?? "date-desc";
|
|
34
|
+
// Indexa por slug pra dedup eficiente.
|
|
35
|
+
const bySlug = new Map();
|
|
36
|
+
// 1) Adiciona LOCAIS primeiro.
|
|
37
|
+
for (const localPost of opts.local) {
|
|
38
|
+
const mapped = opts.mapLocal(localPost);
|
|
39
|
+
if (!mapped)
|
|
40
|
+
continue; // mapper retornou null = filtro
|
|
41
|
+
if (!mapped.slug)
|
|
42
|
+
continue; // post sem slug é ilegível
|
|
43
|
+
bySlug.set(mapped.slug, { ...mapped, source: "local" });
|
|
44
|
+
}
|
|
45
|
+
// 2) Adiciona REMOTOS aplicando estratégia de dedup.
|
|
46
|
+
for (const remoteItem of opts.remote) {
|
|
47
|
+
const unified = remoteToUnified(remoteItem);
|
|
48
|
+
if (!unified)
|
|
49
|
+
continue;
|
|
50
|
+
const existing = bySlug.get(unified.slug);
|
|
51
|
+
if (!existing) {
|
|
52
|
+
bySlug.set(unified.slug, unified);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// Conflito: existe local com mesmo slug.
|
|
56
|
+
switch (dedupeMode) {
|
|
57
|
+
case "remote-wins":
|
|
58
|
+
bySlug.set(unified.slug, unified);
|
|
59
|
+
break;
|
|
60
|
+
case "local-wins":
|
|
61
|
+
// mantém o que já tá lá (local), descarta remoto
|
|
62
|
+
break;
|
|
63
|
+
case "throw":
|
|
64
|
+
throw new MergeConflictError(unified.slug);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// 3) Ordena.
|
|
68
|
+
const all = Array.from(bySlug.values());
|
|
69
|
+
if (sortMode === "none")
|
|
70
|
+
return all;
|
|
71
|
+
return all.sort((a, b) => {
|
|
72
|
+
const dateA = new Date(a.publishedAt).getTime();
|
|
73
|
+
const dateB = new Date(b.publishedAt).getTime();
|
|
74
|
+
// Datas inválidas vão pro final (NaN comparisons sempre false).
|
|
75
|
+
if (Number.isNaN(dateA) && Number.isNaN(dateB))
|
|
76
|
+
return 0;
|
|
77
|
+
if (Number.isNaN(dateA))
|
|
78
|
+
return 1;
|
|
79
|
+
if (Number.isNaN(dateB))
|
|
80
|
+
return -1;
|
|
81
|
+
return sortMode === "date-desc" ? dateB - dateA : dateA - dateB;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.test.d.ts","sourceRoot":"","sources":["../src/merge.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { mergePosts, MergeConflictError } from "./merge.js";
|
|
3
|
+
const localFixture = [
|
|
4
|
+
{
|
|
5
|
+
slug: "post-antigo-2024",
|
|
6
|
+
title: "Post antigo de 2024",
|
|
7
|
+
excerpt: "Resumo do antigo",
|
|
8
|
+
date: "2024-01-15",
|
|
9
|
+
category: "Geral",
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
slug: "post-antigo-2025",
|
|
13
|
+
title: "Post antigo de 2025",
|
|
14
|
+
excerpt: "Resumo de 2025",
|
|
15
|
+
date: "2025-06-10",
|
|
16
|
+
category: "Geral",
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
const remoteFixture = [
|
|
20
|
+
{
|
|
21
|
+
id: "uuid-1",
|
|
22
|
+
slug: "novo-post-ia",
|
|
23
|
+
title: "Novo post gerado por IA",
|
|
24
|
+
featuredImageUrl: "https://cdn.ex.com/1.jpg",
|
|
25
|
+
words: 1200,
|
|
26
|
+
publishedAt: "2026-05-20T10:00:00Z",
|
|
27
|
+
metaDescription: "Resumo SEO do post novo",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "uuid-2",
|
|
31
|
+
slug: "outro-novo-ia",
|
|
32
|
+
title: "Outro post novo",
|
|
33
|
+
featuredImageUrl: null,
|
|
34
|
+
words: 800,
|
|
35
|
+
publishedAt: "2026-04-15T10:00:00Z",
|
|
36
|
+
metaDescription: "Outro resumo",
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
const mapLocal = (p) => ({
|
|
40
|
+
slug: p.slug,
|
|
41
|
+
title: p.title,
|
|
42
|
+
excerpt: p.excerpt,
|
|
43
|
+
publishedAt: p.date,
|
|
44
|
+
category: p.category,
|
|
45
|
+
featuredImageUrl: null,
|
|
46
|
+
});
|
|
47
|
+
// ── Tests ─────────────────────────────────────────────────────────────────
|
|
48
|
+
describe("mergePosts", () => {
|
|
49
|
+
it("merge feliz — sem conflito, ordenado date-desc (default)", () => {
|
|
50
|
+
const result = mergePosts({
|
|
51
|
+
local: localFixture,
|
|
52
|
+
remote: remoteFixture,
|
|
53
|
+
mapLocal,
|
|
54
|
+
});
|
|
55
|
+
expect(result).toHaveLength(4);
|
|
56
|
+
// Mais recente primeiro
|
|
57
|
+
expect(result.map((p) => p.slug)).toEqual([
|
|
58
|
+
"novo-post-ia", // 2026-05-20 (remoto)
|
|
59
|
+
"outro-novo-ia", // 2026-04-15 (remoto)
|
|
60
|
+
"post-antigo-2025", // 2025-06-10 (local)
|
|
61
|
+
"post-antigo-2024", // 2024-01-15 (local)
|
|
62
|
+
]);
|
|
63
|
+
// Source flag preservado
|
|
64
|
+
expect(result[0]?.source).toBe("remote");
|
|
65
|
+
expect(result[3]?.source).toBe("local");
|
|
66
|
+
});
|
|
67
|
+
it("ordena date-asc quando solicitado", () => {
|
|
68
|
+
const result = mergePosts({
|
|
69
|
+
local: localFixture,
|
|
70
|
+
remote: remoteFixture,
|
|
71
|
+
mapLocal,
|
|
72
|
+
sortBy: "date-asc",
|
|
73
|
+
});
|
|
74
|
+
expect(result.map((p) => p.slug)).toEqual([
|
|
75
|
+
"post-antigo-2024",
|
|
76
|
+
"post-antigo-2025",
|
|
77
|
+
"outro-novo-ia",
|
|
78
|
+
"novo-post-ia",
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
81
|
+
it("sortBy 'none' mantém ordem (locais primeiro, depois remotos)", () => {
|
|
82
|
+
const result = mergePosts({
|
|
83
|
+
local: localFixture,
|
|
84
|
+
remote: remoteFixture,
|
|
85
|
+
mapLocal,
|
|
86
|
+
sortBy: "none",
|
|
87
|
+
});
|
|
88
|
+
expect(result.map((p) => p.slug)).toEqual([
|
|
89
|
+
"post-antigo-2024",
|
|
90
|
+
"post-antigo-2025",
|
|
91
|
+
"novo-post-ia",
|
|
92
|
+
"outro-novo-ia",
|
|
93
|
+
]);
|
|
94
|
+
});
|
|
95
|
+
it("dedupe 'remote-wins' (default) — remoto substitui local com mesmo slug", () => {
|
|
96
|
+
const localCom = [...localFixture, { ...localFixture[0], slug: "novo-post-ia", title: "Versão local antiga" }];
|
|
97
|
+
const result = mergePosts({
|
|
98
|
+
local: localCom,
|
|
99
|
+
remote: remoteFixture,
|
|
100
|
+
mapLocal,
|
|
101
|
+
});
|
|
102
|
+
expect(result).toHaveLength(4);
|
|
103
|
+
const post = result.find((p) => p.slug === "novo-post-ia");
|
|
104
|
+
expect(post.title).toBe("Novo post gerado por IA");
|
|
105
|
+
expect(post.source).toBe("remote");
|
|
106
|
+
});
|
|
107
|
+
it("dedupe 'local-wins' — mantém o local, ignora o remoto", () => {
|
|
108
|
+
const localCom = [
|
|
109
|
+
...localFixture,
|
|
110
|
+
{ ...localFixture[0], slug: "novo-post-ia", title: "Versão local sagrada" },
|
|
111
|
+
];
|
|
112
|
+
const result = mergePosts({
|
|
113
|
+
local: localCom,
|
|
114
|
+
remote: remoteFixture,
|
|
115
|
+
mapLocal,
|
|
116
|
+
dedupe: "local-wins",
|
|
117
|
+
});
|
|
118
|
+
expect(result).toHaveLength(4);
|
|
119
|
+
const post = result.find((p) => p.slug === "novo-post-ia");
|
|
120
|
+
expect(post.title).toBe("Versão local sagrada");
|
|
121
|
+
expect(post.source).toBe("local");
|
|
122
|
+
});
|
|
123
|
+
it("dedupe 'throw' — lança MergeConflictError com slug do conflito", () => {
|
|
124
|
+
const localCom = [
|
|
125
|
+
...localFixture,
|
|
126
|
+
{ ...localFixture[0], slug: "novo-post-ia", title: "Conflito" },
|
|
127
|
+
];
|
|
128
|
+
expect(() => mergePosts({
|
|
129
|
+
local: localCom,
|
|
130
|
+
remote: remoteFixture,
|
|
131
|
+
mapLocal,
|
|
132
|
+
dedupe: "throw",
|
|
133
|
+
})).toThrowError(MergeConflictError);
|
|
134
|
+
});
|
|
135
|
+
it("mapLocal retornando null filtra o post (cliente quer esconder rascunhos)", () => {
|
|
136
|
+
const result = mergePosts({
|
|
137
|
+
local: localFixture,
|
|
138
|
+
remote: remoteFixture,
|
|
139
|
+
mapLocal: (p) => (p.slug === "post-antigo-2024" ? null : mapLocal(p)),
|
|
140
|
+
});
|
|
141
|
+
expect(result.find((p) => p.slug === "post-antigo-2024")).toBeUndefined();
|
|
142
|
+
expect(result).toHaveLength(3);
|
|
143
|
+
});
|
|
144
|
+
it("filtra remotos sem slug/title/publishedAt (defesa contra API inconsistente)", () => {
|
|
145
|
+
const remoteCom = [
|
|
146
|
+
...remoteFixture,
|
|
147
|
+
// sem slug
|
|
148
|
+
{ id: "x", slug: null, title: "x", featuredImageUrl: null, words: 0, publishedAt: "2026-01-01" },
|
|
149
|
+
// sem title
|
|
150
|
+
{ id: "y", slug: "y", title: null, featuredImageUrl: null, words: 0, publishedAt: "2026-01-01" },
|
|
151
|
+
// sem publishedAt
|
|
152
|
+
{ id: "z", slug: "z", title: "z", featuredImageUrl: null, words: 0, publishedAt: null },
|
|
153
|
+
];
|
|
154
|
+
const result = mergePosts({ local: [], remote: remoteCom, mapLocal });
|
|
155
|
+
expect(result).toHaveLength(2); // só os 2 válidos do fixture
|
|
156
|
+
});
|
|
157
|
+
it("lista vazia em ambos os lados retorna []", () => {
|
|
158
|
+
const result = mergePosts({ local: [], remote: [], mapLocal });
|
|
159
|
+
expect(result).toEqual([]);
|
|
160
|
+
});
|
|
161
|
+
it("só locais (cliente sem painel ainda) retorna locais ordenados", () => {
|
|
162
|
+
const result = mergePosts({ local: localFixture, remote: [], mapLocal });
|
|
163
|
+
expect(result).toHaveLength(2);
|
|
164
|
+
expect(result[0].source).toBe("local");
|
|
165
|
+
});
|
|
166
|
+
it("só remotos (cliente sem posts antigos) retorna remotos ordenados", () => {
|
|
167
|
+
const result = mergePosts({ local: [], remote: remoteFixture, mapLocal });
|
|
168
|
+
expect(result).toHaveLength(2);
|
|
169
|
+
expect(result[0].source).toBe("remote");
|
|
170
|
+
});
|
|
171
|
+
it("ArticleListItem em modo 'plain' (sem metaDescription) vira excerpt null", () => {
|
|
172
|
+
const remotePlain = [
|
|
173
|
+
{
|
|
174
|
+
id: "uuid-3",
|
|
175
|
+
slug: "post-cancelled",
|
|
176
|
+
title: "Post de site cancelado",
|
|
177
|
+
featuredImageUrl: null,
|
|
178
|
+
words: 500,
|
|
179
|
+
publishedAt: "2026-05-01T10:00:00Z",
|
|
180
|
+
// sem metaTitle/metaDescription (plain mode)
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
const result = mergePosts({ local: [], remote: remotePlain, mapLocal });
|
|
184
|
+
expect(result).toHaveLength(1);
|
|
185
|
+
expect(result[0].excerpt).toBeNull();
|
|
186
|
+
});
|
|
187
|
+
it("data inválida vai pro final do feed sem quebrar", () => {
|
|
188
|
+
const remoteInvalido = [
|
|
189
|
+
{
|
|
190
|
+
id: "good",
|
|
191
|
+
slug: "good",
|
|
192
|
+
title: "Good",
|
|
193
|
+
featuredImageUrl: null,
|
|
194
|
+
words: 100,
|
|
195
|
+
publishedAt: "2026-05-20T10:00:00Z",
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: "bad",
|
|
199
|
+
slug: "bad",
|
|
200
|
+
title: "Bad",
|
|
201
|
+
featuredImageUrl: null,
|
|
202
|
+
words: 100,
|
|
203
|
+
publishedAt: "not-a-date",
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
const result = mergePosts({ local: [], remote: remoteInvalido, mapLocal });
|
|
207
|
+
expect(result).toHaveLength(2);
|
|
208
|
+
expect(result[0].slug).toBe("good"); // válido primeiro
|
|
209
|
+
expect(result[1].slug).toBe("bad"); // inválido vai pro final
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe("UnifiedPost type", () => {
|
|
213
|
+
it("source flag permite filtrar por origem na UI", () => {
|
|
214
|
+
const result = mergePosts({
|
|
215
|
+
local: localFixture,
|
|
216
|
+
remote: remoteFixture,
|
|
217
|
+
mapLocal,
|
|
218
|
+
});
|
|
219
|
+
const onlyRemote = result.filter((p) => p.source === "remote");
|
|
220
|
+
expect(onlyRemote).toHaveLength(2);
|
|
221
|
+
onlyRemote.forEach((p) => expect(p.source).toBe("remote"));
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
//# sourceMappingURL=merge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.test.js","sourceRoot":"","sources":["../src/merge.test.ts"],"names":[],"mappings":"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"}
|
package/dist/react.d.ts
CHANGED
|
@@ -88,4 +88,62 @@ export interface ArticleMetadata {
|
|
|
88
88
|
*/
|
|
89
89
|
export declare function articleToMetadata(article: ArticleMetadataInput): ArticleMetadata;
|
|
90
90
|
export type { Article, CustomMetaTag } from "./types.js";
|
|
91
|
+
/**
|
|
92
|
+
* Selo de transparência. Fecha a linha do revisor na ASSINATURA, no fim do
|
|
93
|
+
* artigo — nunca na barra do topo.
|
|
94
|
+
*/
|
|
95
|
+
export declare const SELO_IA = "Apoio de IA \u00B7 Revis\u00E3o humana";
|
|
96
|
+
export interface AutoriaDoArtigo {
|
|
97
|
+
/** Quem assina. SEMPRE preenchido: cai para a equipe da empresa. */
|
|
98
|
+
autor: string;
|
|
99
|
+
/** "Nome, cargo, registro" do revisor, ou `null` quando não há cadastro. */
|
|
100
|
+
revisor: string | null;
|
|
101
|
+
/** ISO da revisão, quando o schema traz `dateModified`. */
|
|
102
|
+
revisadoEm: string | null;
|
|
103
|
+
/** `false` quando a autoria veio da queda, e não do schema. */
|
|
104
|
+
temCadastro: boolean;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Lê a autoria do `schemaJson` do artigo.
|
|
108
|
+
*
|
|
109
|
+
* ⚠️ `author` SÓ vale quando é `Organization`. Texto produzido com apoio de IA
|
|
110
|
+
* e assinado por uma PESSOA é o que os Termos do Google proíbem desde
|
|
111
|
+
* 30/07/2026 — então, quando o schema traz uma Person em `author`, ela é
|
|
112
|
+
* ignorada aqui. O profissional aparece como REVISOR, via `contributor`.
|
|
113
|
+
*
|
|
114
|
+
* NUNCA devolve vazio: sem autoria no schema, assina a equipe da empresa
|
|
115
|
+
* (`empresa`, ou o `publisher.name` do próprio schema). Artigo no ar sem dizer
|
|
116
|
+
* quem assina e sem declarar o apoio de IA não é uma saída aceitável — foi o
|
|
117
|
+
* que esta função existe para impedir.
|
|
118
|
+
*/
|
|
119
|
+
export declare function autoriaDoArtigo(article: {
|
|
120
|
+
schemaJson?: unknown | null;
|
|
121
|
+
}, opts?: {
|
|
122
|
+
empresa?: string;
|
|
123
|
+
}): AutoriaDoArtigo;
|
|
124
|
+
export interface AuthorBarProps {
|
|
125
|
+
article: {
|
|
126
|
+
schemaJson?: unknown | null;
|
|
127
|
+
};
|
|
128
|
+
/** Nome do negócio, para a queda. Sem ele, usa o `publisher` do schema. */
|
|
129
|
+
empresa?: string;
|
|
130
|
+
/** Classe do contêiner. O estilo é do SITE — o SDK não traz CSS. */
|
|
131
|
+
className?: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Barra de autoria, logo abaixo do `<h1>`.
|
|
135
|
+
*
|
|
136
|
+
* SEMPRE renderiza (ver `autoriaDoArtigo`). Não traz CSS: o SDK não pode impor
|
|
137
|
+
* visual a sites que têm cada um o seu. As classes (`ia-autor` por padrão) são
|
|
138
|
+
* ganchos para o site vestir.
|
|
139
|
+
*
|
|
140
|
+
* O selo de IA NÃO vem aqui — ele fecha a linha do revisor em
|
|
141
|
+
* `<AuthorSignature>`, no fim do artigo.
|
|
142
|
+
*/
|
|
143
|
+
export declare function AuthorBar({ article, empresa, className, }: AuthorBarProps): ReactElement;
|
|
144
|
+
/**
|
|
145
|
+
* Assinatura, no FIM do artigo. É aqui que o selo de IA fecha a linha do
|
|
146
|
+
* revisor — e aparece tanto com profissional cadastrado quanto sem.
|
|
147
|
+
*/
|
|
148
|
+
export declare function AuthorSignature({ article, empresa, className, }: AuthorBarProps): ReactElement;
|
|
91
149
|
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
|
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* Renderiza um `<script type="application/ld+json">` com o schema JSON-LD do
|
|
4
4
|
* artigo. Pode ser colocado em qualquer lugar do `<body>` — o Google lê tanto
|
|
@@ -81,4 +81,100 @@ export function articleToMetadata(article) {
|
|
|
81
81
|
...(Object.keys(other).length > 0 ? { other } : {}),
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
85
|
+
// AUTORIA
|
|
86
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
87
|
+
/**
|
|
88
|
+
* Selo de transparência. Fecha a linha do revisor na ASSINATURA, no fim do
|
|
89
|
+
* artigo — nunca na barra do topo.
|
|
90
|
+
*/
|
|
91
|
+
export const SELO_IA = "Apoio de IA · Revisão humana";
|
|
92
|
+
const ehNo = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
93
|
+
const texto = (v) => typeof v === "string" && v.trim() ? v.trim() : null;
|
|
94
|
+
/**
|
|
95
|
+
* Lê a autoria do `schemaJson` do artigo.
|
|
96
|
+
*
|
|
97
|
+
* ⚠️ `author` SÓ vale quando é `Organization`. Texto produzido com apoio de IA
|
|
98
|
+
* e assinado por uma PESSOA é o que os Termos do Google proíbem desde
|
|
99
|
+
* 30/07/2026 — então, quando o schema traz uma Person em `author`, ela é
|
|
100
|
+
* ignorada aqui. O profissional aparece como REVISOR, via `contributor`.
|
|
101
|
+
*
|
|
102
|
+
* NUNCA devolve vazio: sem autoria no schema, assina a equipe da empresa
|
|
103
|
+
* (`empresa`, ou o `publisher.name` do próprio schema). Artigo no ar sem dizer
|
|
104
|
+
* quem assina e sem declarar o apoio de IA não é uma saída aceitável — foi o
|
|
105
|
+
* que esta função existe para impedir.
|
|
106
|
+
*/
|
|
107
|
+
export function autoriaDoArtigo(article, opts) {
|
|
108
|
+
const schema = article.schemaJson;
|
|
109
|
+
const nos = [];
|
|
110
|
+
if (ehNo(schema)) {
|
|
111
|
+
const grafo = schema["@graph"];
|
|
112
|
+
if (Array.isArray(grafo))
|
|
113
|
+
nos.push(...grafo.filter(ehNo));
|
|
114
|
+
else
|
|
115
|
+
nos.push(schema);
|
|
116
|
+
}
|
|
117
|
+
// Nome da empresa para a queda: o que veio por prop vence; senão, o
|
|
118
|
+
// `publisher` do schema, que é justamente a organização do cliente.
|
|
119
|
+
let empresa = texto(opts?.empresa);
|
|
120
|
+
if (!empresa) {
|
|
121
|
+
for (const no of nos) {
|
|
122
|
+
const pub = no.publisher;
|
|
123
|
+
if (ehNo(pub) && texto(pub.name)) {
|
|
124
|
+
empresa = texto(pub.name);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
for (const no of nos) {
|
|
130
|
+
const a = no.author;
|
|
131
|
+
if (!ehNo(a) || a["@type"] !== "Organization")
|
|
132
|
+
continue;
|
|
133
|
+
const autor = texto(a.name);
|
|
134
|
+
if (!autor)
|
|
135
|
+
continue;
|
|
136
|
+
const c = no.contributor;
|
|
137
|
+
const revisor = ehNo(c) && texto(c.name)
|
|
138
|
+
? [texto(c.name), texto(c.jobTitle), texto(c.identifier)]
|
|
139
|
+
.filter(Boolean)
|
|
140
|
+
.join(", ")
|
|
141
|
+
: null;
|
|
142
|
+
return { autor, revisor, revisadoEm: texto(no.dateModified), temCadastro: true };
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
autor: empresa ? `Equipe Editorial ${empresa}` : "Equipe Editorial",
|
|
146
|
+
revisor: null,
|
|
147
|
+
revisadoEm: null,
|
|
148
|
+
temCadastro: false,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/** Texto da linha de revisão, igual nos dois blocos. */
|
|
152
|
+
function linhaDeRevisao(a, empresa) {
|
|
153
|
+
const quem = a.revisor
|
|
154
|
+
? `Revisado por ${a.revisor}`
|
|
155
|
+
: `Revisado pela equipe ${empresa?.trim() || a.autor.replace(/^Equipe Editorial\s*/, "") || "editorial"}`;
|
|
156
|
+
return `${quem} · ${SELO_IA}`;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Barra de autoria, logo abaixo do `<h1>`.
|
|
160
|
+
*
|
|
161
|
+
* SEMPRE renderiza (ver `autoriaDoArtigo`). Não traz CSS: o SDK não pode impor
|
|
162
|
+
* visual a sites que têm cada um o seu. As classes (`ia-autor` por padrão) são
|
|
163
|
+
* ganchos para o site vestir.
|
|
164
|
+
*
|
|
165
|
+
* O selo de IA NÃO vem aqui — ele fecha a linha do revisor em
|
|
166
|
+
* `<AuthorSignature>`, no fim do artigo.
|
|
167
|
+
*/
|
|
168
|
+
export function AuthorBar({ article, empresa, className = "ia-autor", }) {
|
|
169
|
+
const a = autoriaDoArtigo(article, { empresa });
|
|
170
|
+
return (_jsxs("div", { className: className, children: [_jsxs("strong", { children: ["por ", a.autor] }), a.revisor ? _jsxs("span", { children: ["Revis\u00E3o: ", a.revisor] }) : null] }));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Assinatura, no FIM do artigo. É aqui que o selo de IA fecha a linha do
|
|
174
|
+
* revisor — e aparece tanto com profissional cadastrado quanto sem.
|
|
175
|
+
*/
|
|
176
|
+
export function AuthorSignature({ article, empresa, className = "ia-assinatura", }) {
|
|
177
|
+
const a = autoriaDoArtigo(article, { empresa });
|
|
178
|
+
return (_jsxs("section", { className: className, "aria-label": "Autoria", children: [_jsxs("p", { className: `${className}-nome`, children: ["Escrito por ", a.autor] }), _jsx("p", { className: `${className}-cargo`, children: linhaDeRevisao(a, empresa) })] }));
|
|
179
|
+
}
|
|
84
180
|
//# sourceMappingURL=react.js.map
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
|