@elytracms/studio 0.0.101 → 0.0.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/convex/asset-meta-patch.test.ts +7 -27
- package/convex/assets.ts +6 -41
- package/convex/cms.ts +2 -29
- package/convex/delivery.ts +2 -2
- package/convex/ingest.test.ts +54 -21
- package/convex/ingest.ts +52 -15
- package/convex/record-functions.ts +15 -82
- package/convex/redirects.ts +11 -116
- package/convex/schema.ts +4 -23
- package/convex/triggers.ts +7 -14
- package/dist/components/ai/ai-chat-panel.js +8 -5
- package/dist/components/ai/ai-chat-panel.js.map +1 -1
- package/dist/components/ai/translate-document-dialog.d.ts +43 -0
- package/dist/components/ai/translate-document-dialog.js +104 -36
- package/dist/components/ai/translate-document-dialog.js.map +1 -1
- package/dist/components/ai/translate-skipped.d.ts +19 -3
- package/dist/components/ai/translate-skipped.js +34 -7
- package/dist/components/ai/translate-skipped.js.map +1 -1
- package/dist/components/assets/asset-detail.js +1 -2
- package/dist/components/assets/asset-detail.js.map +1 -1
- package/dist/components/assets/asset-metadata.d.ts +2 -9
- package/dist/components/assets/asset-metadata.js +3 -10
- package/dist/components/assets/asset-metadata.js.map +1 -1
- package/dist/components/assets/asset-search.js +1 -1
- package/dist/components/assets/asset-search.js.map +1 -1
- package/dist/components/assets/asset-selection.js +2 -2
- package/dist/components/assets/asset-selection.js.map +1 -1
- package/dist/components/assets/assets-collection-view-source.d.ts +2 -3
- package/dist/components/assets/assets-collection-view-source.js +2 -3
- package/dist/components/assets/assets-collection-view-source.js.map +1 -1
- package/dist/components/builder/__fixtures__/reuse-race.d.ts +30 -0
- package/dist/components/builder/__fixtures__/reuse-race.js +77 -0
- package/dist/components/builder/__fixtures__/reuse-race.js.map +1 -0
- package/dist/components/builder/composition-field-editor.js +3 -3
- package/dist/components/builder/composition-field-editor.js.map +1 -1
- package/dist/components/builder/reuse-context.d.ts +2 -1
- package/dist/components/builder/reuse-context.js +5 -20
- package/dist/components/builder/reuse-context.js.map +1 -1
- package/dist/components/builder/reuse.d.ts +18 -11
- package/dist/components/builder/reuse.js +12 -14
- package/dist/components/builder/reuse.js.map +1 -1
- package/dist/components/cms/asset-field.js +1 -3
- package/dist/components/cms/asset-field.js.map +1 -1
- package/dist/components/cms/cell.d.ts +2 -2
- package/dist/components/cms/cell.js +8 -18
- package/dist/components/cms/cell.js.map +1 -1
- package/dist/components/cms/detail-editor.js +2 -1
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/field-control.js +13 -1
- package/dist/components/cms/field-control.js.map +1 -1
- package/dist/lib/ai/chat-context.d.ts +6 -2
- package/dist/lib/ai/chat-context.js +11 -5
- package/dist/lib/ai/chat-context.js.map +1 -1
- package/dist/lib/ai/knowledge.d.ts +9 -9
- package/dist/lib/ai/knowledge.js +22 -0
- package/dist/lib/ai/knowledge.js.map +1 -1
- package/dist/lib/ai/tools.d.ts +8 -1
- package/dist/lib/ai/tools.js +33 -15
- package/dist/lib/ai/tools.js.map +1 -1
- package/dist/lib/ai/translate-apply.d.ts +69 -0
- package/dist/lib/ai/translate-apply.js +36 -0
- package/dist/lib/ai/translate-apply.js.map +1 -0
- package/dist/lib/ai/translate-document.d.ts +101 -7
- package/dist/lib/ai/translate-document.js +189 -54
- package/dist/lib/ai/translate-document.js.map +1 -1
- package/dist/lib/ai/update-fields.js +5 -12
- package/dist/lib/ai/update-fields.js.map +1 -1
- package/dist/lib/ai/writer-form.d.ts +93 -1
- package/dist/lib/ai/writer-form.js +389 -37
- package/dist/lib/ai/writer-form.js.map +1 -1
- package/dist/lib/assets/upload.d.ts +1 -2
- package/dist/lib/assets/upload.js +1 -2
- package/dist/lib/assets/upload.js.map +1 -1
- package/dist/lib/engine-version.d.ts +1 -1
- package/dist/lib/engine-version.js +1 -1
- package/dist/lib/engine-version.js.map +1 -1
- package/dist/lib/i18n/messages.de.js +54 -4
- package/dist/lib/i18n/messages.de.js.map +1 -1
- package/dist/lib/i18n/messages.en.d.ts +44 -1
- package/dist/lib/i18n/messages.en.js +58 -4
- package/dist/lib/i18n/messages.en.js.map +1 -1
- package/dist/lib/operations/cms-persistence.d.ts +20 -10
- package/dist/lib/operations/cms-persistence.js +11 -3
- package/dist/lib/operations/cms-persistence.js.map +1 -1
- package/dist/lib/persistence/convex-adapter.js +7 -2
- package/dist/lib/persistence/convex-adapter.js.map +1 -1
- package/package.json +3 -3
- package/convex/asset-alt-migration.test.ts +0 -127
- package/convex/redirect-migration.test.ts +0 -205
- package/convex/version-kind-stamping.test.ts +0 -118
|
@@ -222,6 +222,9 @@ declare const MESSAGES: {
|
|
|
222
222
|
'operations.error.documentSchemaViolation': import("./types.js").SourceMessage;
|
|
223
223
|
'operations.error.strictReferencesBlockDelete': import("./types.js").SourceMessage;
|
|
224
224
|
'operations.error.strictReferencesBlockDeleteOne': import("./types.js").SourceMessage;
|
|
225
|
+
'operations.error.referencesBlockDelete': import("./types.js").SourceMessage;
|
|
226
|
+
'operations.error.referencesBlockDeleteOne': import("./types.js").SourceMessage;
|
|
227
|
+
'operations.error.referenceChangedBack': import("./types.js").SourceMessage;
|
|
225
228
|
'operations.error.strictReferencesBlockUnpublish': import("./types.js").SourceMessage;
|
|
226
229
|
'operations.error.strictReferencesBlockUnpublishOne': import("./types.js").SourceMessage;
|
|
227
230
|
'operations.error.strictTargetsUnpublishedOne': import("./types.js").SourceMessage;
|
|
@@ -230,7 +233,17 @@ declare const MESSAGES: {
|
|
|
230
233
|
'operations.error.versionNotPinnable': import("./types.js").SourceMessage;
|
|
231
234
|
'operations.error.changesetBlocked': import("./types.js").SourceMessage;
|
|
232
235
|
'operations.error.changesetDeleteNotReversible': import("./types.js").SourceMessage;
|
|
236
|
+
'operations.error.revertReferencedDeleteOne': import("./types.js").SourceMessage;
|
|
237
|
+
'operations.error.revertReferencedDelete': import("./types.js").SourceMessage;
|
|
238
|
+
'operations.error.revertStrictReferencedDeleteOne': import("./types.js").SourceMessage;
|
|
239
|
+
'operations.error.revertStrictReferencedDelete': import("./types.js").SourceMessage;
|
|
240
|
+
'operations.error.revertUnrecorded': import("./types.js").SourceMessage;
|
|
241
|
+
'operations.error.revertChangedSince': import("./types.js").SourceMessage;
|
|
242
|
+
'operations.error.revertGone': import("./types.js").SourceMessage;
|
|
233
243
|
'operations.errorDetail.andMore': import("./types.js").SourceMessage;
|
|
244
|
+
'operations.errorDetail.changesetStepRaced': import("./types.js").SourceMessage;
|
|
245
|
+
'operations.errorDetail.changesetPatchNotInvertible': import("./types.js").SourceMessage;
|
|
246
|
+
'operations.errorDetail.changesetNoInverse': import("./types.js").SourceMessage;
|
|
234
247
|
'content.queryError.nonFilterableField': import("./types.js").SourceMessage;
|
|
235
248
|
'content.queryError.unknownField': import("./types.js").SourceMessage;
|
|
236
249
|
'content.queryError.unknownCollection': import("./types.js").SourceMessage;
|
|
@@ -481,6 +494,7 @@ declare const MESSAGES: {
|
|
|
481
494
|
'cms.issueMessage.preConvergenceV1': import("./types.js").SourceMessage;
|
|
482
495
|
'cms.issueMessage.preConvergenceBareBlocks': import("./types.js").SourceMessage;
|
|
483
496
|
'cms.issueMessage.preConvergencePlaintext': import("./types.js").SourceMessage;
|
|
497
|
+
'cms.issueMessage.untaggedSequenceComponent': import("./types.js").SourceMessage;
|
|
484
498
|
'cms.issueMessage.gateUnknownCollection': import("./types.js").SourceMessage;
|
|
485
499
|
'cms.issueMessage.gateAssetLibraryUnready': import("./types.js").SourceMessage;
|
|
486
500
|
'cms.issueMessage.gateNoLocales': import("./types.js").SourceMessage;
|
|
@@ -664,6 +678,8 @@ declare const MESSAGES: {
|
|
|
664
678
|
'cms.reference.publishedBadge': import("./types.js").SourceMessage;
|
|
665
679
|
'cms.field.rendererCrashed': import("./types.js").SourceMessage;
|
|
666
680
|
'cms.field.noRenderer': import("./types.js").SourceMessage;
|
|
681
|
+
'cms.field.blocksInFieldRow': import("./types.js").SourceMessage;
|
|
682
|
+
'cms.field.noControlForType': import("./types.js").SourceMessage;
|
|
667
683
|
'cms.field.itemActions': import("./types.js").SourceMessage;
|
|
668
684
|
'cms.field.moveUp': import("./types.js").SourceMessage;
|
|
669
685
|
'cms.field.moveDown': import("./types.js").SourceMessage;
|
|
@@ -1139,15 +1155,35 @@ declare const MESSAGES: {
|
|
|
1139
1155
|
'ai.translate.targetsLabel': import("./types.js").SourceMessage;
|
|
1140
1156
|
'ai.translate.scopeLabel': import("./types.js").SourceMessage;
|
|
1141
1157
|
'ai.translate.fillMissing': import("./types.js").SourceMessage;
|
|
1158
|
+
'ai.translate.fillMissingHint': import("./types.js").SourceMessage;
|
|
1142
1159
|
'ai.translate.retranslateAll': import("./types.js").SourceMessage;
|
|
1143
|
-
'ai.translate.
|
|
1160
|
+
'ai.translate.retranslateHint': import("./types.js").SourceMessage;
|
|
1161
|
+
'ai.translate.planReplaceTitle': import("./types.js").SourceMessage;
|
|
1162
|
+
'ai.translate.planReplaceNone': import("./types.js").SourceMessage;
|
|
1163
|
+
'ai.translate.planFillTitle': import("./types.js").SourceMessage;
|
|
1164
|
+
'ai.translate.planWhole': import("./types.js").SourceMessage;
|
|
1165
|
+
'ai.translate.planSlugsKept': import("./types.js").SourceMessage;
|
|
1166
|
+
'ai.translate.planRestorePoint': import("./types.js").SourceMessage;
|
|
1167
|
+
'ai.translate.planKeptTitle': import("./types.js").SourceMessage;
|
|
1144
1168
|
'ai.translate.confirm': import("./types.js").SourceMessage;
|
|
1169
|
+
'ai.translate.confirmReplace': import("./types.js").SourceMessage;
|
|
1145
1170
|
'ai.translate.preparing': import("./types.js").SourceMessage;
|
|
1146
1171
|
'ai.translate.progress': import("./types.js").SourceMessage;
|
|
1147
1172
|
'ai.translate.applying': import("./types.js").SourceMessage;
|
|
1173
|
+
'ai.translate.snapshotLabel': import("./types.js").SourceMessage;
|
|
1174
|
+
'ai.translate.snapshotFailed': import("./types.js").SourceMessage;
|
|
1148
1175
|
'ai.translate.nothing': import("./types.js").SourceMessage;
|
|
1176
|
+
'ai.translate.retranslateNothing': import("./types.js").SourceMessage;
|
|
1149
1177
|
'ai.translate.applied': import("./types.js").SourceMessage;
|
|
1178
|
+
'ai.translate.retranslateDone': import("./types.js").SourceMessage;
|
|
1179
|
+
'ai.translate.replacedTitle': import("./types.js").SourceMessage;
|
|
1180
|
+
'ai.translate.filledTitle': import("./types.js").SourceMessage;
|
|
1181
|
+
'ai.translate.slugsTitle': import("./types.js").SourceMessage;
|
|
1182
|
+
'ai.translate.keptTitle': import("./types.js").SourceMessage;
|
|
1183
|
+
'ai.translate.refusedTitle': import("./types.js").SourceMessage;
|
|
1184
|
+
'ai.translate.restorePoint': import("./types.js").SourceMessage;
|
|
1150
1185
|
'ai.translate.cancelled': import("./types.js").SourceMessage;
|
|
1186
|
+
'ai.translate.retranslateCancelled': import("./types.js").SourceMessage;
|
|
1151
1187
|
'ai.translate.failed': import("./types.js").SourceMessage;
|
|
1152
1188
|
'ai.translate.close': import("./types.js").SourceMessage;
|
|
1153
1189
|
'ai.translate.proposalTitle': import("./types.js").SourceMessage;
|
|
@@ -1157,6 +1193,10 @@ declare const MESSAGES: {
|
|
|
1157
1193
|
'ai.translate.skipped.unreadable': import("./types.js").SourceMessage;
|
|
1158
1194
|
'ai.translate.skipped.notReturned': import("./types.js").SourceMessage;
|
|
1159
1195
|
'ai.translate.skipped.structureChanged': import("./types.js").SourceMessage;
|
|
1196
|
+
'ai.translate.skipped.retranslate.unreadable': import("./types.js").SourceMessage;
|
|
1197
|
+
'ai.translate.skipped.retranslate.notReturned': import("./types.js").SourceMessage;
|
|
1198
|
+
'ai.translate.skipped.retranslate.structureChanged': import("./types.js").SourceMessage;
|
|
1199
|
+
'ai.translate.skipped.locked': import("./types.js").SourceMessage;
|
|
1160
1200
|
'ai.update.proposalTitle': import("./types.js").SourceMessage;
|
|
1161
1201
|
'ai.update.diffBefore': import("./types.js").SourceMessage;
|
|
1162
1202
|
'ai.update.diffAfter': import("./types.js").SourceMessage;
|
|
@@ -1172,12 +1212,15 @@ declare const MESSAGES: {
|
|
|
1172
1212
|
'cms.issueMessage.nonCanonicalValue': import("./types.js").SourceMessage;
|
|
1173
1213
|
'cms.issueMessage.propsNotJudged': import("./types.js").SourceMessage;
|
|
1174
1214
|
'cms.issueMessage.assetHoldsUrl': import("./types.js").SourceMessage;
|
|
1215
|
+
'cms.issueMessage.slugNotSegment': import("./types.js").SourceMessage;
|
|
1216
|
+
'cms.issueMessage.slugNotAddressable': import("./types.js").SourceMessage;
|
|
1175
1217
|
'cms.issueMessage.emptyAllow': import("./types.js").SourceMessage;
|
|
1176
1218
|
'cms.issueMessage.unknownAllowComponent': import("./types.js").SourceMessage;
|
|
1177
1219
|
'cms.issueMessage.blocksNotTopLevel': import("./types.js").SourceMessage;
|
|
1178
1220
|
'cms.issueMessage.placementKeyReserved': import("./types.js").SourceMessage;
|
|
1179
1221
|
'cms.issueMessage.placementNotScalar': import("./types.js").SourceMessage;
|
|
1180
1222
|
'cms.issueMessage.sourceNotOnAssetCollection': import("./types.js").SourceMessage;
|
|
1223
|
+
'cms.issueMessage.blocksOnAssetCollection': import("./types.js").SourceMessage;
|
|
1181
1224
|
'cms.issueMessage.sourceTypeMismatch': import("./types.js").SourceMessage;
|
|
1182
1225
|
'cms.issueMessage.uniqueNotTopLevel': import("./types.js").SourceMessage;
|
|
1183
1226
|
'cms.issueMessage.localizedOnProp': import("./types.js").SourceMessage;
|
|
@@ -291,6 +291,11 @@ const MESSAGES = {
|
|
|
291
291
|
'operations.error.documentSchemaViolation': msg('Document “{collection}:{id}” violates its collection schema.', 'The publish gate rejected the draft; the per-field lines follow beneath it.'),
|
|
292
292
|
'operations.error.strictReferencesBlockDelete': msg('Cannot delete “{target}”: {count} documents reference it through strict relation fields — {named}{more}. Remove these references first.', '{named} is an identifier list “collection:id” (field); {more} is the andMore fragment or empty.'),
|
|
293
293
|
'operations.error.strictReferencesBlockDeleteOne': msg('Cannot delete “{target}”: {count} document references it through strict relation fields — {named}. Remove these references first.'),
|
|
294
|
+
// EC-739 — an UNREFERENCED delete (a cleanup, e.g. Make reusable's Undo): refused by a reference of any strictness.
|
|
295
|
+
'operations.error.referencesBlockDelete': msg('Cannot delete “{target}”: {count} documents reference it — {named}{more}. This delete runs only while nothing references it.', '{named} is an identifier list “collection:id” (field); {more} is the andMore fragment or empty.'),
|
|
296
|
+
'operations.error.referencesBlockDeleteOne': msg('Cannot delete “{target}”: {count} document references it — {named}. This delete runs only while nothing references it.'),
|
|
297
|
+
// EC-745 item 2 — the store refused a write on a reference precondition, and the fresh re-judge found nothing wrong.
|
|
298
|
+
'operations.error.referenceChangedBack': msg('“{target}” was not written: a reference it depends on changed while the write was on its way, and has changed back since — try again.'),
|
|
294
299
|
'operations.error.strictReferencesBlockUnpublish': msg('Cannot unpublish “{target}”: {count} documents reference it through strict relation fields — {named}{more}. Remove these references first.'),
|
|
295
300
|
'operations.error.strictReferencesBlockUnpublishOne': msg('Cannot unpublish “{target}”: {count} document references it through strict relation fields — {named}. Remove these references first.'),
|
|
296
301
|
// EC-589 — the referrer direction of `strict: true`: publish refused while a strict target is missing or unpublished.
|
|
@@ -301,7 +306,19 @@ const MESSAGES = {
|
|
|
301
306
|
// EC-648 — changesets: apply blocked by an issue, and the step a changeset refuses because no undo can reverse it.
|
|
302
307
|
'operations.error.changesetBlocked': msg('Changeset “{changeset}” has blocking validation issues and cannot be applied.', '{changeset} is a changeset id, e.g. cs-0001; the blocking issues follow beneath it.'),
|
|
303
308
|
'operations.error.changesetDeleteNotReversible': msg('Step {step}: “{target}” cannot be deleted inside a changeset — a delete removes its version history and publication, which no undo can restore. Delete it on its own.', 'EC-648: {step} is the 0-based step number; {target} is the document key collection:id.'),
|
|
309
|
+
// EC-745 — a changeset revert refused whole, before any write: it would delete a document referenced since (deleteReferenced is a caller option, an identifier), a step that recorded no undo, or a document that moved.
|
|
310
|
+
'operations.error.revertReferencedDeleteOne': msg('Revert of changeset “{changeset}” refused: it would delete “{target}”, and {count} document references it — {named}. Nothing was reverted. Revert with deleteReferenced: true to delete it anyway; the reference then dangles.', '“deleteReferenced: true” is a code option — keep it untranslated.'),
|
|
311
|
+
'operations.error.revertReferencedDelete': msg('Revert of changeset “{changeset}” refused: it would delete “{target}”, and {count} documents reference it — {named}{more}. Nothing was reverted. Revert with deleteReferenced: true to delete it anyway; the references then dangle.', '{named} is an identifier list “collection:id” (field); {more} is the andMore fragment or empty.'),
|
|
312
|
+
'operations.error.revertStrictReferencedDeleteOne': msg('Revert of changeset “{changeset}” refused: it would delete “{target}”, and {count} document references it through strict relation fields — {named}. Nothing was reverted. Remove these references first.'),
|
|
313
|
+
'operations.error.revertStrictReferencedDelete': msg('Revert of changeset “{changeset}” refused: it would delete “{target}”, and {count} documents reference it through strict relation fields — {named}{more}. Nothing was reverted. Remove these references first.'),
|
|
314
|
+
'operations.error.revertUnrecorded': msg('Revert of changeset “{changeset}” refused: step {step} (“{operation}”, {target}): {reason} — nothing was reverted.', '{operation} is a dotted operation name; {reason} is one of the changeset step reasons below.'),
|
|
315
|
+
'operations.error.revertChangedSince': msg('Revert of changeset “{changeset}” refused: “{target}” changed since the changeset applied (now at revision {revision}, the changeset left it at {left}) — nothing was reverted.', '{revision} and {left} are revision numbers.'),
|
|
316
|
+
'operations.error.revertGone': msg('Revert of changeset “{changeset}” refused: “{target}” no longer exists — nothing was reverted.'),
|
|
304
317
|
'operations.errorDetail.andMore': msg(', and {count} more', 'Truncation fragment spliced into the strict-reference sentences; keeps its leading comma and space.'),
|
|
318
|
+
// EC-745 — the reasons a changeset step records for having no undo, spliced into revertUnrecorded's {reason}.
|
|
319
|
+
'operations.errorDetail.changesetStepRaced': msg('another write landed between the changeset’s read of the document and this step’s own write, so what the step replaced was never recorded'),
|
|
320
|
+
'operations.errorDetail.changesetPatchNotInvertible': msg('another write landed between the changeset’s read and this patch’s own write, and the patch changed structure (or its patch-log row is gone), which cannot be undone position by position'),
|
|
321
|
+
'operations.errorDetail.changesetNoInverse': msg('no inverse was recorded'),
|
|
305
322
|
// EC-494 — content-query errors (`core/content`'s validateWhere/validateSort/
|
|
306
323
|
// validateLimit). Two studio surfaces render them: the filter builder's per-clause
|
|
307
324
|
// line and the canvas listing notice.
|
|
@@ -621,6 +638,7 @@ const MESSAGES = {
|
|
|
621
638
|
'cms.issueMessage.preConvergenceV1': msg('Field "{field}" holds a pre-convergence content shape (the v1 "{ version, doc }" envelope) — the engine reads only the converged "{ version: 2, content }" sequence. Re-seed this content.'),
|
|
622
639
|
'cms.issueMessage.preConvergenceBareBlocks': msg('Field "{field}" holds a pre-convergence content shape (a bare composition node list) — the engine reads only the converged "{ version: 2, content }" sequence. Re-seed this content.'),
|
|
623
640
|
'cms.issueMessage.preConvergencePlaintext': msg('Field "{field}" holds a pre-convergence content shape (legacy plain text) — the engine reads only the converged "{ version: 2, content }" sequence. Re-seed this content.'),
|
|
641
|
+
'cms.issueMessage.untaggedSequenceComponent': msg('Field "{field}" holds the component "{component}" (node "{node}") without its "elytra/component" tag in a content list — the engine reads only tagged components there, so the whole value renders its invalid-content fallback. It was written past the write path; save the field again through the editor or re-seed it.'),
|
|
624
642
|
'cms.issueMessage.gateUnknownCollection': msg('The project declares no collection “{collection}” — there are no rules to publish it by.', 'EC-595 A2 (F23): the publish gate refuses a document of a collection the project config does not declare. {collection} is the collection id.'),
|
|
625
643
|
'cms.issueMessage.gateAssetLibraryUnready': msg('The asset library could not be read — refusing to publish unverified asset references. Try again.', 'EC-595 A2 (EC-588, ruled 1f): the publish gate could not read the asset library, so a document that references assets is refused instead of published with the asset checks off.'),
|
|
626
644
|
'cms.issueMessage.gateNoLocales': msg('The project declares no locales — refusing to publish without them.', 'EC-595 A2: the publish gate refuses when the project config declares no locales (the storage key of every localized value).'),
|
|
@@ -827,6 +845,8 @@ const MESSAGES = {
|
|
|
827
845
|
// ─────────────────────────────────────────────────────────────────────────
|
|
828
846
|
'cms.field.rendererCrashed': msg('Custom renderer crashed — showing the built-in control.'),
|
|
829
847
|
'cms.field.noRenderer': msg('No field renderer registered for control “{control}”.'),
|
|
848
|
+
'cms.field.blocksInFieldRow': msg('A blocks field is edited as the page canvas on a form tab of its own — it has no field row here.', 'EC-740: notice in place of a field row for a blocks (composition) field, e.g. one placed in the Details pane.'),
|
|
849
|
+
'cms.field.noControlForType': msg('No built-in control for the field type “{type}”.'),
|
|
830
850
|
'cms.field.itemActions': msg('Item actions'),
|
|
831
851
|
'cms.field.moveUp': msg('Move up'),
|
|
832
852
|
'cms.field.moveDown': msg('Move down'),
|
|
@@ -1386,21 +1406,42 @@ const MESSAGES = {
|
|
|
1386
1406
|
'ai.error.stepCap': msg('The assistant stopped after {max} tool steps. Send a follow-up message to continue.', 'EC-334 per-turn step cap. {max} is a number.'),
|
|
1387
1407
|
// EC-332 — full-document translation (header action + chat tool)
|
|
1388
1408
|
'ai.translate.action': msg('Translate document'),
|
|
1389
|
-
'ai.translate.tooltip': msg('
|
|
1409
|
+
'ai.translate.tooltip': msg('Translate this document into its other languages with AI'),
|
|
1390
1410
|
'ai.translate.dialogTitle': msg('Translate document'),
|
|
1391
|
-
'ai.translate.dialogDescription': msg('
|
|
1411
|
+
'ai.translate.dialogDescription': msg('Translate this document from {base} using AI.', '{base} is a language name, e.g. English.'),
|
|
1392
1412
|
'ai.translate.targetsLabel': msg('Target languages'),
|
|
1393
1413
|
'ai.translate.scopeLabel': msg('What to translate'),
|
|
1394
1414
|
'ai.translate.fillMissing': msg('Fill missing translations only'),
|
|
1415
|
+
'ai.translate.fillMissingHint': msg('Fills only the values that still follow {base}. A value with its own translation is never overwritten.', '{base} is a language name, e.g. English.'),
|
|
1395
1416
|
'ai.translate.retranslateAll': msg('Re-translate everything'),
|
|
1396
|
-
|
|
1417
|
+
// EC-752 — re-translate everything: the confirm lists what it replaces (from the run's own plan).
|
|
1418
|
+
'ai.translate.retranslateHint': msg('Translates every value again from {base} — values that already have their own translation are replaced.', '{base} is a language name, e.g. English.'),
|
|
1419
|
+
'ai.translate.planReplaceTitle': msg('Replaced with a new translation of {base} (up to {count})', 'Heading of the list of field × language values a re-translation overwrites, rebuilt from the source language. "Up to": a value whose translation does not fully arrive is left as it was. {base} is a language name, {count} a number.'),
|
|
1420
|
+
'ai.translate.planReplaceNone': msg('No value has its own translation yet — nothing is replaced.'),
|
|
1421
|
+
'ai.translate.planFillTitle': msg('Filled from {base} (up to {count})', '{base} is a language name, {count} a number.'),
|
|
1422
|
+
'ai.translate.planWhole': msg('A value is replaced only when all of it was translated; otherwise it is left as it was.'),
|
|
1423
|
+
'ai.translate.planSlugsKept': msg('A slug a language already has is kept — changing it would move the page’s address.'),
|
|
1424
|
+
'ai.translate.planRestorePoint': msg('A version of the document is saved first, so you can restore any replaced value from Versions.', '"Versions" is the document’s version-history pane (cms.version.paneLabel).'),
|
|
1425
|
+
'ai.translate.planKeptTitle': msg('Left as they are ({count})', '{count} is a number.'),
|
|
1397
1426
|
'ai.translate.confirm': msg('Translate'),
|
|
1427
|
+
'ai.translate.confirmReplace': msg('Re-translate and replace', 'The deliberate confirm of a re-translation that overwrites existing translations.'),
|
|
1398
1428
|
'ai.translate.preparing': msg('Preparing translation…'),
|
|
1399
1429
|
'ai.translate.progress': msg('Translating {completed} of {total}…', '{completed}/{total} are numbers.'),
|
|
1400
1430
|
'ai.translate.applying': msg('Saving translations…'),
|
|
1431
|
+
'ai.translate.snapshotLabel': msg('Before re-translation', 'The label of the version saved right before a re-translation replaces values.'),
|
|
1432
|
+
'ai.translate.snapshotFailed': msg('Could not save a version before re-translating — nothing was changed. Please try again.'),
|
|
1401
1433
|
'ai.translate.nothing': msg('Everything is already translated — there is nothing to fill.'),
|
|
1434
|
+
'ai.translate.retranslateNothing': msg('There is nothing to re-translate — no field holds text in {base}.', '{base} is a language name, e.g. English.'),
|
|
1402
1435
|
'ai.translate.applied': msg('Filled {count} translations across {locales} languages.', '{count}/{locales} are numbers.'),
|
|
1436
|
+
'ai.translate.retranslateDone': msg('Re-translation finished.'),
|
|
1437
|
+
'ai.translate.replacedTitle': msg('Replaced ({count})', '{count} is a number.'),
|
|
1438
|
+
'ai.translate.filledTitle': msg('Filled ({count})', '{count} is a number.'),
|
|
1439
|
+
'ai.translate.slugsTitle': msg('Slugs set from the translation ({count})', '{count} is a number.'),
|
|
1440
|
+
'ai.translate.keptTitle': msg('Left as they were ({count})', '{count} is a number.'),
|
|
1441
|
+
'ai.translate.refusedTitle': msg('Changed by someone else meanwhile ({count}) — decide in the editor', '{count} is a number.'),
|
|
1442
|
+
'ai.translate.restorePoint': msg('The values from before are saved as version v{version} — restore any of them from Versions.', '{version} is a version number. "Versions" is the document’s version-history pane.'),
|
|
1403
1443
|
'ai.translate.cancelled': msg('Translation cancelled — partial results were kept on the draft.'),
|
|
1444
|
+
'ai.translate.retranslateCancelled': msg('Re-translation cancelled — values translated completely were replaced; the rest were left as they were.'),
|
|
1404
1445
|
'ai.translate.failed': msg('Translation failed. Please try again.'),
|
|
1405
1446
|
'ai.translate.close': msg('Close'),
|
|
1406
1447
|
'ai.translate.proposalTitle': msg('Translation of {collection}'),
|
|
@@ -1411,6 +1452,13 @@ const MESSAGES = {
|
|
|
1411
1452
|
'ai.translate.skipped.unreadable': msg('its stored value could not be read'),
|
|
1412
1453
|
'ai.translate.skipped.notReturned': msg('the assistant returned no text for it'),
|
|
1413
1454
|
'ai.translate.skipped.structureChanged': msg('the translation lost formatting, links or embedded items — the original was kept'),
|
|
1455
|
+
// EC-752 — in a re-translation a value is written whole or not at all.
|
|
1456
|
+
'ai.translate.skipped.retranslate.unreadable': msg('its stored value could not be read — the whole value was left as it was'),
|
|
1457
|
+
'ai.translate.skipped.retranslate.notReturned': msg('the assistant returned no text for it — the whole value was left as it was'),
|
|
1458
|
+
'ai.translate.skipped.retranslate.structureChanged': msg('the translation lost formatting, links or embedded items — the whole value was left as it was'),
|
|
1459
|
+
// EC-738 — a bucket whose read-only (or AI-excluded) content is shaped differently from the source's;
|
|
1460
|
+
// EC-748/752 — or stored in a shape the configuration no longer reads.
|
|
1461
|
+
'ai.translate.skipped.locked': msg('it holds content that cannot be changed here, arranged differently from the source or stored in a shape the configuration no longer reads (save it in the editor first) — left as it is'),
|
|
1414
1462
|
// EC-378 — the update (edit-existing) proposal
|
|
1415
1463
|
'ai.update.proposalTitle': msg('Changes to {collection}'),
|
|
1416
1464
|
'ai.update.diffBefore': msg('Current'),
|
|
@@ -1430,9 +1478,13 @@ const MESSAGES = {
|
|
|
1430
1478
|
'builder.inspector.unset': msg('Not set', 'An inspector prop with no value — the component uses its own default.'),
|
|
1431
1479
|
'builder.inspector.unsetWithHint': msg('Not set (default: {hint})', '{hint} is the manifest default shown as a suggestion, e.g. "vertical" or "2".'),
|
|
1432
1480
|
// EC-586 / EC-581 (wave-0092, zone A) — canonical values and the per-FieldType definition
|
|
1433
|
-
'cms.issueMessage.nonCanonicalValue': msg('Field "{field}" is stored in a non-canonical form for a "{type}" field — it was written past the write path that stores one form per field type.
|
|
1481
|
+
'cms.issueMessage.nonCanonicalValue': msg('Field "{field}" is stored in a non-canonical form for a "{type}" field — it was written past the write path that stores one form per field type. Save the field again through the editor or an operation to store the canonical form.'),
|
|
1434
1482
|
'cms.issueMessage.propsNotJudged': msg('The component props in field "{field}" were not judged: the page was resolved without a component registry, so they are delivered as stored and their issues are not reported.'),
|
|
1435
1483
|
'cms.issueMessage.assetHoldsUrl': msg('Asset field "{field}" holds a URL — an asset value is a library asset, never a URL. Upload the image to the library and pick it, or put an external image’s address in the component’s URL prop (the Image’s “Image URL”).'),
|
|
1484
|
+
// EC-733 — the slug role holds what the slug rule writes
|
|
1485
|
+
'cms.issueMessage.slugNotSegment': msg('Slug field "{field}" holds "{value}", which is not a slug by the field\'s slug rule — the rule writes "{slug}" for it. Store the slug the rule writes.'),
|
|
1486
|
+
// EC-749 — a slug the route codec cannot carry as one URL segment
|
|
1487
|
+
'cms.issueMessage.slugNotAddressable': msg('Slug field "{field}" holds "{value}", which cannot be one URL segment: a browser removes a "." or ".." segment before the request, and a "/" reads as a nested path. No URL is built from it — change the slug.'),
|
|
1436
1488
|
// EC-584 — the AllowList parse (config load / registration).
|
|
1437
1489
|
'cms.issueMessage.emptyAllow': msg('Field "{field}" declares an empty "allow" — a list permits exactly the ids it names, so an empty one permits nothing. Omit "allow" for the type\'s default vocabulary, or list the component ids.'),
|
|
1438
1490
|
'cms.issueMessage.unknownAllowComponent': msg('Field "{field}" allows "{component}", which is not a component of this project — check the id, or remove it from "allow".', '{component} is the component id as declared in the field\'s allow list.'),
|
|
@@ -1440,6 +1492,8 @@ const MESSAGES = {
|
|
|
1440
1492
|
'cms.issueMessage.placementKeyReserved': msg('Asset field "{asset}" declares the per-use sub-field "{field}", a name the asset itself owns — it would never reach a component (the asset\'s own "{field}" wins). Rename it; an image\'s alt, credit or AI fact belongs on the asset collection.'),
|
|
1441
1493
|
'cms.issueMessage.placementNotScalar': msg('Asset field "{asset}" declares the per-use sub-field "{field}" of type "{type}" — a placement holds data about this use of the image (a caption, a layout), never a reference or rich text.'),
|
|
1442
1494
|
'cms.issueMessage.sourceNotOnAssetCollection': msg('Field "{field}" declares source "{source}" — an embedded-metadata source fills a top-level field of the asset collection only.'),
|
|
1495
|
+
// EC-753 — no canvas on an asset
|
|
1496
|
+
'cms.issueMessage.blocksOnAssetCollection': msg('Field "{field}" is a "blocks" field on the asset collection "{collection}" — an asset holds facts about its file (alt text, a credit, a caption), never a canvas. Remove the field; a page composition belongs on a document collection.'),
|
|
1443
1497
|
'cms.issueMessage.sourceTypeMismatch': msg('Field "{field}" declares source "{source}", which cannot fill a "{type}" field (every source fills text; iptc:digitalSourceType also a boolean).'),
|
|
1444
1498
|
'cms.issueMessage.uniqueNotTopLevel': msg('Sub-field "{field}" declares "unique" — uniqueness is judged across a collection\'s documents, so it applies to top-level fields only.'),
|
|
1445
1499
|
'cms.issueMessage.localizedOnProp': msg('Component prop "{field}" declares "localized" — a localized value is stored per locale under the document, so only a top-level document field can be localized (localize the field that holds the composition).'),
|