@yak-io/prismic 0.2.2 → 0.3.1
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/dist/index.cjs +327 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.js +294 -3
- package/dist/index.js.map +7 -0
- package/package.json +6 -5
- package/dist/graphql-adapter.js +0 -150
- package/dist/route-adapter.js +0 -22
- package/dist/tool-adapter.js +0 -119
- package/dist/types.js +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
createPrismicGraphQLToolAdapter: () => createPrismicGraphQLToolAdapter,
|
|
34
|
+
createPrismicRouteAdapter: () => createPrismicRouteAdapter,
|
|
35
|
+
createPrismicToolAdapter: () => createPrismicToolAdapter
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// src/graphql-adapter.ts
|
|
40
|
+
var import_graphql = require("@yak-io/graphql");
|
|
41
|
+
var INTROSPECTION_QUERY = `query IntrospectionQuery {
|
|
42
|
+
__schema {
|
|
43
|
+
queryType { name }
|
|
44
|
+
mutationType { name }
|
|
45
|
+
subscriptionType { name }
|
|
46
|
+
types {
|
|
47
|
+
...FullType
|
|
48
|
+
}
|
|
49
|
+
directives {
|
|
50
|
+
name
|
|
51
|
+
description
|
|
52
|
+
locations
|
|
53
|
+
args { ...InputValue }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
fragment FullType on __Type {
|
|
58
|
+
kind
|
|
59
|
+
name
|
|
60
|
+
description
|
|
61
|
+
fields(includeDeprecated: true) {
|
|
62
|
+
name
|
|
63
|
+
description
|
|
64
|
+
args { ...InputValue }
|
|
65
|
+
type { ...TypeRef }
|
|
66
|
+
isDeprecated
|
|
67
|
+
deprecationReason
|
|
68
|
+
}
|
|
69
|
+
inputFields { ...InputValue }
|
|
70
|
+
interfaces { ...TypeRef }
|
|
71
|
+
enumValues(includeDeprecated: true) {
|
|
72
|
+
name
|
|
73
|
+
description
|
|
74
|
+
isDeprecated
|
|
75
|
+
deprecationReason
|
|
76
|
+
}
|
|
77
|
+
possibleTypes { ...TypeRef }
|
|
78
|
+
}
|
|
79
|
+
fragment InputValue on __InputValue {
|
|
80
|
+
name
|
|
81
|
+
description
|
|
82
|
+
type { ...TypeRef }
|
|
83
|
+
defaultValue
|
|
84
|
+
}
|
|
85
|
+
fragment TypeRef on __Type {
|
|
86
|
+
kind
|
|
87
|
+
name
|
|
88
|
+
ofType {
|
|
89
|
+
kind
|
|
90
|
+
name
|
|
91
|
+
ofType {
|
|
92
|
+
kind
|
|
93
|
+
name
|
|
94
|
+
ofType {
|
|
95
|
+
kind
|
|
96
|
+
name
|
|
97
|
+
ofType {
|
|
98
|
+
kind
|
|
99
|
+
name
|
|
100
|
+
ofType {
|
|
101
|
+
kind
|
|
102
|
+
name
|
|
103
|
+
ofType {
|
|
104
|
+
kind
|
|
105
|
+
name
|
|
106
|
+
ofType { kind name }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}`;
|
|
114
|
+
function deriveGraphQLEndpoint(restEndpoint) {
|
|
115
|
+
const trimmed = restEndpoint.replace(/\/api\/v\d+\/?$/, "");
|
|
116
|
+
return `${trimmed}/graphql`;
|
|
117
|
+
}
|
|
118
|
+
async function buildHeaders(source, base) {
|
|
119
|
+
const headers = new Headers(base);
|
|
120
|
+
const resolved = typeof source === "function" ? await source() : source;
|
|
121
|
+
if (resolved) {
|
|
122
|
+
for (const [key, value] of new Headers(resolved)) {
|
|
123
|
+
headers.set(key, value);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return headers;
|
|
127
|
+
}
|
|
128
|
+
async function loadGraphQLModule() {
|
|
129
|
+
try {
|
|
130
|
+
return await import("graphql");
|
|
131
|
+
} catch {
|
|
132
|
+
throw new Error(
|
|
133
|
+
"createPrismicGraphQLToolAdapter requires the 'graphql' package. Install it as a peer dependency: pnpm add graphql"
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function createPrismicGraphQLToolAdapter(config) {
|
|
138
|
+
const fetchFn = config.fetchFn ?? fetch;
|
|
139
|
+
const endpoint = config.endpoint ?? deriveGraphQLEndpoint(config.client.endpoint);
|
|
140
|
+
const response = await fetchFn(endpoint, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: { "Content-Type": "application/json" },
|
|
143
|
+
body: JSON.stringify({ query: INTROSPECTION_QUERY })
|
|
144
|
+
});
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Prismic GraphQL introspection failed: ${response.status} ${response.statusText}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
const payload = await response.json();
|
|
151
|
+
if (payload.errors || !payload.data) {
|
|
152
|
+
throw new Error("Prismic GraphQL introspection returned no data");
|
|
153
|
+
}
|
|
154
|
+
const { buildClientSchema, printSchema } = await loadGraphQLModule();
|
|
155
|
+
const schema = buildClientSchema(payload.data);
|
|
156
|
+
const sdl = printSchema(schema);
|
|
157
|
+
return (0, import_graphql.createGraphQLToolAdapter)({
|
|
158
|
+
name: config.name ?? "prismic",
|
|
159
|
+
schema: sdl,
|
|
160
|
+
id: config.id,
|
|
161
|
+
// Prismic owns its own transport: POST the model-authored query to the repo's GraphQL
|
|
162
|
+
// endpoint with the caller-supplied headers (typically the required `Prismic-ref`).
|
|
163
|
+
execute: async (request) => {
|
|
164
|
+
const res = await fetchFn(endpoint, {
|
|
165
|
+
method: "POST",
|
|
166
|
+
headers: await buildHeaders(config.headers, { "Content-Type": "application/json" }),
|
|
167
|
+
body: JSON.stringify({
|
|
168
|
+
query: request.query,
|
|
169
|
+
variables: request.variables,
|
|
170
|
+
operationName: request.operationName
|
|
171
|
+
})
|
|
172
|
+
});
|
|
173
|
+
if (!res.ok) {
|
|
174
|
+
throw new Error(`Prismic GraphQL request failed (${res.status})`);
|
|
175
|
+
}
|
|
176
|
+
const payload2 = await res.json();
|
|
177
|
+
if (payload2.errors?.length) {
|
|
178
|
+
throw new Error(payload2.errors[0]?.message ?? "Prismic GraphQL request returned errors");
|
|
179
|
+
}
|
|
180
|
+
return payload2.data;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/route-adapter.ts
|
|
186
|
+
var prismic = __toESM(require("@prismicio/client"), 1);
|
|
187
|
+
function createPrismicRouteAdapter(config) {
|
|
188
|
+
return {
|
|
189
|
+
id: config.id ?? "prismic",
|
|
190
|
+
getRoutes: async () => {
|
|
191
|
+
const docs = await config.client.dangerouslyGetAll({
|
|
192
|
+
filters: [
|
|
193
|
+
prismic.filter.any("document.type", config.documentTypes),
|
|
194
|
+
...config.filters ?? []
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
const routes = [];
|
|
198
|
+
for (const doc of docs) {
|
|
199
|
+
const route = config.resolveRoute(doc);
|
|
200
|
+
if (route !== null) {
|
|
201
|
+
routes.push(route);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return routes;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/tool-adapter.ts
|
|
210
|
+
var prismic2 = __toESM(require("@prismicio/client"), 1);
|
|
211
|
+
var TOOL_DEFINITIONS = [
|
|
212
|
+
{
|
|
213
|
+
name: "prismic.getByUID",
|
|
214
|
+
description: "Fetch a single Prismic document by document type and UID. Use this when you know the exact UID of a page or post.",
|
|
215
|
+
inputSchema: {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: {
|
|
218
|
+
type: {
|
|
219
|
+
type: "string",
|
|
220
|
+
description: "The Prismic custom type (for example 'page' or 'blog_post')"
|
|
221
|
+
},
|
|
222
|
+
uid: {
|
|
223
|
+
type: "string",
|
|
224
|
+
description: "The unique identifier of the document"
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
required: ["type", "uid"]
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: "prismic.getAllByType",
|
|
232
|
+
description: "Fetch all Prismic documents of a given type. Use this to list pages or posts of a particular kind.",
|
|
233
|
+
inputSchema: {
|
|
234
|
+
type: "object",
|
|
235
|
+
properties: {
|
|
236
|
+
type: {
|
|
237
|
+
type: "string",
|
|
238
|
+
description: "The Prismic custom type to list"
|
|
239
|
+
},
|
|
240
|
+
limit: {
|
|
241
|
+
type: "number",
|
|
242
|
+
description: "Maximum number of documents to return (default 20)"
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
required: ["type"]
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "prismic.search",
|
|
250
|
+
description: "Full-text search across Prismic documents. Returns documents whose fields match the query.",
|
|
251
|
+
inputSchema: {
|
|
252
|
+
type: "object",
|
|
253
|
+
properties: {
|
|
254
|
+
query: {
|
|
255
|
+
type: "string",
|
|
256
|
+
description: "The free-text search query"
|
|
257
|
+
},
|
|
258
|
+
types: {
|
|
259
|
+
type: "array",
|
|
260
|
+
items: { type: "string" },
|
|
261
|
+
description: "Optional list of document types to restrict the search to. Defaults to all allowed types."
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
required: ["query"]
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
];
|
|
268
|
+
function buildGraphQuery(fields, type) {
|
|
269
|
+
const typeFields = fields?.[type];
|
|
270
|
+
if (!typeFields || typeFields.length === 0) {
|
|
271
|
+
return void 0;
|
|
272
|
+
}
|
|
273
|
+
return `{ ${type} { ${typeFields.join(" ")} } }`;
|
|
274
|
+
}
|
|
275
|
+
function createPrismicToolAdapter(config) {
|
|
276
|
+
const allowed = new Set(config.allowedTypes);
|
|
277
|
+
const assertAllowed = (type) => {
|
|
278
|
+
if (typeof type !== "string" || !allowed.has(type)) {
|
|
279
|
+
throw new Error(`Prismic document type '${String(type)}' is not in allowedTypes`);
|
|
280
|
+
}
|
|
281
|
+
return type;
|
|
282
|
+
};
|
|
283
|
+
const executor = async (name, args) => {
|
|
284
|
+
const input = args ?? {};
|
|
285
|
+
switch (name) {
|
|
286
|
+
case "prismic.getByUID": {
|
|
287
|
+
const type = assertAllowed(input.type);
|
|
288
|
+
const uid = input.uid;
|
|
289
|
+
if (typeof uid !== "string" || uid.length === 0) {
|
|
290
|
+
throw new Error("prismic.getByUID requires a 'uid' string");
|
|
291
|
+
}
|
|
292
|
+
const graphQuery = buildGraphQuery(config.fields, type);
|
|
293
|
+
return await config.client.getByUID(type, uid, graphQuery ? { graphQuery } : void 0);
|
|
294
|
+
}
|
|
295
|
+
case "prismic.getAllByType": {
|
|
296
|
+
const type = assertAllowed(input.type);
|
|
297
|
+
const limit = typeof input.limit === "number" ? input.limit : 20;
|
|
298
|
+
const graphQuery = buildGraphQuery(config.fields, type);
|
|
299
|
+
return await config.client.getAllByType(type, {
|
|
300
|
+
limit,
|
|
301
|
+
...graphQuery ? { graphQuery } : {}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
case "prismic.search": {
|
|
305
|
+
const query = input.query;
|
|
306
|
+
if (typeof query !== "string" || query.length === 0) {
|
|
307
|
+
throw new Error("prismic.search requires a 'query' string");
|
|
308
|
+
}
|
|
309
|
+
const requestedTypes = Array.isArray(input.types) ? input.types.map((t) => assertAllowed(t)) : [...allowed];
|
|
310
|
+
return await config.client.get({
|
|
311
|
+
filters: [
|
|
312
|
+
prismic2.filter.fulltext("document", query),
|
|
313
|
+
prismic2.filter.any("document.type", requestedTypes)
|
|
314
|
+
]
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
default:
|
|
318
|
+
throw new Error(`Unknown Prismic tool: ${name}`);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
return {
|
|
322
|
+
id: config.id ?? "prismic",
|
|
323
|
+
getTools: async () => TOOL_DEFINITIONS,
|
|
324
|
+
executeTool: executor
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/graphql-adapter.ts", "../src/route-adapter.ts", "../src/tool-adapter.ts"],
|
|
4
|
+
"sourcesContent": ["export { createPrismicGraphQLToolAdapter } from \"./graphql-adapter.js\";\nexport { createPrismicRouteAdapter } from \"./route-adapter.js\";\nexport { createPrismicToolAdapter } from \"./tool-adapter.js\";\nexport type {\n PrismicGraphQLToolAdapterConfig,\n PrismicRouteAdapterConfig,\n PrismicToolAdapterConfig,\n} from \"./types.js\";\n\nexport type {\n RouteInfo,\n RouteSource,\n ToolDefinition,\n ToolExecutor,\n ToolManifest,\n ToolSource,\n} from \"@yak-io/javascript/server\";\n\nexport type { ToolAdapter } from \"@yak-io/javascript\";\n", "import { createGraphQLToolAdapter } from \"@yak-io/graphql\";\nimport type { ToolAdapter } from \"@yak-io/javascript\";\nimport type { PrismicGraphQLToolAdapterConfig } from \"./types.js\";\n\nconst INTROSPECTION_QUERY = `query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args { ...InputValue }\n }\n }\n}\nfragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args { ...InputValue }\n type { ...TypeRef }\n isDeprecated\n deprecationReason\n }\n inputFields { ...InputValue }\n interfaces { ...TypeRef }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes { ...TypeRef }\n}\nfragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n}\nfragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType { kind name }\n }\n }\n }\n }\n }\n }\n}`;\n\nfunction deriveGraphQLEndpoint(restEndpoint: string): string {\n const trimmed = restEndpoint.replace(/\\/api\\/v\\d+\\/?$/, \"\");\n return `${trimmed}/graphql`;\n}\n\nasync function buildHeaders(\n source: PrismicGraphQLToolAdapterConfig[\"headers\"],\n base?: Record<string, string>\n): Promise<Headers> {\n const headers = new Headers(base);\n const resolved = typeof source === \"function\" ? await source() : source;\n if (resolved) {\n for (const [key, value] of new Headers(resolved)) {\n headers.set(key, value);\n }\n }\n return headers;\n}\n\nasync function loadGraphQLModule(): Promise<typeof import(\"graphql\")> {\n try {\n return await import(\"graphql\");\n } catch {\n throw new Error(\n \"createPrismicGraphQLToolAdapter requires the 'graphql' package. Install it as a peer dependency: pnpm add graphql\"\n );\n }\n}\n\n/**\n * Introspect a Prismic repository's GraphQL schema and return a browser-executed\n * GraphQL {@link ToolAdapter} (built on `@yak-io/graphql`). Compose it into a\n * {@link createYakToolset}; the LLM authors queries from the introspected SDL and\n * the adapter executes them against the repo's GraphQL endpoint.\n *\n * Prismic's GraphQL endpoint requires a `Prismic-ref` header at execution time \u2014\n * supply it via `headers` (it may be async to fetch the master ref per call).\n */\nexport async function createPrismicGraphQLToolAdapter(\n config: PrismicGraphQLToolAdapterConfig\n): Promise<ToolAdapter> {\n const fetchFn = config.fetchFn ?? fetch;\n const endpoint = config.endpoint ?? deriveGraphQLEndpoint(config.client.endpoint);\n\n const response = await fetchFn(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ query: INTROSPECTION_QUERY }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Prismic GraphQL introspection failed: ${response.status} ${response.statusText}`\n );\n }\n\n const payload = (await response.json()) as { data?: unknown; errors?: unknown };\n if (payload.errors || !payload.data) {\n throw new Error(\"Prismic GraphQL introspection returned no data\");\n }\n\n const { buildClientSchema, printSchema } = await loadGraphQLModule();\n const schema = buildClientSchema(payload.data as Parameters<typeof buildClientSchema>[0]);\n const sdl = printSchema(schema);\n\n return createGraphQLToolAdapter({\n name: config.name ?? \"prismic\",\n schema: sdl,\n id: config.id,\n // Prismic owns its own transport: POST the model-authored query to the repo's GraphQL\n // endpoint with the caller-supplied headers (typically the required `Prismic-ref`).\n execute: async (request) => {\n const res = await fetchFn(endpoint, {\n method: \"POST\",\n headers: await buildHeaders(config.headers, { \"Content-Type\": \"application/json\" }),\n body: JSON.stringify({\n query: request.query,\n variables: request.variables,\n operationName: request.operationName,\n }),\n });\n if (!res.ok) {\n throw new Error(`Prismic GraphQL request failed (${res.status})`);\n }\n const payload = (await res.json()) as {\n data?: unknown;\n errors?: Array<{ message?: string }>;\n };\n if (payload.errors?.length) {\n throw new Error(payload.errors[0]?.message ?? \"Prismic GraphQL request returned errors\");\n }\n return payload.data;\n },\n });\n}\n", "import * as prismic from \"@prismicio/client\";\nimport type { RouteInfo, RouteSource } from \"@yak-io/javascript/server\";\nimport type { PrismicRouteAdapterConfig } from \"./types.js\";\n\nexport function createPrismicRouteAdapter(config: PrismicRouteAdapterConfig): RouteSource {\n return {\n id: config.id ?? \"prismic\",\n getRoutes: async () => {\n const docs = await config.client.dangerouslyGetAll({\n filters: [\n prismic.filter.any(\"document.type\", config.documentTypes),\n ...(config.filters ?? []),\n ],\n });\n\n const routes: RouteInfo[] = [];\n for (const doc of docs) {\n const route = config.resolveRoute(doc);\n if (route !== null) {\n routes.push(route);\n }\n }\n return routes;\n },\n };\n}\n", "import * as prismic from \"@prismicio/client\";\nimport type { ToolDefinition, ToolExecutor, ToolSource } from \"@yak-io/javascript/server\";\nimport type { PrismicToolAdapterConfig } from \"./types.js\";\n\nconst TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n name: \"prismic.getByUID\",\n description:\n \"Fetch a single Prismic document by document type and UID. Use this when you know the exact UID of a page or post.\",\n inputSchema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"The Prismic custom type (for example 'page' or 'blog_post')\",\n },\n uid: {\n type: \"string\",\n description: \"The unique identifier of the document\",\n },\n },\n required: [\"type\", \"uid\"],\n },\n },\n {\n name: \"prismic.getAllByType\",\n description:\n \"Fetch all Prismic documents of a given type. Use this to list pages or posts of a particular kind.\",\n inputSchema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"The Prismic custom type to list\",\n },\n limit: {\n type: \"number\",\n description: \"Maximum number of documents to return (default 20)\",\n },\n },\n required: [\"type\"],\n },\n },\n {\n name: \"prismic.search\",\n description:\n \"Full-text search across Prismic documents. Returns documents whose fields match the query.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"The free-text search query\",\n },\n types: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Optional list of document types to restrict the search to. Defaults to all allowed types.\",\n },\n },\n required: [\"query\"],\n },\n },\n];\n\nfunction buildGraphQuery(\n fields: Record<string, string[]> | undefined,\n type: string\n): string | undefined {\n const typeFields = fields?.[type];\n if (!typeFields || typeFields.length === 0) {\n return undefined;\n }\n return `{ ${type} { ${typeFields.join(\" \")} } }`;\n}\n\nexport function createPrismicToolAdapter(config: PrismicToolAdapterConfig): ToolSource {\n const allowed = new Set(config.allowedTypes);\n\n const assertAllowed = (type: unknown): string => {\n if (typeof type !== \"string\" || !allowed.has(type)) {\n throw new Error(`Prismic document type '${String(type)}' is not in allowedTypes`);\n }\n return type;\n };\n\n const executor: ToolExecutor = async (name, args) => {\n const input = (args ?? {}) as Record<string, unknown>;\n\n switch (name) {\n case \"prismic.getByUID\": {\n const type = assertAllowed(input.type);\n const uid = input.uid;\n if (typeof uid !== \"string\" || uid.length === 0) {\n throw new Error(\"prismic.getByUID requires a 'uid' string\");\n }\n const graphQuery = buildGraphQuery(config.fields, type);\n return await config.client.getByUID(type, uid, graphQuery ? { graphQuery } : undefined);\n }\n\n case \"prismic.getAllByType\": {\n const type = assertAllowed(input.type);\n const limit = typeof input.limit === \"number\" ? input.limit : 20;\n const graphQuery = buildGraphQuery(config.fields, type);\n return await config.client.getAllByType(type, {\n limit,\n ...(graphQuery ? { graphQuery } : {}),\n });\n }\n\n case \"prismic.search\": {\n const query = input.query;\n if (typeof query !== \"string\" || query.length === 0) {\n throw new Error(\"prismic.search requires a 'query' string\");\n }\n const requestedTypes = Array.isArray(input.types)\n ? (input.types as unknown[]).map((t) => assertAllowed(t))\n : [...allowed];\n return await config.client.get({\n filters: [\n prismic.filter.fulltext(\"document\", query),\n prismic.filter.any(\"document.type\", requestedTypes),\n ],\n });\n }\n\n default:\n throw new Error(`Unknown Prismic tool: ${name}`);\n }\n };\n\n return {\n id: config.id ?? \"prismic\",\n getTools: async () => TOOL_DEFINITIONS,\n executeTool: executor,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["payload", "prismic"]
|
|
7
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,294 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/graphql-adapter.ts
|
|
2
|
+
import { createGraphQLToolAdapter } from "@yak-io/graphql";
|
|
3
|
+
var INTROSPECTION_QUERY = `query IntrospectionQuery {
|
|
4
|
+
__schema {
|
|
5
|
+
queryType { name }
|
|
6
|
+
mutationType { name }
|
|
7
|
+
subscriptionType { name }
|
|
8
|
+
types {
|
|
9
|
+
...FullType
|
|
10
|
+
}
|
|
11
|
+
directives {
|
|
12
|
+
name
|
|
13
|
+
description
|
|
14
|
+
locations
|
|
15
|
+
args { ...InputValue }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
fragment FullType on __Type {
|
|
20
|
+
kind
|
|
21
|
+
name
|
|
22
|
+
description
|
|
23
|
+
fields(includeDeprecated: true) {
|
|
24
|
+
name
|
|
25
|
+
description
|
|
26
|
+
args { ...InputValue }
|
|
27
|
+
type { ...TypeRef }
|
|
28
|
+
isDeprecated
|
|
29
|
+
deprecationReason
|
|
30
|
+
}
|
|
31
|
+
inputFields { ...InputValue }
|
|
32
|
+
interfaces { ...TypeRef }
|
|
33
|
+
enumValues(includeDeprecated: true) {
|
|
34
|
+
name
|
|
35
|
+
description
|
|
36
|
+
isDeprecated
|
|
37
|
+
deprecationReason
|
|
38
|
+
}
|
|
39
|
+
possibleTypes { ...TypeRef }
|
|
40
|
+
}
|
|
41
|
+
fragment InputValue on __InputValue {
|
|
42
|
+
name
|
|
43
|
+
description
|
|
44
|
+
type { ...TypeRef }
|
|
45
|
+
defaultValue
|
|
46
|
+
}
|
|
47
|
+
fragment TypeRef on __Type {
|
|
48
|
+
kind
|
|
49
|
+
name
|
|
50
|
+
ofType {
|
|
51
|
+
kind
|
|
52
|
+
name
|
|
53
|
+
ofType {
|
|
54
|
+
kind
|
|
55
|
+
name
|
|
56
|
+
ofType {
|
|
57
|
+
kind
|
|
58
|
+
name
|
|
59
|
+
ofType {
|
|
60
|
+
kind
|
|
61
|
+
name
|
|
62
|
+
ofType {
|
|
63
|
+
kind
|
|
64
|
+
name
|
|
65
|
+
ofType {
|
|
66
|
+
kind
|
|
67
|
+
name
|
|
68
|
+
ofType { kind name }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}`;
|
|
76
|
+
function deriveGraphQLEndpoint(restEndpoint) {
|
|
77
|
+
const trimmed = restEndpoint.replace(/\/api\/v\d+\/?$/, "");
|
|
78
|
+
return `${trimmed}/graphql`;
|
|
79
|
+
}
|
|
80
|
+
async function buildHeaders(source, base) {
|
|
81
|
+
const headers = new Headers(base);
|
|
82
|
+
const resolved = typeof source === "function" ? await source() : source;
|
|
83
|
+
if (resolved) {
|
|
84
|
+
for (const [key, value] of new Headers(resolved)) {
|
|
85
|
+
headers.set(key, value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return headers;
|
|
89
|
+
}
|
|
90
|
+
async function loadGraphQLModule() {
|
|
91
|
+
try {
|
|
92
|
+
return await import("graphql");
|
|
93
|
+
} catch {
|
|
94
|
+
throw new Error(
|
|
95
|
+
"createPrismicGraphQLToolAdapter requires the 'graphql' package. Install it as a peer dependency: pnpm add graphql"
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function createPrismicGraphQLToolAdapter(config) {
|
|
100
|
+
const fetchFn = config.fetchFn ?? fetch;
|
|
101
|
+
const endpoint = config.endpoint ?? deriveGraphQLEndpoint(config.client.endpoint);
|
|
102
|
+
const response = await fetchFn(endpoint, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: { "Content-Type": "application/json" },
|
|
105
|
+
body: JSON.stringify({ query: INTROSPECTION_QUERY })
|
|
106
|
+
});
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`Prismic GraphQL introspection failed: ${response.status} ${response.statusText}`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
const payload = await response.json();
|
|
113
|
+
if (payload.errors || !payload.data) {
|
|
114
|
+
throw new Error("Prismic GraphQL introspection returned no data");
|
|
115
|
+
}
|
|
116
|
+
const { buildClientSchema, printSchema } = await loadGraphQLModule();
|
|
117
|
+
const schema = buildClientSchema(payload.data);
|
|
118
|
+
const sdl = printSchema(schema);
|
|
119
|
+
return createGraphQLToolAdapter({
|
|
120
|
+
name: config.name ?? "prismic",
|
|
121
|
+
schema: sdl,
|
|
122
|
+
id: config.id,
|
|
123
|
+
// Prismic owns its own transport: POST the model-authored query to the repo's GraphQL
|
|
124
|
+
// endpoint with the caller-supplied headers (typically the required `Prismic-ref`).
|
|
125
|
+
execute: async (request) => {
|
|
126
|
+
const res = await fetchFn(endpoint, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: await buildHeaders(config.headers, { "Content-Type": "application/json" }),
|
|
129
|
+
body: JSON.stringify({
|
|
130
|
+
query: request.query,
|
|
131
|
+
variables: request.variables,
|
|
132
|
+
operationName: request.operationName
|
|
133
|
+
})
|
|
134
|
+
});
|
|
135
|
+
if (!res.ok) {
|
|
136
|
+
throw new Error(`Prismic GraphQL request failed (${res.status})`);
|
|
137
|
+
}
|
|
138
|
+
const payload2 = await res.json();
|
|
139
|
+
if (payload2.errors?.length) {
|
|
140
|
+
throw new Error(payload2.errors[0]?.message ?? "Prismic GraphQL request returned errors");
|
|
141
|
+
}
|
|
142
|
+
return payload2.data;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/route-adapter.ts
|
|
148
|
+
import * as prismic from "@prismicio/client";
|
|
149
|
+
function createPrismicRouteAdapter(config) {
|
|
150
|
+
return {
|
|
151
|
+
id: config.id ?? "prismic",
|
|
152
|
+
getRoutes: async () => {
|
|
153
|
+
const docs = await config.client.dangerouslyGetAll({
|
|
154
|
+
filters: [
|
|
155
|
+
prismic.filter.any("document.type", config.documentTypes),
|
|
156
|
+
...config.filters ?? []
|
|
157
|
+
]
|
|
158
|
+
});
|
|
159
|
+
const routes = [];
|
|
160
|
+
for (const doc of docs) {
|
|
161
|
+
const route = config.resolveRoute(doc);
|
|
162
|
+
if (route !== null) {
|
|
163
|
+
routes.push(route);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return routes;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// src/tool-adapter.ts
|
|
172
|
+
import * as prismic2 from "@prismicio/client";
|
|
173
|
+
var TOOL_DEFINITIONS = [
|
|
174
|
+
{
|
|
175
|
+
name: "prismic.getByUID",
|
|
176
|
+
description: "Fetch a single Prismic document by document type and UID. Use this when you know the exact UID of a page or post.",
|
|
177
|
+
inputSchema: {
|
|
178
|
+
type: "object",
|
|
179
|
+
properties: {
|
|
180
|
+
type: {
|
|
181
|
+
type: "string",
|
|
182
|
+
description: "The Prismic custom type (for example 'page' or 'blog_post')"
|
|
183
|
+
},
|
|
184
|
+
uid: {
|
|
185
|
+
type: "string",
|
|
186
|
+
description: "The unique identifier of the document"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
required: ["type", "uid"]
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: "prismic.getAllByType",
|
|
194
|
+
description: "Fetch all Prismic documents of a given type. Use this to list pages or posts of a particular kind.",
|
|
195
|
+
inputSchema: {
|
|
196
|
+
type: "object",
|
|
197
|
+
properties: {
|
|
198
|
+
type: {
|
|
199
|
+
type: "string",
|
|
200
|
+
description: "The Prismic custom type to list"
|
|
201
|
+
},
|
|
202
|
+
limit: {
|
|
203
|
+
type: "number",
|
|
204
|
+
description: "Maximum number of documents to return (default 20)"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
required: ["type"]
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "prismic.search",
|
|
212
|
+
description: "Full-text search across Prismic documents. Returns documents whose fields match the query.",
|
|
213
|
+
inputSchema: {
|
|
214
|
+
type: "object",
|
|
215
|
+
properties: {
|
|
216
|
+
query: {
|
|
217
|
+
type: "string",
|
|
218
|
+
description: "The free-text search query"
|
|
219
|
+
},
|
|
220
|
+
types: {
|
|
221
|
+
type: "array",
|
|
222
|
+
items: { type: "string" },
|
|
223
|
+
description: "Optional list of document types to restrict the search to. Defaults to all allowed types."
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
required: ["query"]
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
];
|
|
230
|
+
function buildGraphQuery(fields, type) {
|
|
231
|
+
const typeFields = fields?.[type];
|
|
232
|
+
if (!typeFields || typeFields.length === 0) {
|
|
233
|
+
return void 0;
|
|
234
|
+
}
|
|
235
|
+
return `{ ${type} { ${typeFields.join(" ")} } }`;
|
|
236
|
+
}
|
|
237
|
+
function createPrismicToolAdapter(config) {
|
|
238
|
+
const allowed = new Set(config.allowedTypes);
|
|
239
|
+
const assertAllowed = (type) => {
|
|
240
|
+
if (typeof type !== "string" || !allowed.has(type)) {
|
|
241
|
+
throw new Error(`Prismic document type '${String(type)}' is not in allowedTypes`);
|
|
242
|
+
}
|
|
243
|
+
return type;
|
|
244
|
+
};
|
|
245
|
+
const executor = async (name, args) => {
|
|
246
|
+
const input = args ?? {};
|
|
247
|
+
switch (name) {
|
|
248
|
+
case "prismic.getByUID": {
|
|
249
|
+
const type = assertAllowed(input.type);
|
|
250
|
+
const uid = input.uid;
|
|
251
|
+
if (typeof uid !== "string" || uid.length === 0) {
|
|
252
|
+
throw new Error("prismic.getByUID requires a 'uid' string");
|
|
253
|
+
}
|
|
254
|
+
const graphQuery = buildGraphQuery(config.fields, type);
|
|
255
|
+
return await config.client.getByUID(type, uid, graphQuery ? { graphQuery } : void 0);
|
|
256
|
+
}
|
|
257
|
+
case "prismic.getAllByType": {
|
|
258
|
+
const type = assertAllowed(input.type);
|
|
259
|
+
const limit = typeof input.limit === "number" ? input.limit : 20;
|
|
260
|
+
const graphQuery = buildGraphQuery(config.fields, type);
|
|
261
|
+
return await config.client.getAllByType(type, {
|
|
262
|
+
limit,
|
|
263
|
+
...graphQuery ? { graphQuery } : {}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
case "prismic.search": {
|
|
267
|
+
const query = input.query;
|
|
268
|
+
if (typeof query !== "string" || query.length === 0) {
|
|
269
|
+
throw new Error("prismic.search requires a 'query' string");
|
|
270
|
+
}
|
|
271
|
+
const requestedTypes = Array.isArray(input.types) ? input.types.map((t) => assertAllowed(t)) : [...allowed];
|
|
272
|
+
return await config.client.get({
|
|
273
|
+
filters: [
|
|
274
|
+
prismic2.filter.fulltext("document", query),
|
|
275
|
+
prismic2.filter.any("document.type", requestedTypes)
|
|
276
|
+
]
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
default:
|
|
280
|
+
throw new Error(`Unknown Prismic tool: ${name}`);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
return {
|
|
284
|
+
id: config.id ?? "prismic",
|
|
285
|
+
getTools: async () => TOOL_DEFINITIONS,
|
|
286
|
+
executeTool: executor
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
export {
|
|
290
|
+
createPrismicGraphQLToolAdapter,
|
|
291
|
+
createPrismicRouteAdapter,
|
|
292
|
+
createPrismicToolAdapter
|
|
293
|
+
};
|
|
294
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/graphql-adapter.ts", "../src/route-adapter.ts", "../src/tool-adapter.ts"],
|
|
4
|
+
"sourcesContent": ["import { createGraphQLToolAdapter } from \"@yak-io/graphql\";\nimport type { ToolAdapter } from \"@yak-io/javascript\";\nimport type { PrismicGraphQLToolAdapterConfig } from \"./types.js\";\n\nconst INTROSPECTION_QUERY = `query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args { ...InputValue }\n }\n }\n}\nfragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args { ...InputValue }\n type { ...TypeRef }\n isDeprecated\n deprecationReason\n }\n inputFields { ...InputValue }\n interfaces { ...TypeRef }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes { ...TypeRef }\n}\nfragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n}\nfragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType { kind name }\n }\n }\n }\n }\n }\n }\n}`;\n\nfunction deriveGraphQLEndpoint(restEndpoint: string): string {\n const trimmed = restEndpoint.replace(/\\/api\\/v\\d+\\/?$/, \"\");\n return `${trimmed}/graphql`;\n}\n\nasync function buildHeaders(\n source: PrismicGraphQLToolAdapterConfig[\"headers\"],\n base?: Record<string, string>\n): Promise<Headers> {\n const headers = new Headers(base);\n const resolved = typeof source === \"function\" ? await source() : source;\n if (resolved) {\n for (const [key, value] of new Headers(resolved)) {\n headers.set(key, value);\n }\n }\n return headers;\n}\n\nasync function loadGraphQLModule(): Promise<typeof import(\"graphql\")> {\n try {\n return await import(\"graphql\");\n } catch {\n throw new Error(\n \"createPrismicGraphQLToolAdapter requires the 'graphql' package. Install it as a peer dependency: pnpm add graphql\"\n );\n }\n}\n\n/**\n * Introspect a Prismic repository's GraphQL schema and return a browser-executed\n * GraphQL {@link ToolAdapter} (built on `@yak-io/graphql`). Compose it into a\n * {@link createYakToolset}; the LLM authors queries from the introspected SDL and\n * the adapter executes them against the repo's GraphQL endpoint.\n *\n * Prismic's GraphQL endpoint requires a `Prismic-ref` header at execution time \u2014\n * supply it via `headers` (it may be async to fetch the master ref per call).\n */\nexport async function createPrismicGraphQLToolAdapter(\n config: PrismicGraphQLToolAdapterConfig\n): Promise<ToolAdapter> {\n const fetchFn = config.fetchFn ?? fetch;\n const endpoint = config.endpoint ?? deriveGraphQLEndpoint(config.client.endpoint);\n\n const response = await fetchFn(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ query: INTROSPECTION_QUERY }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Prismic GraphQL introspection failed: ${response.status} ${response.statusText}`\n );\n }\n\n const payload = (await response.json()) as { data?: unknown; errors?: unknown };\n if (payload.errors || !payload.data) {\n throw new Error(\"Prismic GraphQL introspection returned no data\");\n }\n\n const { buildClientSchema, printSchema } = await loadGraphQLModule();\n const schema = buildClientSchema(payload.data as Parameters<typeof buildClientSchema>[0]);\n const sdl = printSchema(schema);\n\n return createGraphQLToolAdapter({\n name: config.name ?? \"prismic\",\n schema: sdl,\n id: config.id,\n // Prismic owns its own transport: POST the model-authored query to the repo's GraphQL\n // endpoint with the caller-supplied headers (typically the required `Prismic-ref`).\n execute: async (request) => {\n const res = await fetchFn(endpoint, {\n method: \"POST\",\n headers: await buildHeaders(config.headers, { \"Content-Type\": \"application/json\" }),\n body: JSON.stringify({\n query: request.query,\n variables: request.variables,\n operationName: request.operationName,\n }),\n });\n if (!res.ok) {\n throw new Error(`Prismic GraphQL request failed (${res.status})`);\n }\n const payload = (await res.json()) as {\n data?: unknown;\n errors?: Array<{ message?: string }>;\n };\n if (payload.errors?.length) {\n throw new Error(payload.errors[0]?.message ?? \"Prismic GraphQL request returned errors\");\n }\n return payload.data;\n },\n });\n}\n", "import * as prismic from \"@prismicio/client\";\nimport type { RouteInfo, RouteSource } from \"@yak-io/javascript/server\";\nimport type { PrismicRouteAdapterConfig } from \"./types.js\";\n\nexport function createPrismicRouteAdapter(config: PrismicRouteAdapterConfig): RouteSource {\n return {\n id: config.id ?? \"prismic\",\n getRoutes: async () => {\n const docs = await config.client.dangerouslyGetAll({\n filters: [\n prismic.filter.any(\"document.type\", config.documentTypes),\n ...(config.filters ?? []),\n ],\n });\n\n const routes: RouteInfo[] = [];\n for (const doc of docs) {\n const route = config.resolveRoute(doc);\n if (route !== null) {\n routes.push(route);\n }\n }\n return routes;\n },\n };\n}\n", "import * as prismic from \"@prismicio/client\";\nimport type { ToolDefinition, ToolExecutor, ToolSource } from \"@yak-io/javascript/server\";\nimport type { PrismicToolAdapterConfig } from \"./types.js\";\n\nconst TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n name: \"prismic.getByUID\",\n description:\n \"Fetch a single Prismic document by document type and UID. Use this when you know the exact UID of a page or post.\",\n inputSchema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"The Prismic custom type (for example 'page' or 'blog_post')\",\n },\n uid: {\n type: \"string\",\n description: \"The unique identifier of the document\",\n },\n },\n required: [\"type\", \"uid\"],\n },\n },\n {\n name: \"prismic.getAllByType\",\n description:\n \"Fetch all Prismic documents of a given type. Use this to list pages or posts of a particular kind.\",\n inputSchema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"The Prismic custom type to list\",\n },\n limit: {\n type: \"number\",\n description: \"Maximum number of documents to return (default 20)\",\n },\n },\n required: [\"type\"],\n },\n },\n {\n name: \"prismic.search\",\n description:\n \"Full-text search across Prismic documents. Returns documents whose fields match the query.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"The free-text search query\",\n },\n types: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Optional list of document types to restrict the search to. Defaults to all allowed types.\",\n },\n },\n required: [\"query\"],\n },\n },\n];\n\nfunction buildGraphQuery(\n fields: Record<string, string[]> | undefined,\n type: string\n): string | undefined {\n const typeFields = fields?.[type];\n if (!typeFields || typeFields.length === 0) {\n return undefined;\n }\n return `{ ${type} { ${typeFields.join(\" \")} } }`;\n}\n\nexport function createPrismicToolAdapter(config: PrismicToolAdapterConfig): ToolSource {\n const allowed = new Set(config.allowedTypes);\n\n const assertAllowed = (type: unknown): string => {\n if (typeof type !== \"string\" || !allowed.has(type)) {\n throw new Error(`Prismic document type '${String(type)}' is not in allowedTypes`);\n }\n return type;\n };\n\n const executor: ToolExecutor = async (name, args) => {\n const input = (args ?? {}) as Record<string, unknown>;\n\n switch (name) {\n case \"prismic.getByUID\": {\n const type = assertAllowed(input.type);\n const uid = input.uid;\n if (typeof uid !== \"string\" || uid.length === 0) {\n throw new Error(\"prismic.getByUID requires a 'uid' string\");\n }\n const graphQuery = buildGraphQuery(config.fields, type);\n return await config.client.getByUID(type, uid, graphQuery ? { graphQuery } : undefined);\n }\n\n case \"prismic.getAllByType\": {\n const type = assertAllowed(input.type);\n const limit = typeof input.limit === \"number\" ? input.limit : 20;\n const graphQuery = buildGraphQuery(config.fields, type);\n return await config.client.getAllByType(type, {\n limit,\n ...(graphQuery ? { graphQuery } : {}),\n });\n }\n\n case \"prismic.search\": {\n const query = input.query;\n if (typeof query !== \"string\" || query.length === 0) {\n throw new Error(\"prismic.search requires a 'query' string\");\n }\n const requestedTypes = Array.isArray(input.types)\n ? (input.types as unknown[]).map((t) => assertAllowed(t))\n : [...allowed];\n return await config.client.get({\n filters: [\n prismic.filter.fulltext(\"document\", query),\n prismic.filter.any(\"document.type\", requestedTypes),\n ],\n });\n }\n\n default:\n throw new Error(`Unknown Prismic tool: ${name}`);\n }\n };\n\n return {\n id: config.id ?? \"prismic\",\n getTools: async () => TOOL_DEFINITIONS,\n executeTool: executor,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["payload", "prismic"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yak-io/prismic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Prismic CMS adapter for yak chatbot - exposes Prismic documents as routes, tools, and schema sources",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -29,20 +29,21 @@
|
|
|
29
29
|
"LICENSE"
|
|
30
30
|
],
|
|
31
31
|
"sideEffects": false,
|
|
32
|
-
"main": "./dist/index.
|
|
32
|
+
"main": "./dist/index.cjs",
|
|
33
33
|
"module": "./dist/index.js",
|
|
34
34
|
"types": "./dist/index.d.ts",
|
|
35
35
|
"exports": {
|
|
36
36
|
".": {
|
|
37
37
|
"types": "./dist/index.d.ts",
|
|
38
38
|
"import": "./dist/index.js",
|
|
39
|
+
"require": "./dist/index.cjs",
|
|
39
40
|
"default": "./dist/index.js"
|
|
40
41
|
},
|
|
41
42
|
"./package.json": "./package.json"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"@yak-io/graphql": "0.1
|
|
45
|
-
"@yak-io/javascript": "0.
|
|
45
|
+
"@yak-io/graphql": "0.2.1",
|
|
46
|
+
"@yak-io/javascript": "0.11.1"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
49
|
"@prismicio/client": "^7.0.0",
|
|
@@ -62,7 +63,7 @@
|
|
|
62
63
|
},
|
|
63
64
|
"homepage": "https://docs.yak.io/docs/sdks/prismic",
|
|
64
65
|
"scripts": {
|
|
65
|
-
"build": "tsc",
|
|
66
|
+
"build": "node ../../scripts/build-package.mjs && tsc --emitDeclarationOnly",
|
|
66
67
|
"check-types": "tsc --noEmit",
|
|
67
68
|
"test": "vitest run",
|
|
68
69
|
"lint": "biome lint ./src --fix",
|
package/dist/graphql-adapter.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { createGraphQLToolAdapter } from "@yak-io/graphql";
|
|
2
|
-
const INTROSPECTION_QUERY = `query IntrospectionQuery {
|
|
3
|
-
__schema {
|
|
4
|
-
queryType { name }
|
|
5
|
-
mutationType { name }
|
|
6
|
-
subscriptionType { name }
|
|
7
|
-
types {
|
|
8
|
-
...FullType
|
|
9
|
-
}
|
|
10
|
-
directives {
|
|
11
|
-
name
|
|
12
|
-
description
|
|
13
|
-
locations
|
|
14
|
-
args { ...InputValue }
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
fragment FullType on __Type {
|
|
19
|
-
kind
|
|
20
|
-
name
|
|
21
|
-
description
|
|
22
|
-
fields(includeDeprecated: true) {
|
|
23
|
-
name
|
|
24
|
-
description
|
|
25
|
-
args { ...InputValue }
|
|
26
|
-
type { ...TypeRef }
|
|
27
|
-
isDeprecated
|
|
28
|
-
deprecationReason
|
|
29
|
-
}
|
|
30
|
-
inputFields { ...InputValue }
|
|
31
|
-
interfaces { ...TypeRef }
|
|
32
|
-
enumValues(includeDeprecated: true) {
|
|
33
|
-
name
|
|
34
|
-
description
|
|
35
|
-
isDeprecated
|
|
36
|
-
deprecationReason
|
|
37
|
-
}
|
|
38
|
-
possibleTypes { ...TypeRef }
|
|
39
|
-
}
|
|
40
|
-
fragment InputValue on __InputValue {
|
|
41
|
-
name
|
|
42
|
-
description
|
|
43
|
-
type { ...TypeRef }
|
|
44
|
-
defaultValue
|
|
45
|
-
}
|
|
46
|
-
fragment TypeRef on __Type {
|
|
47
|
-
kind
|
|
48
|
-
name
|
|
49
|
-
ofType {
|
|
50
|
-
kind
|
|
51
|
-
name
|
|
52
|
-
ofType {
|
|
53
|
-
kind
|
|
54
|
-
name
|
|
55
|
-
ofType {
|
|
56
|
-
kind
|
|
57
|
-
name
|
|
58
|
-
ofType {
|
|
59
|
-
kind
|
|
60
|
-
name
|
|
61
|
-
ofType {
|
|
62
|
-
kind
|
|
63
|
-
name
|
|
64
|
-
ofType {
|
|
65
|
-
kind
|
|
66
|
-
name
|
|
67
|
-
ofType { kind name }
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}`;
|
|
75
|
-
function deriveGraphQLEndpoint(restEndpoint) {
|
|
76
|
-
const trimmed = restEndpoint.replace(/\/api\/v\d+\/?$/, "");
|
|
77
|
-
return `${trimmed}/graphql`;
|
|
78
|
-
}
|
|
79
|
-
async function buildHeaders(source, base) {
|
|
80
|
-
const headers = new Headers(base);
|
|
81
|
-
const resolved = typeof source === "function" ? await source() : source;
|
|
82
|
-
if (resolved) {
|
|
83
|
-
for (const [key, value] of new Headers(resolved)) {
|
|
84
|
-
headers.set(key, value);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return headers;
|
|
88
|
-
}
|
|
89
|
-
async function loadGraphQLModule() {
|
|
90
|
-
try {
|
|
91
|
-
return await import("graphql");
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
throw new Error("createPrismicGraphQLToolAdapter requires the 'graphql' package. Install it as a peer dependency: pnpm add graphql");
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Introspect a Prismic repository's GraphQL schema and return a browser-executed
|
|
99
|
-
* GraphQL {@link ToolAdapter} (built on `@yak-io/graphql`). Compose it into a
|
|
100
|
-
* {@link createYakToolset}; the LLM authors queries from the introspected SDL and
|
|
101
|
-
* the adapter executes them against the repo's GraphQL endpoint.
|
|
102
|
-
*
|
|
103
|
-
* Prismic's GraphQL endpoint requires a `Prismic-ref` header at execution time —
|
|
104
|
-
* supply it via `headers` (it may be async to fetch the master ref per call).
|
|
105
|
-
*/
|
|
106
|
-
export async function createPrismicGraphQLToolAdapter(config) {
|
|
107
|
-
const fetchFn = config.fetchFn ?? fetch;
|
|
108
|
-
const endpoint = config.endpoint ?? deriveGraphQLEndpoint(config.client.endpoint);
|
|
109
|
-
const response = await fetchFn(endpoint, {
|
|
110
|
-
method: "POST",
|
|
111
|
-
headers: { "Content-Type": "application/json" },
|
|
112
|
-
body: JSON.stringify({ query: INTROSPECTION_QUERY }),
|
|
113
|
-
});
|
|
114
|
-
if (!response.ok) {
|
|
115
|
-
throw new Error(`Prismic GraphQL introspection failed: ${response.status} ${response.statusText}`);
|
|
116
|
-
}
|
|
117
|
-
const payload = (await response.json());
|
|
118
|
-
if (payload.errors || !payload.data) {
|
|
119
|
-
throw new Error("Prismic GraphQL introspection returned no data");
|
|
120
|
-
}
|
|
121
|
-
const { buildClientSchema, printSchema } = await loadGraphQLModule();
|
|
122
|
-
const schema = buildClientSchema(payload.data);
|
|
123
|
-
const sdl = printSchema(schema);
|
|
124
|
-
return createGraphQLToolAdapter({
|
|
125
|
-
name: config.name ?? "prismic",
|
|
126
|
-
schema: sdl,
|
|
127
|
-
id: config.id,
|
|
128
|
-
// Prismic owns its own transport: POST the model-authored query to the repo's GraphQL
|
|
129
|
-
// endpoint with the caller-supplied headers (typically the required `Prismic-ref`).
|
|
130
|
-
execute: async (request) => {
|
|
131
|
-
const res = await fetchFn(endpoint, {
|
|
132
|
-
method: "POST",
|
|
133
|
-
headers: await buildHeaders(config.headers, { "Content-Type": "application/json" }),
|
|
134
|
-
body: JSON.stringify({
|
|
135
|
-
query: request.query,
|
|
136
|
-
variables: request.variables,
|
|
137
|
-
operationName: request.operationName,
|
|
138
|
-
}),
|
|
139
|
-
});
|
|
140
|
-
if (!res.ok) {
|
|
141
|
-
throw new Error(`Prismic GraphQL request failed (${res.status})`);
|
|
142
|
-
}
|
|
143
|
-
const payload = (await res.json());
|
|
144
|
-
if (payload.errors?.length) {
|
|
145
|
-
throw new Error(payload.errors[0]?.message ?? "Prismic GraphQL request returned errors");
|
|
146
|
-
}
|
|
147
|
-
return payload.data;
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
}
|
package/dist/route-adapter.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import * as prismic from "@prismicio/client";
|
|
2
|
-
export function createPrismicRouteAdapter(config) {
|
|
3
|
-
return {
|
|
4
|
-
id: config.id ?? "prismic",
|
|
5
|
-
getRoutes: async () => {
|
|
6
|
-
const docs = await config.client.dangerouslyGetAll({
|
|
7
|
-
filters: [
|
|
8
|
-
prismic.filter.any("document.type", config.documentTypes),
|
|
9
|
-
...(config.filters ?? []),
|
|
10
|
-
],
|
|
11
|
-
});
|
|
12
|
-
const routes = [];
|
|
13
|
-
for (const doc of docs) {
|
|
14
|
-
const route = config.resolveRoute(doc);
|
|
15
|
-
if (route !== null) {
|
|
16
|
-
routes.push(route);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return routes;
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
}
|
package/dist/tool-adapter.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import * as prismic from "@prismicio/client";
|
|
2
|
-
const TOOL_DEFINITIONS = [
|
|
3
|
-
{
|
|
4
|
-
name: "prismic.getByUID",
|
|
5
|
-
description: "Fetch a single Prismic document by document type and UID. Use this when you know the exact UID of a page or post.",
|
|
6
|
-
inputSchema: {
|
|
7
|
-
type: "object",
|
|
8
|
-
properties: {
|
|
9
|
-
type: {
|
|
10
|
-
type: "string",
|
|
11
|
-
description: "The Prismic custom type (for example 'page' or 'blog_post')",
|
|
12
|
-
},
|
|
13
|
-
uid: {
|
|
14
|
-
type: "string",
|
|
15
|
-
description: "The unique identifier of the document",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
required: ["type", "uid"],
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: "prismic.getAllByType",
|
|
23
|
-
description: "Fetch all Prismic documents of a given type. Use this to list pages or posts of a particular kind.",
|
|
24
|
-
inputSchema: {
|
|
25
|
-
type: "object",
|
|
26
|
-
properties: {
|
|
27
|
-
type: {
|
|
28
|
-
type: "string",
|
|
29
|
-
description: "The Prismic custom type to list",
|
|
30
|
-
},
|
|
31
|
-
limit: {
|
|
32
|
-
type: "number",
|
|
33
|
-
description: "Maximum number of documents to return (default 20)",
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
required: ["type"],
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: "prismic.search",
|
|
41
|
-
description: "Full-text search across Prismic documents. Returns documents whose fields match the query.",
|
|
42
|
-
inputSchema: {
|
|
43
|
-
type: "object",
|
|
44
|
-
properties: {
|
|
45
|
-
query: {
|
|
46
|
-
type: "string",
|
|
47
|
-
description: "The free-text search query",
|
|
48
|
-
},
|
|
49
|
-
types: {
|
|
50
|
-
type: "array",
|
|
51
|
-
items: { type: "string" },
|
|
52
|
-
description: "Optional list of document types to restrict the search to. Defaults to all allowed types.",
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
required: ["query"],
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
function buildGraphQuery(fields, type) {
|
|
60
|
-
const typeFields = fields?.[type];
|
|
61
|
-
if (!typeFields || typeFields.length === 0) {
|
|
62
|
-
return undefined;
|
|
63
|
-
}
|
|
64
|
-
return `{ ${type} { ${typeFields.join(" ")} } }`;
|
|
65
|
-
}
|
|
66
|
-
export function createPrismicToolAdapter(config) {
|
|
67
|
-
const allowed = new Set(config.allowedTypes);
|
|
68
|
-
const assertAllowed = (type) => {
|
|
69
|
-
if (typeof type !== "string" || !allowed.has(type)) {
|
|
70
|
-
throw new Error(`Prismic document type '${String(type)}' is not in allowedTypes`);
|
|
71
|
-
}
|
|
72
|
-
return type;
|
|
73
|
-
};
|
|
74
|
-
const executor = async (name, args) => {
|
|
75
|
-
const input = (args ?? {});
|
|
76
|
-
switch (name) {
|
|
77
|
-
case "prismic.getByUID": {
|
|
78
|
-
const type = assertAllowed(input.type);
|
|
79
|
-
const uid = input.uid;
|
|
80
|
-
if (typeof uid !== "string" || uid.length === 0) {
|
|
81
|
-
throw new Error("prismic.getByUID requires a 'uid' string");
|
|
82
|
-
}
|
|
83
|
-
const graphQuery = buildGraphQuery(config.fields, type);
|
|
84
|
-
return await config.client.getByUID(type, uid, graphQuery ? { graphQuery } : undefined);
|
|
85
|
-
}
|
|
86
|
-
case "prismic.getAllByType": {
|
|
87
|
-
const type = assertAllowed(input.type);
|
|
88
|
-
const limit = typeof input.limit === "number" ? input.limit : 20;
|
|
89
|
-
const graphQuery = buildGraphQuery(config.fields, type);
|
|
90
|
-
return await config.client.getAllByType(type, {
|
|
91
|
-
limit,
|
|
92
|
-
...(graphQuery ? { graphQuery } : {}),
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
case "prismic.search": {
|
|
96
|
-
const query = input.query;
|
|
97
|
-
if (typeof query !== "string" || query.length === 0) {
|
|
98
|
-
throw new Error("prismic.search requires a 'query' string");
|
|
99
|
-
}
|
|
100
|
-
const requestedTypes = Array.isArray(input.types)
|
|
101
|
-
? input.types.map((t) => assertAllowed(t))
|
|
102
|
-
: [...allowed];
|
|
103
|
-
return await config.client.get({
|
|
104
|
-
filters: [
|
|
105
|
-
prismic.filter.fulltext("document", query),
|
|
106
|
-
prismic.filter.any("document.type", requestedTypes),
|
|
107
|
-
],
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
default:
|
|
111
|
-
throw new Error(`Unknown Prismic tool: ${name}`);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
return {
|
|
115
|
-
id: config.id ?? "prismic",
|
|
116
|
-
getTools: async () => TOOL_DEFINITIONS,
|
|
117
|
-
executeTool: executor,
|
|
118
|
-
};
|
|
119
|
-
}
|
package/dist/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|