canopycms 0.0.67 → 0.0.68-int.100

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 (268) hide show
  1. package/README.md +21 -14
  2. package/dist/ai/handler.js +8 -0
  3. package/dist/api/admin-branch-health.js +17 -20
  4. package/dist/api/admin.d.ts +30 -9
  5. package/dist/api/admin.js +32 -2
  6. package/dist/api/assets.js +84 -76
  7. package/dist/api/branch-create-window.d.ts +12 -0
  8. package/dist/api/branch-create-window.js +13 -0
  9. package/dist/api/branch-review.d.ts +3 -3
  10. package/dist/api/branch-review.js +14 -5
  11. package/dist/api/branch-status.d.ts +5 -5
  12. package/dist/api/branch-status.js +26 -6
  13. package/dist/api/branch-withdraw.d.ts +2 -2
  14. package/dist/api/branch-withdraw.js +7 -2
  15. package/dist/api/branch.d.ts +15 -2
  16. package/dist/api/branch.js +111 -92
  17. package/dist/api/client.d.ts +18 -6
  18. package/dist/api/client.js +79 -12
  19. package/dist/api/content.d.ts +6 -5
  20. package/dist/api/content.js +44 -41
  21. package/dist/api/entries.js +16 -15
  22. package/dist/api/github-sync.d.ts +10 -1
  23. package/dist/api/github-sync.js +20 -10
  24. package/dist/api/index.d.ts +1 -1
  25. package/dist/api/reference-options.js +1 -1
  26. package/dist/api/resolve-references.js +14 -40
  27. package/dist/api/settings-helpers.d.ts +1 -1
  28. package/dist/api/settings-helpers.js +1 -4
  29. package/dist/api/user.d.ts +3 -0
  30. package/dist/api/user.js +3 -0
  31. package/dist/assets/asset-url.d.ts +22 -16
  32. package/dist/assets/asset-url.js +42 -25
  33. package/dist/assets/factory.d.ts +5 -0
  34. package/dist/assets/factory.js +5 -0
  35. package/dist/assets/index.d.ts +1 -1
  36. package/dist/assets/materialize.d.ts +122 -0
  37. package/dist/assets/materialize.js +305 -0
  38. package/dist/assets/store-local.d.ts +4 -0
  39. package/dist/assets/store-local.js +11 -0
  40. package/dist/assets/store-s3.d.ts +10 -1
  41. package/dist/assets/store-s3.js +55 -3
  42. package/dist/assets/transform-directives.d.ts +52 -13
  43. package/dist/assets/transform-directives.js +87 -27
  44. package/dist/assets/transform.d.ts +3 -3
  45. package/dist/assets/transform.js +13 -8
  46. package/dist/assets/types.d.ts +14 -1
  47. package/dist/auth/file-based-auth-cache.js +7 -8
  48. package/dist/authorization/content.d.ts +5 -4
  49. package/dist/authorization/content.js +5 -5
  50. package/dist/authorization/path.d.ts +11 -6
  51. package/dist/authorization/path.js +11 -6
  52. package/dist/authorization/types.d.ts +2 -2
  53. package/dist/branch-health.d.ts +7 -1
  54. package/dist/branch-health.js +8 -3
  55. package/dist/branch-metadata.d.ts +5 -5
  56. package/dist/branch-metadata.js +44 -36
  57. package/dist/branch-provisioning.d.ts +167 -0
  58. package/dist/branch-provisioning.js +501 -0
  59. package/dist/branch-schema-cache.d.ts +5 -3
  60. package/dist/branch-schema-cache.js +29 -11
  61. package/dist/branch-sparse.d.ts +23 -0
  62. package/dist/branch-sparse.js +118 -0
  63. package/dist/branch-workspace.d.ts +42 -3
  64. package/dist/branch-workspace.js +240 -94
  65. package/dist/build/asset-refs.d.ts +93 -0
  66. package/dist/build/asset-refs.js +251 -0
  67. package/dist/build-identity.d.ts +3 -0
  68. package/dist/build-identity.js +13 -0
  69. package/dist/cli/asset-refs.d.ts +30 -0
  70. package/dist/cli/asset-refs.js +168 -0
  71. package/dist/cli/cli.d.ts +2 -1
  72. package/dist/cli/cli.js +4843 -1870
  73. package/dist/cli/generate-ai-content.js +1584 -444
  74. package/dist/cli/github-app-manifest.d.ts +4 -3
  75. package/dist/cli/github-app-manifest.js +4 -3
  76. package/dist/cli/init.js +30 -27
  77. package/dist/cli/migrate.js +12 -8
  78. package/dist/cli/sync.js +83 -37
  79. package/dist/cli/template-files/Dockerfile.cms.template +8 -0
  80. package/dist/cli/template-files/cdk-app.ts.template +4 -0
  81. package/dist/cli/template-files/cms-stack.ts.template +23 -12
  82. package/dist/cli/template-files/deploy-cms.yml.template +2 -0
  83. package/dist/config/helpers.js +1 -2
  84. package/dist/config/schemas/config.d.ts +19 -32
  85. package/dist/config/schemas/config.js +9 -11
  86. package/dist/config/schemas/field.js +1 -0
  87. package/dist/config/schemas/media.d.ts +4 -13
  88. package/dist/config/schemas/media.js +5 -8
  89. package/dist/config/schemas/url.d.ts +4 -20
  90. package/dist/config/schemas/url.js +6 -22
  91. package/dist/config/types.d.ts +30 -20
  92. package/dist/config/validation.d.ts +6 -0
  93. package/dist/config/validation.js +37 -0
  94. package/dist/content-listing.d.ts +12 -12
  95. package/dist/content-listing.js +10 -6
  96. package/dist/content-reader.d.ts +11 -2
  97. package/dist/content-reader.js +22 -14
  98. package/dist/content-store.d.ts +37 -9
  99. package/dist/content-store.js +70 -43
  100. package/dist/content-tree.d.ts +1 -1
  101. package/dist/content-tree.js +2 -2
  102. package/dist/context.d.ts +27 -9
  103. package/dist/context.js +154 -70
  104. package/dist/editor/BranchManager.d.ts +7 -1
  105. package/dist/editor/BranchManager.js +29 -14
  106. package/dist/editor/CanopyEditor.d.ts +1 -1
  107. package/dist/editor/CanopyEditor.js +2 -6
  108. package/dist/editor/Editor.d.ts +4 -3
  109. package/dist/editor/Editor.js +24 -20
  110. package/dist/editor/FormRenderer.js +34 -18
  111. package/dist/editor/admin/SystemHealthPanel.js +47 -7
  112. package/dist/editor/components/BranchesDrawer.d.ts +9 -0
  113. package/dist/editor/components/BranchesDrawer.js +4 -0
  114. package/dist/editor/components/NoEditPermissionNotice.d.ts +10 -0
  115. package/dist/editor/components/NoEditPermissionNotice.js +17 -0
  116. package/dist/editor/context/AssetContext.d.ts +18 -35
  117. package/dist/editor/context/AssetContext.js +20 -29
  118. package/dist/editor/context/index.d.ts +1 -1
  119. package/dist/editor/context/index.js +1 -1
  120. package/dist/editor/editor-config.d.ts +1 -2
  121. package/dist/editor/editor-config.js +0 -23
  122. package/dist/editor/editor-utils.d.ts +24 -21
  123. package/dist/editor/editor-utils.js +75 -62
  124. package/dist/editor/fields/BlockField.d.ts +1 -0
  125. package/dist/editor/fields/BlockField.js +6 -4
  126. package/dist/editor/fields/CodeField.d.ts +1 -0
  127. package/dist/editor/fields/CodeField.js +2 -2
  128. package/dist/editor/fields/DateTimeField.d.ts +1 -0
  129. package/dist/editor/fields/DateTimeField.js +2 -2
  130. package/dist/editor/fields/FieldDescription.d.ts +16 -0
  131. package/dist/editor/fields/FieldDescription.js +11 -0
  132. package/dist/editor/fields/ImageField.d.ts +1 -0
  133. package/dist/editor/fields/ImageField.js +3 -2
  134. package/dist/editor/fields/InlineGroupField.js +4 -1
  135. package/dist/editor/fields/MarkdownField.d.ts +1 -0
  136. package/dist/editor/fields/MarkdownField.js +115 -20
  137. package/dist/editor/fields/NumberField.d.ts +1 -0
  138. package/dist/editor/fields/NumberField.js +2 -2
  139. package/dist/editor/fields/NumberListField.d.ts +1 -0
  140. package/dist/editor/fields/NumberListField.js +2 -2
  141. package/dist/editor/fields/ObjectField.d.ts +1 -0
  142. package/dist/editor/fields/ObjectField.js +5 -2
  143. package/dist/editor/fields/ReferenceField.d.ts +1 -0
  144. package/dist/editor/fields/ReferenceField.js +5 -4
  145. package/dist/editor/fields/SelectField.d.ts +1 -0
  146. package/dist/editor/fields/SelectField.js +2 -2
  147. package/dist/editor/fields/StringListField.d.ts +1 -0
  148. package/dist/editor/fields/StringListField.js +2 -2
  149. package/dist/editor/fields/TextField.d.ts +1 -0
  150. package/dist/editor/fields/TextField.js +2 -2
  151. package/dist/editor/fields/ToggleField.d.ts +1 -0
  152. package/dist/editor/fields/ToggleField.js +7 -4
  153. package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
  154. package/dist/editor/fields/entry-link/InsertEntryLink.js +3 -2
  155. package/dist/editor/fields/mdx-jsx-support.d.ts +1 -0
  156. package/dist/editor/fields/mdx-jsx-support.js +137 -0
  157. package/dist/editor/hooks/create-branch-request.d.ts +20 -0
  158. package/dist/editor/hooks/create-branch-request.js +52 -0
  159. package/dist/editor/hooks/useBranchActions.d.ts +13 -2
  160. package/dist/editor/hooks/useBranchActions.js +48 -17
  161. package/dist/editor/hooks/useBranchManager.d.ts +11 -0
  162. package/dist/editor/hooks/useBranchManager.js +80 -2
  163. package/dist/editor/hooks/useBranchesData.d.ts +6 -0
  164. package/dist/editor/hooks/useBranchesData.js +9 -3
  165. package/dist/editor/hooks/useCommentSystem.js +25 -6
  166. package/dist/editor/hooks/useDraftManager.d.ts +16 -1
  167. package/dist/editor/hooks/useDraftManager.js +193 -36
  168. package/dist/editor/hooks/useEntriesData.js +3 -3
  169. package/dist/editor/hooks/useEntryManager.d.ts +2 -1
  170. package/dist/editor/hooks/useEntryManager.js +34 -19
  171. package/dist/editor/media/AssetCard.d.ts +1 -1
  172. package/dist/editor/media/crop-math.d.ts +3 -4
  173. package/dist/editor/media/crop-math.js +11 -22
  174. package/dist/editor/media/editor-image-src.d.ts +7 -0
  175. package/dist/editor/media/editor-image-src.js +12 -0
  176. package/dist/editor/preview-asset-base.d.ts +8 -0
  177. package/dist/editor/preview-asset-base.js +13 -0
  178. package/dist/editor/preview-bridge.d.ts +8 -1
  179. package/dist/editor/preview-bridge.js +15 -2
  180. package/dist/editor/preview-path.d.ts +10 -0
  181. package/dist/editor/preview-path.js +20 -0
  182. package/dist/editor/theme.js +2 -2
  183. package/dist/entry-schema-registry.d.ts +4 -4
  184. package/dist/entry-schema-registry.js +10 -6
  185. package/dist/entry-schema.d.ts +27 -4
  186. package/dist/entry-schema.js +20 -3
  187. package/dist/git-manager.d.ts +173 -6
  188. package/dist/git-manager.js +594 -76
  189. package/dist/github-service.d.ts +8 -0
  190. package/dist/github-service.js +5 -1
  191. package/dist/http/handler.js +37 -13
  192. package/dist/http/index.d.ts +2 -0
  193. package/dist/http/index.js +2 -0
  194. package/dist/http/router.d.ts +2 -0
  195. package/dist/http/router.js +2 -1
  196. package/dist/http/types.d.ts +2 -0
  197. package/dist/http/worker-not-ready.d.ts +10 -0
  198. package/dist/http/worker-not-ready.js +24 -0
  199. package/dist/operating-mode/client-unsafe-strategy.js +0 -6
  200. package/dist/operating-mode/types.d.ts +1 -4
  201. package/dist/paths/branch-name.d.ts +5 -0
  202. package/dist/paths/branch-name.js +9 -0
  203. package/dist/paths/branch.d.ts +6 -2
  204. package/dist/paths/branch.js +16 -10
  205. package/dist/paths/index.d.ts +3 -3
  206. package/dist/paths/index.js +3 -3
  207. package/dist/paths/normalize.d.ts +7 -0
  208. package/dist/paths/normalize.js +9 -0
  209. package/dist/paths/validation.js +0 -2
  210. package/dist/reference-resolver.d.ts +5 -21
  211. package/dist/reference-resolver.js +9 -44
  212. package/dist/resolve-canopy-user.js +2 -1
  213. package/dist/schema/schema-store.d.ts +54 -31
  214. package/dist/schema/schema-store.js +77 -31
  215. package/dist/server.d.ts +24 -9
  216. package/dist/server.js +22 -8
  217. package/dist/services.d.ts +18 -6
  218. package/dist/services.js +85 -70
  219. package/dist/settings-workspace.d.ts +23 -3
  220. package/dist/settings-workspace.js +197 -45
  221. package/dist/static/seo.d.ts +2 -14
  222. package/dist/static/seo.js +2 -25
  223. package/dist/submission-attribution.d.ts +73 -0
  224. package/dist/submission-attribution.js +221 -0
  225. package/dist/sync-core.d.ts +12 -1
  226. package/dist/sync-core.js +31 -13
  227. package/dist/task-queue/worker-status.d.ts +8 -0
  228. package/dist/task-queue/worker-status.js +17 -0
  229. package/dist/types.d.ts +31 -2
  230. package/dist/utils/content-write-lock.d.ts +18 -7
  231. package/dist/utils/content-write-lock.js +18 -9
  232. package/dist/utils/debug.d.ts +8 -0
  233. package/dist/utils/debug.js +10 -2
  234. package/dist/utils/git.d.ts +32 -0
  235. package/dist/utils/git.js +42 -0
  236. package/dist/utils/occ-json-write.js +10 -2
  237. package/dist/utils/provision-log.d.ts +25 -0
  238. package/dist/utils/provision-log.js +49 -0
  239. package/dist/utils/provisioning-lock.d.ts +35 -5
  240. package/dist/utils/provisioning-lock.js +73 -12
  241. package/dist/utils/request-timing.d.ts +25 -0
  242. package/dist/utils/request-timing.js +101 -0
  243. package/dist/utils/sanitize-href.d.ts +8 -22
  244. package/dist/utils/sanitize-href.js +11 -28
  245. package/dist/utils/url-prefix.d.ts +30 -0
  246. package/dist/utils/url-prefix.js +61 -0
  247. package/dist/validation/entry-validator.js +9 -3
  248. package/dist/version.d.ts +1 -0
  249. package/dist/version.js +3 -0
  250. package/dist/worker/canopy-state.d.ts +45 -0
  251. package/dist/worker/canopy-state.js +75 -0
  252. package/dist/worker/cms-worker.d.ts +8 -3
  253. package/dist/worker/cms-worker.js +38 -2
  254. package/dist/worker/git-sync.d.ts +30 -12
  255. package/dist/worker/git-sync.js +253 -58
  256. package/dist/worker/history-rewrite.d.ts +1 -1
  257. package/dist/worker/history-rewrite.js +1 -1
  258. package/dist/worker/provisioned-workspace.d.ts +35 -0
  259. package/dist/worker/provisioned-workspace.js +50 -0
  260. package/dist/worker/rebase.d.ts +1 -1
  261. package/dist/worker/rebase.js +95 -23
  262. package/dist/worker/remote-git-maintenance.d.ts +3 -0
  263. package/dist/worker/remote-git-maintenance.js +11 -0
  264. package/dist/worker/sparse-cone.d.ts +20 -0
  265. package/dist/worker/sparse-cone.js +132 -0
  266. package/dist/worker/task-runner.js +39 -4
  267. package/dist/worker/worker-context.d.ts +6 -1
  268. package/package.json +2 -1
@@ -8,46 +8,37 @@ import type { EditorSignInProps, ValidateEntryHook } from '../types.js';
8
8
  export declare const CanopyConfigSchema: z.ZodObject<{
9
9
  media: z.ZodOptional<z.ZodDiscriminatedUnion<"adapter", [z.ZodObject<{
10
10
  adapter: z.ZodLiteral<"local">;
11
- publicBaseUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
12
11
  directory: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>>;
13
12
  }, "strict", z.ZodTypeAny, {
14
13
  adapter: "local";
15
- publicBaseUrl?: string | undefined;
16
14
  directory?: string | undefined;
17
15
  }, {
18
16
  adapter: "local";
19
- publicBaseUrl?: string | undefined;
20
17
  directory?: string | undefined;
21
18
  }>, z.ZodObject<{
22
19
  adapter: z.ZodLiteral<"s3">;
23
20
  bucket: z.ZodString;
24
21
  region: z.ZodString;
25
- publicBaseUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
26
22
  uploadUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
27
23
  maxUploadBytes: z.ZodOptional<z.ZodNumber>;
28
24
  }, "strict", z.ZodTypeAny, {
29
25
  adapter: "s3";
30
26
  bucket: string;
31
27
  region: string;
32
- publicBaseUrl?: string | undefined;
33
28
  uploadUrl?: string | undefined;
34
29
  maxUploadBytes?: number | undefined;
35
30
  }, {
36
31
  adapter: "s3";
37
32
  bucket: string;
38
33
  region: string;
39
- publicBaseUrl?: string | undefined;
40
34
  uploadUrl?: string | undefined;
41
35
  maxUploadBytes?: number | undefined;
42
36
  }>, z.ZodObject<{
43
37
  adapter: z.ZodLiteral<"lfs">;
44
- publicBaseUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
45
38
  }, "strict", z.ZodTypeAny, {
46
39
  adapter: "lfs";
47
- publicBaseUrl?: string | undefined;
48
40
  }, {
49
41
  adapter: "lfs";
50
- publicBaseUrl?: string | undefined;
51
42
  }>]>>;
52
43
  defaultBranchAccess: z.ZodDefault<z.ZodEnum<["allow", "deny"]>>;
53
44
  defaultPathAccess: z.ZodDefault<z.ZodUnion<[z.ZodEnum<["allow", "deny"]>, z.ZodObject<{
@@ -69,12 +60,13 @@ export declare const CanopyConfigSchema: z.ZodObject<{
69
60
  defaultRemoteUrl: z.ZodOptional<z.ZodString>;
70
61
  gitBotAuthorName: z.ZodString;
71
62
  gitBotAuthorEmail: z.ZodString;
63
+ gitEditedByTrailers: z.ZodOptional<z.ZodBoolean>;
64
+ gitCoAuthoredByTrailers: z.ZodOptional<z.ZodBoolean>;
72
65
  githubTokenEnvVar: z.ZodOptional<z.ZodDefault<z.ZodString>>;
73
66
  mode: z.ZodEnum<["prod", "dev"]>;
74
67
  deployedAs: z.ZodDefault<z.ZodEnum<["static", "server"]>>;
75
68
  allowNetworkRemoteInProd: z.ZodOptional<z.ZodBoolean>;
76
69
  settingsBranch: z.ZodOptional<z.ZodString>;
77
- autoCreateSettingsPR: z.ZodOptional<z.ZodBoolean>;
78
70
  deploymentName: z.ZodOptional<z.ZodDefault<z.ZodString>>;
79
71
  contentRoot: z.ZodDefault<z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>>>;
80
72
  sourceRoot: z.ZodOptional<z.ZodOptional<z.ZodString>>;
@@ -83,7 +75,8 @@ export declare const CanopyConfigSchema: z.ZodObject<{
83
75
  title: z.ZodOptional<z.ZodString>;
84
76
  subtitle: z.ZodOptional<z.ZodString>;
85
77
  theme: z.ZodOptional<z.ZodUnknown>;
86
- previewBase: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
78
+ previewBase: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodLiteral<false>]>>>;
79
+ previewPrefix: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
87
80
  onAccountClick: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodVoid>>;
88
81
  onLogoutClick: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodVoid>>;
89
82
  AccountComponent: z.ZodOptional<z.ZodType<import("react").ComponentType<{}>, z.ZodTypeDef, import("react").ComponentType<{}>>>;
@@ -92,7 +85,8 @@ export declare const CanopyConfigSchema: z.ZodObject<{
92
85
  title?: string | undefined;
93
86
  subtitle?: string | undefined;
94
87
  theme?: unknown;
95
- previewBase?: Record<string, string> | undefined;
88
+ previewBase?: Record<string, string | false> | undefined;
89
+ previewPrefix?: string | undefined;
96
90
  onAccountClick?: ((...args: unknown[]) => void) | undefined;
97
91
  onLogoutClick?: ((...args: unknown[]) => void) | undefined;
98
92
  AccountComponent?: import("react").ComponentType<{}> | undefined;
@@ -101,7 +95,8 @@ export declare const CanopyConfigSchema: z.ZodObject<{
101
95
  title?: string | undefined;
102
96
  subtitle?: string | undefined;
103
97
  theme?: unknown;
104
- previewBase?: Record<string, string> | undefined;
98
+ previewBase?: Record<string, string | false> | undefined;
99
+ previewPrefix?: string | undefined;
105
100
  onAccountClick?: ((...args: unknown[]) => void) | undefined;
106
101
  onLogoutClick?: ((...args: unknown[]) => void) | undefined;
107
102
  AccountComponent?: import("react").ComponentType<{}> | undefined;
@@ -135,26 +130,24 @@ export declare const CanopyConfigSchema: z.ZodObject<{
135
130
  settingsBranch?: string | undefined;
136
131
  media?: {
137
132
  adapter: "local";
138
- publicBaseUrl?: string | undefined;
139
133
  directory?: string | undefined;
140
134
  } | {
141
135
  adapter: "s3";
142
136
  bucket: string;
143
137
  region: string;
144
- publicBaseUrl?: string | undefined;
145
138
  uploadUrl?: string | undefined;
146
139
  maxUploadBytes?: number | undefined;
147
140
  } | {
148
141
  adapter: "lfs";
149
- publicBaseUrl?: string | undefined;
150
142
  } | undefined;
151
143
  defaultBaseBranch?: string | undefined;
152
144
  defaultActiveBranch?: string | undefined;
153
145
  defaultRemoteName?: string | undefined;
154
146
  defaultRemoteUrl?: string | undefined;
147
+ gitEditedByTrailers?: boolean | undefined;
148
+ gitCoAuthoredByTrailers?: boolean | undefined;
155
149
  githubTokenEnvVar?: string | undefined;
156
150
  allowNetworkRemoteInProd?: boolean | undefined;
157
- autoCreateSettingsPR?: boolean | undefined;
158
151
  deploymentName?: string | undefined;
159
152
  sourceRoot?: string | undefined;
160
153
  basePath?: string | undefined;
@@ -162,7 +155,8 @@ export declare const CanopyConfigSchema: z.ZodObject<{
162
155
  title?: string | undefined;
163
156
  subtitle?: string | undefined;
164
157
  theme?: unknown;
165
- previewBase?: Record<string, string> | undefined;
158
+ previewBase?: Record<string, string | false> | undefined;
159
+ previewPrefix?: string | undefined;
166
160
  onAccountClick?: ((...args: unknown[]) => void) | undefined;
167
161
  onLogoutClick?: ((...args: unknown[]) => void) | undefined;
168
162
  AccountComponent?: import("react").ComponentType<{}> | undefined;
@@ -181,18 +175,15 @@ export declare const CanopyConfigSchema: z.ZodObject<{
181
175
  settingsBranch?: string | undefined;
182
176
  media?: {
183
177
  adapter: "local";
184
- publicBaseUrl?: string | undefined;
185
178
  directory?: string | undefined;
186
179
  } | {
187
180
  adapter: "s3";
188
181
  bucket: string;
189
182
  region: string;
190
- publicBaseUrl?: string | undefined;
191
183
  uploadUrl?: string | undefined;
192
184
  maxUploadBytes?: number | undefined;
193
185
  } | {
194
186
  adapter: "lfs";
195
- publicBaseUrl?: string | undefined;
196
187
  } | undefined;
197
188
  defaultBranchAccess?: "allow" | "deny" | undefined;
198
189
  defaultPathAccess?: "allow" | "deny" | {
@@ -204,10 +195,11 @@ export declare const CanopyConfigSchema: z.ZodObject<{
204
195
  defaultActiveBranch?: string | undefined;
205
196
  defaultRemoteName?: string | undefined;
206
197
  defaultRemoteUrl?: string | undefined;
198
+ gitEditedByTrailers?: boolean | undefined;
199
+ gitCoAuthoredByTrailers?: boolean | undefined;
207
200
  githubTokenEnvVar?: string | undefined;
208
201
  deployedAs?: "static" | "server" | undefined;
209
202
  allowNetworkRemoteInProd?: boolean | undefined;
210
- autoCreateSettingsPR?: boolean | undefined;
211
203
  deploymentName?: string | undefined;
212
204
  contentRoot?: string | undefined;
213
205
  sourceRoot?: string | undefined;
@@ -216,7 +208,8 @@ export declare const CanopyConfigSchema: z.ZodObject<{
216
208
  title?: string | undefined;
217
209
  subtitle?: string | undefined;
218
210
  theme?: unknown;
219
- previewBase?: Record<string, string> | undefined;
211
+ previewBase?: Record<string, string | false> | undefined;
212
+ previewPrefix?: string | undefined;
220
213
  onAccountClick?: ((...args: unknown[]) => void) | undefined;
221
214
  onLogoutClick?: ((...args: unknown[]) => void) | undefined;
222
215
  AccountComponent?: import("react").ComponentType<{}> | undefined;
@@ -227,16 +220,10 @@ export declare const CanopyConfigSchema: z.ZodObject<{
227
220
  validateEntry?: ValidateEntryHook | undefined;
228
221
  }>;
229
222
  /**
230
- * Default workspace path for prod mode (used when CANOPYCMS_WORKSPACE_ROOT is not set).
231
- *
232
- * WARNING: this fallback assumes a worker-style ROOT mount of EFS at /mnt/efs.
233
- * The CanopyCmsService Lambda mounts EFS THROUGH an access point already rooted
234
- * at /workspace and therefore sets CANOPYCMS_WORKSPACE_ROOT=/mnt/efs explicitly;
235
- * if that env were ever unset on the Lambda this default would resolve to
236
- * /mnt/efs/workspace = EFS:/workspace/workspace (a wrong, nested dir). The CDK
237
- * always sets the env, so this only bites a hand-rolled misconfiguration.
223
+ * Default workspace path for prod mode (used when CANOPYCMS_WORKSPACE_ROOT is not set): where
224
+ * CanopyCmsService mounts the EFS `/workspace` access point in both the Lambda and the worker.
238
225
  */
239
- export declare const DEFAULT_PROD_WORKSPACE = "/mnt/efs/workspace";
226
+ export declare const DEFAULT_PROD_WORKSPACE = "/mnt/efs";
240
227
  export declare const getConfigDefaults: () => {
241
228
  baseBranch: string;
242
229
  remoteName: string;
@@ -4,6 +4,7 @@
4
4
  import { z } from 'zod';
5
5
  import { relativePathSchema } from './collection.js';
6
6
  import { mediaSchema } from './media.js';
7
+ import { previewPrefixSchema } from './url.js';
7
8
  const defaultBranchAccessSchema = z.enum(['allow', 'deny']).default('deny');
8
9
  const defaultPathAccessLevelSchema = z.enum(['allow', 'deny']);
9
10
  // Per-level object form: an omitted level stays undefined after parse (no per-field
@@ -50,7 +51,8 @@ const editorConfigSchema = z.object({
50
51
  title: z.string().optional(),
51
52
  subtitle: z.string().optional(),
52
53
  theme: z.unknown().optional(),
53
- previewBase: z.record(z.string()).optional(),
54
+ previewBase: z.record(z.union([z.string(), z.literal(false)])).optional(),
55
+ previewPrefix: previewPrefixSchema.optional(),
54
56
  // UI handler functions (runtime only, don't serialize)
55
57
  onAccountClick: z.function().returns(z.void()).optional(),
56
58
  onLogoutClick: z.function().returns(z.void()).optional(),
@@ -79,6 +81,9 @@ export const CanopyConfigSchema = z
79
81
  defaultRemoteUrl: defaultRemoteUrlSchema.optional(),
80
82
  gitBotAuthorName: gitBotAuthorNameSchema,
81
83
  gitBotAuthorEmail: gitBotAuthorEmailSchema,
84
+ // Unset reads as on for Edited-by and off for Co-authored-by (services.ts submitBranch).
85
+ gitEditedByTrailers: z.boolean().optional(),
86
+ gitCoAuthoredByTrailers: z.boolean().optional(),
82
87
  githubTokenEnvVar: githubTokenEnvVarSchema.optional(),
83
88
  // Required by design (follow-up to SEC-C1): a prod deploy that omits `mode` must fail
84
89
  // validation loudly rather than silently running header-trusting dev auth semantics.
@@ -89,7 +94,6 @@ export const CanopyConfigSchema = z
89
94
  // Default false/unset — the standard AWS Lambda+worker topology must leave this unset.
90
95
  allowNetworkRemoteInProd: z.boolean().optional(),
91
96
  settingsBranch: z.string().optional(),
92
- autoCreateSettingsPR: z.boolean().optional(),
93
97
  // `.optional()`, NOT bare `deploymentNameSchema`: its own `.default('prod')` would make
94
98
  // `parse(undefined)` resolve to 'prod' instead of staying `undefined`, collapsing the
95
99
  // env > config > modeDefault precedence chain `resolveDeploymentName`
@@ -107,16 +111,10 @@ export const CanopyConfigSchema = z
107
111
  })
108
112
  .strict();
109
113
  /**
110
- * Default workspace path for prod mode (used when CANOPYCMS_WORKSPACE_ROOT is not set).
111
- *
112
- * WARNING: this fallback assumes a worker-style ROOT mount of EFS at /mnt/efs.
113
- * The CanopyCmsService Lambda mounts EFS THROUGH an access point already rooted
114
- * at /workspace and therefore sets CANOPYCMS_WORKSPACE_ROOT=/mnt/efs explicitly;
115
- * if that env were ever unset on the Lambda this default would resolve to
116
- * /mnt/efs/workspace = EFS:/workspace/workspace (a wrong, nested dir). The CDK
117
- * always sets the env, so this only bites a hand-rolled misconfiguration.
114
+ * Default workspace path for prod mode (used when CANOPYCMS_WORKSPACE_ROOT is not set): where
115
+ * CanopyCmsService mounts the EFS `/workspace` access point in both the Lambda and the worker.
118
116
  */
119
- export const DEFAULT_PROD_WORKSPACE = '/mnt/efs/workspace';
117
+ export const DEFAULT_PROD_WORKSPACE = '/mnt/efs';
120
118
  // Note: `mode` has no default by design (SEC-C1) and is intentionally omitted here —
121
119
  // operatingModeSchema.parse(undefined) would throw.
122
120
  //
@@ -81,6 +81,7 @@ const blockFieldSchema = fieldBaseSchema.extend({
81
81
  const objectFieldSchema = fieldBaseSchema.extend({
82
82
  type: z.literal('object'),
83
83
  fields: z.array(z.lazy(() => fieldHolder[0])).min(1),
84
+ itemTitleField: z.string().min(1).optional(),
84
85
  });
85
86
  // Inline group field: visual grouping only, no data nesting
86
87
  const inlineGroupFieldSchema = z.object({
@@ -4,22 +4,18 @@
4
4
  import { z } from 'zod';
5
5
  export declare const mediaSchema: z.ZodDiscriminatedUnion<"adapter", [z.ZodObject<{
6
6
  adapter: z.ZodLiteral<"local">;
7
- publicBaseUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
8
7
  /** Root directory for local asset storage. Defaults to the caller's dev-assets dir. */
9
8
  directory: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>>;
10
9
  }, "strict", z.ZodTypeAny, {
11
10
  adapter: "local";
12
- publicBaseUrl?: string | undefined;
13
11
  directory?: string | undefined;
14
12
  }, {
15
13
  adapter: "local";
16
- publicBaseUrl?: string | undefined;
17
14
  directory?: string | undefined;
18
15
  }>, z.ZodObject<{
19
16
  adapter: z.ZodLiteral<"s3">;
20
17
  bucket: z.ZodString;
21
18
  region: z.ZodString;
22
- publicBaseUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
23
19
  /**
24
20
  * Where the browser POSTs a presigned direct upload. Absolute http(s) URL or a
25
21
  * site-relative path; defaults to the S3 REST endpoint the AWS SDK returns.
@@ -29,10 +25,10 @@ export declare const mediaSchema: z.ZodDiscriminatedUnion<"adapter", [z.ZodObjec
29
25
  * signature is unaffected — a presigned POST's string-to-sign is the base64 policy
30
26
  * alone, so the host never enters it (pinned by store-s3.test.ts).
31
27
  *
32
- * NOT a prefix. Unlike `publicBaseUrl`, nothing is joined onto this value; it replaces
33
- * the POST target outright and is passed through byte-for-byte. Do not route it through
34
- * `joinUrlPrefix` "for consistency" — that would strip the trailing slash and silently
35
- * stop a CDN path pattern like `/asset-upload/*` from matching.
28
+ * NOT a prefix: nothing is joined onto this value; it replaces the POST target outright
29
+ * and is passed through byte-for-byte. Do not route it through `joinUrlPrefix` "for
30
+ * consistency" — that would strip the trailing slash and silently stop a CDN path
31
+ * pattern like `/asset-upload/*` from matching.
36
32
  */
37
33
  uploadUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
38
34
  /** Max upload size in bytes for presigned direct uploads. Defaults to 50 MiB. */
@@ -41,23 +37,18 @@ export declare const mediaSchema: z.ZodDiscriminatedUnion<"adapter", [z.ZodObjec
41
37
  adapter: "s3";
42
38
  bucket: string;
43
39
  region: string;
44
- publicBaseUrl?: string | undefined;
45
40
  uploadUrl?: string | undefined;
46
41
  maxUploadBytes?: number | undefined;
47
42
  }, {
48
43
  adapter: "s3";
49
44
  bucket: string;
50
45
  region: string;
51
- publicBaseUrl?: string | undefined;
52
46
  uploadUrl?: string | undefined;
53
47
  maxUploadBytes?: number | undefined;
54
48
  }>, z.ZodObject<{
55
49
  adapter: z.ZodLiteral<"lfs">;
56
- publicBaseUrl: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
57
50
  }, "strict", z.ZodTypeAny, {
58
51
  adapter: "lfs";
59
- publicBaseUrl?: string | undefined;
60
52
  }, {
61
53
  adapter: "lfs";
62
- publicBaseUrl?: string | undefined;
63
54
  }>]>;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { z } from 'zod';
5
5
  import { relativePathSchema } from './collection.js';
6
- import { assetMountUrlSchema, uploadTargetUrlSchema } from './url.js';
6
+ import { uploadTargetUrlSchema } from './url.js';
7
7
  // Media adapter configuration schema.
8
8
  // Keyed as a discriminated union on `adapter` so each adapter's required fields are
9
9
  // enforced at parse time. With a plain z.union, a malformed s3 config (e.g. missing
@@ -26,7 +26,6 @@ export const mediaSchema = z.discriminatedUnion('adapter', [
26
26
  z
27
27
  .object({
28
28
  adapter: z.literal('local'),
29
- publicBaseUrl: assetMountUrlSchema.optional(),
30
29
  /** Root directory for local asset storage. Defaults to the caller's dev-assets dir. */
31
30
  directory: relativePathSchema.optional(),
32
31
  })
@@ -36,7 +35,6 @@ export const mediaSchema = z.discriminatedUnion('adapter', [
36
35
  adapter: z.literal('s3'),
37
36
  bucket: z.string().min(1),
38
37
  region: z.string().min(1),
39
- publicBaseUrl: assetMountUrlSchema.optional(),
40
38
  /**
41
39
  * Where the browser POSTs a presigned direct upload. Absolute http(s) URL or a
42
40
  * site-relative path; defaults to the S3 REST endpoint the AWS SDK returns.
@@ -46,10 +44,10 @@ export const mediaSchema = z.discriminatedUnion('adapter', [
46
44
  * signature is unaffected — a presigned POST's string-to-sign is the base64 policy
47
45
  * alone, so the host never enters it (pinned by store-s3.test.ts).
48
46
  *
49
- * NOT a prefix. Unlike `publicBaseUrl`, nothing is joined onto this value; it replaces
50
- * the POST target outright and is passed through byte-for-byte. Do not route it through
51
- * `joinUrlPrefix` "for consistency" — that would strip the trailing slash and silently
52
- * stop a CDN path pattern like `/asset-upload/*` from matching.
47
+ * NOT a prefix: nothing is joined onto this value; it replaces the POST target outright
48
+ * and is passed through byte-for-byte. Do not route it through `joinUrlPrefix` "for
49
+ * consistency" — that would strip the trailing slash and silently stop a CDN path
50
+ * pattern like `/asset-upload/*` from matching.
53
51
  */
54
52
  uploadUrl: uploadTargetUrlSchema.optional(),
55
53
  /** Max upload size in bytes for presigned direct uploads. Defaults to 50 MiB. */
@@ -59,7 +57,6 @@ export const mediaSchema = z.discriminatedUnion('adapter', [
59
57
  z
60
58
  .object({
61
59
  adapter: z.literal('lfs'),
62
- publicBaseUrl: assetMountUrlSchema.optional(),
63
60
  })
64
61
  .strict(),
65
62
  ]);
@@ -13,25 +13,9 @@ import { z } from 'zod';
13
13
  /**
14
14
  * Where the browser POSTs a presigned direct upload (`media.uploadUrl`).
15
15
  *
16
- * Stricter than `assetMountUrlSchema` by exactly one case — no protocol-relative `//host` —
17
- * because that spelling is ambiguous rather than insecure: it resolves to http or https
18
- * depending on the editor page issuing the upload, so the config would not determine where a
19
- * live credential is sent. `isHttpUrlOrSameOriginPath`'s doc carries the full reasoning,
20
- * including why bare `http://` is nonetheless accepted.
21
- *
22
- * "Exactly one case" is measured, not asserted: a census over every 4-character string
23
- * drawn from an 11-symbol alphabet (slash, backslash, dot, colon, %2e, ?, #, tab, and three
24
- * letters), plus hand-written shapes, found 39 values the two schemas treat differently — and
25
- * every one is a literal `//host` (three only after `.trim()` strips a leading tab).
16
+ * `isHttpUrlOrSameOriginPath`'s doc carries the reasoning, including why a protocol-relative
17
+ * `//host` is refused while bare `http://` is accepted.
26
18
  */
27
19
  export declare const uploadTargetUrlSchema: z.ZodEffects<z.ZodString, string, string>;
28
- /**
29
- * Where `/assets/…` is mounted for the editor's own previews (`media.publicBaseUrl`).
30
- *
31
- * Accepts an absolute http(s) URL, a protocol-relative `//host` URL, or a site-relative path
32
- * (see `.claude/future-tasks/editor-asset-mount-topology.md` option 1 — the `basePath` fallback
33
- * in `editor/context/AssetContext.tsx` exists for sites that need one and can't set an absolute
34
- * value). Rejects non-http(s) schemes: a plain `z.string().url()` check would accept
35
- * `publicBaseUrl: 'mailto:a@b.c'` and produce `/mailto:a@b.c/assets/…` at render time.
36
- */
37
- export declare const assetMountUrlSchema: z.ZodEffects<z.ZodString, string, string>;
20
+ /** `editor.previewPrefix`, by `uploadTargetUrlSchema`'s rule: `//host` leaves the scheme open. */
21
+ export declare const previewPrefixSchema: z.ZodEffects<z.ZodString, string, string>;
@@ -14,16 +14,8 @@ import { isHttpUrlOrSameOriginPath } from '../../utils/sanitize-href.js';
14
14
  /**
15
15
  * Where the browser POSTs a presigned direct upload (`media.uploadUrl`).
16
16
  *
17
- * Stricter than `assetMountUrlSchema` by exactly one case — no protocol-relative `//host` —
18
- * because that spelling is ambiguous rather than insecure: it resolves to http or https
19
- * depending on the editor page issuing the upload, so the config would not determine where a
20
- * live credential is sent. `isHttpUrlOrSameOriginPath`'s doc carries the full reasoning,
21
- * including why bare `http://` is nonetheless accepted.
22
- *
23
- * "Exactly one case" is measured, not asserted: a census over every 4-character string
24
- * drawn from an 11-symbol alphabet (slash, backslash, dot, colon, %2e, ?, #, tab, and three
25
- * letters), plus hand-written shapes, found 39 values the two schemas treat differently — and
26
- * every one is a literal `//host` (three only after `.trim()` strips a leading tab).
17
+ * `isHttpUrlOrSameOriginPath`'s doc carries the reasoning, including why a protocol-relative
18
+ * `//host` is refused while bare `http://` is accepted.
27
19
  */
28
20
  export const uploadTargetUrlSchema = z
29
21
  .string()
@@ -31,18 +23,10 @@ export const uploadTargetUrlSchema = z
31
23
  .refine((value) => isHttpUrlOrSameOriginPath(value), {
32
24
  message: 'must be an absolute http(s) URL or a site-relative path beginning with a single "/", with no query or fragment',
33
25
  });
34
- /**
35
- * Where `/assets/…` is mounted for the editor's own previews (`media.publicBaseUrl`).
36
- *
37
- * Accepts an absolute http(s) URL, a protocol-relative `//host` URL, or a site-relative path
38
- * (see `.claude/future-tasks/editor-asset-mount-topology.md` option 1 — the `basePath` fallback
39
- * in `editor/context/AssetContext.tsx` exists for sites that need one and can't set an absolute
40
- * value). Rejects non-http(s) schemes: a plain `z.string().url()` check would accept
41
- * `publicBaseUrl: 'mailto:a@b.c'` and produce `/mailto:a@b.c/assets/…` at render time.
42
- */
43
- export const assetMountUrlSchema = z
26
+ /** `editor.previewPrefix`, by `uploadTargetUrlSchema`'s rule: `//host` leaves the scheme open. */
27
+ export const previewPrefixSchema = z
44
28
  .string()
45
29
  .trim()
46
- .refine((value) => isHttpUrlOrSameOriginPath(value, { allowProtocolRelative: true }), {
47
- message: 'must be an absolute http(s) URL, a protocol-relative "//host" URL, or a site-relative path beginning with a single "/", with no query or fragment',
30
+ .refine((value) => isHttpUrlOrSameOriginPath(value), {
31
+ message: 'editor.previewPrefix must be an absolute http(s) URL or a site-relative path beginning with a single "/", with no query or fragment',
48
32
  });
@@ -132,6 +132,11 @@ export interface BlockFieldConfig extends BaseFieldConfig {
132
132
  export interface ObjectFieldConfig extends BaseFieldConfig {
133
133
  type: 'object';
134
134
  fields: FieldConfig[];
135
+ /**
136
+ * On a `list: true` object, a direct `string` or `number` child whose value titles each
137
+ * item's card; a blank or non-finite value falls back to "<label> #N".
138
+ */
139
+ itemTitleField?: string;
135
140
  }
136
141
  /**
137
142
  * Inline group field config: visually groups fields in the editor without creating
@@ -157,19 +162,16 @@ export type CustomFieldConfig = BaseFieldConfig & {
157
162
  export type FieldConfig = PrimitiveFieldConfig | SelectFieldConfig | ReferenceFieldConfig | ImageFieldConfig | BlockFieldConfig | ObjectFieldConfig | InlineGroupFieldConfig | CustomFieldConfig;
158
163
  export type MediaConfig = {
159
164
  adapter: 'local';
160
- publicBaseUrl?: string;
161
165
  directory?: string;
162
166
  } | {
163
167
  adapter: 's3';
164
168
  bucket: string;
165
169
  region: string;
166
- publicBaseUrl?: string;
167
170
  /** POST target for presigned direct uploads; see mediaSchema's s3 branch. */
168
171
  uploadUrl?: string;
169
172
  maxUploadBytes?: number;
170
173
  } | {
171
174
  adapter: 'lfs';
172
- publicBaseUrl?: string;
173
175
  };
174
176
  /**
175
177
  * Field definitions for one entry type — the array of FieldConfig that
@@ -252,15 +254,27 @@ export interface CanopyEditorConfig {
252
254
  subtitle?: string;
253
255
  theme?: unknown;
254
256
  /**
255
- * Per-collection overrides for the preview pane's URL, keyed by collection path or name
256
- * (e.g. `{ 'content/posts': '/blog' }`) for sites whose routes don't mirror their content tree.
257
+ * Preview-pane routes for sites whose routes don't mirror their content tree; otherwise an entry
258
+ * previews its own `urlPath`. Keyed by a root entry's path (the whole route), else collection
259
+ * path or name (plus the slug). `false` means no page, and the pane says so instead of framing one.
257
260
  *
258
- * Values are **site-relative** and must NOT include the deployment `basePath` — that is applied
259
- * on top of whatever this yields (see `CanopyConfig.basePath`), so including it here would
260
- * prefix it twice. An absolute value (`https://…`) is passed through untouched instead, which
261
- * is the escape hatch for previewing against a different origin entirely.
261
+ * Values are **site-relative**, without the deployment `basePath` (applied on top, so including
262
+ * it prefixes it twice), and get `previewPrefix` too. An absolute value (`https://…`) gets no
263
+ * prefix, only the slug (for a collection key) and `?branch=`: for previewing another origin.
262
264
  */
263
- previewBase?: Record<string, string>;
265
+ previewBase?: Record<string, string | false>;
266
+ /**
267
+ * Where the host mounts the pages the preview pane loads, put in front of every entry's preview
268
+ * URL (`'/preview'` makes `/blog/hello` load `/preview/blog/hello`). Set it when the site's
269
+ * public pages are a static export, which cannot render a requested branch, so the preview
270
+ * must load a route the CMS server renders.
271
+ *
272
+ * A path starting with `/`, without the deployment `basePath` (applied on top, as for
273
+ * `previewBase`), or an absolute `http(s)://` URL, which skips the `basePath`. Pages on another
274
+ * origin accept drafts only with `useCanopyPreview({ editorOrigin })`. An absolute `previewBase`
275
+ * value skips this prefix.
276
+ */
277
+ previewPrefix?: string;
264
278
  onAccountClick?: () => void;
265
279
  onLogoutClick?: () => void;
266
280
  AccountComponent?: React.ComponentType;
@@ -346,6 +360,8 @@ export interface CanopyConfig {
346
360
  defaultRemoteUrl?: DefaultRemoteUrl;
347
361
  gitBotAuthorName: GitBotAuthorName;
348
362
  gitBotAuthorEmail: GitBotAuthorEmail;
363
+ gitEditedByTrailers?: boolean;
364
+ gitCoAuthoredByTrailers?: boolean;
349
365
  githubTokenEnvVar?: GithubTokenEnvVar;
350
366
  mode: CanopyOperatingMode;
351
367
  /** How this build is deployed — see {@link CanopyConfigInput.deployedAs}. */
@@ -353,7 +369,6 @@ export interface CanopyConfig {
353
369
  /** Escape hatch for a prod host with real internet access — see {@link CanopyConfigInput.allowNetworkRemoteInProd}. */
354
370
  allowNetworkRemoteInProd?: boolean;
355
371
  settingsBranch?: string;
356
- autoCreateSettingsPR?: boolean;
357
372
  deploymentName?: string;
358
373
  contentRoot: ContentRoot;
359
374
  sourceRoot?: SourceRoot;
@@ -382,6 +397,10 @@ export interface CanopyConfigInput {
382
397
  defaultRemoteUrl?: string;
383
398
  gitBotAuthorName: string;
384
399
  gitBotAuthorEmail: string;
400
+ /** Add `Edited-by: Name (user id)` for the submitter to submit commits. Default true. */
401
+ gitEditedByTrailers?: boolean;
402
+ /** Also add `Co-authored-by: Name <email>`. Default false: emails in public history are public. */
403
+ gitCoAuthoredByTrailers?: boolean;
385
404
  githubTokenEnvVar?: string;
386
405
  /**
387
406
  * Operating mode: 'prod' or 'dev'. Required — no default (SEC-C1). A prod deploy that
@@ -402,7 +421,6 @@ export interface CanopyConfigInput {
402
421
  */
403
422
  allowNetworkRemoteInProd?: boolean;
404
423
  settingsBranch?: string;
405
- autoCreateSettingsPR?: boolean;
406
424
  deploymentName?: string;
407
425
  contentRoot?: string;
408
426
  sourceRoot?: string;
@@ -474,14 +492,6 @@ export type FlatSchemaItem = {
474
492
  */
475
493
  export type CanopyClientConfig = Pick<CanopyConfig, 'defaultBaseBranch' | 'defaultActiveBranch' | 'contentRoot' | 'editor' | 'mode' | 'entryLinkUrl' | 'basePath'> & {
476
494
  flatSchema: FlatSchemaItem[];
477
- /**
478
- * `media.publicBaseUrl`, when configured - the only part of `media` safe/
479
- * useful to expose client-side (the editor may be served from a different
480
- * origin than the site; the rest of `MediaConfig` - bucket, region, etc -
481
- * has no business in a browser bundle). Threaded through to `Editor`'s
482
- * `assetBaseUrl` prop. Undefined means root-relative asset URLs.
483
- */
484
- assetBaseUrl?: string;
485
495
  };
486
496
  export interface ClientOnlyFields {
487
497
  editor?: {
@@ -25,6 +25,12 @@ export declare const ensureReferenceFieldsHaveScope: (fields: unknown) => void;
25
25
  * can run at config-validation and schema-load time, before any entry exists.
26
26
  */
27
27
  export declare const forEachReferenceField: (fields: unknown, visit: (field: Record<string, unknown>) => void) => void;
28
+ /**
29
+ * Check that every `itemTitleField` sits on a `list: true` object and names a direct child
30
+ * of type `string` or `number`, the only values the card heading shows as typed (a reference
31
+ * would show its raw id, a select its stored value). Throws an error when it does not.
32
+ */
33
+ export declare const ensureItemTitleFieldsExist: (fields: unknown) => void;
28
34
  /**
29
35
  * Validate that inline groups don't cause field name collisions within the same scope.
30
36
  * Because inline groups flatten their children into the parent scope, a field name used
@@ -77,6 +77,43 @@ export const forEachReferenceField = (fields, visit) => {
77
77
  }
78
78
  }
79
79
  };
80
+ /**
81
+ * Check that every `itemTitleField` sits on a `list: true` object and names a direct child
82
+ * of type `string` or `number`, the only values the card heading shows as typed (a reference
83
+ * would show its raw id, a select its stored value). Throws an error when it does not.
84
+ */
85
+ export const ensureItemTitleFieldsExist = (fields) => {
86
+ if (!Array.isArray(fields))
87
+ return;
88
+ for (const field of fields) {
89
+ const f = field;
90
+ if (f?.type === 'object') {
91
+ const children = Array.isArray(f.fields) ? f.fields : [];
92
+ if (f.itemTitleField !== undefined) {
93
+ const label = `Object field "${f.name ?? 'unknown'}" has itemTitleField "${String(f.itemTitleField)}"`;
94
+ if (f.list !== true) {
95
+ throw new Error(`${label}, but itemTitleField applies only to list: true objects`);
96
+ }
97
+ const child = children.find((c) => c?.name === f.itemTitleField);
98
+ if (typeof f.itemTitleField !== 'string' || !child) {
99
+ throw new Error(`${label}, which is not one of its child fields`);
100
+ }
101
+ if (child.type !== 'string' && child.type !== 'number') {
102
+ throw new Error(`${label}, which must name a string or number field`);
103
+ }
104
+ }
105
+ ensureItemTitleFieldsExist(children);
106
+ }
107
+ else if (f?.type === 'group') {
108
+ ensureItemTitleFieldsExist(f.fields);
109
+ }
110
+ else if (f?.type === 'block' && Array.isArray(f.templates)) {
111
+ for (const template of f.templates) {
112
+ ensureItemTitleFieldsExist(template.fields);
113
+ }
114
+ }
115
+ }
116
+ };
80
117
  /**
81
118
  * Validate that inline groups don't cause field name collisions within the same scope.
82
119
  * Because inline groups flatten their children into the parent scope, a field name used