@krak-stack/registry 0.1.13 → 0.1.14
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 +19 -0
- package/dist/components/ui/app-brand.d.ts +18 -13
- package/dist/components/ui/app-brand.js +48 -15
- package/dist/components/ui/code-block.js +10 -6
- package/dist/components/ui/copy-button.d.ts +1 -1
- package/dist/components/ui/copy-button.js +1 -1
- package/dist/components/ui/data-table.d.ts +1 -1
- package/dist/components/ui/data-table.js +21 -20
- package/dist/components/ui/effect-form.js +7 -6
- package/dist/components/ui/file-picker.js +2 -1
- package/dist/components/ui/form.js +17 -15
- package/dist/components/ui/google-map.d.ts +6 -10
- package/dist/components/ui/google-map.js +19 -14
- package/dist/components/ui/locale-switcher.js +7 -1
- package/dist/components/ui/sidebar-layout.js +19 -21
- package/dist/components/ui/theme-switcher.js +1 -1
- package/dist/lib/docs-core.js +165 -109
- package/dist/lib/documentation-toolkit.d.ts +1 -1
- package/dist/lib/documentation-toolkit.js +41 -40
- package/dist/lib/httpapi-cli.d.ts +6 -6
- package/dist/lib/httpapi-cli.js +75 -48
- package/dist/lib/httpapi-client.d.ts +8 -2
- package/dist/lib/httpapi-client.js +21 -9
- package/dist/lib/httpapi-helpers.d.ts +15 -21
- package/dist/lib/httpapi-helpers.js +38 -26
- package/dist/lib/httpapi-mcp.js +73 -50
- package/dist/lib/httpapi-toolkit.d.ts +3 -2
- package/dist/lib/httpapi-toolkit.js +93 -65
- package/dist/lib/seo.js +29 -17
- package/dist/oxlint/anti-slop/index.js +1592 -0
- package/dist/services/agent/client/atom.d.ts +7 -7
- package/dist/services/agent/client/index.js +55 -54
- package/dist/services/agent/index.d.ts +71 -71
- package/dist/services/agent/index.js +38 -19
- package/dist/services/notification/channels/index.d.ts +11 -9
- package/dist/services/notification/channels/ses/index.d.ts +6 -6
- package/dist/services/notification/channels/ses/index.js +15 -11
- package/dist/services/notification/client/index.js +3 -2
- package/dist/services/notification/client/notification-menu.d.ts +9 -9
- package/dist/services/notification/index.d.ts +7 -6
- package/dist/services/notification/public.js +3 -2
- package/dist/services/s3/index.d.ts +2 -16
- package/dist/services/s3/index.js +12 -9
- package/package.json +7 -1
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
// ../../src/lib/httpapi-toolkit.ts
|
|
2
|
-
import { Effect as Effect3, Layer as Layer3, Schema as
|
|
2
|
+
import { Effect as Effect3, Layer as Layer3, Option as Option2, Schema as Schema3 } from "effect";
|
|
3
3
|
import { Tool, Toolkit } from "effect/unstable/ai";
|
|
4
4
|
|
|
5
5
|
// ../../src/lib/httpapi-client.ts
|
|
6
|
-
import { Context, Effect, Layer } from "effect";
|
|
6
|
+
import { Context, Effect, Layer, Schema } from "effect";
|
|
7
7
|
import { HttpClient } from "effect/unstable/http";
|
|
8
8
|
import {
|
|
9
9
|
HttpApiClient as EffectHttpApiClient
|
|
10
10
|
} from "effect/unstable/httpapi";
|
|
11
|
+
var HttpApiOperationResult = Schema.Union([
|
|
12
|
+
Schema.Json,
|
|
13
|
+
Schema.DateFromString,
|
|
14
|
+
Schema.Uint8ArrayFromBase64,
|
|
15
|
+
Schema.Undefined
|
|
16
|
+
]).annotate({ identifier: "HttpApiOperationResult" });
|
|
17
|
+
var encodeHttpApiOperationResult = Effect.fn("HttpApiClient.encodeOperationResult")((result) => Schema.encodeUnknownEffect(HttpApiOperationResult)(result).pipe(Effect.map((encoded) => encoded ?? null), Effect.mapError((cause) => new Error("HTTP API result is not serializable", { cause }))));
|
|
18
|
+
var GeneratedOperation = Schema.declare((value) => value instanceof Function).annotate({ identifier: "GeneratedOperation" });
|
|
19
|
+
var GeneratedOperationEffect = Schema.declare((value) => Effect.isEffect(value)).annotate({ identifier: "GeneratedOperationEffect" });
|
|
11
20
|
var makeGeneratedClient = (api, http, baseUrl) => EffectHttpApiClient.makeWith(api, {
|
|
12
21
|
baseUrl,
|
|
13
22
|
httpClient: http
|
|
14
23
|
});
|
|
15
|
-
var isClientEffect = (value) => Effect.isEffect(value);
|
|
16
24
|
var executeGeneratedOperation = Effect.fn("HttpApiClient.executeGeneratedOperation")(function* (client, { input, operation: entry }) {
|
|
17
25
|
const operationId = entry.operation.operationId;
|
|
18
26
|
if (!operationId) {
|
|
@@ -20,22 +28,23 @@ var executeGeneratedOperation = Effect.fn("HttpApiClient.executeGeneratedOperati
|
|
|
20
28
|
}
|
|
21
29
|
const target = Object(client);
|
|
22
30
|
const groupName = Object.keys(target).filter((name) => operationId.startsWith(`${name}.`)).sort((a, b) => b.length - a.length)[0];
|
|
23
|
-
const group = groupName ?
|
|
31
|
+
const group = groupName ? Object.entries(target).find(([name]) => name === groupName)?.[1] : target;
|
|
24
32
|
const endpointName = groupName ? operationId.slice(groupName.length + 1) : operationId;
|
|
25
|
-
const
|
|
26
|
-
|
|
33
|
+
const endpointCandidate = group instanceof Function ? undefined : Object.entries(Object(group)).find(([name]) => name === endpointName)?.[1];
|
|
34
|
+
const endpoint = Schema.decodeUnknownOption(GeneratedOperation)(endpointCandidate);
|
|
35
|
+
if (endpoint._tag === "None") {
|
|
27
36
|
return yield* Effect.fail(new Error(`No generated API client operation for ${operationId}`));
|
|
28
37
|
}
|
|
29
|
-
const result = endpoint({
|
|
38
|
+
const result = Schema.decodeUnknownOption(GeneratedOperationEffect)(endpoint.value({
|
|
30
39
|
headers: input.headers,
|
|
31
40
|
params: input.params,
|
|
32
41
|
query: input.query,
|
|
33
42
|
payload: input.body
|
|
34
|
-
});
|
|
35
|
-
if (
|
|
43
|
+
}));
|
|
44
|
+
if (result._tag === "None") {
|
|
36
45
|
return yield* Effect.fail(new Error(`Generated API client operation ${operationId} is invalid`));
|
|
37
46
|
}
|
|
38
|
-
return yield* result;
|
|
47
|
+
return yield* result.value;
|
|
39
48
|
});
|
|
40
49
|
|
|
41
50
|
class ApiClient extends Context.Service()("ApiClient") {
|
|
@@ -43,6 +52,7 @@ class ApiClient extends Context.Service()("ApiClient") {
|
|
|
43
52
|
const http = yield* HttpClient.HttpClient;
|
|
44
53
|
const client = yield* makeGeneratedClient(config.api, http, config.baseUrl);
|
|
45
54
|
return {
|
|
55
|
+
encodeResult: config.encodeResult ?? ((result) => encodeHttpApiOperationResult(result)),
|
|
46
56
|
execute: Effect.fn("ApiClient.execute")(function* (options) {
|
|
47
57
|
return yield* executeGeneratedOperation(client, options);
|
|
48
58
|
})
|
|
@@ -57,29 +67,29 @@ import {
|
|
|
57
67
|
JsonSchema,
|
|
58
68
|
Layer as Layer2,
|
|
59
69
|
Option,
|
|
60
|
-
Schema,
|
|
70
|
+
Schema as Schema2,
|
|
61
71
|
SchemaRepresentation
|
|
62
72
|
} from "effect";
|
|
63
73
|
import { HttpApi as HttpApi2, OpenApi } from "effect/unstable/httpapi";
|
|
64
|
-
var JsonObjectSchema =
|
|
74
|
+
var JsonObjectSchema = Schema2.Record(Schema2.String, Schema2.Json).annotate({
|
|
65
75
|
identifier: "HttpJsonObject",
|
|
66
76
|
title: "HTTP JSON object",
|
|
67
77
|
description: "A JSON object passed to an HTTP API operation.",
|
|
68
78
|
examples: [{ id: "example-id" }]
|
|
69
79
|
});
|
|
70
|
-
var JsonObjectFromString =
|
|
71
|
-
var JsonValueFromString =
|
|
72
|
-
var JsonSchemaAnnotations =
|
|
73
|
-
title:
|
|
74
|
-
description:
|
|
75
|
-
examples:
|
|
80
|
+
var JsonObjectFromString = Schema2.fromJsonString(JsonObjectSchema);
|
|
81
|
+
var JsonValueFromString = Schema2.fromJsonString(Schema2.Json);
|
|
82
|
+
var JsonSchemaAnnotations = Schema2.Struct({
|
|
83
|
+
title: Schema2.optional(Schema2.String),
|
|
84
|
+
description: Schema2.optional(Schema2.String),
|
|
85
|
+
examples: Schema2.optional(Schema2.Array(Schema2.Json))
|
|
76
86
|
}).annotate({
|
|
77
87
|
identifier: "HttpJsonSchemaAnnotations",
|
|
78
88
|
title: "HTTP JSON Schema annotations",
|
|
79
89
|
description: "JSON Schema annotations surfaced on generated tool inputs."
|
|
80
90
|
});
|
|
81
|
-
var HttpApiToolInputSchema =
|
|
82
|
-
body:
|
|
91
|
+
var HttpApiToolInputSchema = Schema2.Struct({
|
|
92
|
+
body: Schema2.optional(Schema2.Json)
|
|
83
93
|
}).annotate({
|
|
84
94
|
identifier: "HttpApiToolInput",
|
|
85
95
|
title: "HTTP API tool input",
|
|
@@ -93,6 +103,8 @@ var HttpApiMethods = [
|
|
|
93
103
|
"patch",
|
|
94
104
|
"delete"
|
|
95
105
|
];
|
|
106
|
+
var HttpApiOperationSchema = Schema2.declare((value) => Schema2.is(JsonObjectSchema)(value)).annotate({ identifier: "HttpApiOperation" });
|
|
107
|
+
var decodeHttpApiOperation = Schema2.decodeUnknownOption(HttpApiOperationSchema);
|
|
96
108
|
var toHttpError = (message, error) => new Error(message, { cause: error });
|
|
97
109
|
var httpApiToolName = (method, path, operation) => {
|
|
98
110
|
const fallback = `${method}_${path.replace(/^\/api\//, "").replace(/[/:{}]/g, "_")}`;
|
|
@@ -105,9 +117,10 @@ var httpApiOperations = ({
|
|
|
105
117
|
const operations = [];
|
|
106
118
|
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
107
119
|
for (const method of methods) {
|
|
108
|
-
const operation = pathItem[method];
|
|
109
|
-
if (operation)
|
|
110
|
-
operations.push({ method, path, operation });
|
|
120
|
+
const operation = decodeHttpApiOperation(pathItem[method]);
|
|
121
|
+
if (Option.isSome(operation)) {
|
|
122
|
+
operations.push({ method, path, operation: operation.value });
|
|
123
|
+
}
|
|
111
124
|
}
|
|
112
125
|
}
|
|
113
126
|
return operations;
|
|
@@ -128,7 +141,7 @@ var httpApiToolEntries = Effect2.fn("Http.toolEntries")(function* (operations) {
|
|
|
128
141
|
catch: (error) => error instanceof Error ? error : new Error(String(error))
|
|
129
142
|
});
|
|
130
143
|
});
|
|
131
|
-
var decodeAnnotations =
|
|
144
|
+
var decodeAnnotations = Schema2.decodeUnknownOption(JsonSchemaAnnotations);
|
|
132
145
|
var schemaWithVisibleAnnotations = (schema) => {
|
|
133
146
|
const directAnnotations = decodeAnnotations(schema).pipe(Option.getOrElse(() => ({})));
|
|
134
147
|
const allOf = Array.isArray(schema.allOf) ? schema.allOf : [];
|
|
@@ -136,30 +149,36 @@ var schemaWithVisibleAnnotations = (schema) => {
|
|
|
136
149
|
...acc,
|
|
137
150
|
...decodeAnnotations(item).pipe(Option.getOrElse(() => ({})))
|
|
138
151
|
}), directAnnotations);
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
152
|
+
const visible = { ...schema };
|
|
153
|
+
if ("title" in annotations && !("title" in schema)) {
|
|
154
|
+
visible.title = annotations.title;
|
|
155
|
+
}
|
|
156
|
+
if ("description" in annotations && !("description" in schema)) {
|
|
157
|
+
visible.description = annotations.description;
|
|
158
|
+
}
|
|
159
|
+
if ("examples" in annotations && !("examples" in schema)) {
|
|
160
|
+
visible.examples = annotations.examples;
|
|
161
|
+
}
|
|
162
|
+
return visible;
|
|
145
163
|
};
|
|
146
164
|
var referencedDefinitions = (schema, definitions) => {
|
|
147
165
|
const names = new Set;
|
|
148
|
-
const pending = [schema];
|
|
166
|
+
const pending = [Schema2.decodeUnknownSync(Schema2.Json)(schema)];
|
|
149
167
|
while (pending.length > 0) {
|
|
150
168
|
const current = pending.pop();
|
|
151
|
-
if (!current || typeof current !== "object")
|
|
152
|
-
continue;
|
|
153
169
|
if (Array.isArray(current)) {
|
|
154
170
|
pending.push(...current);
|
|
155
171
|
continue;
|
|
156
172
|
}
|
|
157
|
-
|
|
158
|
-
|
|
173
|
+
const record = Schema2.decodeUnknownOption(Schema2.Record(Schema2.String, Schema2.Json))(current);
|
|
174
|
+
if (Option.isNone(record))
|
|
175
|
+
continue;
|
|
176
|
+
for (const [key, value] of Object.entries(record.value)) {
|
|
177
|
+
if (key === "$ref" && Schema2.is(Schema2.String)(value)) {
|
|
159
178
|
const name = value.match(/^#\/(?:\$defs|components\/schemas)\/(.+)$/)?.[1];
|
|
160
179
|
if (name && !names.has(name) && definitions[name]) {
|
|
161
180
|
names.add(name);
|
|
162
|
-
pending.push(definitions[name]);
|
|
181
|
+
pending.push(Schema2.decodeUnknownSync(Schema2.Json)(definitions[name]));
|
|
163
182
|
}
|
|
164
183
|
} else if (key !== "$defs") {
|
|
165
184
|
pending.push(value);
|
|
@@ -182,10 +201,12 @@ var httpApiOperationInputSchema = (operation) => {
|
|
|
182
201
|
...queryParameters,
|
|
183
202
|
...headerParameters
|
|
184
203
|
]) {
|
|
185
|
-
|
|
186
|
-
...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
|
|
187
|
-
...parameter.description ? { description: parameter.description } : {}
|
|
204
|
+
const property = {
|
|
205
|
+
...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
|
|
188
206
|
};
|
|
207
|
+
if (parameter.description)
|
|
208
|
+
property.description = parameter.description;
|
|
209
|
+
properties[parameter.name] = property;
|
|
189
210
|
if (parameter.required)
|
|
190
211
|
required.push(parameter.name);
|
|
191
212
|
}
|
|
@@ -201,10 +222,10 @@ var httpApiOperationInputSchema = (operation) => {
|
|
|
201
222
|
additionalProperties: false
|
|
202
223
|
};
|
|
203
224
|
};
|
|
204
|
-
var decodeJsonObject =
|
|
225
|
+
var decodeJsonObject = Schema2.decodeUnknownOption(JsonObjectSchema);
|
|
205
226
|
var decodeHttpApiOperationInput = Effect2.fn("Http.decodeApiOperationInput")(function* (input, operation) {
|
|
206
|
-
const payload = yield*
|
|
207
|
-
const decoded = yield*
|
|
227
|
+
const payload = yield* Schema2.decodeUnknownEffect(JsonObjectSchema)(input ?? {}).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
|
|
228
|
+
const decoded = yield* Schema2.decodeUnknownEffect(HttpApiToolInputSchema)(payload).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
|
|
208
229
|
const parameters = operation.parameters ?? [];
|
|
209
230
|
const pickParameters = (location) => {
|
|
210
231
|
const nestedKey = location === "path" ? "params" : location;
|
|
@@ -224,12 +245,12 @@ var decodeHttpApiOperationInput = Effect2.fn("Http.decodeApiOperationInput")(fun
|
|
|
224
245
|
var parseJsonObject = Effect2.fn("Http.parseJsonObject")(function* (value, label) {
|
|
225
246
|
if (!value)
|
|
226
247
|
return {};
|
|
227
|
-
return yield*
|
|
248
|
+
return yield* Schema2.decodeUnknownEffect(JsonObjectFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be a JSON object`)));
|
|
228
249
|
});
|
|
229
250
|
var parseJsonValue = Effect2.fn("Http.parseJsonValue")(function* (value, label) {
|
|
230
251
|
if (!value)
|
|
231
252
|
return;
|
|
232
|
-
return yield*
|
|
253
|
+
return yield* Schema2.decodeUnknownEffect(JsonValueFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be valid JSON`)));
|
|
233
254
|
});
|
|
234
255
|
|
|
235
256
|
class HttpApiSpec extends Context2.Service()("HttpApiSpec", {
|
|
@@ -251,10 +272,11 @@ class HttpApiSpec extends Context2.Service()("HttpApiSpec", {
|
|
|
251
272
|
});
|
|
252
273
|
const definitions = document.definitions ?? {};
|
|
253
274
|
const usedDefinitions = referencedDefinitions(document.schema, definitions);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
275
|
+
const result = { ...document.schema };
|
|
276
|
+
if (Object.keys(usedDefinitions).length > 0) {
|
|
277
|
+
result.$defs = usedDefinitions;
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
258
280
|
};
|
|
259
281
|
return {
|
|
260
282
|
info: spec.info,
|
|
@@ -274,33 +296,38 @@ class HttpApiSpec extends Context2.Service()("HttpApiSpec", {
|
|
|
274
296
|
}
|
|
275
297
|
|
|
276
298
|
// ../../src/lib/httpapi-toolkit.ts
|
|
277
|
-
var HttpApiToolParameters =
|
|
299
|
+
var HttpApiToolParameters = Schema3.Struct({}).annotate({
|
|
278
300
|
identifier: "HttpApiToolParameters"
|
|
279
301
|
});
|
|
280
302
|
var makeOpenAiStrictJsonSchema = (schema) => {
|
|
303
|
+
const JsonRecord = Schema3.Record(Schema3.String, Schema3.Json);
|
|
281
304
|
const visit = (value) => {
|
|
282
305
|
if (Array.isArray(value))
|
|
283
306
|
return value.map(visit);
|
|
284
|
-
|
|
307
|
+
const record = Schema3.decodeUnknownOption(JsonRecord)(value);
|
|
308
|
+
if (Option2.isNone(record))
|
|
285
309
|
return value;
|
|
286
|
-
|
|
287
|
-
const allOf =
|
|
310
|
+
let transformed2 = Object.fromEntries(Object.entries(record.value).map(([key, child]) => [key, visit(child)]));
|
|
311
|
+
const allOf = transformed2.allOf;
|
|
288
312
|
if (Array.isArray(allOf)) {
|
|
289
|
-
delete
|
|
313
|
+
delete transformed2.allOf;
|
|
290
314
|
for (const item of allOf) {
|
|
291
|
-
|
|
292
|
-
|
|
315
|
+
const itemRecord = Schema3.decodeUnknownOption(JsonRecord)(item);
|
|
316
|
+
if (Option2.isSome(itemRecord)) {
|
|
317
|
+
transformed2 = { ...transformed2, ...itemRecord.value };
|
|
318
|
+
}
|
|
293
319
|
}
|
|
294
320
|
}
|
|
295
|
-
if (
|
|
296
|
-
const properties =
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
321
|
+
if (transformed2.type === "object") {
|
|
322
|
+
const properties = Schema3.decodeUnknownOption(JsonRecord)(transformed2.properties).pipe(Option2.getOrElse(() => ({})));
|
|
323
|
+
transformed2.properties = properties;
|
|
324
|
+
transformed2.required = Object.keys(properties);
|
|
325
|
+
transformed2.additionalProperties = false;
|
|
300
326
|
}
|
|
301
|
-
return
|
|
327
|
+
return transformed2;
|
|
302
328
|
};
|
|
303
|
-
|
|
329
|
+
const transformed = Schema3.decodeUnknownSync(JsonRecord)(visit(Schema3.decodeUnknownSync(Schema3.Json)(schema)));
|
|
330
|
+
return { ...schema, ...transformed };
|
|
304
331
|
};
|
|
305
332
|
var makeOperationTool = (entry, config, spec) => {
|
|
306
333
|
const { method, operation } = entry;
|
|
@@ -314,8 +341,8 @@ var makeOperationTool = (entry, config, spec) => {
|
|
|
314
341
|
|
|
315
342
|
${guidance}` : guidance,
|
|
316
343
|
parameters: strict ? makeOpenAiStrictJsonSchema(parameters) : parameters,
|
|
317
|
-
success:
|
|
318
|
-
failure:
|
|
344
|
+
success: Schema3.Json,
|
|
345
|
+
failure: Schema3.String,
|
|
319
346
|
failureMode: "return",
|
|
320
347
|
needsApproval: config.needsApproval?.(entry) ?? !readOnly
|
|
321
348
|
}).setParameters(HttpApiToolParameters).annotate(Tool.Title, operation.summary ?? operation.operationId ?? entry.name).annotate(Tool.Strict, strict).annotate(Tool.Readonly, readOnly).annotate(Tool.Destructive, method === "delete").annotate(Tool.Idempotent, method === "get" || method === "put" || method === "delete").annotate(Tool.OpenWorld, false);
|
|
@@ -346,7 +373,8 @@ var HttpApiToolkitLayer = (config) => Layer3.unwrap(buildHttpApiToolkit(config).
|
|
|
346
373
|
query: decoded.query
|
|
347
374
|
}
|
|
348
375
|
});
|
|
349
|
-
|
|
376
|
+
const encoded = yield* client.encodeResult(result, entry);
|
|
377
|
+
return config.transformResult?.(entry, encoded) ?? encoded;
|
|
350
378
|
}).pipe(Effect3.mapError((error) => error instanceof Error ? error.message : String(error)))
|
|
351
379
|
])))))));
|
|
352
380
|
export {
|
package/dist/lib/seo.js
CHANGED
|
@@ -65,24 +65,36 @@ var seo = ({
|
|
|
65
65
|
const siteUrl = origin?.replace(/\/$/, "") ?? canonical;
|
|
66
66
|
const publisher = {
|
|
67
67
|
"@type": "Organization",
|
|
68
|
-
name: siteName
|
|
69
|
-
...siteUrl ? { url: siteUrl } : {},
|
|
70
|
-
...sameAs?.length ? { sameAs } : {}
|
|
71
|
-
};
|
|
72
|
-
const structuredData = type === "article" ? {
|
|
73
|
-
"@type": "Article",
|
|
74
|
-
headline: title,
|
|
75
|
-
description,
|
|
76
|
-
...canonical ? { url: canonical } : {},
|
|
77
|
-
...locale ? { inLanguage: locale } : {},
|
|
78
|
-
...image ? { image } : {},
|
|
79
|
-
publisher
|
|
80
|
-
} : {
|
|
81
|
-
"@type": "WebSite",
|
|
82
|
-
name: siteName,
|
|
83
|
-
...siteUrl ? { url: siteUrl } : {},
|
|
84
|
-
publisher
|
|
68
|
+
name: siteName
|
|
85
69
|
};
|
|
70
|
+
if (siteUrl)
|
|
71
|
+
publisher.url = siteUrl;
|
|
72
|
+
if (sameAs?.length)
|
|
73
|
+
publisher.sameAs = sameAs;
|
|
74
|
+
const structuredData = type === "article" ? (() => {
|
|
75
|
+
const article = {
|
|
76
|
+
"@type": "Article",
|
|
77
|
+
headline: title,
|
|
78
|
+
description,
|
|
79
|
+
publisher
|
|
80
|
+
};
|
|
81
|
+
if (canonical)
|
|
82
|
+
article.url = canonical;
|
|
83
|
+
if (locale)
|
|
84
|
+
article.inLanguage = locale;
|
|
85
|
+
if (image)
|
|
86
|
+
article.image = image;
|
|
87
|
+
return article;
|
|
88
|
+
})() : (() => {
|
|
89
|
+
const website = {
|
|
90
|
+
"@type": "WebSite",
|
|
91
|
+
name: siteName,
|
|
92
|
+
publisher
|
|
93
|
+
};
|
|
94
|
+
if (siteUrl)
|
|
95
|
+
website.url = siteUrl;
|
|
96
|
+
return website;
|
|
97
|
+
})();
|
|
86
98
|
const scripts = [
|
|
87
99
|
{
|
|
88
100
|
type: "application/ld+json",
|