@we8/client 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 +113 -0
- package/dist/client.d.ts +74 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +143 -0
- package/dist/client.js.map +1 -0
- package/dist/contract.d.ts +179 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +53 -0
- package/dist/contract.js.map +1 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +80 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# @we8/client
|
|
2
|
+
|
|
3
|
+
A typed client for the we8 public API. It is a thin convenience layer over the
|
|
4
|
+
OpenAPI-documented HTTP contract: every method maps 1:1 to a `/v1` route, so you
|
|
5
|
+
never lose anything by dropping down to `fetch`. The API is the product; this
|
|
6
|
+
package is the ergonomic way to call it.
|
|
7
|
+
|
|
8
|
+
- Zero runtime dependencies. The wire contract lives in this package as plain
|
|
9
|
+
TypeScript (`src/contract.ts`), so nothing is pulled in at build or run time.
|
|
10
|
+
- Runs in browsers, Node, and edge runtimes (anywhere `fetch` exists).
|
|
11
|
+
- Speaks the same `/v1` dialect as a managed we8 tenant, so the same code works
|
|
12
|
+
against a self-hosted CMS and a managed one.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- Node 20 or newer, any modern browser, or an edge runtime. Zero runtime
|
|
17
|
+
dependencies.
|
|
18
|
+
- A we8 CMS to talk to: the self-hosted `@we8/cms` or a managed we8.io tenant.
|
|
19
|
+
Both speak the same `/v1` dialect. For a self-hosted CMS, pass its origin as
|
|
20
|
+
`baseUrl` (the default `/api` is the managed platform's same-origin shape).
|
|
21
|
+
- A publishable (`pk_`) key for reads and beacons; a secret (`sk_`) key only
|
|
22
|
+
where a route demands one.
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npm install @we8/client
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { createClient } from '@we8/client';
|
|
33
|
+
|
|
34
|
+
const we8 = createClient({
|
|
35
|
+
key: process.env.WE8_PUBLISHABLE_KEY!, // pk_... (public) or sk_... (server only)
|
|
36
|
+
baseUrl: 'https://cms.example.com', // your CMS origin, no path on the end
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Posts
|
|
40
|
+
const page = await we8.posts.list({ page: 1, pageSize: 10, tag: 'launch' });
|
|
41
|
+
const { post, jsonld } = await we8.posts.get('hello-world');
|
|
42
|
+
|
|
43
|
+
// Site identity (name, canonical URL, SEO fallbacks, publisher)
|
|
44
|
+
const site = await we8.site.config();
|
|
45
|
+
|
|
46
|
+
// Forms (formKey plus arbitrary fields; the API validates per form)
|
|
47
|
+
const { id } = await we8.forms.submit('contact', { email: 'a@b.com', body: 'hi' });
|
|
48
|
+
|
|
49
|
+
// Events (analytics; safe to fire from the browser with a pk_ key)
|
|
50
|
+
await we8.events.visit({ pathname: '/', sessionId });
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Keys and the base URL
|
|
54
|
+
|
|
55
|
+
- A publishable key (`pk_...`) is sent as `X-We8-Key` and is safe to embed in a
|
|
56
|
+
shipped frontend. A secret key (`sk_...`) is sent as `Authorization: Bearer`
|
|
57
|
+
and is for server or build-time use only; never ship it to a browser.
|
|
58
|
+
- `baseUrl` is the API base every route hangs off: the client requests
|
|
59
|
+
`${baseUrl}/v1/...`. **Pass it explicitly for a self-hosted we8 CMS**, as the
|
|
60
|
+
CMS origin with no path on the end (`https://cms.example.com`, or
|
|
61
|
+
`http://localhost:8787` in development). The default is the same-origin
|
|
62
|
+
`/api`, which is the managed platform's shape, and it 404s against a
|
|
63
|
+
standalone CMS.
|
|
64
|
+
- Pass a `fetch` implementation via `options.fetch` in tests or runtimes without
|
|
65
|
+
a global `fetch`.
|
|
66
|
+
|
|
67
|
+
## Surface
|
|
68
|
+
|
|
69
|
+
| Group | Methods |
|
|
70
|
+
| ----------- | ----------------------------------------------------------------------------- |
|
|
71
|
+
| `posts` | `list(params?)`, `get(slug)`, `view(slug, sessionId)`, `like(slug, sessionId)` |
|
|
72
|
+
| `authors` | `get(slug)` |
|
|
73
|
+
| `site` | `config()` |
|
|
74
|
+
| `documents` | `get(kind)` where `kind` is `'design-md'` or `'llms-txt'` |
|
|
75
|
+
| `forms` | `submit(formKey, data, { turnstileToken? })` |
|
|
76
|
+
| `events` | `visit(input)`, `consent(input)` |
|
|
77
|
+
| top level | `sitemapUrl()` |
|
|
78
|
+
|
|
79
|
+
Every call throws a `We8ApiError` (carrying the API's stable `code` and the HTTP
|
|
80
|
+
`status`) on failure; a transport failure surfaces as `code: 'internal'`,
|
|
81
|
+
`status: 0`. Use `isWe8ApiError(err)` to narrow without importing the class.
|
|
82
|
+
|
|
83
|
+
## The contract
|
|
84
|
+
|
|
85
|
+
`src/contract.ts` is the typed statement of the `/v1` dialect: the response
|
|
86
|
+
envelope, the frozen vocabularies (`POST_TYPES`, `AUTHOR_TYPES`,
|
|
87
|
+
`CONSENT_DECISIONS`, `SITE_DOCUMENT_KINDS`, `CTA_STYLES`, `ERROR_CODES`), and
|
|
88
|
+
the record shapes. The vocabularies are exported as runtime constants as well
|
|
89
|
+
as types, so a frontend can build a filter or a select box from them without
|
|
90
|
+
restating the list. `test/contract.test.ts` pins every member, so a change to
|
|
91
|
+
the dialect cannot land quietly.
|
|
92
|
+
|
|
93
|
+
The full, authoritative interface is the OpenAPI document your CMS serves:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
https://cms.example.com/v1/openapi.json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
It is keyless, so you can read the contract before anyone has issued you a key.
|
|
100
|
+
|
|
101
|
+
## Environment contract
|
|
102
|
+
|
|
103
|
+
Headless and build-time callers typically read these from the environment and
|
|
104
|
+
pass them in:
|
|
105
|
+
|
|
106
|
+
- `WE8_API_URL`: the absolute API base given to `createClient({ baseUrl })`,
|
|
107
|
+
which for a self-hosted CMS is its origin.
|
|
108
|
+
- `WE8_PUBLISHABLE_KEY`: the publishable (`pk_`) key given to
|
|
109
|
+
`createClient({ key })`.
|
|
110
|
+
|
|
111
|
+
See [the API doc](https://github.com/reveriext/we8-package/blob/main/docs/api.md) for the dialect in prose, and [the
|
|
112
|
+
frontend doc](https://github.com/reveriext/we8-package/blob/main/docs/frontend.md) for how `@we8/astro` and the starter
|
|
113
|
+
template build on this.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { SiteDocumentKind } from './contract.js';
|
|
2
|
+
import type { We8Author, We8ConsentInput, We8Document, We8FormData, We8FormSubmitOptions, We8JsonLd, We8LikeResult, We8PostDetail, We8PostList, We8PostListParams, We8SiteConfig, We8VisitInput } from './types.js';
|
|
3
|
+
export interface We8ClientOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The site API key. A publishable key (`pk_...`) is sent as `X-We8-Key`; a
|
|
6
|
+
* secret key (`sk_...`) is sent as `Authorization: Bearer`. Publishable keys
|
|
7
|
+
* are safe to embed in a shipped frontend (that is their purpose); secret
|
|
8
|
+
* keys are for server and build-time use only and must never reach a browser.
|
|
9
|
+
*/
|
|
10
|
+
key: string;
|
|
11
|
+
/**
|
|
12
|
+
* API base URL: every route is requested as `${baseUrl}/v1/...`. It
|
|
13
|
+
* defaults to the same-origin `/api`, which is the shape managed we8 serves
|
|
14
|
+
* behind its router. A SELF-HOSTED @we8/cms worker is the API origin itself
|
|
15
|
+
* and serves `/v1` at its root, so pass its origin with no path on the end:
|
|
16
|
+
* `https://cms.example.com`, or `http://localhost:8787` in development.
|
|
17
|
+
*/
|
|
18
|
+
baseUrl?: string;
|
|
19
|
+
/**
|
|
20
|
+
* A `fetch` implementation to use instead of the global. Useful in tests and
|
|
21
|
+
* in runtimes without a global `fetch`.
|
|
22
|
+
*/
|
|
23
|
+
fetch?: typeof fetch;
|
|
24
|
+
}
|
|
25
|
+
/** Result of `forms.submit`. `id` is null when the submission was accepted but silently dropped (honeypot or dedupe). */
|
|
26
|
+
export interface We8FormSubmitResult {
|
|
27
|
+
id: string | null;
|
|
28
|
+
}
|
|
29
|
+
export interface We8Client {
|
|
30
|
+
posts: {
|
|
31
|
+
/** List published posts (paged, optionally filtered by tag, category, or type). */
|
|
32
|
+
list(params?: We8PostListParams): Promise<We8PostList>;
|
|
33
|
+
/** Fetch a single published post by slug, with its JSON-LD. */
|
|
34
|
+
get(slug: string): Promise<We8PostDetail>;
|
|
35
|
+
/** Record a view for a post (deduped per session by the API). */
|
|
36
|
+
view(slug: string, sessionId: string): Promise<void>;
|
|
37
|
+
/** Toggle a like for a post; returns the new liked state and count. */
|
|
38
|
+
like(slug: string, sessionId: string): Promise<We8LikeResult>;
|
|
39
|
+
};
|
|
40
|
+
authors: {
|
|
41
|
+
/** Fetch a single author profile by slug. */
|
|
42
|
+
get(slug: string): Promise<We8Author>;
|
|
43
|
+
};
|
|
44
|
+
site: {
|
|
45
|
+
/** Fetch the site identity card: name, canonical URL, SEO fallbacks, publisher, content paths. */
|
|
46
|
+
config(): Promise<We8SiteConfig>;
|
|
47
|
+
};
|
|
48
|
+
documents: {
|
|
49
|
+
/** Fetch a site document (design.md or llms.txt); empty content when never written. */
|
|
50
|
+
get(kind: SiteDocumentKind): Promise<We8Document>;
|
|
51
|
+
};
|
|
52
|
+
forms: {
|
|
53
|
+
/** Submit a form by its key. Extra fields pass through; the API validates per form. */
|
|
54
|
+
submit(formKey: string, data: We8FormData, options?: We8FormSubmitOptions): Promise<We8FormSubmitResult>;
|
|
55
|
+
};
|
|
56
|
+
events: {
|
|
57
|
+
/** Record a page visit. */
|
|
58
|
+
visit(input: We8VisitInput): Promise<void>;
|
|
59
|
+
/** Record a cookie-consent decision. */
|
|
60
|
+
consent(input: We8ConsentInput): Promise<void>;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The absolute-or-relative URL of this site's sitemap, fetchable AS-IS: the
|
|
64
|
+
* public router requires a key on every request, so for a publishable
|
|
65
|
+
* (`pk_`) key the key is embedded as `?key=` (pk keys are public by design;
|
|
66
|
+
* this is what makes the URL usable in a robots.txt or by a search engine).
|
|
67
|
+
* A secret (`sk_`) key must never appear in a URL, so an sk-keyed client
|
|
68
|
+
* gets the bare URL and must fetch it with auth headers itself.
|
|
69
|
+
*/
|
|
70
|
+
sitemapUrl(): string;
|
|
71
|
+
}
|
|
72
|
+
export declare function createClient(options: We8ClientOptions): We8Client;
|
|
73
|
+
export type { We8JsonLd };
|
|
74
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,yHAAyH;AACzH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE;QACL,mFAAmF;QACnF,IAAI,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QACvD,+DAA+D;QAC/D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAC1C,iEAAiE;QACjE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACrD,uEAAuE;QACvE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;KAC/D,CAAC;IACF,OAAO,EAAE;QACP,6CAA6C;QAC7C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;KACvC,CAAC;IACF,IAAI,EAAE;QACJ,kGAAkG;QAClG,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;KAClC,CAAC;IACF,SAAS,EAAE;QACT,uFAAuF;QACvF,GAAG,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;KACnD,CAAC;IACF,KAAK,EAAE;QACL,uFAAuF;QACvF,MAAM,CACJ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAAC;KACjC,CAAC;IACF,MAAM,EAAE;QACN,2BAA2B;QAC3B,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3C,wCAAwC;QACxC,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAChD,CAAC;IACF;;;;;;;OAOG;IACH,UAAU,IAAI,MAAM,CAAC;CACtB;AAiCD,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA+HjE;AAED,YAAY,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { We8ApiError } from './errors.js';
|
|
2
|
+
function authHeader(key) {
|
|
3
|
+
// The public router accepts a secret key via `Authorization: Bearer` and a
|
|
4
|
+
// publishable key via `X-We8-Key`. Anything that is not explicitly `sk_` is
|
|
5
|
+
// treated as publishable, so an unknown or future key prefix still reaches
|
|
6
|
+
// the router on the header that does not read as a bearer credential.
|
|
7
|
+
return key.startsWith('sk_') ? { Authorization: `Bearer ${key}` } : { 'X-We8-Key': key };
|
|
8
|
+
}
|
|
9
|
+
function statusToCode(status) {
|
|
10
|
+
switch (status) {
|
|
11
|
+
case 400:
|
|
12
|
+
return 'validation_error';
|
|
13
|
+
case 401:
|
|
14
|
+
return 'unauthorized';
|
|
15
|
+
case 403:
|
|
16
|
+
return 'forbidden';
|
|
17
|
+
case 404:
|
|
18
|
+
return 'not_found';
|
|
19
|
+
case 413:
|
|
20
|
+
return 'payload_too_large';
|
|
21
|
+
case 429:
|
|
22
|
+
return 'rate_limited';
|
|
23
|
+
default:
|
|
24
|
+
return 'internal';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function messageOf(cause) {
|
|
28
|
+
return cause instanceof Error ? cause.message : String(cause);
|
|
29
|
+
}
|
|
30
|
+
export function createClient(options) {
|
|
31
|
+
if (!options.key)
|
|
32
|
+
throw new Error('createClient: a `key` is required');
|
|
33
|
+
const { key } = options;
|
|
34
|
+
const baseUrl = (options.baseUrl ?? '/api').replace(/\/+$/, '');
|
|
35
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
36
|
+
if (typeof fetchImpl !== 'function') {
|
|
37
|
+
throw new Error('createClient: no global `fetch` found; pass one via `options.fetch`');
|
|
38
|
+
}
|
|
39
|
+
function buildUrl(path, query) {
|
|
40
|
+
let url = `${baseUrl}/v1/${path}`;
|
|
41
|
+
if (query) {
|
|
42
|
+
const qs = new URLSearchParams(query).toString();
|
|
43
|
+
if (qs)
|
|
44
|
+
url += `?${qs}`;
|
|
45
|
+
}
|
|
46
|
+
return url;
|
|
47
|
+
}
|
|
48
|
+
async function request(method, path, opts = {}) {
|
|
49
|
+
const url = buildUrl(path, opts.query);
|
|
50
|
+
const headers = { Accept: 'application/json', ...authHeader(key) };
|
|
51
|
+
let body;
|
|
52
|
+
if (opts.body !== undefined) {
|
|
53
|
+
headers['Content-Type'] = 'application/json';
|
|
54
|
+
body = JSON.stringify(opts.body);
|
|
55
|
+
}
|
|
56
|
+
let res;
|
|
57
|
+
try {
|
|
58
|
+
res = await fetchImpl(url, { method, headers, ...(body === undefined ? {} : { body }) });
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
// Transport-level failure (offline, DNS, CORS block): no HTTP status.
|
|
62
|
+
throw new We8ApiError('internal', `request to ${url} failed: ${messageOf(cause)}`, 0);
|
|
63
|
+
}
|
|
64
|
+
const text = await res.text();
|
|
65
|
+
let envelope;
|
|
66
|
+
if (text) {
|
|
67
|
+
try {
|
|
68
|
+
envelope = JSON.parse(text);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Non-JSON body; handled below by the status checks.
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (envelope && envelope.ok === false) {
|
|
75
|
+
throw new We8ApiError(envelope.code, envelope.error, res.status);
|
|
76
|
+
}
|
|
77
|
+
if (!res.ok) {
|
|
78
|
+
throw new We8ApiError(statusToCode(res.status), `HTTP ${res.status} from ${url}`, res.status);
|
|
79
|
+
}
|
|
80
|
+
if (!envelope) {
|
|
81
|
+
throw new We8ApiError('internal', `unexpected non-JSON response from ${url}`, res.status);
|
|
82
|
+
}
|
|
83
|
+
// Strip the `ok: true` discriminant, leaving just the typed data payload.
|
|
84
|
+
const { ok: _ok, ...data } = envelope;
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
const enc = encodeURIComponent;
|
|
88
|
+
// Normalize the typed list params into a string query record, dropping
|
|
89
|
+
// absent or empty values. Explicit (rather than a generic index signature)
|
|
90
|
+
// so it stays clean under exactOptionalPropertyTypes and the client owns
|
|
91
|
+
// exactly which query keys it forwards.
|
|
92
|
+
function postListQuery(params) {
|
|
93
|
+
const q = {};
|
|
94
|
+
if (params?.page !== undefined)
|
|
95
|
+
q['page'] = String(params.page);
|
|
96
|
+
if (params?.pageSize !== undefined)
|
|
97
|
+
q['pageSize'] = String(params.pageSize);
|
|
98
|
+
if (params?.tag)
|
|
99
|
+
q['tag'] = params.tag;
|
|
100
|
+
if (params?.category)
|
|
101
|
+
q['category'] = params.category;
|
|
102
|
+
if (params?.type)
|
|
103
|
+
q['type'] = params.type;
|
|
104
|
+
return q;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
posts: {
|
|
108
|
+
list: (params) => request('GET', 'posts', { query: postListQuery(params) }),
|
|
109
|
+
get: (slug) => request('GET', `posts/${enc(slug)}`),
|
|
110
|
+
view: (slug, sessionId) => request('POST', `posts/${enc(slug)}/view`, {
|
|
111
|
+
body: { sessionId },
|
|
112
|
+
}).then(() => undefined),
|
|
113
|
+
like: (slug, sessionId) => request('POST', `posts/${enc(slug)}/like`, { body: { sessionId } }),
|
|
114
|
+
},
|
|
115
|
+
authors: {
|
|
116
|
+
get: (slug) => request('GET', `authors/${enc(slug)}`).then((d) => d.author),
|
|
117
|
+
},
|
|
118
|
+
site: {
|
|
119
|
+
config: () => request('GET', 'site').then((d) => d.site),
|
|
120
|
+
},
|
|
121
|
+
documents: {
|
|
122
|
+
get: (kind) => request('GET', `documents/${enc(kind)}`).then((d) => d.document),
|
|
123
|
+
},
|
|
124
|
+
forms: {
|
|
125
|
+
submit: (formKey, data, opts) => request('POST', `forms/${enc(formKey)}/submissions`, {
|
|
126
|
+
body: opts?.turnstileToken ? { ...data, turnstileToken: opts.turnstileToken } : data,
|
|
127
|
+
}),
|
|
128
|
+
},
|
|
129
|
+
events: {
|
|
130
|
+
visit: (input) => request('POST', 'events/visit', { body: input }).then(() => undefined),
|
|
131
|
+
consent: (input) => request('POST', 'events/consent', { body: input }).then(() => undefined),
|
|
132
|
+
},
|
|
133
|
+
sitemapUrl: () => {
|
|
134
|
+
const url = `${baseUrl}/v1/sitemap.xml`;
|
|
135
|
+
// Without a key the public router 401s (it requires a key on EVERY
|
|
136
|
+
// path), so a bare URL would be dead on arrival for any consumer that
|
|
137
|
+
// cannot send headers (robots.txt, a search engine). Embed a
|
|
138
|
+
// publishable key via the router's ?key= channel; never embed a secret.
|
|
139
|
+
return key.startsWith('sk_') ? url : `${url}?key=${encodeURIComponent(key)}`;
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//# 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,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire contract of the we8 public API, expressed as plain TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* In the managed platform these shapes are derived from Zod schemas in a
|
|
5
|
+
* shared package. This package has zero runtime dependencies by design, so the
|
|
6
|
+
* contract is restated here as types plus a handful of frozen vocabularies.
|
|
7
|
+
* The `/v1` dialect is the same one a managed we8 tenant speaks, so a site
|
|
8
|
+
* built on this client works against either backend unchanged.
|
|
9
|
+
*
|
|
10
|
+
* Everything here is the PUBLIC half of the contract: what `/v1/*` serves and
|
|
11
|
+
* accepts. Admin-only shapes live in the CMS package, not here.
|
|
12
|
+
*/
|
|
13
|
+
/** Every stable machine-readable error code the API can return. */
|
|
14
|
+
export declare const ERROR_CODES: readonly ["validation_error", "unauthorized", "forbidden", "not_found", "conflict", "rate_limited", "payload_too_large", "internal"];
|
|
15
|
+
export type ErrorCode = (typeof ERROR_CODES)[number];
|
|
16
|
+
/** A successful envelope: `ok: true` plus the payload fields, flattened. */
|
|
17
|
+
export type Ok<T extends object = object> = {
|
|
18
|
+
ok: true;
|
|
19
|
+
} & T;
|
|
20
|
+
/** A failed envelope. `code` is stable; `error` is a human-readable message. */
|
|
21
|
+
export interface Err {
|
|
22
|
+
ok: false;
|
|
23
|
+
error: string;
|
|
24
|
+
code: ErrorCode;
|
|
25
|
+
}
|
|
26
|
+
export type Envelope<T extends object = object> = Ok<T> | Err;
|
|
27
|
+
/**
|
|
28
|
+
* Content types: a fixed vocabulary, deliberately not extensible per site,
|
|
29
|
+
* because type drives routing (contentPaths), the sitemap, the JSON-LD
|
|
30
|
+
* `@type`, template switching, and filters. Adding a member later is an
|
|
31
|
+
* additive change; open values would break all five consumers.
|
|
32
|
+
*/
|
|
33
|
+
export declare const POST_TYPES: readonly ["blog", "article", "news", "research", "whitepaper", "case-study"];
|
|
34
|
+
export type PostType = (typeof POST_TYPES)[number];
|
|
35
|
+
export declare const AUTHOR_TYPES: readonly ["team", "guest", "advisor", "partner"];
|
|
36
|
+
export type AuthorType = (typeof AUTHOR_TYPES)[number];
|
|
37
|
+
export declare const CONSENT_DECISIONS: readonly ["accepted", "partial", "declined"];
|
|
38
|
+
export type ConsentDecision = (typeof CONSENT_DECISIONS)[number];
|
|
39
|
+
/**
|
|
40
|
+
* Site documents: small site-authored texts served at the frontend's root.
|
|
41
|
+
* A fixed two-member vocabulary, one entry per document the platform knows how
|
|
42
|
+
* to serve.
|
|
43
|
+
*/
|
|
44
|
+
export declare const SITE_DOCUMENT_KINDS: readonly ["design-md", "llms-txt"];
|
|
45
|
+
export type SiteDocumentKind = (typeof SITE_DOCUMENT_KINDS)[number];
|
|
46
|
+
export declare const CTA_STYLES: readonly ["link", "gated-download"];
|
|
47
|
+
export type CtaStyle = (typeof CTA_STYLES)[number];
|
|
48
|
+
/**
|
|
49
|
+
* An inline call to action, versioned with the post's content. `link` renders
|
|
50
|
+
* a plain button to `url`. `gated-download` embeds the form named by `formKey`
|
|
51
|
+
* and reveals `assetUrl` once the form submits successfully: thank-you-surface
|
|
52
|
+
* delivery, not DRM.
|
|
53
|
+
*/
|
|
54
|
+
export interface Cta {
|
|
55
|
+
style: CtaStyle;
|
|
56
|
+
heading?: string;
|
|
57
|
+
buttonLabel: string;
|
|
58
|
+
/** Required when `style` is `link`. */
|
|
59
|
+
url?: string;
|
|
60
|
+
/** The form's stable key (for example `contact`). Required when `style` is `gated-download`. */
|
|
61
|
+
formKey?: string;
|
|
62
|
+
/** The asset revealed after a successful gated submission. */
|
|
63
|
+
assetUrl?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The content fields of a published version. `We8Post` composes this with the
|
|
67
|
+
* post-level identity and counters to form what `/v1/posts` serves.
|
|
68
|
+
*/
|
|
69
|
+
export interface PostVersionRecord {
|
|
70
|
+
id: string;
|
|
71
|
+
postId: string;
|
|
72
|
+
version: number;
|
|
73
|
+
title: string;
|
|
74
|
+
excerpt: string | null;
|
|
75
|
+
content: string;
|
|
76
|
+
coverImageUrl: string | null;
|
|
77
|
+
category: string | null;
|
|
78
|
+
tags: string[];
|
|
79
|
+
ogTitle: string | null;
|
|
80
|
+
ogDescription: string | null;
|
|
81
|
+
ogImageUrl: string | null;
|
|
82
|
+
/** AEO (0.1): editor-authored answer summary. Absent on older backends. */
|
|
83
|
+
answerSummary?: string | null;
|
|
84
|
+
/** AEO (0.1): the question this post answers. Absent on older backends. */
|
|
85
|
+
questionHeading?: string | null;
|
|
86
|
+
cta: Cta | null;
|
|
87
|
+
authorIds: string[];
|
|
88
|
+
wordCount: number | null;
|
|
89
|
+
note: string | null;
|
|
90
|
+
publishedAt: string;
|
|
91
|
+
publishedBy: string | null;
|
|
92
|
+
}
|
|
93
|
+
export interface AuthorLink {
|
|
94
|
+
label: string;
|
|
95
|
+
url: string;
|
|
96
|
+
}
|
|
97
|
+
export interface AuthorRecord {
|
|
98
|
+
id: string;
|
|
99
|
+
slug: string;
|
|
100
|
+
name: string;
|
|
101
|
+
type: AuthorType;
|
|
102
|
+
roleTitle?: string;
|
|
103
|
+
avatarUrl?: string;
|
|
104
|
+
bio?: string;
|
|
105
|
+
links: AuthorLink[];
|
|
106
|
+
createdAt: string;
|
|
107
|
+
updatedAt: string;
|
|
108
|
+
}
|
|
109
|
+
export interface SiteDocumentRecord {
|
|
110
|
+
kind: SiteDocumentKind;
|
|
111
|
+
content: string;
|
|
112
|
+
/** AEO (0.1): editor-authored answer summary. Absent on older backends. */
|
|
113
|
+
answerSummary?: string | null;
|
|
114
|
+
/** `null` when the document was never written. */
|
|
115
|
+
updatedAt: string | null;
|
|
116
|
+
}
|
|
117
|
+
export interface VisitEventInput {
|
|
118
|
+
pathname: string;
|
|
119
|
+
referrer?: string;
|
|
120
|
+
sessionId: string;
|
|
121
|
+
}
|
|
122
|
+
export interface ConsentEventInput {
|
|
123
|
+
sessionId: string;
|
|
124
|
+
decision: ConsentDecision;
|
|
125
|
+
analytics: boolean;
|
|
126
|
+
performance: boolean;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Site-level SEO fallbacks. A template's own values always win; these fill the
|
|
130
|
+
* gaps. `titleTemplate` uses `%s` as the page-title placeholder, for example
|
|
131
|
+
* `%s | Northgate Tools`.
|
|
132
|
+
*/
|
|
133
|
+
export interface SeoSettings {
|
|
134
|
+
defaultTitle?: string;
|
|
135
|
+
titleTemplate?: string;
|
|
136
|
+
metaDescription?: string;
|
|
137
|
+
ogTitle?: string;
|
|
138
|
+
ogDescription?: string;
|
|
139
|
+
ogImageUrl?: string;
|
|
140
|
+
twitterHandle?: string;
|
|
141
|
+
discourageSearchEngines: boolean;
|
|
142
|
+
}
|
|
143
|
+
/** schema.org Organization, minimal shape. Used as the JSON-LD `publisher`. */
|
|
144
|
+
export interface PublisherSettings {
|
|
145
|
+
name: string;
|
|
146
|
+
logoUrl?: string;
|
|
147
|
+
}
|
|
148
|
+
/** Brand asset slots: the minimal icon set plus display logos. */
|
|
149
|
+
export interface BrandSettings {
|
|
150
|
+
logoUrl?: string;
|
|
151
|
+
logoDarkUrl?: string;
|
|
152
|
+
iconSvgUrl?: string;
|
|
153
|
+
faviconIcoUrl?: string;
|
|
154
|
+
appleTouchIconUrl?: string;
|
|
155
|
+
icon192Url?: string;
|
|
156
|
+
icon512Url?: string;
|
|
157
|
+
icon512MaskUrl?: string;
|
|
158
|
+
}
|
|
159
|
+
/** A partial map from post type to the path prefix that section is served at. */
|
|
160
|
+
export type ContentPaths = Partial<Record<PostType, string>>;
|
|
161
|
+
/**
|
|
162
|
+
* The public site-config payload (`GET /v1/site`): the site's identity card
|
|
163
|
+
* for templates and SDKs. The code-first merge over `seo` lives in
|
|
164
|
+
* `@we8/astro` `mergeSeo`, not in the backend.
|
|
165
|
+
*/
|
|
166
|
+
export interface SiteConfig {
|
|
167
|
+
name: string | null;
|
|
168
|
+
siteUrl: string;
|
|
169
|
+
seo: SeoSettings;
|
|
170
|
+
publisher: PublisherSettings | null;
|
|
171
|
+
/** The universal prefix used for any type without its own path. */
|
|
172
|
+
postsPathPrefix: string;
|
|
173
|
+
/** Fully resolved per-type paths: every post type is present. */
|
|
174
|
+
contentPaths: Record<PostType, string>;
|
|
175
|
+
/** `null` when unconfigured; `''` is never served. */
|
|
176
|
+
gaMeasurementId: string | null;
|
|
177
|
+
brand: BrandSettings;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,mEAAmE;AACnE,eAAO,MAAM,WAAW,sIASd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,4EAA4E;AAC5E,MAAM,MAAM,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,CAAC,CAAC;AAE7D,gFAAgF;AAChF,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAM9D;;;;;GAKG;AACH,eAAO,MAAM,UAAU,8EAOb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,eAAO,MAAM,YAAY,kDAAmD,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,iBAAiB,8CAA+C,CAAC;AAC9E,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,oCAAqC,CAAC;AACtE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,UAAU,qCAAsC,CAAC;AAC9D,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAMnD;;;;;GAKG;AACH,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kDAAkD;IAClD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAMD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB;AAMD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,iFAAiF;AACjF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7D;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,WAAW,CAAC;IACjB,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,sDAAsD;IACtD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,aAAa,CAAC;CACtB"}
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire contract of the we8 public API, expressed as plain TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* In the managed platform these shapes are derived from Zod schemas in a
|
|
5
|
+
* shared package. This package has zero runtime dependencies by design, so the
|
|
6
|
+
* contract is restated here as types plus a handful of frozen vocabularies.
|
|
7
|
+
* The `/v1` dialect is the same one a managed we8 tenant speaks, so a site
|
|
8
|
+
* built on this client works against either backend unchanged.
|
|
9
|
+
*
|
|
10
|
+
* Everything here is the PUBLIC half of the contract: what `/v1/*` serves and
|
|
11
|
+
* accepts. Admin-only shapes live in the CMS package, not here.
|
|
12
|
+
*/
|
|
13
|
+
/* -------------------------------------------------------------------------- */
|
|
14
|
+
/* Response envelope */
|
|
15
|
+
/* -------------------------------------------------------------------------- */
|
|
16
|
+
/** Every stable machine-readable error code the API can return. */
|
|
17
|
+
export const ERROR_CODES = [
|
|
18
|
+
'validation_error',
|
|
19
|
+
'unauthorized',
|
|
20
|
+
'forbidden',
|
|
21
|
+
'not_found',
|
|
22
|
+
'conflict',
|
|
23
|
+
'rate_limited',
|
|
24
|
+
'payload_too_large',
|
|
25
|
+
'internal',
|
|
26
|
+
];
|
|
27
|
+
/* -------------------------------------------------------------------------- */
|
|
28
|
+
/* Frozen vocabularies */
|
|
29
|
+
/* -------------------------------------------------------------------------- */
|
|
30
|
+
/**
|
|
31
|
+
* Content types: a fixed vocabulary, deliberately not extensible per site,
|
|
32
|
+
* because type drives routing (contentPaths), the sitemap, the JSON-LD
|
|
33
|
+
* `@type`, template switching, and filters. Adding a member later is an
|
|
34
|
+
* additive change; open values would break all five consumers.
|
|
35
|
+
*/
|
|
36
|
+
export const POST_TYPES = [
|
|
37
|
+
'blog',
|
|
38
|
+
'article',
|
|
39
|
+
'news',
|
|
40
|
+
'research',
|
|
41
|
+
'whitepaper',
|
|
42
|
+
'case-study',
|
|
43
|
+
];
|
|
44
|
+
export const AUTHOR_TYPES = ['team', 'guest', 'advisor', 'partner'];
|
|
45
|
+
export const CONSENT_DECISIONS = ['accepted', 'partial', 'declined'];
|
|
46
|
+
/**
|
|
47
|
+
* Site documents: small site-authored texts served at the frontend's root.
|
|
48
|
+
* A fixed two-member vocabulary, one entry per document the platform knows how
|
|
49
|
+
* to serve.
|
|
50
|
+
*/
|
|
51
|
+
export const SITE_DOCUMENT_KINDS = ['design-md', 'llms-txt'];
|
|
52
|
+
export const CTA_STYLES = ['link', 'gated-download'];
|
|
53
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,mEAAmE;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,kBAAkB;IAClB,cAAc;IACd,WAAW;IACX,WAAW;IACX,UAAU;IACV,cAAc;IACd,mBAAmB;IACnB,UAAU;CACF,CAAC;AAgBX,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM;IACN,SAAS;IACT,MAAM;IACN,UAAU;IACV,YAAY;IACZ,YAAY;CACJ,CAAC;AAIX,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAU,CAAC;AAG7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAG9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,WAAW,EAAE,UAAU,CAAU,CAAC;AAGtE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAU,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ErrorCode } from './contract.js';
|
|
2
|
+
/**
|
|
3
|
+
* The single error type every we8 client call can throw. It carries the API's
|
|
4
|
+
* own error `code` (the stable machine-readable enum from the response
|
|
5
|
+
* envelope) and the HTTP `status`, so callers can branch on either.
|
|
6
|
+
*
|
|
7
|
+
* - A non-2xx response with a decodable error envelope surfaces that envelope's
|
|
8
|
+
* `code`/`error` verbatim.
|
|
9
|
+
* - A non-2xx response WITHOUT a usable envelope synthesizes a code from the
|
|
10
|
+
* status (for example 404 becomes `not_found`, else `internal`).
|
|
11
|
+
* - A transport failure (fetch rejected, DNS, offline) surfaces as
|
|
12
|
+
* `code: 'internal'`, `status: 0`.
|
|
13
|
+
*/
|
|
14
|
+
export declare class We8ApiError extends Error {
|
|
15
|
+
readonly code: ErrorCode;
|
|
16
|
+
readonly status: number;
|
|
17
|
+
constructor(code: ErrorCode, message: string, status: number);
|
|
18
|
+
}
|
|
19
|
+
/** Narrowing helper so consumers do not need to import the class to `instanceof`. */
|
|
20
|
+
export declare function isWe8ApiError(value: unknown): value is We8ApiError;
|
|
21
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAS7D;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAElE"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single error type every we8 client call can throw. It carries the API's
|
|
3
|
+
* own error `code` (the stable machine-readable enum from the response
|
|
4
|
+
* envelope) and the HTTP `status`, so callers can branch on either.
|
|
5
|
+
*
|
|
6
|
+
* - A non-2xx response with a decodable error envelope surfaces that envelope's
|
|
7
|
+
* `code`/`error` verbatim.
|
|
8
|
+
* - A non-2xx response WITHOUT a usable envelope synthesizes a code from the
|
|
9
|
+
* status (for example 404 becomes `not_found`, else `internal`).
|
|
10
|
+
* - A transport failure (fetch rejected, DNS, offline) surfaces as
|
|
11
|
+
* `code: 'internal'`, `status: 0`.
|
|
12
|
+
*/
|
|
13
|
+
export class We8ApiError extends Error {
|
|
14
|
+
code;
|
|
15
|
+
status;
|
|
16
|
+
constructor(code, message, status) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'We8ApiError';
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.status = status;
|
|
21
|
+
// Restore the prototype chain when the output is transpiled down to ES5-ish
|
|
22
|
+
// targets (a bundler may do this for older browser targets).
|
|
23
|
+
Object.setPrototypeOf(this, We8ApiError.prototype);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Narrowing helper so consumers do not need to import the class to `instanceof`. */
|
|
27
|
+
export function isWe8ApiError(value) {
|
|
28
|
+
return value instanceof We8ApiError;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAY;IAChB,MAAM,CAAS;IAExB,YAAY,IAAe,EAAE,OAAe,EAAE,MAAc;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,4EAA4E;QAC5E,6DAA6D;QAC7D,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;CACF;AAED,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,KAAK,YAAY,WAAW,CAAC;AACtC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createClient } from './client.js';
|
|
2
|
+
export type { We8Client, We8ClientOptions, We8FormSubmitResult } from './client.js';
|
|
3
|
+
export { We8ApiError, isWe8ApiError } from './errors.js';
|
|
4
|
+
export type { SiteDocumentKind, We8Author, We8ConsentInput, We8Document, We8FormData, We8FormSubmitOptions, We8JsonLd, We8LikeResult, We8Post, We8PostDetail, We8PostList, We8PostListParams, We8SiteConfig, We8VisitInput, } from './types.js';
|
|
5
|
+
export { AUTHOR_TYPES, CONSENT_DECISIONS, CTA_STYLES, ERROR_CODES, POST_TYPES, SITE_DOCUMENT_KINDS, } from './contract.js';
|
|
6
|
+
export type { AuthorLink, AuthorRecord, AuthorType, BrandSettings, ConsentDecision, ConsentEventInput, ContentPaths, Cta, CtaStyle, Envelope, Err, ErrorCode, Ok, PostType, PostVersionRecord, PublisherSettings, SeoSettings, SiteConfig, SiteDocumentRecord, VisitEventInput, } from './contract.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,OAAO,EACP,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AAKpB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,UAAU,EACV,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,GAAG,EACH,QAAQ,EACR,QAAQ,EACR,GAAG,EACH,SAAS,EACT,EAAE,EACF,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,eAAe,GAChB,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createClient } from './client.js';
|
|
2
|
+
export { We8ApiError, isWe8ApiError } from './errors.js';
|
|
3
|
+
// The wire contract itself. Types are what most callers need; the frozen
|
|
4
|
+
// vocabularies are exported as runtime constants too, so a template can build
|
|
5
|
+
// a type filter or a select box from them without restating the list.
|
|
6
|
+
export { AUTHOR_TYPES, CONSENT_DECISIONS, CTA_STYLES, ERROR_CODES, POST_TYPES, SITE_DOCUMENT_KINDS, } from './contract.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAkBzD,yEAAyE;AACzE,8EAA8E;AAC9E,sEAAsE;AACtE,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,UAAU,EACV,mBAAmB,GACpB,MAAM,eAAe,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { AuthorRecord, ConsentEventInput, PostType, PostVersionRecord, SiteConfig, SiteDocumentKind, SiteDocumentRecord, VisitEventInput } from './contract.js';
|
|
2
|
+
/**
|
|
3
|
+
* A published post as returned by the public API: the current published
|
|
4
|
+
* version's content fields, plus the post-level `slug`, `type`, `viewCount`,
|
|
5
|
+
* and `likeCount`.
|
|
6
|
+
*/
|
|
7
|
+
export type We8Post = PostVersionRecord & {
|
|
8
|
+
slug: string;
|
|
9
|
+
/** The structural content type: picks the site section via contentPaths. */
|
|
10
|
+
type: PostType;
|
|
11
|
+
viewCount: number;
|
|
12
|
+
likeCount: number;
|
|
13
|
+
};
|
|
14
|
+
/** A public author profile. */
|
|
15
|
+
export type We8Author = AuthorRecord;
|
|
16
|
+
/**
|
|
17
|
+
* JSON-LD blob the API builds for a post's detail page (schema.org
|
|
18
|
+
* `BlogPosting`/`Article`). Opaque to the client: pass it straight into a
|
|
19
|
+
* `<script type="application/ld+json">` tag.
|
|
20
|
+
*/
|
|
21
|
+
export type We8JsonLd = Record<string, unknown>;
|
|
22
|
+
/** `GET /v1/posts`: a page of published posts. */
|
|
23
|
+
export interface We8PostList {
|
|
24
|
+
items: We8Post[];
|
|
25
|
+
page: number;
|
|
26
|
+
pageSize: number;
|
|
27
|
+
total: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* `GET /v1/posts/:slug`: a single post, its bylined authors, and its JSON-LD.
|
|
31
|
+
*
|
|
32
|
+
* `authors` ships resolved rather than as the post's `authorIds`, because a
|
|
33
|
+
* public consumer has no way to turn an id into a name or an avatar: the
|
|
34
|
+
* public authors route is by-slug only. Any frontend rendering a byline needs
|
|
35
|
+
* them, and the route already loads them to build the JSON-LD.
|
|
36
|
+
*/
|
|
37
|
+
export interface We8PostDetail {
|
|
38
|
+
post: We8Post;
|
|
39
|
+
authors: We8Author[];
|
|
40
|
+
jsonld: We8JsonLd;
|
|
41
|
+
}
|
|
42
|
+
/** Filters and paging for `posts.list()`. All optional; the API applies defaults. */
|
|
43
|
+
export interface We8PostListParams {
|
|
44
|
+
page?: number;
|
|
45
|
+
pageSize?: number;
|
|
46
|
+
tag?: string;
|
|
47
|
+
category?: string;
|
|
48
|
+
type?: PostType;
|
|
49
|
+
}
|
|
50
|
+
/** Result of toggling a like on a post. */
|
|
51
|
+
export interface We8LikeResult {
|
|
52
|
+
liked: boolean;
|
|
53
|
+
likeCount: number;
|
|
54
|
+
}
|
|
55
|
+
/** Fields for a form submission. Arbitrary keys; the API validates per form. */
|
|
56
|
+
export type We8FormData = Record<string, unknown>;
|
|
57
|
+
/** Options for `forms.submit()`. */
|
|
58
|
+
export interface We8FormSubmitOptions {
|
|
59
|
+
/** A Cloudflare Turnstile token, when the target form requires one. */
|
|
60
|
+
turnstileToken?: string;
|
|
61
|
+
}
|
|
62
|
+
/** A visit beacon payload. */
|
|
63
|
+
export type We8VisitInput = VisitEventInput;
|
|
64
|
+
/** A cookie-consent decision payload. */
|
|
65
|
+
export type We8ConsentInput = ConsentEventInput;
|
|
66
|
+
/**
|
|
67
|
+
* The site identity card (`GET /v1/site`): name, canonical URL, SEO
|
|
68
|
+
* fallbacks, publisher, brand assets, and the content paths. The code-first
|
|
69
|
+
* merge over `seo` lives in `@we8/astro` `mergeSeo`.
|
|
70
|
+
*/
|
|
71
|
+
export type We8SiteConfig = SiteConfig;
|
|
72
|
+
/**
|
|
73
|
+
* A site document (`GET /v1/documents/:kind`): design.md or llms.txt.
|
|
74
|
+
* `content` is `''` and `updatedAt` is `null` when the site never wrote one,
|
|
75
|
+
* the same meaning a 404 would carry elsewhere, not an error.
|
|
76
|
+
*/
|
|
77
|
+
export type We8Document = SiteDocumentRecord;
|
|
78
|
+
/** The fixed document-kind vocabulary, re-exported so callers can type a `kind` parameter. */
|
|
79
|
+
export type { SiteDocumentKind };
|
|
80
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EAChB,MAAM,eAAe,CAAC;AAEvB;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,iBAAiB,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,+BAA+B;AAC/B,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC;AAErC;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,gFAAgF;AAChF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElD,oCAAoC;AACpC,MAAM,WAAW,oBAAoB;IACnC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8BAA8B;AAC9B,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAE5C,yCAAyC;AACzC,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC;AAEvC;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAE7C,8FAA8F;AAC9F,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@we8/client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/reveriext/we8-package.git",
|
|
8
|
+
"directory": "packages/client"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/reveriext/we8-package/tree/main/packages/client#readme",
|
|
11
|
+
"bugs": "https://github.com/reveriext/we8-package/issues",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"description": "Typed client for the we8 public API. No runtime dependencies; works in browsers, Node, and edge runtimes.",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"we8",
|
|
16
|
+
"cms",
|
|
17
|
+
"headless-cms",
|
|
18
|
+
"api-client",
|
|
19
|
+
"typescript"
|
|
20
|
+
],
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"@we8/source": "./src/index.ts",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"default": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"sideEffects": false,
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -p tsconfig.build.json",
|
|
37
|
+
"prepare": "npm run build",
|
|
38
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"prepack": "npm run build"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"vitest": "^4.1.9"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=20"
|
|
50
|
+
}
|
|
51
|
+
}
|