blodemd 0.0.13 → 0.0.15

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 (136) hide show
  1. package/README.md +1 -1
  2. package/dev-server/lib/local-runtime.tsx +12 -15
  3. package/dev-server/package.json +5 -1
  4. package/dist/cli.mjs +1211 -983
  5. package/dist/cli.mjs.map +1 -1
  6. package/docs/app/globals.css +1 -1
  7. package/docs/components/api/api-playground.tsx +2 -5
  8. package/docs/components/api/api-reference.tsx +29 -3
  9. package/docs/components/docs/contextual-menu.tsx +37 -33
  10. package/docs/components/docs/copy-page-menu.tsx +18 -0
  11. package/docs/components/docs/doc-header.tsx +4 -1
  12. package/docs/components/docs/doc-shell.tsx +48 -18
  13. package/docs/components/docs/doc-sidebar.tsx +131 -89
  14. package/docs/components/docs/doc-toc.tsx +1 -0
  15. package/docs/components/docs/mobile-nav.tsx +72 -68
  16. package/docs/components/docs/sidebar-active-highlight.tsx +34 -0
  17. package/docs/components/docs/sidebar-scroll-area.tsx +9 -4
  18. package/docs/components/git/repo-picker.tsx +5 -2
  19. package/docs/components/mdx/index.tsx +31 -21
  20. package/docs/components/posthog-provider.tsx +42 -0
  21. package/docs/components/tenant-analytics.tsx +49 -0
  22. package/docs/components/third-parties.tsx +4 -1
  23. package/docs/components/ui/copy-button.tsx +16 -2
  24. package/docs/components/ui/search-dialog.tsx +431 -0
  25. package/docs/components/ui/search.tsx +44 -427
  26. package/docs/components/web-mcp.tsx +115 -0
  27. package/docs/lib/agent-skills.ts +48 -0
  28. package/docs/lib/config.ts +4 -5
  29. package/docs/lib/docs-collection.ts +7 -22
  30. package/docs/lib/docs-runtime.tsx +160 -10
  31. package/docs/lib/llms-full.ts +82 -0
  32. package/docs/lib/marketing-markdown.ts +79 -0
  33. package/docs/lib/marketing-site.ts +31 -0
  34. package/docs/lib/mdx.ts +17 -6
  35. package/docs/lib/routes.ts +19 -3
  36. package/docs/lib/shiki.ts +4 -0
  37. package/docs/lib/tenancy.ts +15 -2
  38. package/docs/lib/tenant-headers.ts +29 -0
  39. package/docs/lib/tenant-static.ts +73 -99
  40. package/package.json +8 -5
  41. package/packages/@repo/common/package.json +1 -1
  42. package/packages/@repo/contracts/dist/analytics.d.ts +21 -0
  43. package/packages/@repo/contracts/dist/analytics.d.ts.map +1 -0
  44. package/packages/@repo/contracts/dist/analytics.js +18 -0
  45. package/packages/@repo/contracts/dist/deployment.js +1 -1
  46. package/packages/@repo/contracts/dist/git.js +2 -2
  47. package/packages/@repo/contracts/dist/ids.d.ts.map +1 -1
  48. package/packages/@repo/contracts/dist/ids.js +2 -1
  49. package/packages/@repo/contracts/dist/index.d.ts +1 -0
  50. package/packages/@repo/contracts/dist/index.d.ts.map +1 -1
  51. package/packages/@repo/contracts/dist/index.js +1 -0
  52. package/packages/@repo/contracts/dist/project.d.ts +18 -1
  53. package/packages/@repo/contracts/dist/project.d.ts.map +1 -1
  54. package/packages/@repo/contracts/dist/project.js +3 -1
  55. package/packages/@repo/contracts/dist/tenant.d.ts +36 -0
  56. package/packages/@repo/contracts/dist/tenant.d.ts.map +1 -1
  57. package/packages/@repo/contracts/dist/tenant.js +2 -0
  58. package/packages/@repo/contracts/package.json +1 -1
  59. package/packages/@repo/contracts/src/analytics.ts +33 -0
  60. package/packages/@repo/contracts/src/deployment.ts +1 -1
  61. package/packages/@repo/contracts/src/git.ts +2 -2
  62. package/packages/@repo/contracts/src/ids.ts +2 -1
  63. package/packages/@repo/contracts/src/index.ts +1 -0
  64. package/packages/@repo/contracts/src/project.ts +3 -1
  65. package/packages/@repo/contracts/src/tenant.ts +2 -0
  66. package/packages/@repo/models/dist/docs-config.d.ts +0 -198
  67. package/packages/@repo/models/dist/docs-config.d.ts.map +1 -1
  68. package/packages/@repo/models/dist/docs-config.js +3 -2
  69. package/packages/@repo/models/dist/tenant.d.ts +12 -0
  70. package/packages/@repo/models/dist/tenant.d.ts.map +1 -1
  71. package/packages/@repo/models/package.json +1 -1
  72. package/packages/@repo/models/src/docs-config.ts +3 -3
  73. package/packages/@repo/models/src/tenant.ts +15 -0
  74. package/packages/@repo/prebuild/dist/openapi.d.ts.map +1 -1
  75. package/packages/@repo/prebuild/dist/openapi.js +32 -4
  76. package/packages/@repo/prebuild/package.json +1 -1
  77. package/packages/@repo/prebuild/src/openapi.ts +42 -4
  78. package/packages/@repo/previewing/dist/blob-source.d.ts.map +1 -1
  79. package/packages/@repo/previewing/dist/blob-source.js +18 -5
  80. package/packages/@repo/previewing/dist/config-loader.d.ts +134 -0
  81. package/packages/@repo/previewing/dist/config-loader.d.ts.map +1 -0
  82. package/packages/@repo/previewing/dist/config-loader.js +231 -0
  83. package/packages/@repo/previewing/dist/constants.d.ts +15 -0
  84. package/packages/@repo/previewing/dist/constants.d.ts.map +1 -0
  85. package/packages/@repo/previewing/dist/constants.js +14 -0
  86. package/packages/@repo/previewing/dist/content-index.d.ts +7 -0
  87. package/packages/@repo/previewing/dist/content-index.d.ts.map +1 -0
  88. package/packages/@repo/previewing/dist/content-index.js +291 -0
  89. package/packages/@repo/previewing/dist/index.d.ts +13 -121
  90. package/packages/@repo/previewing/dist/index.d.ts.map +1 -1
  91. package/packages/@repo/previewing/dist/index.js +11 -1003
  92. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +3 -0
  93. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +1 -0
  94. package/packages/@repo/previewing/dist/markdown/agent-markdown.js +176 -0
  95. package/packages/@repo/previewing/dist/markdown/format.d.ts +8 -0
  96. package/packages/@repo/previewing/dist/markdown/format.d.ts.map +1 -0
  97. package/packages/@repo/previewing/dist/markdown/format.js +43 -0
  98. package/packages/@repo/previewing/dist/markdown/links.d.ts +3 -0
  99. package/packages/@repo/previewing/dist/markdown/links.d.ts.map +1 -0
  100. package/packages/@repo/previewing/dist/markdown/links.js +31 -0
  101. package/packages/@repo/previewing/dist/openapi-pages.d.ts +7 -0
  102. package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +1 -0
  103. package/packages/@repo/previewing/dist/openapi-pages.js +200 -0
  104. package/packages/@repo/previewing/dist/search-index.d.ts +4 -0
  105. package/packages/@repo/previewing/dist/search-index.d.ts.map +1 -0
  106. package/packages/@repo/previewing/dist/search-index.js +23 -0
  107. package/packages/@repo/previewing/dist/serialization.d.ts +13 -0
  108. package/packages/@repo/previewing/dist/serialization.d.ts.map +1 -0
  109. package/packages/@repo/previewing/dist/serialization.js +108 -0
  110. package/packages/@repo/previewing/dist/toc-index.d.ts +5 -0
  111. package/packages/@repo/previewing/dist/toc-index.d.ts.map +1 -0
  112. package/packages/@repo/previewing/dist/toc-index.js +53 -0
  113. package/packages/@repo/previewing/dist/types.d.ts +92 -0
  114. package/packages/@repo/previewing/dist/types.d.ts.map +1 -0
  115. package/packages/@repo/previewing/dist/types.js +1 -0
  116. package/packages/@repo/previewing/dist/utility-index.d.ts +7 -0
  117. package/packages/@repo/previewing/dist/utility-index.d.ts.map +1 -0
  118. package/packages/@repo/previewing/dist/utility-index.js +201 -0
  119. package/packages/@repo/previewing/package.json +1 -1
  120. package/packages/@repo/previewing/src/blob-source.ts +20 -5
  121. package/packages/@repo/previewing/src/config-loader.ts +316 -0
  122. package/packages/@repo/previewing/src/constants.ts +16 -0
  123. package/packages/@repo/previewing/src/content-index.ts +384 -0
  124. package/packages/@repo/previewing/src/index.ts +69 -1515
  125. package/packages/@repo/previewing/src/markdown/agent-markdown.ts +254 -0
  126. package/packages/@repo/previewing/src/markdown/format.ts +63 -0
  127. package/packages/@repo/previewing/src/markdown/links.ts +46 -0
  128. package/packages/@repo/previewing/src/openapi-pages.ts +319 -0
  129. package/packages/@repo/previewing/src/search-index.ts +38 -0
  130. package/packages/@repo/previewing/src/serialization.ts +191 -0
  131. package/packages/@repo/previewing/src/toc-index.ts +72 -0
  132. package/packages/@repo/previewing/src/types.ts +105 -0
  133. package/packages/@repo/previewing/src/utility-index.ts +304 -0
  134. package/packages/@repo/validation/package.json +1 -1
  135. package/scripts/repo-packages.mjs +8 -0
  136. package/docs/components/ui/site-footer.tsx +0 -41
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+
3
+ const GA4_MEASUREMENT_ID_REGEX = /^G-[A-Z0-9]{4,20}$/;
4
+ const POSTHOG_PROJECT_KEY_REGEX = /^phc_[A-Za-z0-9]{20,}$/;
5
+
6
+ export const ProjectAnalyticsGa4Schema = z.object({
7
+ measurementId: z
8
+ .string()
9
+ .regex(
10
+ GA4_MEASUREMENT_ID_REGEX,
11
+ "GA4 measurement IDs look like G-XXXXXXXXXX."
12
+ ),
13
+ });
14
+ export type ProjectAnalyticsGa4 = z.infer<typeof ProjectAnalyticsGa4Schema>;
15
+
16
+ export const ProjectAnalyticsPosthogSchema = z.object({
17
+ host: z.string().url().optional(),
18
+ projectKey: z
19
+ .string()
20
+ .regex(
21
+ POSTHOG_PROJECT_KEY_REGEX,
22
+ "PostHog project keys start with phc_. Personal API keys (phx_) are not supported."
23
+ ),
24
+ });
25
+ export type ProjectAnalyticsPosthog = z.infer<
26
+ typeof ProjectAnalyticsPosthogSchema
27
+ >;
28
+
29
+ export const ProjectAnalyticsSchema = z.object({
30
+ ga4: ProjectAnalyticsGa4Schema.optional(),
31
+ posthog: ProjectAnalyticsPosthogSchema.optional(),
32
+ });
33
+ export type ProjectAnalytics = z.infer<typeof ProjectAnalyticsSchema>;
@@ -42,7 +42,7 @@ export type PublishDeploymentCreateInput = z.infer<
42
42
  >;
43
43
 
44
44
  export const PublishDeploymentFileSchema = z.object({
45
- contentBase64: z.string().min(1),
45
+ contentBase64: z.string().base64(),
46
46
  contentType: z.string().min(1).optional(),
47
47
  path: z.string().min(1),
48
48
  });
@@ -12,7 +12,7 @@ export const GitConnectionSchema = z.object({
12
12
  createdAt: IsoDateSchema,
13
13
  docsPath: z.string().min(1),
14
14
  id: IdSchema,
15
- installationId: z.number().int().positive(),
15
+ installationId: z.number().int().positive().safe(),
16
16
  projectId: IdSchema,
17
17
  provider: GitProviderSchema,
18
18
  repository: z.string().min(1),
@@ -23,7 +23,7 @@ export type GitConnection = z.infer<typeof GitConnectionSchema>;
23
23
  export const GitConnectionBindSchema = z.object({
24
24
  branch: z.string().min(1).default("main"),
25
25
  docsPath: z.string().min(1).default("docs"),
26
- installationId: z.number().int().positive(),
26
+ installationId: z.number().int().positive().safe(),
27
27
  repository: z.string().regex(/^[\w.-]+\/[\w.-]+$/, {
28
28
  message: "Repository must be in the format owner/repo.",
29
29
  }),
@@ -6,7 +6,8 @@ export type Id = z.infer<typeof IdSchema>;
6
6
  export const SlugSchema = z
7
7
  .string()
8
8
  .min(1)
9
- .regex(/^[a-z0-9-]+$/);
9
+ .max(63)
10
+ .regex(/^(?!-)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/);
10
11
  export type Slug = z.infer<typeof SlugSchema>;
11
12
 
12
13
  export const EmailSchema = z.string().email();
@@ -1,5 +1,6 @@
1
1
  // biome-ignore lint/performance/noBarrelFile: This is the main entry point for the package
2
2
  // eslint-disable-next-line no-barrel-file
3
+ export * from "./analytics.js";
3
4
  export * from "./dates.js";
4
5
  export * from "./deployment.js";
5
6
  export * from "./domain.js";
@@ -1,9 +1,11 @@
1
1
  import { z } from "zod";
2
2
 
3
+ import { ProjectAnalyticsSchema } from "./analytics.js";
3
4
  import { IsoDateSchema } from "./dates.js";
4
5
  import { IdSchema, SlugSchema } from "./ids.js";
5
6
 
6
7
  export const ProjectSchema = z.object({
8
+ analytics: ProjectAnalyticsSchema.nullable().optional(),
7
9
  createdAt: IsoDateSchema,
8
10
  deploymentName: z.string().min(1),
9
11
  description: z.string().optional(),
@@ -15,7 +17,6 @@ export const ProjectSchema = z.object({
15
17
  export type Project = z.infer<typeof ProjectSchema>;
16
18
 
17
19
  export const ProjectCreateSchema = z.object({
18
- deploymentName: z.string().min(1),
19
20
  description: z.string().optional(),
20
21
  name: z.string().min(1),
21
22
  slug: SlugSchema,
@@ -23,6 +24,7 @@ export const ProjectCreateSchema = z.object({
23
24
  export type ProjectCreateInput = z.infer<typeof ProjectCreateSchema>;
24
25
 
25
26
  export const ProjectUpdateSchema = z.object({
27
+ analytics: ProjectAnalyticsSchema.nullable().optional(),
26
28
  deploymentName: z.string().min(1).optional(),
27
29
  description: z.string().nullable().optional(),
28
30
  name: z.string().min(1).optional(),
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
 
3
+ import { ProjectAnalyticsSchema } from "./analytics.js";
3
4
  import {
4
5
  HostnameSchema,
5
6
  IdSchema,
@@ -14,6 +15,7 @@ export type TenantStatus = z.infer<typeof TenantStatusSchema>;
14
15
  export const TenantSchema = z.object({
15
16
  activeDeploymentId: IdSchema.optional(),
16
17
  activeDeploymentManifestUrl: UrlSchema.optional(),
18
+ analytics: ProjectAnalyticsSchema.optional(),
17
19
  customDomains: z.array(HostnameSchema),
18
20
  description: z.string().optional(),
19
21
  id: IdSchema,
@@ -450,204 +450,6 @@ export declare const DocsConfigSchema: z.ZodObject<{
450
450
  slug: z.ZodOptional<z.ZodString>;
451
451
  }, z.core.$strict>;
452
452
  export type DocsConfig = z.infer<typeof DocsConfigSchema>;
453
- export declare const MintlifyDocsConfigSchema: z.ZodObject<{
454
- $schema: z.ZodOptional<z.ZodString>;
455
- api: z.ZodOptional<z.ZodObject<{
456
- asyncapi: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
457
- basePath: z.ZodOptional<z.ZodString>;
458
- directory: z.ZodOptional<z.ZodString>;
459
- include: z.ZodOptional<z.ZodArray<z.ZodString>>;
460
- source: z.ZodString;
461
- }, z.core.$strict>]>>;
462
- examples: z.ZodOptional<z.ZodObject<{
463
- autogenerate: z.ZodOptional<z.ZodBoolean>;
464
- defaults: z.ZodOptional<z.ZodEnum<{
465
- all: "all";
466
- required: "required";
467
- }>>;
468
- languages: z.ZodOptional<z.ZodArray<z.ZodString>>;
469
- prefill: z.ZodOptional<z.ZodBoolean>;
470
- }, z.core.$strict>>;
471
- mdx: z.ZodOptional<z.ZodObject<{
472
- auth: z.ZodOptional<z.ZodObject<{
473
- method: z.ZodOptional<z.ZodEnum<{
474
- basic: "basic";
475
- bearer: "bearer";
476
- cobo: "cobo";
477
- key: "key";
478
- }>>;
479
- name: z.ZodOptional<z.ZodString>;
480
- }, z.core.$strict>>;
481
- server: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
482
- }, z.core.$strict>>;
483
- openapi: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
484
- basePath: z.ZodOptional<z.ZodString>;
485
- directory: z.ZodOptional<z.ZodString>;
486
- include: z.ZodOptional<z.ZodArray<z.ZodString>>;
487
- source: z.ZodString;
488
- }, z.core.$strict>]>>;
489
- params: z.ZodOptional<z.ZodObject<{
490
- expanded: z.ZodOptional<z.ZodEnum<{
491
- all: "all";
492
- closed: "closed";
493
- }>>;
494
- }, z.core.$strict>>;
495
- playground: z.ZodOptional<z.ZodObject<{
496
- credentials: z.ZodOptional<z.ZodBoolean>;
497
- display: z.ZodOptional<z.ZodEnum<{
498
- auth: "auth";
499
- interactive: "interactive";
500
- none: "none";
501
- simple: "simple";
502
- }>>;
503
- proxy: z.ZodOptional<z.ZodBoolean>;
504
- }, z.core.$strict>>;
505
- url: z.ZodOptional<z.ZodLiteral<"full">>;
506
- }, z.core.$strict>>;
507
- appearance: z.ZodOptional<z.ZodObject<{
508
- default: z.ZodOptional<z.ZodEnum<{
509
- dark: "dark";
510
- light: "light";
511
- system: "system";
512
- }>>;
513
- strict: z.ZodOptional<z.ZodBoolean>;
514
- }, z.core.$strict>>;
515
- contextual: z.ZodOptional<z.ZodObject<{
516
- display: z.ZodOptional<z.ZodEnum<{
517
- toc: "toc";
518
- header: "header";
519
- }>>;
520
- options: z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
521
- "add-mcp": "add-mcp";
522
- aistudio: "aistudio";
523
- assistant: "assistant";
524
- chatgpt: "chatgpt";
525
- claude: "claude";
526
- copy: "copy";
527
- cursor: "cursor";
528
- devin: "devin";
529
- "devin-mcp": "devin-mcp";
530
- gemini: "gemini";
531
- grok: "grok";
532
- mcp: "mcp";
533
- perplexity: "perplexity";
534
- view: "view";
535
- vscode: "vscode";
536
- windsurf: "windsurf";
537
- }>, z.ZodObject<{
538
- description: z.ZodString;
539
- href: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
540
- base: z.ZodString;
541
- query: z.ZodArray<z.ZodObject<{
542
- key: z.ZodString;
543
- value: z.ZodString;
544
- }, z.core.$strict>>;
545
- }, z.core.$strict>]>;
546
- icon: z.ZodString;
547
- iconType: z.ZodOptional<z.ZodString>;
548
- title: z.ZodString;
549
- }, z.core.$strict>]>>;
550
- }, z.core.$strict>>;
551
- description: z.ZodOptional<z.ZodString>;
552
- favicon: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
553
- dark: z.ZodString;
554
- light: z.ZodString;
555
- }, z.core.$strict>]>>;
556
- logo: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
557
- dark: z.ZodString;
558
- href: z.ZodOptional<z.ZodString>;
559
- light: z.ZodString;
560
- }, z.core.$strict>]>>;
561
- metadata: z.ZodOptional<z.ZodObject<{
562
- timestamp: z.ZodOptional<z.ZodBoolean>;
563
- }, z.core.$strict>>;
564
- name: z.ZodString;
565
- navbar: z.ZodOptional<z.ZodObject<{
566
- links: z.ZodOptional<z.ZodArray<z.ZodObject<{
567
- href: z.ZodString;
568
- icon: z.ZodOptional<z.ZodString>;
569
- iconType: z.ZodOptional<z.ZodString>;
570
- label: z.ZodOptional<z.ZodString>;
571
- type: z.ZodOptional<z.ZodEnum<{
572
- discord: "discord";
573
- github: "github";
574
- }>>;
575
- }, z.core.$strict>>>;
576
- primary: z.ZodOptional<z.ZodObject<{
577
- href: z.ZodString;
578
- label: z.ZodOptional<z.ZodString>;
579
- type: z.ZodEnum<{
580
- discord: "discord";
581
- github: "github";
582
- button: "button";
583
- }>;
584
- }, z.core.$strict>>;
585
- }, z.core.$strict>>;
586
- navigation: z.ZodObject<{
587
- global: z.ZodOptional<z.ZodObject<{
588
- anchors: z.ZodOptional<z.ZodArray<z.ZodObject<{
589
- anchor: z.ZodString;
590
- color: z.ZodOptional<z.ZodObject<{
591
- dark: z.ZodOptional<z.ZodString>;
592
- light: z.ZodOptional<z.ZodString>;
593
- }, z.core.$strict>>;
594
- hidden: z.ZodOptional<z.ZodBoolean>;
595
- href: z.ZodString;
596
- icon: z.ZodOptional<z.ZodString>;
597
- iconType: z.ZodOptional<z.ZodString>;
598
- }, z.core.$strict>>>;
599
- }, z.core.$strict>>;
600
- groups: z.ZodOptional<z.ZodArray<z.ZodObject<{
601
- expanded: z.ZodOptional<z.ZodBoolean>;
602
- group: z.ZodString;
603
- hidden: z.ZodOptional<z.ZodBoolean>;
604
- icon: z.ZodOptional<z.ZodString>;
605
- pages: z.ZodOptional<z.ZodArray<z.ZodString>>;
606
- root: z.ZodOptional<z.ZodString>;
607
- tag: z.ZodOptional<z.ZodString>;
608
- }, z.core.$strict>>>;
609
- languages: z.ZodOptional<z.ZodArray<z.ZodObject<{
610
- default: z.ZodOptional<z.ZodBoolean>;
611
- hidden: z.ZodOptional<z.ZodBoolean>;
612
- href: z.ZodString;
613
- language: z.ZodString;
614
- }, z.core.$strict>>>;
615
- pages: z.ZodOptional<z.ZodArray<z.ZodString>>;
616
- tabs: z.ZodOptional<z.ZodArray<z.ZodObject<{
617
- groups: z.ZodOptional<z.ZodArray<z.ZodObject<{
618
- expanded: z.ZodOptional<z.ZodBoolean>;
619
- group: z.ZodString;
620
- hidden: z.ZodOptional<z.ZodBoolean>;
621
- icon: z.ZodOptional<z.ZodString>;
622
- pages: z.ZodOptional<z.ZodArray<z.ZodString>>;
623
- root: z.ZodOptional<z.ZodString>;
624
- tag: z.ZodOptional<z.ZodString>;
625
- }, z.core.$strict>>>;
626
- hidden: z.ZodOptional<z.ZodBoolean>;
627
- href: z.ZodOptional<z.ZodString>;
628
- icon: z.ZodOptional<z.ZodString>;
629
- pages: z.ZodOptional<z.ZodArray<z.ZodString>>;
630
- tab: z.ZodString;
631
- }, z.core.$strict>>>;
632
- versions: z.ZodOptional<z.ZodArray<z.ZodObject<{
633
- default: z.ZodOptional<z.ZodBoolean>;
634
- hidden: z.ZodOptional<z.ZodBoolean>;
635
- href: z.ZodString;
636
- version: z.ZodString;
637
- }, z.core.$strict>>>;
638
- }, z.core.$strict>;
639
- search: z.ZodOptional<z.ZodObject<{
640
- prompt: z.ZodOptional<z.ZodString>;
641
- }, z.core.$strict>>;
642
- seo: z.ZodOptional<z.ZodObject<{
643
- indexing: z.ZodOptional<z.ZodEnum<{
644
- default: "default";
645
- all: "all";
646
- }>>;
647
- }, z.core.$strict>>;
648
- slug: z.ZodOptional<z.ZodString>;
649
- }, z.core.$strict>;
650
- export type MintlifyDocsConfig = DocsConfig;
651
453
  export declare const ContentTypeSchema: z.ZodEnum<{
652
454
  site: "site";
653
455
  blog: "blog";
@@ -1 +1 @@
1
- {"version":3,"file":"docs-config.d.ts","sourceRoot":"","sources":["../src/docs-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docs-config.d.ts","sourceRoot":"","sources":["../src/docs-config.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,9 @@ const UrlOrPathSchema = z.string().min(1);
3
3
  const SlugSchema = z
4
4
  .string()
5
5
  .min(1)
6
- .regex(/^[a-z0-9-]+$/);
6
+ // Lowercase alphanumeric segments joined by single hyphens: no leading,
7
+ // trailing, or consecutive hyphens, and never a bare "-".
8
+ .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
7
9
  export const DocsColorsSchema = z
8
10
  .object({
9
11
  background: z.string().optional(),
@@ -378,7 +380,6 @@ export const DocsConfigSchema = z
378
380
  slug: SlugSchema.optional(),
379
381
  })
380
382
  .strict();
381
- export const MintlifyDocsConfigSchema = DocsConfigSchema;
382
383
  export const ContentTypeSchema = z.enum([
383
384
  "site",
384
385
  "blog",
@@ -1,3 +1,14 @@
1
+ export interface TenantAnalyticsGa4 {
2
+ measurementId: string;
3
+ }
4
+ export interface TenantAnalyticsPosthog {
5
+ projectKey: string;
6
+ host?: string;
7
+ }
8
+ export interface TenantAnalytics {
9
+ ga4?: TenantAnalyticsGa4;
10
+ posthog?: TenantAnalyticsPosthog;
11
+ }
1
12
  export interface Tenant {
2
13
  id: string;
3
14
  slug: string;
@@ -5,6 +16,7 @@ export interface Tenant {
5
16
  description?: string;
6
17
  activeDeploymentId?: string;
7
18
  activeDeploymentManifestUrl?: string;
19
+ analytics?: TenantAnalytics;
8
20
  primaryDomain: string;
9
21
  subdomain: string;
10
22
  customDomains: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../src/tenant.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EACF,qBAAqB,GACrB,sBAAsB,GACtB,uBAAuB,CAAC;IAC5B,UAAU,EAAE,YAAY,EAAE,CAAC;CAC5B"}
1
+ {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../src/tenant.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,kBAAkB,CAAC;IACzB,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EACF,qBAAqB,GACrB,sBAAsB,GACtB,uBAAuB,CAAC;IAC5B,UAAU,EAAE,YAAY,EAAE,CAAC;CAC5B"}
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "devDependencies": {
30
30
  "@repo/typescript-config": "*",
31
- "@types/node": "^22.19.15",
31
+ "@types/node": "^24.12.2",
32
32
  "oxfmt": "^0.42.0",
33
33
  "oxlint": "^1.57.0",
34
34
  "typescript": "6.0.2",
@@ -4,7 +4,9 @@ const UrlOrPathSchema = z.string().min(1);
4
4
  const SlugSchema = z
5
5
  .string()
6
6
  .min(1)
7
- .regex(/^[a-z0-9-]+$/);
7
+ // Lowercase alphanumeric segments joined by single hyphens: no leading,
8
+ // trailing, or consecutive hyphens, and never a bare "-".
9
+ .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
8
10
 
9
11
  export const DocsColorsSchema = z
10
12
  .object({
@@ -442,8 +444,6 @@ export const DocsConfigSchema = z
442
444
  .strict();
443
445
 
444
446
  export type DocsConfig = z.infer<typeof DocsConfigSchema>;
445
- export const MintlifyDocsConfigSchema = DocsConfigSchema;
446
- export type MintlifyDocsConfig = DocsConfig;
447
447
 
448
448
  export const ContentTypeSchema = z.enum([
449
449
  "site",
@@ -1,3 +1,17 @@
1
+ export interface TenantAnalyticsGa4 {
2
+ measurementId: string;
3
+ }
4
+
5
+ export interface TenantAnalyticsPosthog {
6
+ projectKey: string;
7
+ host?: string;
8
+ }
9
+
10
+ export interface TenantAnalytics {
11
+ ga4?: TenantAnalyticsGa4;
12
+ posthog?: TenantAnalyticsPosthog;
13
+ }
14
+
1
15
  export interface Tenant {
2
16
  id: string;
3
17
  slug: string;
@@ -5,6 +19,7 @@ export interface Tenant {
5
19
  description?: string;
6
20
  activeDeploymentId?: string;
7
21
  activeDeploymentManifestUrl?: string;
22
+ analytics?: TenantAnalytics;
8
23
  primaryDomain: string;
9
24
  subdomain: string;
10
25
  customDomains: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,EAAE,mBAAe,KAAG,WAgB/D,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,cAAc,MAAM,KACnB,OAAO,CAAC,WAAW,CACmD,CAAC;AAE1E,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,EAAE,WAAW,MAAM,WAC3B,CAAC;AAEzC,eAAO,MAAM,WAAW,GACtB,QAAQ,MAAM,EACd,WAAW,MAAM,EACjB,kBAAiB,WAUlB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,MAAM,WAAW,EACjB,YAAY,MAAM;;;CA+BnB,CAAC"}
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAmBD,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,EAAE,mBAAe,KAAG,WAgB/D,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,cAAc,MAAM,KACnB,OAAO,CAAC,WAAW,CACmD,CAAC;AAE1E,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,EAAE,WAAW,MAAM,WAC3B,CAAC;AAEzC,eAAO,MAAM,WAAW,GACtB,QAAQ,MAAM,EACd,WAAW,MAAM,EACjB,kBAAiB,WAUlB,CAAC;AAgBF,eAAO,MAAM,wBAAwB,GACnC,MAAM,WAAW,EACjB,YAAY,MAAM;;;CAsCnB,CAAC"}
@@ -2,19 +2,33 @@ import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { normalizePath, slugify } from "@repo/common";
4
4
  import YAML from "yaml";
5
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
6
+ // A YAML/JSON document can parse to a scalar, null, or array — none of which
7
+ // are usable as an OpenAPI spec. Validate the shape before the cast so callers
8
+ // fail with a clear message instead of crashing while iterating `paths`.
9
+ const asOpenApiSpec = (value, sourcePath) => {
10
+ const label = sourcePath ? ` (${sourcePath})` : "";
11
+ if (!isRecord(value)) {
12
+ throw new Error(`OpenAPI spec${label} must be an object.`);
13
+ }
14
+ if (value.paths !== undefined && !isRecord(value.paths)) {
15
+ throw new Error(`OpenAPI spec${label} has an invalid "paths" section.`);
16
+ }
17
+ return value;
18
+ };
5
19
  export const parseOpenApiSpec = (raw, sourcePath = "") => {
6
20
  const ext = path.extname(sourcePath).toLowerCase();
7
21
  if (ext === ".json") {
8
- return JSON.parse(raw);
22
+ return asOpenApiSpec(JSON.parse(raw), sourcePath);
9
23
  }
10
24
  if (ext === ".yaml" || ext === ".yml") {
11
- return YAML.parse(raw);
25
+ return asOpenApiSpec(YAML.parse(raw), sourcePath);
12
26
  }
13
27
  try {
14
- return JSON.parse(raw);
28
+ return asOpenApiSpec(JSON.parse(raw), sourcePath);
15
29
  }
16
30
  catch {
17
- return YAML.parse(raw);
31
+ return asOpenApiSpec(YAML.parse(raw), sourcePath);
18
32
  }
19
33
  };
20
34
  export const loadOpenApiSpec = async (absolutePath) => parseOpenApiSpec(await fs.readFile(absolutePath, "utf8"), absolutePath);
@@ -29,11 +43,25 @@ export const openApiSlug = (method, routePath, directory = "api") => {
29
43
  const slug = slugify(`${method.toLowerCase()}-${base}`);
30
44
  return normalizePath(path.join(directory, slug));
31
45
  };
46
+ const HTTP_METHODS = new Set([
47
+ "delete",
48
+ "get",
49
+ "head",
50
+ "options",
51
+ "patch",
52
+ "post",
53
+ "put",
54
+ "trace",
55
+ ]);
56
+ const isOperationObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
32
57
  export const extractOpenApiOperations = (spec, directory) => {
33
58
  const ops = [];
34
59
  const paths = spec.paths ?? {};
35
60
  for (const [routePath, methods] of Object.entries(paths)) {
36
61
  for (const [method, operation] of Object.entries(methods)) {
62
+ if (!(HTTP_METHODS.has(method.toLowerCase()) && isOperationObject(operation))) {
63
+ continue;
64
+ }
37
65
  const upper = method.toUpperCase();
38
66
  const id = operation.operationId ?? openApiIdentifier(upper, routePath);
39
67
  ops.push({
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@repo/typescript-config": "*",
33
- "@types/node": "^22.19.15",
33
+ "@types/node": "^24.12.2",
34
34
  "oxfmt": "^0.42.0",
35
35
  "oxlint": "^1.57.0",
36
36
  "typescript": "6.0.2",
@@ -39,21 +39,38 @@ export interface OpenApiOperation {
39
39
  responses?: Record<string, unknown>;
40
40
  }
41
41
 
42
+ const isRecord = (value: unknown): value is Record<string, unknown> =>
43
+ typeof value === "object" && value !== null && !Array.isArray(value);
44
+
45
+ // A YAML/JSON document can parse to a scalar, null, or array — none of which
46
+ // are usable as an OpenAPI spec. Validate the shape before the cast so callers
47
+ // fail with a clear message instead of crashing while iterating `paths`.
48
+ const asOpenApiSpec = (value: unknown, sourcePath: string): OpenApiSpec => {
49
+ const label = sourcePath ? ` (${sourcePath})` : "";
50
+ if (!isRecord(value)) {
51
+ throw new Error(`OpenAPI spec${label} must be an object.`);
52
+ }
53
+ if (value.paths !== undefined && !isRecord(value.paths)) {
54
+ throw new Error(`OpenAPI spec${label} has an invalid "paths" section.`);
55
+ }
56
+ return value as OpenApiSpec;
57
+ };
58
+
42
59
  export const parseOpenApiSpec = (raw: string, sourcePath = ""): OpenApiSpec => {
43
60
  const ext = path.extname(sourcePath).toLowerCase();
44
61
 
45
62
  if (ext === ".json") {
46
- return JSON.parse(raw) as OpenApiSpec;
63
+ return asOpenApiSpec(JSON.parse(raw), sourcePath);
47
64
  }
48
65
 
49
66
  if (ext === ".yaml" || ext === ".yml") {
50
- return YAML.parse(raw) as OpenApiSpec;
67
+ return asOpenApiSpec(YAML.parse(raw), sourcePath);
51
68
  }
52
69
 
53
70
  try {
54
- return JSON.parse(raw) as OpenApiSpec;
71
+ return asOpenApiSpec(JSON.parse(raw), sourcePath);
55
72
  } catch {
56
- return YAML.parse(raw) as OpenApiSpec;
73
+ return asOpenApiSpec(YAML.parse(raw), sourcePath);
57
74
  }
58
75
  };
59
76
 
@@ -80,6 +97,20 @@ export const openApiSlug = (
80
97
  return normalizePath(path.join(directory, slug));
81
98
  };
82
99
 
100
+ const HTTP_METHODS = new Set([
101
+ "delete",
102
+ "get",
103
+ "head",
104
+ "options",
105
+ "patch",
106
+ "post",
107
+ "put",
108
+ "trace",
109
+ ]);
110
+
111
+ const isOperationObject = (value: unknown): value is OpenApiOperationSpec =>
112
+ typeof value === "object" && value !== null && !Array.isArray(value);
113
+
83
114
  export const extractOpenApiOperations = (
84
115
  spec: OpenApiSpec,
85
116
  directory?: string
@@ -89,6 +120,13 @@ export const extractOpenApiOperations = (
89
120
 
90
121
  for (const [routePath, methods] of Object.entries(paths)) {
91
122
  for (const [method, operation] of Object.entries(methods)) {
123
+ if (
124
+ !(
125
+ HTTP_METHODS.has(method.toLowerCase()) && isOperationObject(operation)
126
+ )
127
+ ) {
128
+ continue;
129
+ }
92
130
  const upper = method.toUpperCase();
93
131
  const id = operation.operationId ?? openApiIdentifier(upper, routePath);
94
132
 
@@ -1 +1 @@
1
- {"version":3,"file":"blob-source.d.ts","sourceRoot":"","sources":["../src/blob-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8C5E,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,eAAe,CAAC,CAA+B;gBAE3C,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAKlD,OAAO,CAAC,eAAe;YAaT,YAAY;IA2BpB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc/C,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAe/C,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK9C,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKxD,eAAe,CACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAuBrC;AAED,eAAO,MAAM,gBAAgB,GAC3B,aAAa,MAAM,EACnB,WAAW,MAAM,KAChB,aAA6D,CAAC"}
1
+ {"version":3,"file":"blob-source.d.ts","sourceRoot":"","sources":["../src/blob-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8C5E,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,eAAe,CAAC,CAA+B;gBAE3C,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAKlD,OAAO,CAAC,eAAe;YAaT,YAAY;IA2BpB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc/C,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA8B/C,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK9C,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKxD,eAAe,CACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAuBrC;AAED,eAAO,MAAM,gBAAgB,GAC3B,aAAa,MAAM,EACnB,WAAW,MAAM,KAChB,aAA6D,CAAC"}
@@ -72,12 +72,25 @@ export class BlobContentSource {
72
72
  async listFiles(directory) {
73
73
  const manifest = await this.loadManifest();
74
74
  const prefix = normalizeDirectory(directory);
75
- const files = [...manifest.keys()].filter((file) => {
76
- if (shouldIgnoreRootDocsFile(file)) {
77
- return false;
75
+ const files = [];
76
+ for (const file of manifest.keys()) {
77
+ if (prefix && !file.startsWith(prefix)) {
78
+ continue;
78
79
  }
79
- return prefix ? file.startsWith(prefix) : true;
80
- });
80
+ // Return paths relative to the listed directory, matching
81
+ // FsContentSource so callers can join them onto the collection root.
82
+ const relativePath = prefix ? file.slice(prefix.length) : file;
83
+ if (!relativePath) {
84
+ continue;
85
+ }
86
+ // Only top-level entries of the listed directory are subject to the
87
+ // root-docs-file ignore list, again matching FsContentSource.
88
+ if (!relativePath.includes("/") &&
89
+ shouldIgnoreRootDocsFile(relativePath)) {
90
+ continue;
91
+ }
92
+ files.push(relativePath);
93
+ }
81
94
  // oxlint-disable-next-line eslint-plugin-unicorn/no-array-sort
82
95
  files.sort();
83
96
  return files;