@heyo-sh/create-heyo-docs 1.0.1 → 3.0.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.
Files changed (118) hide show
  1. package/deployments/cloudflare/astro/package.json +2 -1
  2. package/deployments/cloudflare/astro/src/env.d.ts +2 -1
  3. package/deployments/cloudflare/astro/src/pages/heyo-docs-internal/ai-chat.ts +9 -7
  4. package/deployments/cloudflare/next/app/heyo-docs-internal/ai-chat/route.ts +9 -7
  5. package/deployments/cloudflare/next/cloudflare-env.d.ts +2 -1
  6. package/deployments/cloudflare/react-router/app/cloudflare-env.d.ts +2 -1
  7. package/deployments/cloudflare/react-router/app/routes/ai-chat.ts +9 -8
  8. package/deployments/cloudflare/react-router/package.json +2 -1
  9. package/deployments/vercel/astro/package.json +1 -0
  10. package/dist/index.js +24 -4
  11. package/dist/scaffold.d.ts.map +1 -1
  12. package/dist/utils.d.ts.map +1 -1
  13. package/package.json +1 -1
  14. package/templates/astro/content/index.mdx +8 -0
  15. package/templates/astro/heyo-docs.config.ts +4 -48
  16. package/templates/astro/src/components/docs-app.tsx +30 -130
  17. package/templates/astro/src/heyo-docs-icons.tsx +3 -1
  18. package/templates/astro/src/layouts/docs-layout.astro +10 -436
  19. package/templates/astro/src/lib/docs.ts +3 -2
  20. package/templates/astro/src/lib/openapi-request.ts +6 -146
  21. package/templates/astro/src/pages/[...slug].astro +7 -15
  22. package/templates/astro/src/pages/[...slug].md.ts +4 -1
  23. package/templates/astro/src/pages/heyo-docs-internal/ai-chat.ts +5 -7
  24. package/templates/astro/src/pages/heyo-docs-internal/openapi-request.ts +6 -0
  25. package/templates/astro/src/pages/index.astro +18 -9
  26. package/templates/astro/src/pages/llms-full.txt.ts +1 -1
  27. package/templates/astro/src/pages/llms.txt.ts +1 -1
  28. package/templates/astro/src/pages/rss.xml.ts +1 -1
  29. package/templates/astro/src/pages/sitemap.xml.ts +2 -2
  30. package/templates/astro/src/virtual.d.ts +5 -5
  31. package/templates/next/app/[[...slug]]/page.tsx +10 -9
  32. package/templates/next/app/components/docs-app.tsx +28 -120
  33. package/templates/next/app/heyo-docs-icons.tsx +1 -1
  34. package/templates/next/app/heyo-docs-internal/ai-chat/route.ts +6 -7
  35. package/templates/next/app/heyo-docs-internal/markdown/[[...slug]]/route.ts +1 -1
  36. package/templates/next/app/layout.tsx +25 -444
  37. package/templates/next/app/lib/docs.ts +3 -3
  38. package/templates/next/app/lib/openapi-request.ts +4 -136
  39. package/templates/next/app/llms-full.txt/route.ts +1 -1
  40. package/templates/next/app/llms.txt/route.ts +1 -1
  41. package/templates/next/app/rss.xml/route.ts +1 -1
  42. package/templates/next/app/sitemap.xml/route.ts +1 -1
  43. package/templates/next/content/index.mdx +8 -0
  44. package/templates/next/heyo-docs.config.ts +3 -47
  45. package/templates/next/next.config.ts +7 -1
  46. package/templates/react-router/app/heyo-docs-icons.tsx +3 -1
  47. package/templates/react-router/app/root.tsx +28 -465
  48. package/templates/react-router/app/routes/ai-chat.ts +4 -8
  49. package/templates/react-router/app/routes/docs.tsx +22 -63
  50. package/templates/react-router/app/routes/home.tsx +6 -1
  51. package/templates/react-router/app/routes/llms-full.ts +1 -1
  52. package/templates/react-router/app/routes/llms.ts +1 -1
  53. package/templates/react-router/app/routes/markdown.ts +4 -1
  54. package/templates/react-router/app/routes/openapi-request.ts +11 -144
  55. package/templates/react-router/app/routes/rss.ts +1 -1
  56. package/templates/react-router/app/routes/sitemap.ts +5 -8
  57. package/templates/react-router/app/virtual.d.ts +5 -5
  58. package/templates/react-router/content/index.mdx +8 -0
  59. package/templates/react-router/heyo-docs.config.ts +4 -48
  60. package/templates/astro/content/api-overview.mdx +0 -20
  61. package/templates/astro/content/assets/local-architecture.svg +0 -22
  62. package/templates/astro/content/assets/quick-reference.txt +0 -5
  63. package/templates/astro/content/changelog.mdx +0 -38
  64. package/templates/astro/content/configuration.mdx +0 -117
  65. package/templates/astro/content/deploying.mdx +0 -70
  66. package/templates/astro/content/essentials/callouts.mdx +0 -34
  67. package/templates/astro/content/essentials/code-blocks.mdx +0 -43
  68. package/templates/astro/content/essentials/lists.mdx +0 -36
  69. package/templates/astro/content/essentials/tables.mdx +0 -30
  70. package/templates/astro/content/essentials/tabs.mdx +0 -40
  71. package/templates/astro/content/essentials/text-styling.mdx +0 -43
  72. package/templates/astro/content/getting-started.mdx +0 -16
  73. package/templates/astro/content/mdx-components.mdx +0 -44
  74. package/templates/astro/content/openapi-petstore.json +0 -160
  75. package/templates/astro/content/openapi.json +0 -278
  76. package/templates/astro/content/quickstart.mdx +0 -60
  77. package/templates/astro/src/components/theme-provider.tsx +0 -106
  78. package/templates/astro/src/lib/seo.ts +0 -221
  79. package/templates/astro/src/lib/theme.ts +0 -74
  80. package/templates/next/app/components/theme-provider.tsx +0 -93
  81. package/templates/next/app/lib/seo.ts +0 -189
  82. package/templates/next/app/lib/theme.ts +0 -61
  83. package/templates/next/content/api-overview.mdx +0 -20
  84. package/templates/next/content/assets/local-architecture.svg +0 -22
  85. package/templates/next/content/assets/quick-reference.txt +0 -5
  86. package/templates/next/content/changelog.mdx +0 -38
  87. package/templates/next/content/configuration.mdx +0 -117
  88. package/templates/next/content/deploying.mdx +0 -70
  89. package/templates/next/content/essentials/callouts.mdx +0 -34
  90. package/templates/next/content/essentials/code-blocks.mdx +0 -43
  91. package/templates/next/content/essentials/lists.mdx +0 -36
  92. package/templates/next/content/essentials/tables.mdx +0 -30
  93. package/templates/next/content/essentials/tabs.mdx +0 -40
  94. package/templates/next/content/essentials/text-styling.mdx +0 -43
  95. package/templates/next/content/getting-started.mdx +0 -16
  96. package/templates/next/content/mdx-components.mdx +0 -41
  97. package/templates/next/content/openapi-petstore.json +0 -160
  98. package/templates/next/content/openapi.json +0 -278
  99. package/templates/next/content/quickstart.mdx +0 -60
  100. package/templates/react-router/app/components/theme-provider.tsx +0 -106
  101. package/templates/react-router/app/lib/theme.ts +0 -74
  102. package/templates/react-router/content/api-overview.mdx +0 -20
  103. package/templates/react-router/content/assets/local-architecture.svg +0 -22
  104. package/templates/react-router/content/assets/quick-reference.txt +0 -5
  105. package/templates/react-router/content/changelog.mdx +0 -38
  106. package/templates/react-router/content/configuration.mdx +0 -117
  107. package/templates/react-router/content/deploying.mdx +0 -70
  108. package/templates/react-router/content/essentials/callouts.mdx +0 -34
  109. package/templates/react-router/content/essentials/code-blocks.mdx +0 -43
  110. package/templates/react-router/content/essentials/lists.mdx +0 -36
  111. package/templates/react-router/content/essentials/tables.mdx +0 -30
  112. package/templates/react-router/content/essentials/tabs.mdx +0 -40
  113. package/templates/react-router/content/essentials/text-styling.mdx +0 -43
  114. package/templates/react-router/content/getting-started.mdx +0 -16
  115. package/templates/react-router/content/mdx-components.mdx +0 -293
  116. package/templates/react-router/content/openapi-petstore.json +0 -160
  117. package/templates/react-router/content/openapi.json +0 -278
  118. package/templates/react-router/content/quickstart.mdx +0 -60
@@ -1,67 +1,13 @@
1
1
  ---
2
2
  import config from "../../heyo-docs.config";
3
- import { adobeAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/adobe";
4
- import { amplitudeAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/amplitude";
5
- import { clarityBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/clarity";
6
- import { clearbitAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/clearbit";
7
- import { fathomAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/fathom";
8
3
  import {
9
- googleAnalyticsBootstrapScript,
10
- googleAnalyticsScript,
11
- } from "@heyo-sh/heyo-docs/integrations/analytics/google-analytics";
12
- import {
13
- googleTagManagerBootstrapScript,
14
- googleTagManagerNoScriptUrl,
15
- } from "@heyo-sh/heyo-docs/integrations/analytics/google-tag-manager";
16
- import { heapBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/heap";
17
- import { hotjarBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/hotjar";
18
- import {
19
- logRocketBootstrapScript,
20
- logRocketScript,
21
- } from "@heyo-sh/heyo-docs/integrations/analytics/logrocket";
22
- import {
23
- mixpanelBootstrapScript,
24
- mixpanelScript,
25
- } from "@heyo-sh/heyo-docs/integrations/analytics/mixpanel";
26
- import {
27
- openpanelBootstrapScript,
28
- openpanelScript,
29
- } from "@heyo-sh/heyo-docs/integrations/analytics/openpanel";
30
- import { openReplayBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/openreplay";
31
- import { osanoConsentScript } from "@heyo-sh/heyo-docs/integrations/consent/osano";
32
- import {
33
- transcendConsentScript,
34
- transcendGoogleConsentModeDefaultsScript,
35
- } from "@heyo-sh/heyo-docs/integrations/consent/transcend";
36
- import { pirschAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/pirsch";
37
- import { plausibleAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/plausible";
38
- import {
39
- posthogApiHost,
40
- posthogBootstrapScript,
41
- posthogScript,
42
- } from "@heyo-sh/heyo-docs/integrations/analytics/posthog";
43
- import { rybbitAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/rybbit";
44
- import {
45
- swetrixBootstrapScript,
46
- swetrixScript,
47
- } from "@heyo-sh/heyo-docs/integrations/analytics/swetrix";
48
- import { chaskiqBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/chaskiq";
49
- import { chatwootBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/chatwoot";
50
- import {
51
- frontChatBootstrapScript,
52
- frontChatScript,
53
- } from "@heyo-sh/heyo-docs/integrations/support/front";
54
- import { intercomBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/intercom";
55
- import { papercupsBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/papercups";
56
- import { typebotBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/typebot";
57
- import { umamiAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/umami";
58
- import {
59
- zammadBootstrapScript,
60
- zammadChatScript,
61
- } from "@heyo-sh/heyo-docs/integrations/support/zammad";
62
- import "../styles/app.css";
4
+ DEFAULT_THEME_STORAGE_KEY,
5
+ themeBootstrapScript,
6
+ } from "@heyo-sh/heyo-docs/theme/script";
7
+ import { IntegrationScripts } from "@heyo-sh/heyo-docs/integrations";
8
+ import { serializeJsonLd } from "@heyo-sh/heyo-docs/seo";
63
9
  import "virtual:heyo-docs-theme.css";
64
- import { getThemeScript, THEME_STORAGE_KEY } from "../lib/theme";
10
+ import "../styles/app.css";
65
11
 
66
12
  interface Props {
67
13
  title: string;
@@ -78,131 +24,16 @@ const {
78
24
  robots = "index, follow",
79
25
  structuredData,
80
26
  } = Astro.props;
81
- const jsonLd = JSON.stringify(structuredData).replace(/</g, "\\u003c");
27
+ const jsonLd = serializeJsonLd(structuredData);
82
28
  const hasChangelog = config.groups.some((group) => group.type === "changelog");
83
- const osano = config.integrations.consent.osano
84
- ? osanoConsentScript(config.integrations.consent.osano)
85
- : undefined;
86
- const transcend = config.integrations.consent.transcend
87
- ? transcendConsentScript(config.integrations.consent.transcend)
88
- : undefined;
89
- const transcendGoogleConsentDefaults =
90
- transcend &&
91
- (config.integrations.analytics.ga4 || config.integrations.analytics.gtm)
92
- ? transcendGoogleConsentModeDefaultsScript()
93
- : undefined;
94
- const adobe = config.integrations.analytics.adobe
95
- ? adobeAnalyticsScript(config.integrations.analytics.adobe)
96
- : undefined;
97
- const amplitude = config.integrations.analytics.amplitude
98
- ? amplitudeAnalyticsScript(config.integrations.analytics.amplitude)
99
- : undefined;
100
- const clarity = config.integrations.analytics.clarity
101
- ? clarityBootstrapScript()
102
- : undefined;
103
- const clearbit = config.integrations.analytics.clearbit
104
- ? clearbitAnalyticsScript(config.integrations.analytics.clearbit)
105
- : undefined;
106
- const fathom = config.integrations.analytics.fathom
107
- ? fathomAnalyticsScript(config.integrations.analytics.fathom)
108
- : undefined;
109
- const googleAnalytics = config.integrations.analytics.ga4
110
- ? googleAnalyticsScript(config.integrations.analytics.ga4)
111
- : undefined;
112
- const googleAnalyticsBootstrap = googleAnalytics
113
- ? googleAnalyticsBootstrapScript()
114
- : undefined;
115
- const googleTagManager = config.integrations.analytics.gtm
116
- ? googleTagManagerBootstrapScript()
117
- : undefined;
118
- const googleTagManagerNoScript = config.integrations.analytics.gtm
119
- ? googleTagManagerNoScriptUrl(config.integrations.analytics.gtm)
120
- : undefined;
121
- const heap = config.integrations.analytics.heap
122
- ? heapBootstrapScript()
123
- : undefined;
124
- const hotjar = config.integrations.analytics.hotjar
125
- ? hotjarBootstrapScript()
126
- : undefined;
127
- const logRocket = config.integrations.analytics.logrocket
128
- ? logRocketScript()
129
- : undefined;
130
- const logRocketBootstrap = logRocket ? logRocketBootstrapScript() : undefined;
131
- const mixpanel = config.integrations.analytics.mixpanel
132
- ? mixpanelScript()
133
- : undefined;
134
- const mixpanelBootstrap = mixpanel ? mixpanelBootstrapScript() : undefined;
135
- const openpanel = config.integrations.analytics.openpanel
136
- ? openpanelScript()
137
- : undefined;
138
- const openpanelBootstrap = openpanel ? openpanelBootstrapScript() : undefined;
139
- const openReplay = config.integrations.analytics.openreplay
140
- ? openReplayBootstrapScript()
141
- : undefined;
142
- const pirsch = config.integrations.analytics.pirsch
143
- ? pirschAnalyticsScript(config.integrations.analytics.pirsch)
144
- : undefined;
145
- const plausible = config.integrations.analytics.plausible
146
- ? plausibleAnalyticsScript(config.integrations.analytics.plausible)
147
- : undefined;
148
- const posthog = config.integrations.analytics.posthog
149
- ? posthogScript(config.integrations.analytics.posthog)
150
- : undefined;
151
- const posthogBootstrap = posthog ? posthogBootstrapScript() : undefined;
152
- const posthogHost = config.integrations.analytics.posthog
153
- ? posthogApiHost(config.integrations.analytics.posthog)
154
- : undefined;
155
- const rybbit = config.integrations.analytics.rybbit
156
- ? rybbitAnalyticsScript(config.integrations.analytics.rybbit)
157
- : undefined;
158
- const swetrix = config.integrations.analytics.swetrix
159
- ? swetrixScript()
160
- : undefined;
161
- const swetrixBootstrap = swetrix ? swetrixBootstrapScript() : undefined;
162
- const umami = config.integrations.analytics.umami
163
- ? umamiAnalyticsScript(config.integrations.analytics.umami)
164
- : undefined;
165
- const intercom = config.integrations.support.intercom
166
- ? intercomBootstrapScript()
167
- : undefined;
168
- const front = config.integrations.support.front ? frontChatScript() : undefined;
169
- const frontBootstrap = front ? frontChatBootstrapScript() : undefined;
170
- const chatwoot = config.integrations.support.chatwoot
171
- ? chatwootBootstrapScript()
172
- : undefined;
173
- const chaskiq = config.integrations.support.chaskiq
174
- ? chaskiqBootstrapScript()
175
- : undefined;
176
- const papercups = config.integrations.support.papercups
177
- ? papercupsBootstrapScript()
178
- : undefined;
179
- const typebot = config.integrations.support.typebot
180
- ? typebotBootstrapScript()
181
- : undefined;
182
- const zammad = config.integrations.support.zammad
183
- ? zammadChatScript(config.integrations.support.zammad)
184
- : undefined;
185
- const zammadBootstrap = zammad ? zammadBootstrapScript() : undefined;
186
29
  ---
187
30
 
188
31
  <!doctype html>
189
32
  <html lang="en">
190
33
  <head>
191
- {transcendGoogleConsentDefaults && (
192
- <script is:inline set:html={transcendGoogleConsentDefaults}></script>
193
- )}
194
- {transcend && (
195
- <script
196
- is:inline
197
- data-cfasync={transcend.dataCfasync}
198
- src={transcend.src}
199
- ></script>
200
- )}
201
34
  <meta charset="utf-8" />
202
35
  <meta name="viewport" content="width=device-width, initial-scale=1" />
203
- <meta name="color-scheme" content="light dark" />
204
36
  <meta name="robots" content={robots} />
205
- <meta name="referrer" content="strict-origin-when-cross-origin" />
206
37
  <title>{title}</title>
207
38
  <meta name="description" content={description} />
208
39
  <meta property="og:type" content="article" />
@@ -227,272 +58,15 @@ const zammadBootstrap = zammad ? zammadBootstrapScript() : undefined;
227
58
  title={`${config.title} updates`}
228
59
  />
229
60
  )}
230
- {osano && <script is:inline src={osano.src}></script>}
231
- {googleTagManager && (
232
- <script
233
- is:inline
234
- data-google-tag-manager-container-id={
235
- config.integrations.analytics.gtm?.containerId
236
- }
237
- set:html={googleTagManager}
238
- ></script>
239
- )}
240
61
  <script
241
62
  is:inline
242
- set:html={getThemeScript(THEME_STORAGE_KEY, config.mode)}
63
+ set:html={themeBootstrapScript(DEFAULT_THEME_STORAGE_KEY, config.mode)}
243
64
  ></script>
244
- {adobe && <script is:inline async src={adobe.src}></script>}
245
- {amplitude && <script is:inline src={amplitude.src}></script>}
246
- {clarity && (
247
- <script
248
- is:inline
249
- data-clarity-project-id={
250
- config.integrations.analytics.clarity?.projectId
251
- }
252
- set:html={clarity}
253
- ></script>
254
- )}
255
- {clearbit && <script is:inline src={clearbit.src}></script>}
256
- {fathom && (
257
- <script
258
- is:inline
259
- data-site={fathom.siteId}
260
- data-spa={fathom.spa}
261
- defer={fathom.defer}
262
- src={fathom.src}
263
- ></script>
264
- )}
265
- {googleAnalytics && googleAnalyticsBootstrap && (
266
- <>
267
- <script
268
- is:inline
269
- async={googleAnalytics.async}
270
- src={googleAnalytics.src}
271
- ></script>
272
- <script
273
- is:inline
274
- data-google-analytics-measurement-id={
275
- config.integrations.analytics.ga4?.measurementId
276
- }
277
- set:html={googleAnalyticsBootstrap}
278
- ></script>
279
- </>
280
- )}
281
- {heap && (
282
- <script
283
- is:inline
284
- data-heap-environment-id={
285
- config.integrations.analytics.heap?.environmentId
286
- }
287
- set:html={heap}
288
- ></script>
289
- )}
290
- {hotjar && (
291
- <script
292
- is:inline
293
- data-hotjar-site-id={config.integrations.analytics.hotjar?.siteId}
294
- data-hotjar-snippet-version={
295
- config.integrations.analytics.hotjar?.snippetVersion
296
- }
297
- set:html={hotjar}
298
- ></script>
299
- )}
300
- {logRocket && logRocketBootstrap && (
301
- <>
302
- <script
303
- is:inline
304
- crossorigin={logRocket.crossOrigin}
305
- src={logRocket.src}
306
- ></script>
307
- <script
308
- is:inline
309
- data-logrocket-app-id={config.integrations.analytics.logrocket?.appId}
310
- set:html={logRocketBootstrap}
311
- ></script>
312
- </>
313
- )}
314
- {mixpanel && mixpanelBootstrap && (
315
- <>
316
- <script is:inline src={mixpanel.src}></script>
317
- <script
318
- is:inline
319
- data-mixpanel-project-token={
320
- config.integrations.analytics.mixpanel?.projectToken
321
- }
322
- set:html={mixpanelBootstrap}
323
- ></script>
324
- </>
325
- )}
326
- {openpanel && openpanelBootstrap && (
327
- <>
328
- <script
329
- is:inline
330
- data-openpanel-api-url={
331
- config.integrations.analytics.openpanel?.apiUrl
332
- }
333
- data-openpanel-client-id={
334
- config.integrations.analytics.openpanel?.clientId
335
- }
336
- set:html={openpanelBootstrap}
337
- ></script>
338
- <script
339
- is:inline
340
- async={openpanel.async}
341
- defer={openpanel.defer}
342
- src={openpanel.src}
343
- ></script>
344
- </>
345
- )}
346
- {openReplay && (
347
- <script
348
- is:inline
349
- data-openreplay-ingest-point={
350
- config.integrations.analytics.openreplay?.ingestPoint
351
- }
352
- data-openreplay-project-key={
353
- config.integrations.analytics.openreplay?.projectKey
354
- }
355
- set:html={openReplay}
356
- ></script>
357
- )}
358
- {pirsch && (
359
- <script
360
- is:inline
361
- data-code={pirsch.code}
362
- defer={pirsch.defer}
363
- src={pirsch.src}
364
- ></script>
365
- )}
366
- {plausible && (
367
- <script
368
- is:inline
369
- data-domain={plausible.domain}
370
- defer={plausible.defer}
371
- src={plausible.src}
372
- ></script>
373
- )}
374
- {posthog && posthogBootstrap && posthogHost && (
375
- <>
376
- <script is:inline src={posthog.src}></script>
377
- <script
378
- is:inline
379
- data-posthog-api-host={posthogHost}
380
- data-posthog-project-api-key={
381
- config.integrations.analytics.posthog?.projectApiKey
382
- }
383
- set:html={posthogBootstrap}
384
- ></script>
385
- </>
386
- )}
387
- {rybbit && (
388
- <script
389
- is:inline
390
- data-site-id={rybbit.siteId}
391
- defer={rybbit.defer}
392
- src={rybbit.src}
393
- ></script>
394
- )}
395
- {umami && (
396
- <script
397
- is:inline
398
- data-website-id={umami.websiteId}
399
- defer={umami.defer}
400
- src={umami.src}
401
- ></script>
402
- )}
403
- {chaskiq && (
404
- <script
405
- is:inline
406
- data-chaskiq-app-id={config.integrations.support.chaskiq?.appId}
407
- data-chaskiq-base-url={config.integrations.support.chaskiq?.baseUrl}
408
- data-chaskiq-ws-url={config.integrations.support.chaskiq?.wsUrl}
409
- set:html={chaskiq}
410
- ></script>
411
- )}
412
- {papercups && (
413
- <script
414
- is:inline
415
- data-papercups-base-url={config.integrations.support.papercups?.baseUrl}
416
- data-papercups-inbox={config.integrations.support.papercups?.inbox}
417
- data-papercups-token={config.integrations.support.papercups?.token}
418
- set:html={papercups}
419
- ></script>
420
- )}
421
- {typebot && (
422
- <script
423
- is:inline
424
- data-heyo-typebot
425
- data-typebot-api-host={config.integrations.support.typebot?.apiHost}
426
- data-typebot-id={config.integrations.support.typebot?.typebot}
427
- set:html={typebot}
428
- type="module"
429
- ></script>
430
- )}
65
+ <IntegrationScripts integrations={config.integrations} placement="head" />
431
66
  <script is:inline type="application/ld+json" set:html={jsonLd}></script>
432
67
  </head>
433
68
  <body>
434
- {googleTagManagerNoScript && (
435
- <noscript>
436
- <iframe
437
- height="0"
438
- src={googleTagManagerNoScript}
439
- style="display:none;visibility:hidden"
440
- title="Google Tag Manager"
441
- width="0"
442
- ></iframe>
443
- </noscript>
444
- )}
445
69
  <slot />
446
- {swetrix && swetrixBootstrap && (
447
- <>
448
- <script is:inline defer={swetrix.defer} src={swetrix.src}></script>
449
- <script
450
- is:inline
451
- data-swetrix-api-url={config.integrations.analytics.swetrix?.apiUrl}
452
- data-swetrix-project-id={
453
- config.integrations.analytics.swetrix?.projectId
454
- }
455
- set:html={swetrixBootstrap}
456
- ></script>
457
- </>
458
- )}
459
- {intercom && (
460
- <script
461
- is:inline
462
- data-intercom-app-id={config.integrations.support.intercom?.appId}
463
- data-intercom-api-base={config.integrations.support.intercom?.apiBase}
464
- set:html={intercom}
465
- ></script>
466
- )}
467
- {front && frontBootstrap && (
468
- <>
469
- <script is:inline src={front.src}></script>
470
- <script
471
- is:inline
472
- data-front-chat-id={config.integrations.support.front?.chatId}
473
- set:html={frontBootstrap}
474
- ></script>
475
- </>
476
- )}
477
- {chatwoot && (
478
- <script
479
- is:inline
480
- data-chatwoot-base-url={config.integrations.support.chatwoot?.baseUrl}
481
- data-chatwoot-website-token={
482
- config.integrations.support.chatwoot?.websiteToken
483
- }
484
- set:html={chatwoot}
485
- ></script>
486
- )}
487
- {zammad && zammadBootstrap && (
488
- <>
489
- <script is:inline src={zammad.src}></script>
490
- <script
491
- is:inline
492
- data-zammad-chat-id={config.integrations.support.zammad?.chatId}
493
- set:html={zammadBootstrap}
494
- ></script>
495
- </>
496
- )}
70
+ <IntegrationScripts integrations={config.integrations} placement="body" />
497
71
  </body>
498
72
  </html>
@@ -1,10 +1,10 @@
1
1
  import {
2
- changelogGroupForPage,
3
2
  createDocsModel,
4
3
  findDocsPage,
5
4
  findOpenApiEndpoint,
6
5
  normaliseDocsPathname,
7
- } from "@heyo-sh/heyo-docs";
6
+ } from "@heyo-sh/heyo-docs/model";
7
+ import { changelogGroupForPage } from "@heyo-sh/heyo-docs/navigation";
8
8
 
9
9
  import config from "../../heyo-docs.config";
10
10
  import { openApiDocuments } from "virtual:heyo-docs-openapi";
@@ -22,6 +22,7 @@ export function docsContext(pathname: string) {
22
22
  return {
23
23
  config,
24
24
  model,
25
+ navigation: model.navigation,
25
26
  page,
26
27
  endpoint,
27
28
  changelogGroup: page
@@ -1,160 +1,20 @@
1
- import {
2
- createDocsModel,
3
- findOpenApiEndpoint,
4
- type OpenApiEndpoint,
5
- } from "@heyo-sh/heyo-docs";
1
+ import { createDocsModel } from "@heyo-sh/heyo-docs/model";
2
+ import { handleOpenApiRequest as forwardOpenApiRequest } from "@heyo-sh/heyo-docs/openapi/request";
6
3
 
7
4
  import config from "../../heyo-docs.config";
8
5
  import { openApiDocuments } from "virtual:heyo-docs-openapi";
9
6
  import { pages } from "virtual:heyo-docs-content";
10
7
 
11
- interface OpenApiRequestPayload {
12
- bearerToken: string;
13
- body?: string;
14
- endpointSlug: string;
15
- parameters: Record<string, string>;
16
- server: string;
17
- }
18
-
19
- /**
20
- * Sends documented API calls from the server, so browsers do not need the API
21
- * to expose CORS headers. Targets are limited to servers from the OpenAPI file.
22
- */
23
8
  export async function handleOpenApiRequest(
24
9
  request: Request,
25
10
  ): Promise<Response> {
26
11
  if (request.method !== "POST")
27
12
  return new Response("Method Not Allowed", {
28
- headers: { Allow: "POST" },
29
13
  status: 405,
14
+ headers: { Allow: "POST" },
30
15
  });
31
-
32
- const payload = await requestPayload(request);
33
- if (!payload)
34
- return new Response("Invalid OpenAPI request.", { status: 400 });
35
-
36
- const model = createDocsModel(config, pages, openApiDocuments);
37
- const endpoint = findOpenApiEndpoint(model.endpoints, payload.endpointSlug);
38
- if (!endpoint) return new Response("Endpoint not found.", { status: 404 });
39
- if (endpoint.servers.length && !endpoint.servers.includes(payload.server))
40
- return new Response("API server is not declared in the OpenAPI schema.", {
41
- status: 400,
42
- });
43
- if (!endpoint.servers.length && payload.server)
44
- return new Response("This endpoint does not declare an API server.", {
45
- status: 400,
46
- });
47
-
48
- const headers = requestHeaders(
49
- endpoint,
50
- payload.parameters,
51
- payload.bearerToken,
52
- );
53
- const url = requestUrl(
54
- endpoint,
55
- payload.server,
56
- payload.parameters,
57
- request.url,
58
- );
59
-
60
- try {
61
- const response = await fetch(url, {
62
- method: endpoint.method.toUpperCase(),
63
- headers,
64
- body: payload.body,
65
- });
66
- const responseHeaders = new Headers();
67
- const contentType = response.headers.get("content-type");
68
- if (contentType) responseHeaders.set("content-type", contentType);
69
- const body = [204, 205, 304].includes(response.status)
70
- ? null
71
- : await response.arrayBuffer();
72
- return new Response(body, {
73
- headers: responseHeaders,
74
- status: response.status,
75
- statusText: response.statusText,
76
- });
77
- } catch {
78
- return new Response("The API server could not be reached.", {
79
- status: 502,
80
- });
81
- }
82
- }
83
-
84
- async function requestPayload(
85
- request: Request,
86
- ): Promise<OpenApiRequestPayload | undefined> {
87
- try {
88
- const value: unknown = await request.json();
89
- if (!isRecord(value)) return undefined;
90
- const endpointSlug = stringValue(value.endpointSlug);
91
- const server = stringValue(value.server);
92
- if (!endpointSlug || server === undefined) return undefined;
93
- return {
94
- bearerToken: stringValue(value.bearerToken) ?? "",
95
- body: stringValue(value.body),
96
- endpointSlug,
97
- parameters: stringRecord(value.parameters),
98
- server,
99
- };
100
- } catch {
101
- return undefined;
102
- }
103
- }
104
-
105
- function requestUrl(
106
- endpoint: OpenApiEndpoint,
107
- server: string,
108
- parameters: Record<string, string>,
109
- requestUrl: string,
110
- ) {
111
- let path = endpoint.path.replace(/\{([^}]+)\}/g, (match, name: string) => {
112
- const value = parameters[`path:${name}`];
113
- return value ? encodeURIComponent(value) : match;
114
- });
115
- const query = new URLSearchParams();
116
- for (const parameter of endpoint.parameters) {
117
- if (parameter.in !== "query") continue;
118
- const value = parameters[`query:${parameter.name}`];
119
- if (value) query.set(parameter.name, value);
120
- }
121
- const search = query.toString();
122
- path = `${path}${search ? `?${search}` : ""}`;
123
- return server
124
- ? `${server.replace(/\/$/, "")}${path}`
125
- : new URL(path, requestUrl).toString();
126
- }
127
-
128
- function requestHeaders(
129
- endpoint: OpenApiEndpoint,
130
- parameters: Record<string, string>,
131
- bearerToken: string,
132
- ) {
133
- const headers = new Headers();
134
- for (const parameter of endpoint.parameters) {
135
- if (parameter.in !== "header") continue;
136
- const value = parameters[`header:${parameter.name}`];
137
- if (value) headers.set(parameter.name, value);
138
- }
139
- if (endpoint.requestBody?.contentType)
140
- headers.set("Content-Type", endpoint.requestBody.contentType);
141
- if (bearerToken) headers.set("Authorization", `Bearer ${bearerToken}`);
142
- return headers;
143
- }
144
-
145
- function isRecord(value: unknown): value is Record<string, unknown> {
146
- return typeof value === "object" && value !== null && !Array.isArray(value);
147
- }
148
-
149
- function stringRecord(value: unknown): Record<string, string> {
150
- if (!isRecord(value)) return {};
151
- return Object.fromEntries(
152
- Object.entries(value).filter(
153
- (entry): entry is [string, string] => typeof entry[1] === "string",
154
- ),
16
+ return forwardOpenApiRequest(
17
+ request,
18
+ createDocsModel(config, pages, openApiDocuments).endpoints,
155
19
  );
156
20
  }
157
-
158
- function stringValue(value: unknown): string | undefined {
159
- return typeof value === "string" ? value : undefined;
160
- }