@gentbajko/slopify 3.25.9 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/account-limits.js +30 -0
- package/dist/adapters/alignment/audio.js +1 -1
- package/dist/adapters/alignment/cache.js +4 -6
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +2 -4
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/runner.js +1 -1
- package/dist/adapters/alignment/worker.js +3 -2
- package/dist/adapters/explain.js +10 -12
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +21 -4
- package/dist/adapters/host-cli/transport.js +2 -1
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/bytes.js +2 -1
- package/dist/adapters/image/codex.js +42 -9
- package/dist/adapters/image/fal.js +21 -53
- package/dist/adapters/image/google.js +33 -56
- package/dist/adapters/image/models.js +2 -2
- package/dist/adapters/image/openai.js +22 -48
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +21 -49
- package/dist/adapters/image/video.js +2 -1
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +54 -3
- package/dist/adapters/llm/antigravity-models.js +1 -1
- package/dist/adapters/llm/antigravity.js +11 -6
- package/dist/adapters/llm/assistant-cli.js +388 -0
- package/dist/adapters/llm/child-session.js +83 -0
- package/dist/adapters/llm/claude-code-models.js +52 -99
- package/dist/adapters/llm/claude-code.js +16 -4
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-models.js +1 -1
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/document-workspace.js +3 -2
- package/dist/adapters/llm/image-workspace.js +3 -2
- package/dist/adapters/llm/openrouter.js +12 -48
- package/dist/adapters/llm/run-cli.js +9 -24
- package/dist/adapters/llm/sse-lines.js +5 -1
- package/dist/adapters/model-access.js +37 -0
- package/dist/adapters/tts/cartesia.js +15 -46
- package/dist/adapters/tts/elevenlabs.js +20 -52
- package/dist/adapters/tts/gemini.js +21 -41
- package/dist/adapters/tts/inworld-async.js +6 -2
- package/dist/adapters/tts/inworld.js +6 -2
- package/dist/adapters/tts/openai.js +20 -50
- package/dist/adapters/tts/system.js +2 -1
- package/dist/assets/models-lifecycle.yaml +6 -0
- package/dist/assistant-wiring.js +60 -0
- package/dist/autopilot-timers.js +59 -0
- package/dist/catalog/lifecycle.js +52 -0
- package/dist/catalog/propose.js +204 -0
- package/dist/catalog/registry.js +23 -14
- package/dist/catalog/schema.js +4 -1
- package/dist/catalog/store.js +39 -0
- package/dist/catalog/validate.js +5 -2
- package/dist/edge/autostart/native.js +3 -5
- package/dist/edge/autostart/prompt.js +2 -1
- package/dist/edge/autostart/service.js +3 -4
- package/dist/edge/cli-args.js +3 -4
- package/dist/edge/cli.js +2 -1
- package/dist/edge/docker-install/apply.js +11 -11
- package/dist/edge/docker-install/run.js +2 -1
- package/dist/edge/docker-install/state.js +4 -3
- package/dist/edge/docker-install/tree.js +2 -4
- package/dist/edge/docker-install/volume.js +3 -2
- package/dist/edge/docker.js +5 -4
- package/dist/edge/events/hub.js +5 -5
- package/dist/edge/http/actions.js +11 -32
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +86 -11
- package/dist/edge/http/assistant.js +129 -0
- package/dist/edge/http/audio-preview.js +4 -11
- package/dist/edge/http/auditions.js +1 -1
- package/dist/edge/http/autostart.js +5 -5
- package/dist/edge/http/backups.js +2 -4
- package/dist/edge/http/channel-memory.js +9 -22
- package/dist/edge/http/channels.js +14 -27
- package/dist/edge/http/checkpoints.js +39 -21
- package/dist/edge/http/design-templates.js +167 -0
- package/dist/edge/http/designs.js +178 -0
- package/dist/edge/http/diagnostics.js +5 -1
- package/dist/edge/http/document-themes.js +5 -14
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +5 -10
- package/dist/edge/http/drafts.js +3 -3
- package/dist/edge/http/entries.js +6 -9
- package/dist/edge/http/extension-auth.js +27 -0
- package/dist/edge/http/external-reviews.js +12 -11
- package/dist/edge/http/files.js +5 -11
- package/dist/edge/http/folder-location.js +1 -4
- package/dist/edge/http/fonts.js +0 -7
- package/dist/edge/http/home.js +47 -14
- package/dist/edge/http/host-cli.js +18 -8
- package/dist/edge/http/ids.js +8 -0
- package/dist/edge/http/keywords.js +35 -0
- package/dist/edge/http/model-checks.js +132 -0
- package/dist/edge/http/narration-peaks.js +5 -13
- package/dist/edge/http/onboarding.js +30 -26
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +7 -14
- package/dist/edge/http/patch-notes.js +6 -12
- package/dist/edge/http/planning.js +3 -7
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +2 -1
- package/dist/edge/http/project-templates.js +31 -19
- package/dist/edge/http/projects.js +24 -16
- package/dist/edge/http/prompts.js +9 -16
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +48 -34
- package/dist/edge/http/refusal.js +29 -0
- package/dist/edge/http/remote-access.js +40 -0
- package/dist/edge/http/remote-guard.js +71 -0
- package/dist/edge/http/request-guard.js +91 -0
- package/dist/edge/http/reviews.js +12 -25
- package/dist/edge/http/revision-files.js +6 -11
- package/dist/edge/http/revisions.js +14 -19
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +69 -40
- package/dist/edge/http/settings.js +27 -14
- package/dist/edge/http/social.js +283 -0
- package/dist/edge/http/staging.js +3 -5
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +33 -25
- package/dist/edge/http/studio.js +94 -69
- package/dist/edge/http/style-preview.js +3 -6
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +436 -0
- package/dist/edge/http/trash.js +11 -12
- package/dist/edge/http/tutorial.js +1 -2
- package/dist/edge/http/tutorials.js +5 -11
- package/dist/edge/http/update.js +7 -13
- package/dist/edge/http/waveform.js +3 -6
- package/dist/edge/http/youtube-edits.js +3 -4
- package/dist/edge/mcp/assistant.js +279 -0
- package/dist/edge/mcp/attribution.js +8 -2
- package/dist/edge/mcp/call-route.js +11 -2
- package/dist/edge/mcp/excluded-routes.js +29 -3
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +6 -4
- package/dist/edge/mcp/library-tools.js +9 -5
- package/dist/edge/mcp/remake-tools.js +7 -4
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +11 -9
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +19 -7
- package/dist/edge/mcp/tools-planning.js +40 -21
- package/dist/edge/mcp/tools-projects.js +38 -11
- package/dist/edge/mcp/tools-publishing.js +9 -9
- package/dist/edge/mcp/tools-runs.js +23 -10
- package/dist/edge/mcp/tools-schedules.js +32 -8
- package/dist/edge/mcp/tools-setup.js +75 -11
- package/dist/edge/mcp/tools-social.js +47 -0
- package/dist/edge/mcp/tools-storage.js +11 -3
- package/dist/edge/mcp/tools-template-studio.js +166 -0
- package/dist/edge/mcp/tools.js +6 -0
- package/dist/edge/remote-access/cli.js +71 -0
- package/dist/edge/remote-access/model.js +32 -0
- package/dist/edge/remote-access/rules.js +207 -0
- package/dist/edge/remote-access/service.js +203 -0
- package/dist/edge/remote-access/store.js +44 -0
- package/dist/edge/remote-access/views.js +43 -0
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/host-cli/install.js +2 -2
- package/dist/host-cli/open-folder.js +2 -2
- package/dist/host-cli/paths.js +2 -4
- package/dist/host-cli/server.js +4 -4
- package/dist/host-cli/service.js +3 -3
- package/dist/host-cli/status.js +7 -7
- package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
- package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
- package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
- package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
- package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
- package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
- package/dist/kernel/db/migrations/0070-designs.sql +53 -0
- package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
- package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
- package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
- package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
- package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
- package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
- package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
- package/dist/kernel/db/migrations/0078-uploaded-from-links.sql +7 -0
- package/dist/kernel/db/tx.js +2 -4
- package/dist/kernel/errors.js +27 -1
- package/dist/kernel/json-answer.js +15 -0
- package/dist/kernel/lock.js +4 -9
- package/dist/kernel/paths.js +8 -0
- package/dist/kernel/pipeline.js +12 -0
- package/dist/kernel/ports/assistant-cli.js +4 -0
- package/dist/kernel/ports/host-cli.js +3 -0
- package/dist/kernel/ports/interest.js +4 -0
- package/dist/kernel/ports/languages.js +0 -3
- package/dist/kernel/ports/model.js +2 -0
- package/dist/kernel/ports/settings-places.js +31 -0
- package/dist/kernel/ports/system-speech.js +31 -3
- package/dist/kernel/runner/attempt.js +14 -4
- package/dist/kernel/runner/audition.js +3 -1
- package/dist/kernel/runner/checkpoint-authority.js +2 -1
- package/dist/kernel/runner/index.js +8 -10
- package/dist/kernel/runner/model-access.js +40 -0
- package/dist/kernel/runner/model-check.js +153 -0
- package/dist/kernel/runner/providers.js +18 -12
- package/dist/kernel/runner/standalone.js +11 -7
- package/dist/main.js +338 -21
- package/dist/model-catalog.js +20 -0
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/4.1.0.md +42 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/listing-facts.js +95 -0
- package/dist/slices/admission/repo.js +11 -7
- package/dist/slices/admission/rules.js +50 -15
- package/dist/slices/admission/schema.js +8 -0
- package/dist/slices/admission/stage-writes.js +0 -3
- package/dist/slices/admission/start.js +48 -31
- package/dist/slices/admission/state-words.js +34 -5
- package/dist/slices/admission/substitute.js +7 -4
- package/dist/slices/agents/attention-posts.js +31 -0
- package/dist/slices/agents/attention-templates.js +33 -0
- package/dist/slices/agents/attention.js +10 -1
- package/dist/slices/agents/connection.js +2 -6
- package/dist/slices/agents/model.js +6 -3
- package/dist/slices/agents/repo.js +15 -7
- package/dist/slices/article/continuation.js +0 -63
- package/dist/slices/article/plain.js +3 -2
- package/dist/slices/article/segments.js +2 -62
- package/dist/slices/assistant/access.js +1 -0
- package/dist/slices/assistant/asks.js +80 -0
- package/dist/slices/assistant/cost.js +54 -0
- package/dist/slices/assistant/gate.js +222 -0
- package/dist/slices/assistant/model.js +86 -0
- package/dist/slices/assistant/names.js +23 -0
- package/dist/slices/assistant/prompt.js +74 -0
- package/dist/slices/assistant/repo.js +74 -0
- package/dist/slices/assistant/tokens.js +18 -0
- package/dist/slices/assistant/turn.js +344 -0
- package/dist/slices/autopilot/buffer.js +76 -0
- package/dist/slices/autopilot/model.js +14 -0
- package/dist/slices/autopilot/notify.js +27 -0
- package/dist/slices/autopilot/repo.js +34 -0
- package/dist/slices/autopilot/signals.js +194 -0
- package/dist/slices/autopilot/warnings.js +85 -0
- package/dist/slices/autopilot/weekly.js +100 -0
- package/dist/slices/backups/files.js +2 -6
- package/dist/slices/backups/repo.js +3 -15
- package/dist/slices/backups/service.js +8 -7
- package/dist/slices/channels/cast-images.js +3 -2
- package/dist/slices/channels/model.js +0 -1
- package/dist/slices/channels/rebrand.js +0 -3
- package/dist/slices/channels/repo.js +4 -0
- package/dist/slices/channels/schema.js +7 -1
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +3 -15
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +2 -28
- package/dist/slices/designs/artwork.js +66 -0
- package/dist/slices/designs/budget.js +23 -0
- package/dist/slices/designs/calls.js +124 -0
- package/dist/slices/designs/check-context.js +38 -0
- package/dist/slices/designs/check-text.js +43 -0
- package/dist/slices/designs/fields.js +88 -0
- package/dist/slices/designs/frames.js +34 -0
- package/dist/slices/designs/gate.js +130 -0
- package/dist/slices/designs/layout.js +293 -0
- package/dist/slices/designs/model.js +35 -0
- package/dist/slices/designs/pdf-job.js +23 -0
- package/dist/slices/designs/pdf-pages.js +30 -0
- package/dist/slices/designs/pdf-runner.js +68 -0
- package/dist/slices/designs/pdf-worker.js +24 -0
- package/dist/slices/designs/picture-size.js +79 -0
- package/dist/slices/designs/pictures.js +55 -0
- package/dist/slices/designs/quote.js +24 -0
- package/dist/slices/designs/render-args.js +36 -0
- package/dist/slices/designs/render-input.js +59 -0
- package/dist/slices/designs/render.js +215 -0
- package/dist/slices/designs/repo.js +101 -0
- package/dist/slices/designs/requests.js +80 -0
- package/dist/slices/designs/runner.js +239 -0
- package/dist/slices/designs/sample-repo.js +91 -0
- package/dist/slices/designs/sample.js +223 -0
- package/dist/slices/designs/schema.js +87 -0
- package/dist/slices/designs/sections.js +44 -0
- package/dist/slices/designs/service.js +233 -0
- package/dist/slices/designs/steps-repo.js +102 -0
- package/dist/slices/designs/studio-kind.js +39 -0
- package/dist/slices/designs/template-checks.js +44 -0
- package/dist/slices/designs/template-make.js +118 -0
- package/dist/slices/designs/templates.js +218 -0
- package/dist/slices/document/fonts.js +2 -1
- package/dist/slices/document/model.js +7 -4
- package/dist/slices/document/render.js +2 -1
- package/dist/slices/document/theme-schema.js +1 -1
- package/dist/slices/document/theme.js +49 -3
- package/dist/slices/episodes/summarize.js +6 -2
- package/dist/slices/estimate/index.js +72 -28
- package/dist/slices/estimate/requests.js +4 -4
- package/dist/slices/fixes/rules.js +3 -1
- package/dist/slices/fonts/catalog.js +5 -3
- package/dist/slices/fonts/coverage.js +2 -1
- package/dist/slices/fonts/discovery.js +3 -2
- package/dist/slices/fonts/files.js +2 -6
- package/dist/slices/fonts/index.js +0 -1
- package/dist/slices/fonts/sfnt.js +45 -10
- package/dist/slices/images/appearance.js +8 -16
- package/dist/slices/images/scenes.js +102 -28
- package/dist/slices/keywords/digest.js +85 -0
- package/dist/slices/keywords/facts.js +92 -0
- package/dist/slices/keywords/fill.js +80 -0
- package/dist/slices/keywords/model.js +75 -0
- package/dist/slices/keywords/rules.js +187 -0
- package/dist/slices/keywords/schema.js +28 -0
- package/dist/slices/keywords/specs.js +260 -0
- package/dist/slices/keywords/values.js +74 -0
- package/dist/slices/library/lint.js +29 -12
- package/dist/slices/library/model.js +2 -0
- package/dist/slices/library/photorealistic.js +4 -12
- package/dist/slices/library/rename.js +9 -7
- package/dist/slices/library/save.js +14 -10
- package/dist/slices/library/slots.js +37 -11
- package/dist/slices/library/transfer.js +5 -4
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +53 -12
- package/dist/slices/loudness/model.js +3 -2
- package/dist/slices/loudness/sentence-level.js +2 -1
- package/dist/slices/model-checks/cost.js +61 -0
- package/dist/slices/model-checks/listing.js +124 -0
- package/dist/slices/model-checks/model.js +20 -0
- package/dist/slices/model-checks/record.js +32 -0
- package/dist/slices/model-checks/repo.js +120 -0
- package/dist/slices/model-checks/rules.js +125 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/model.js +1 -1
- package/dist/slices/model-upkeep/switch.js +72 -27
- package/dist/slices/model-upkeep/usage.js +39 -13
- package/dist/slices/narration/breaths.js +3 -1
- package/dist/slices/narration/clean-pieces.js +3 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/pauses-model.js +3 -2
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +6 -4
- package/dist/slices/narration/steering.js +4 -3
- package/dist/slices/notifications/notifier.js +4 -3
- package/dist/slices/notifications/rules.js +5 -2
- package/dist/slices/notifications/settings.js +4 -12
- package/dist/slices/notifications/subject.js +4 -3
- package/dist/slices/onboarding/copy.js +21 -3
- package/dist/slices/onboarding/first-run.js +16 -40
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +6 -4
- package/dist/slices/onboarding/model.js +26 -37
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/preferred-model.js +14 -0
- package/dist/slices/onboarding/quick-short.js +105 -65
- package/dist/slices/onboarding/sample.js +4 -2
- package/dist/slices/onboarding/state.js +9 -11
- package/dist/slices/onboarding/template.js +8 -6
- package/dist/slices/outputs/add.js +3 -2
- package/dist/slices/outputs/service.js +2 -2
- package/dist/slices/patch-notes/library.js +4 -3
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/readiness.js +3 -3
- package/dist/slices/play-drafts/review-inputs.js +9 -3
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/play-drafts/service.js +17 -7
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/next-chapter.js +2 -1
- package/dist/slices/project-templates/provider-defaults.js +22 -0
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup-sections.js +26 -0
- package/dist/slices/project-templates/setup.js +14 -1
- package/dist/slices/project-templates/stand-ins.js +22 -0
- package/dist/slices/rebuild/activity.js +2 -0
- package/dist/slices/rebuild/admission-repo.js +3 -2
- package/dist/slices/rebuild/narration-history.js +4 -5
- package/dist/slices/rebuild/narration-retry.js +2 -1
- package/dist/slices/rebuild/preview-details.js +32 -14
- package/dist/slices/rebuild/preview-plan.js +3 -8
- package/dist/slices/rebuild/recipe-build.js +8 -3
- package/dist/slices/rebuild/recipe-describe.js +3 -3
- package/dist/slices/rebuild/recipe-digest.js +58 -0
- package/dist/slices/rebuild/recipe-input-schema.js +10 -0
- package/dist/slices/rebuild/recipe-keywords.js +71 -0
- package/dist/slices/rebuild/recipe-legacy.js +5 -1
- package/dist/slices/rebuild/recipe-model.js +4 -0
- package/dist/slices/rebuild/recipe-narration-text.js +2 -1
- package/dist/slices/rebuild/recipe-preparation.js +4 -4
- package/dist/slices/rebuild/recipe-reference.js +8 -4
- package/dist/slices/rebuild/recipe-reviews.js +27 -7
- package/dist/slices/rebuild/recipe-save.js +8 -5
- package/dist/slices/rebuild/recipe-scenes.js +40 -11
- package/dist/slices/rebuild/recipe-shorts.js +8 -8
- package/dist/slices/rebuild/recipe-social.js +46 -0
- package/dist/slices/rebuild/recipe-text.js +64 -20
- package/dist/slices/rebuild/recipe-validation.js +102 -31
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-voices.js +3 -2
- package/dist/slices/rebuild/recipe-work.js +19 -7
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +9 -8
- package/dist/slices/rebuild/remake-outdated.js +5 -5
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +3 -2
- package/dist/slices/rebuild/runtime-admission.js +4 -3
- package/dist/slices/rebuild/runtime-agent-review.js +11 -5
- package/dist/slices/rebuild/runtime-animate.js +10 -9
- package/dist/slices/rebuild/runtime-article.js +7 -5
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +11 -13
- package/dist/slices/rebuild/runtime-export-bed.js +8 -12
- package/dist/slices/rebuild/runtime-export-edit.js +8 -16
- package/dist/slices/rebuild/runtime-export-inputs.js +12 -11
- package/dist/slices/rebuild/runtime-export-short.js +9 -5
- package/dist/slices/rebuild/runtime-export.js +38 -15
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +8 -12
- package/dist/slices/rebuild/runtime-instructions.js +2 -0
- package/dist/slices/rebuild/runtime-keywords.js +59 -0
- package/dist/slices/rebuild/runtime-lines.js +2 -11
- package/dist/slices/rebuild/runtime-local.js +17 -22
- package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
- package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
- package/dist/slices/rebuild/runtime-narration-text.js +13 -17
- package/dist/slices/rebuild/runtime-pictures.js +2 -4
- package/dist/slices/rebuild/runtime-piece-label.js +10 -6
- package/dist/slices/rebuild/runtime-plan.js +31 -5
- package/dist/slices/rebuild/runtime-provider.js +67 -25
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +39 -33
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +31 -50
- package/dist/slices/rebuild/runtime-store.js +20 -10
- package/dist/slices/rebuild/runtime-subtitles.js +28 -25
- package/dist/slices/rebuild/runtime-voices.js +10 -16
- package/dist/slices/rebuild/runtime-youtube.js +14 -31
- package/dist/slices/rebuild/service-readiness.js +11 -3
- package/dist/slices/rebuild/transition-repo.js +6 -5
- package/dist/slices/rebuild/work-records.js +6 -0
- package/dist/slices/reruns/cascade.js +1 -2
- package/dist/slices/reruns/index.js +6 -9
- package/dist/slices/research/synthesis.js +3 -2
- package/dist/slices/reviews/external-model.js +4 -1
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/holds.js +5 -4
- package/dist/slices/reviews/model.js +32 -11
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +4 -3
- package/dist/slices/reviews/verdict.js +2 -1
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/image-plan.js +1 -1
- package/dist/slices/revisions/mutation-assets.js +9 -5
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +3 -3
- package/dist/slices/revisions/repo.js +3 -1
- package/dist/slices/revisions/schema.js +1 -0
- package/dist/slices/revisions/view.js +20 -0
- package/dist/slices/run-cost/limits.js +5 -2
- package/dist/slices/run-cost/meter.js +12 -5
- package/dist/slices/run-cost/panel.js +8 -74
- package/dist/slices/run-cost/plan-readings.js +127 -0
- package/dist/slices/run-cost/plan-use.js +169 -0
- package/dist/slices/run-cost/pricing.js +3 -3
- package/dist/slices/run-cost/week.js +32 -4
- package/dist/slices/schedules/agenda.js +18 -7
- package/dist/slices/schedules/by-date.js +42 -0
- package/dist/slices/schedules/calendar.js +5 -0
- package/dist/slices/schedules/design-agenda.js +36 -0
- package/dist/slices/schedules/design-check.js +41 -0
- package/dist/slices/schedules/design-run.js +126 -0
- package/dist/slices/schedules/next-run.js +62 -0
- package/dist/slices/schedules/prepare.js +18 -2
- package/dist/slices/schedules/repo.js +30 -21
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +57 -3
- package/dist/slices/schedules/score.js +107 -0
- package/dist/slices/schedules/service.js +57 -24
- package/dist/slices/schedules/topic-list.js +15 -0
- package/dist/slices/schedules/topic-scores.js +104 -0
- package/dist/slices/schedules/topics.js +53 -41
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +8 -43
- package/dist/slices/settings/health.js +30 -15
- package/dist/slices/settings/key-test.js +1 -1
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +14 -2
- package/dist/slices/settings/playback.js +34 -23
- package/dist/slices/settings/probe-read.js +16 -0
- package/dist/slices/settings/repo.js +33 -0
- package/dist/slices/settings/tutorial.js +2 -2
- package/dist/slices/settings/voices.js +4 -12
- package/dist/slices/shorts/keep.js +2 -1
- package/dist/slices/shorts/pick.js +6 -18
- package/dist/slices/shorts/prompts.js +4 -14
- package/dist/slices/shorts/render.js +6 -2
- package/dist/slices/social/channel.js +44 -0
- package/dist/slices/social/defaults.js +17 -0
- package/dist/slices/social/due.js +36 -0
- package/dist/slices/social/extension.js +18 -0
- package/dist/slices/social/fit.js +115 -0
- package/dist/slices/social/limits.js +186 -0
- package/dist/slices/social/links.js +21 -0
- package/dist/slices/social/media.js +132 -0
- package/dist/slices/social/model.js +75 -0
- package/dist/slices/social/notice.js +19 -0
- package/dist/slices/social/pack.js +176 -0
- package/dist/slices/social/post-prompt.js +56 -0
- package/dist/slices/social/queue.js +31 -0
- package/dist/slices/social/repo.js +133 -0
- package/dist/slices/social/reshape.js +97 -0
- package/dist/slices/social/rules.js +5 -0
- package/dist/slices/social/schema.js +70 -0
- package/dist/slices/social/serve.js +51 -0
- package/dist/slices/social/service.js +129 -0
- package/dist/slices/social/settings.js +21 -0
- package/dist/slices/social/sources.js +114 -0
- package/dist/slices/social/state.js +110 -0
- package/dist/slices/social/text.js +149 -0
- package/dist/slices/storage/arrange.js +3 -1
- package/dist/slices/storage/assets.js +8 -10
- package/dist/slices/storage/backup-designs.js +74 -0
- package/dist/slices/storage/backup-export.js +8 -3
- package/dist/slices/storage/backup-format.js +10 -0
- package/dist/slices/storage/backup-import.js +22 -4
- package/dist/slices/storage/delete-project.js +6 -5
- package/dist/slices/storage/files-location.js +6 -8
- package/dist/slices/storage/layout.js +13 -2
- package/dist/slices/storage/model.js +3 -0
- package/dist/slices/storage/portable.js +17 -12
- package/dist/slices/storage/schema.js +2 -0
- package/dist/slices/storage/staging-refs.js +2 -1
- package/dist/slices/storage/staging.js +6 -9
- package/dist/slices/storage/trim.js +26 -9
- package/dist/slices/studio/calendar.js +7 -2
- package/dist/slices/studio/disclosure.js +4 -4
- package/dist/slices/studio/model.js +1 -1
- package/dist/slices/studio/pack.js +9 -8
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +7 -16
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +20 -57
- package/dist/slices/studio/videos.js +35 -4
- package/dist/slices/style-preview/render.js +37 -16
- package/dist/slices/style-preview/schema.js +14 -1
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- package/dist/slices/subtitles/captions.js +1 -1
- package/dist/slices/telemetry/collector-client.js +2 -4
- package/dist/slices/telemetry/flush.js +2 -4
- package/dist/slices/telemetry/model.js +0 -7
- package/dist/slices/telemetry/record.js +10 -3
- package/dist/slices/template-studio/anatomy-view.js +161 -0
- package/dist/slices/template-studio/anatomy.js +73 -0
- package/dist/slices/template-studio/bakeoff-make.js +225 -0
- package/dist/slices/template-studio/bakeoff-repo.js +83 -0
- package/dist/slices/template-studio/bakeoff.js +333 -0
- package/dist/slices/template-studio/budget.js +106 -0
- package/dist/slices/template-studio/cards.js +78 -0
- package/dist/slices/template-studio/checks.js +322 -0
- package/dist/slices/template-studio/document-sample.js +56 -0
- package/dist/slices/template-studio/edit.js +15 -0
- package/dist/slices/template-studio/for-all.js +161 -0
- package/dist/slices/template-studio/free-video.js +31 -0
- package/dist/slices/template-studio/free.js +176 -0
- package/dist/slices/template-studio/gate.js +40 -0
- package/dist/slices/template-studio/hidden.js +20 -0
- package/dist/slices/template-studio/jobs.js +79 -0
- package/dist/slices/template-studio/loudness.js +111 -0
- package/dist/slices/template-studio/make.js +40 -0
- package/dist/slices/template-studio/model.js +58 -0
- package/dist/slices/template-studio/pack-import.js +253 -0
- package/dist/slices/template-studio/pack-samples.js +60 -0
- package/dist/slices/template-studio/pack.js +207 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +355 -0
- package/dist/slices/template-studio/quote.js +155 -0
- package/dist/slices/template-studio/ready.js +104 -0
- package/dist/slices/template-studio/repo.js +134 -0
- package/dist/slices/template-studio/reviews-path.js +58 -0
- package/dist/slices/template-studio/runner.js +84 -0
- package/dist/slices/template-studio/save.js +236 -0
- package/dist/slices/template-studio/say-it-as.js +248 -0
- package/dist/slices/template-studio/schedule-gate.js +34 -0
- package/dist/slices/template-studio/schedule-price.js +32 -0
- package/dist/slices/template-studio/schedule-sample.js +91 -0
- package/dist/slices/template-studio/schema.js +243 -0
- package/dist/slices/template-studio/scope.js +124 -0
- package/dist/slices/template-studio/sections.js +176 -0
- package/dist/slices/template-studio/service.js +175 -0
- package/dist/slices/template-studio/status.js +191 -0
- package/dist/slices/template-studio/topic.js +223 -0
- package/dist/slices/thumbnail/by-llm.js +1 -1
- package/dist/slices/trash/designs.js +76 -0
- package/dist/slices/trash/model.js +13 -4
- package/dist/slices/trash/service.js +52 -2
- package/dist/slices/tutorials/library.js +3 -2
- package/dist/slices/uploads/repo.js +37 -1
- package/dist/slices/uploads/rules.js +3 -2
- package/dist/slices/video/ass-text.js +17 -0
- package/dist/slices/video/audio-export.js +2 -64
- package/dist/slices/video/edit-list.js +2 -2
- package/dist/slices/video/edit-settings.js +1 -1
- package/dist/slices/video/encoding.js +169 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/plan.js +2 -1
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/attribution.js +3 -2
- package/dist/slices/voices/model.js +9 -8
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/voices/script.js +2 -1
- package/dist/slices/youtube/answer.js +4 -16
- package/dist/slices/youtube/edits-repo.js +3 -12
- package/dist/tutorials/AI-CLIs.md +25 -25
- package/dist/tutorials/Agents-MCP.md +34 -33
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Backups.md +7 -7
- package/dist/tutorials/Calendar.md +17 -25
- package/dist/tutorials/Cast-Library.md +19 -19
- package/dist/tutorials/Channels.md +42 -35
- package/dist/tutorials/Costs-and-Run-Cost.md +38 -40
- package/dist/tutorials/Create-Article.md +114 -0
- package/dist/tutorials/Create-Extras.md +112 -0
- package/dist/tutorials/Create-Images.md +165 -0
- package/dist/tutorials/Create-Narration.md +178 -0
- package/dist/tutorials/Create-Overview.md +244 -0
- package/dist/tutorials/Create-Video-and-Style.md +144 -0
- package/dist/tutorials/Docker.md +3 -3
- package/dist/tutorials/Document-Themes.md +32 -32
- package/dist/tutorials/Editing-a-Project.md +94 -94
- package/dist/tutorials/FAQ.md +18 -18
- package/dist/tutorials/First-Launch-and-Welcome.md +50 -64
- package/dist/tutorials/Home-and-Projects.md +115 -71
- package/dist/tutorials/Home.md +33 -33
- package/dist/tutorials/Install.md +14 -13
- package/dist/tutorials/Intros-and-Outros.md +33 -34
- package/dist/tutorials/Keyboard-Shortcuts-and-Command-Palette.md +62 -58
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +53 -21
- package/dist/tutorials/Multiple-Voices.md +41 -40
- package/dist/tutorials/Narration-Aliases-and-Glossary.md +14 -14
- package/dist/tutorials/Notifications.md +27 -17
- package/dist/tutorials/Other-Languages.md +15 -15
- package/dist/tutorials/PDF-Documents.md +38 -29
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Project-Page.md +118 -120
- package/dist/tutorials/Prompts-and-Templates.md +84 -0
- package/dist/tutorials/Prompts.md +48 -44
- package/dist/tutorials/Providers-and-Keys.md +105 -98
- package/dist/tutorials/Publishing-to-YouTube.md +31 -31
- package/dist/tutorials/Recovery-and-Retries.md +31 -31
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +98 -90
- package/dist/tutorials/Schedules.md +46 -27
- package/dist/tutorials/Settings-Reference.md +194 -174
- package/dist/tutorials/Shorts.md +34 -33
- package/dist/tutorials/Start-at-Login.md +3 -3
- package/dist/tutorials/Studio-Extension.md +22 -24
- package/dist/tutorials/Template-Studio.md +128 -0
- package/dist/tutorials/Templates.md +51 -77
- package/dist/tutorials/Trash.md +4 -4
- package/dist/tutorials/Troubleshooting.md +44 -44
- package/dist/tutorials/Uninstalling-and-Moving.md +5 -5
- package/dist/tutorials/Updating-and-Patch-Notes.md +18 -18
- package/dist/tutorials/Video-Editing.md +34 -34
- package/dist/tutorials/Where-Your-Files-Live.md +10 -10
- package/dist/tutorials/YouTube-Description.md +26 -26
- package/dist/tutorials/Your-First-Short.md +35 -35
- package/dist/tutorials/_Sidebar.md +19 -14
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-BNftKQrA.css +1 -0
- package/dist/web/assets/index-Cpa58woP.js +459 -0
- package/dist/web/assets/pdf-BKh8f7R6.js +56 -0
- package/dist/web/assets/pdf.worker.min-BmVo14Nb.mjs +28 -0
- package/dist/web/assets/pdf.worker.min-D7i8o3wR.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +6 -2
- package/dist/slices/article/provided-entries.js +0 -66
- package/dist/slices/article/run.js +0 -145
- package/dist/slices/images/run.js +0 -234
- package/dist/slices/narration/legacy-plan.js +0 -58
- package/dist/slices/narration/run.js +0 -270
- package/dist/slices/rebuild/runtime-actions.js +0 -90
- package/dist/slices/research/run.js +0 -224
- package/dist/slices/subtitles/prepare.js +0 -194
- package/dist/slices/subtitles/transcript.js +0 -34
- package/dist/slices/thumbnail/run.js +0 -219
- package/dist/slices/video/audio-inputs.js +0 -33
- package/dist/slices/video/reuse-audio.js +0 -62
- package/dist/slices/video/run.js +0 -78
- package/dist/slices/video/write-export.js +0 -158
- package/dist/slices/video/write-subtitles.js +0 -59
- package/dist/tutorials/Library-Overview.md +0 -76
- package/dist/tutorials/Play-Images.md +0 -161
- package/dist/tutorials/Play-Narration.md +0 -167
- package/dist/tutorials/Play-Outputs.md +0 -109
- package/dist/tutorials/Play-Overview.md +0 -227
- package/dist/tutorials/Play-Title-and-Article.md +0 -136
- package/dist/tutorials/Play-Video-and-Style.md +0 -143
- package/dist/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
- package/dist/web/assets/pdf-T7MCwjIv.js +0 -54
- package/dist/web/assets/pdf.worker.min-Dswkl-cV.mjs +0 -29
- package/dist/web/assets/pdf.worker.min-zC6nfbxG.js +0 -1
|
@@ -5,7 +5,8 @@ import { bodyLimit } from "hono/body-limit";
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { clearChannelVideos, deleteChannelVideo, importChannelVideos, listChannelVideos, previewChannelVideos, } from "../../slices/channels/videos.js";
|
|
7
7
|
import { channelEpisodes, deleteMemory, editMemory, setEpisodeMemory, } from "../../slices/episodes/service.js";
|
|
8
|
-
import { onInvalid
|
|
8
|
+
import { onInvalid } from "./problem.js";
|
|
9
|
+
import { jsonBody, refusal } from "./refusal.js";
|
|
9
10
|
const idParam = z.object({ id: z.uuid() });
|
|
10
11
|
const memoryParam = idParam.extend({ memoryId: z.string().min(1).max(100) });
|
|
11
12
|
const videoParam = idParam.extend({ videoId: z.uuid() });
|
|
@@ -22,12 +23,12 @@ export function channelMemoryRoutes(deps) {
|
|
|
22
23
|
return result.ok ? c.json(result.value) : refused(c, result, "episode");
|
|
23
24
|
})
|
|
24
25
|
.put("/:id/episodes/setting", zValidator("param", idParam, onInvalid), async (c) => {
|
|
25
|
-
const result = setEpisodeMemory(service, c.req.valid("param").id, await
|
|
26
|
+
const result = setEpisodeMemory(service, c.req.valid("param").id, await jsonBody(c));
|
|
26
27
|
return result.ok ? c.json(result.value) : refused(c, result, "episode");
|
|
27
28
|
})
|
|
28
29
|
.put("/:id/episodes/:memoryId", zValidator("param", memoryParam, onInvalid), async (c) => {
|
|
29
30
|
const { id, memoryId } = c.req.valid("param");
|
|
30
|
-
const result = editMemory(service, id, memoryId, await
|
|
31
|
+
const result = editMemory(service, id, memoryId, await jsonBody(c));
|
|
31
32
|
return result.ok ? c.json(result.value) : refused(c, result, "episode");
|
|
32
33
|
})
|
|
33
34
|
.delete("/:id/episodes/:memoryId", zValidator("param", memoryParam, onInvalid), (c) => {
|
|
@@ -40,11 +41,11 @@ export function channelMemoryRoutes(deps) {
|
|
|
40
41
|
return result.ok ? c.json({ videos: result.value }) : refused(c, result, "video");
|
|
41
42
|
})
|
|
42
43
|
.post("/:id/videos/preview", zValidator("param", idParam, onInvalid), importLimit(), async (c) => {
|
|
43
|
-
const result = previewChannelVideos(service, c.req.valid("param").id, await
|
|
44
|
+
const result = previewChannelVideos(service, c.req.valid("param").id, await jsonBody(c));
|
|
44
45
|
return result.ok ? c.json(result.value) : refused(c, result, "video");
|
|
45
46
|
})
|
|
46
47
|
.post("/:id/videos", zValidator("param", idParam, onInvalid), importLimit(), async (c) => {
|
|
47
|
-
const result = importChannelVideos(service, c.req.valid("param").id, await
|
|
48
|
+
const result = importChannelVideos(service, c.req.valid("param").id, await jsonBody(c));
|
|
48
49
|
return result.ok ? c.json(result.value, 201) : refused(c, result, "video");
|
|
49
50
|
})
|
|
50
51
|
.delete("/:id/videos", zValidator("param", idParam, onInvalid), (c) => {
|
|
@@ -67,26 +68,12 @@ function importLimit() {
|
|
|
67
68
|
}, "video"),
|
|
68
69
|
});
|
|
69
70
|
}
|
|
70
|
-
async function body(c) {
|
|
71
|
-
try {
|
|
72
|
-
return await c.req.json();
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
return undefined;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
71
|
function refused(c, result, about) {
|
|
79
|
-
const status = result.reason === "not-found" ? 404 : 400;
|
|
80
72
|
const detail = result.message ??
|
|
81
73
|
(result.reason === "not-found"
|
|
82
74
|
? about === "episode"
|
|
83
|
-
? "This channel or episode summary no longer exists; it may have been deleted in another tab. Reload the channel's
|
|
84
|
-
: "This channel or video title no longer exists; it may have been deleted in another tab. Reload the channel's
|
|
75
|
+
? "This channel or episode summary no longer exists; it may have been deleted in another tab. Reload the channel's Memory tab."
|
|
76
|
+
: "This channel or video title no longer exists; it may have been deleted in another tab. Reload the channel's Titles to avoid tab."
|
|
85
77
|
: "This request isn't valid. Reload the page and try again.");
|
|
86
|
-
return
|
|
87
|
-
status,
|
|
88
|
-
title: titleOf(status),
|
|
89
|
-
detail,
|
|
90
|
-
extensions: { reason: result.reason },
|
|
91
|
-
});
|
|
78
|
+
return refusal(c, result.reason, { statuses: { "not-found": 404 }, otherwise: 400, detail });
|
|
92
79
|
}
|
|
@@ -7,7 +7,8 @@ import { deleteCastImage, generateCastImage, uploadCastImage, } from "../../slic
|
|
|
7
7
|
import { castImageMaxBytes } from "../../slices/channels/images.js";
|
|
8
8
|
import { imageBlob } from "../../slices/channels/repo.js";
|
|
9
9
|
import { createCastMember, createChannel, deleteCastMember, deleteChannel, listChannels, moveCastMember, moveTemplate, readChannel, setChannelAiDisclosure, updateCastMember, updateChannel, } from "../../slices/channels/service.js";
|
|
10
|
-
import { onInvalid
|
|
10
|
+
import { onInvalid } from "./problem.js";
|
|
11
|
+
import { jsonBody, refusal } from "./refusal.js";
|
|
11
12
|
const idParam = z.object({ id: z.uuid() });
|
|
12
13
|
const memberParam = z.object({ memberId: z.uuid() });
|
|
13
14
|
const imageParam = memberParam.extend({ imageId: z.uuid() });
|
|
@@ -26,7 +27,7 @@ export function channelRoutes(deps) {
|
|
|
26
27
|
return (new Hono()
|
|
27
28
|
.get("/", (c) => c.json({ channels: listChannels(service) }))
|
|
28
29
|
.post("/", async (c) => {
|
|
29
|
-
const result = createChannel(service, await
|
|
30
|
+
const result = createChannel(service, await jsonBody(c));
|
|
30
31
|
return result.ok ? c.json(result.value, 201) : refused(c, result);
|
|
31
32
|
})
|
|
32
33
|
// The pictures by content hash: they never change, so the browser may keep them.
|
|
@@ -41,11 +42,11 @@ export function channelRoutes(deps) {
|
|
|
41
42
|
});
|
|
42
43
|
})
|
|
43
44
|
.put("/templates/:templateId", zValidator("param", templateParam, onInvalid), async (c) => {
|
|
44
|
-
const result = moveTemplate(service, c.req.valid("param").templateId, await
|
|
45
|
+
const result = moveTemplate(service, c.req.valid("param").templateId, await jsonBody(c));
|
|
45
46
|
return result.ok ? c.json(result.value) : refused(c, result);
|
|
46
47
|
})
|
|
47
48
|
.put("/cast/:memberId", zValidator("param", memberParam, onInvalid), async (c) => {
|
|
48
|
-
const result = updateCastMember(service, c.req.valid("param").memberId, await
|
|
49
|
+
const result = updateCastMember(service, c.req.valid("param").memberId, await jsonBody(c));
|
|
49
50
|
return result.ok ? c.json(result.value) : refused(c, result);
|
|
50
51
|
})
|
|
51
52
|
.delete("/cast/:memberId", zValidator("param", memberParam, onInvalid), (c) => {
|
|
@@ -66,7 +67,7 @@ export function channelRoutes(deps) {
|
|
|
66
67
|
return result.ok ? c.json(result.value, 201) : refused(c, result);
|
|
67
68
|
})
|
|
68
69
|
.post("/cast/:memberId/generate", zValidator("param", memberParam, onInvalid), async (c) => {
|
|
69
|
-
const result = generateCastImage(service, c.req.valid("param").memberId, await
|
|
70
|
+
const result = generateCastImage(service, c.req.valid("param").memberId, await jsonBody(c));
|
|
70
71
|
return result.ok ? c.json(result.value, 202) : refused(c, result);
|
|
71
72
|
})
|
|
72
73
|
.delete("/cast/:memberId/images/:imageId", zValidator("param", imageParam, onInvalid), (c) => {
|
|
@@ -79,11 +80,11 @@ export function channelRoutes(deps) {
|
|
|
79
80
|
return result.ok ? c.json(result.value) : refused(c, result);
|
|
80
81
|
})
|
|
81
82
|
.put("/:id", zValidator("param", idParam, onInvalid), async (c) => {
|
|
82
|
-
const result = updateChannel(service, c.req.valid("param").id, await
|
|
83
|
+
const result = updateChannel(service, c.req.valid("param").id, await jsonBody(c));
|
|
83
84
|
return result.ok ? c.json(result.value) : refused(c, result);
|
|
84
85
|
})
|
|
85
86
|
.put("/:id/ai-disclosure", zValidator("param", idParam, onInvalid), async (c) => {
|
|
86
|
-
const result = setChannelAiDisclosure(service, c.req.valid("param").id, await
|
|
87
|
+
const result = setChannelAiDisclosure(service, c.req.valid("param").id, await jsonBody(c));
|
|
87
88
|
return result.ok ? c.json(result.value) : refused(c, result);
|
|
88
89
|
})
|
|
89
90
|
.delete("/:id", zValidator("param", idParam, onInvalid), (c) => {
|
|
@@ -91,23 +92,15 @@ export function channelRoutes(deps) {
|
|
|
91
92
|
return result.ok ? c.body(null, 204) : refused(c, result);
|
|
92
93
|
})
|
|
93
94
|
.post("/:id/cast", zValidator("param", idParam, onInvalid), async (c) => {
|
|
94
|
-
const result = createCastMember(service, c.req.valid("param").id, await
|
|
95
|
+
const result = createCastMember(service, c.req.valid("param").id, await jsonBody(c));
|
|
95
96
|
return result.ok ? c.json(result.value, 201) : refused(c, result);
|
|
96
97
|
})
|
|
97
98
|
// Move up, Move down and their Undo: one member to a place in the cast's order.
|
|
98
99
|
.post("/:id/cast/move", zValidator("param", idParam, onInvalid), async (c) => {
|
|
99
|
-
const result = moveCastMember(service, c.req.valid("param").id, await
|
|
100
|
+
const result = moveCastMember(service, c.req.valid("param").id, await jsonBody(c));
|
|
100
101
|
return result.ok ? c.json({ cast: result.value }) : refused(c, result);
|
|
101
102
|
}));
|
|
102
103
|
}
|
|
103
|
-
async function body(c) {
|
|
104
|
-
try {
|
|
105
|
-
return await c.req.json();
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
return undefined;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
104
|
const details = {
|
|
112
105
|
"not-found": "This channel, cast member or picture no longer exists; it may have been deleted in another tab. Go back to Channels.",
|
|
113
106
|
conflict: "This changed in another tab while you were editing. Reload the page to see the latest, then make your change again.",
|
|
@@ -116,18 +109,12 @@ const details = {
|
|
|
116
109
|
"has-templates": "This channel still has templates. Move them to another channel in its Templates tab, or delete them, then delete the channel.",
|
|
117
110
|
"not-an-image": "This file is not a PNG or JPEG picture. Upload a PNG or JPEG file.",
|
|
118
111
|
"too-many-images": "This cast member already has the most pictures it can keep. Delete one first.",
|
|
119
|
-
"no-image-provider": "Slopify can't make pictures here yet. Set up an image
|
|
112
|
+
"no-image-provider": "Slopify can't make pictures here yet. Set up an image service in Settings → Keys & services, or upload a picture instead.",
|
|
120
113
|
};
|
|
121
114
|
function refused(c, result) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
:
|
|
125
|
-
? 409
|
|
126
|
-
: 400;
|
|
127
|
-
return problem(c, {
|
|
128
|
-
status,
|
|
129
|
-
title: titleOf(status),
|
|
115
|
+
return refusal(c, result.reason, {
|
|
116
|
+
statuses: { "not-found": 404, conflict: 409, "has-templates": 409 },
|
|
117
|
+
otherwise: 400,
|
|
130
118
|
detail: result.message ?? details[result.reason],
|
|
131
|
-
extensions: { reason: result.reason },
|
|
132
119
|
});
|
|
133
120
|
}
|
|
@@ -1,38 +1,47 @@
|
|
|
1
1
|
import { zValidator } from "@hono/zod-validator";
|
|
2
2
|
import { Hono } from "hono";
|
|
3
|
-
import {
|
|
3
|
+
import { errorText } from "../../kernel/errors.js";
|
|
4
|
+
import { stageWords } from "../../kernel/pipeline.js";
|
|
5
|
+
import { projectPaused } from "../../slices/admission/repo.js";
|
|
4
6
|
import { changeCheckpoints, checkpointChangeSchema, readCheckpointStatus, replayCheckpointApproval, validateCheckpointApproval, } from "../../slices/checkpoints/change.js";
|
|
7
|
+
import { listCheckpoints } from "../../slices/checkpoints/repo.js";
|
|
5
8
|
import { checkpointApprovalSchema, checkpointRowSchema } from "../../slices/checkpoints/schema.js";
|
|
6
9
|
import { withProjectControl } from "../../slices/control/lock.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const projectParam = z.object({ id });
|
|
10
|
+
import { projectHolds } from "../../slices/reviews/holds.js";
|
|
11
|
+
import { idParam, idString } from "./ids.js";
|
|
12
|
+
import { onInvalid, problem } from "./problem.js";
|
|
13
|
+
import { refusal } from "./refusal.js";
|
|
14
|
+
const id = idString;
|
|
15
|
+
const projectParam = idParam;
|
|
14
16
|
const approvalParam = projectParam.extend({ checkpointId: id });
|
|
15
|
-
const approvalBody = checkpointApprovalSchema
|
|
17
|
+
export const approvalBody = checkpointApprovalSchema
|
|
16
18
|
.unwrap()
|
|
17
19
|
.omit({ projectId: true, checkpointId: true, approvedAt: true });
|
|
18
20
|
function refused(c, reason) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
title: titleOf(status),
|
|
21
|
+
return refusal(c, reason, {
|
|
22
|
+
statuses: { "not-found": 404, "invalid-input": 400 },
|
|
23
|
+
otherwise: 409,
|
|
23
24
|
detail: reason === "not-found"
|
|
24
|
-
? "This
|
|
25
|
+
? "This pause no longer exists; the project may have moved on or changed. Reload the page to see where it is now."
|
|
25
26
|
: reason === "invalid-input"
|
|
26
|
-
? "This
|
|
27
|
-
: "This
|
|
28
|
-
|
|
27
|
+
? "This answer to the pause could not be read. Reload the page and try again."
|
|
28
|
+
: "This pause changed since the page loaded, for example it was already approved. Reload the page to see its current state, then try again.",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// Taking a checkpoint off that holds the run now would start the paid steps behind it without
|
|
32
|
+
// the review: that goes through Approve, which checks what is approved is what was looked at.
|
|
33
|
+
function heldThere(c, stage) {
|
|
34
|
+
const name = stageWords[stage];
|
|
35
|
+
return problem(c, {
|
|
36
|
+
status: 409,
|
|
37
|
+
detail: `The run is waiting for your review before ${name}, so that pause can't be taken off now: that would start the next steps without the review. Look over what is made, then press Approve and make the ${name.toLowerCase()} (agents: approve_checkpoint).`,
|
|
38
|
+
extensions: { reason: "held-at-checkpoint" },
|
|
29
39
|
});
|
|
30
40
|
}
|
|
31
41
|
function alreadyApproved(c) {
|
|
32
42
|
return problem(c, {
|
|
33
43
|
status: 409,
|
|
34
|
-
|
|
35
|
-
detail: "This checkpoint was already approved, so nothing changed. Reload the page (or call needs_attention) to see what waits now.",
|
|
44
|
+
detail: "This pause was already approved, so nothing changed. Reload the page (or call needs_attention) to see what waits now.",
|
|
36
45
|
extensions: { reason: "already-approved" },
|
|
37
46
|
});
|
|
38
47
|
}
|
|
@@ -47,7 +56,7 @@ function buildCheckpointRoutes(deps) {
|
|
|
47
56
|
catch (error) {
|
|
48
57
|
deps.log.write("error", "checkpoint.notify", {
|
|
49
58
|
projectId,
|
|
50
|
-
detail:
|
|
59
|
+
detail: errorText(error),
|
|
51
60
|
});
|
|
52
61
|
}
|
|
53
62
|
if (wake) {
|
|
@@ -57,7 +66,7 @@ function buildCheckpointRoutes(deps) {
|
|
|
57
66
|
catch (error) {
|
|
58
67
|
deps.log.write("error", "checkpoint.wake", {
|
|
59
68
|
projectId,
|
|
60
|
-
detail:
|
|
69
|
+
detail: errorText(error),
|
|
61
70
|
});
|
|
62
71
|
}
|
|
63
72
|
}
|
|
@@ -95,6 +104,15 @@ function buildCheckpointRoutes(deps) {
|
|
|
95
104
|
const projectId = c.req.valid("param").id;
|
|
96
105
|
const body = c.req.valid("json");
|
|
97
106
|
return withProjectControl(deps.db, projectId, () => {
|
|
107
|
+
// A paused run goes on only through Continue the run, so taking a checkpoint off
|
|
108
|
+
// then releases nothing by itself.
|
|
109
|
+
const holding = projectPaused(deps.db, projectId)
|
|
110
|
+
? []
|
|
111
|
+
: (projectHolds(deps.db, { projectId }).holding.get(projectId) ?? []);
|
|
112
|
+
const removed = listCheckpoints(deps.db, projectId, body.revisionId).filter((row) => !body.stages.includes(row.stage));
|
|
113
|
+
const held = holding.find((hold) => removed.some((row) => row.checkpointId === hold.checkpointId));
|
|
114
|
+
if (held !== undefined)
|
|
115
|
+
return heldThere(c, held.stage);
|
|
98
116
|
const result = changeCheckpoints(deps, { ...body, projectId });
|
|
99
117
|
if (!result.ok)
|
|
100
118
|
return refused(c, result.reason);
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { zValidator } from "@hono/zod-validator";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { designDocumentSchema } from "../../slices/designs/schema.js";
|
|
5
|
+
import { designAffectedSections, sampleNeedsPicture } from "../../slices/designs/sections.js";
|
|
6
|
+
import { freeSample } from "../../slices/designs/studio-kind.js";
|
|
7
|
+
import { makeFromTemplate, quoteDocument, quoteTemplate, } from "../../slices/designs/template-make.js";
|
|
8
|
+
import { createTemplate, getTemplate, listTemplates, markTemplateReady, saveTemplate, } from "../../slices/designs/templates.js";
|
|
9
|
+
import { trashDesignTemplate } from "../../slices/trash/designs.js";
|
|
10
|
+
import { designRefused } from "./designs.js";
|
|
11
|
+
import { idParam } from "./ids.js";
|
|
12
|
+
import { onInvalid, problem } from "./problem.js";
|
|
13
|
+
import { jsonBody } from "./refusal.js";
|
|
14
|
+
export const sampleRequestSchema = z
|
|
15
|
+
.object({
|
|
16
|
+
version: z.number().int().min(1),
|
|
17
|
+
acknowledgedHigh: z.number().min(0).max(1000),
|
|
18
|
+
// That the button said the picture's price is unknown, and the person pressed it anyway.
|
|
19
|
+
acknowledgedUnknown: z.boolean().optional(),
|
|
20
|
+
})
|
|
21
|
+
.strict();
|
|
22
|
+
const quoteBodySchema = z.object({ document: designDocumentSchema }).strict();
|
|
23
|
+
const notFoundRefusal = {
|
|
24
|
+
reason: "not-found",
|
|
25
|
+
message: "This design template no longer exists. Open Templates → Poster templates to choose another.",
|
|
26
|
+
};
|
|
27
|
+
export function designTemplateRoutes(deps) {
|
|
28
|
+
const unavailable = (c) => problem(c, {
|
|
29
|
+
status: 503,
|
|
30
|
+
detail: "Design templates aren't available in this copy of Slopify. Restart Slopify; if it keeps happening, reinstall it.",
|
|
31
|
+
});
|
|
32
|
+
return new Hono()
|
|
33
|
+
.get("/", (c) => deps === undefined ? unavailable(c) : c.json({ templates: listTemplates(deps.service.db) }))
|
|
34
|
+
.post("/", async (c) => {
|
|
35
|
+
if (deps === undefined)
|
|
36
|
+
return unavailable(c);
|
|
37
|
+
const result = createTemplate(deps.service, await jsonBody(c));
|
|
38
|
+
return result.ok ? c.json(result.value, 201) : designRefused(c, result);
|
|
39
|
+
})
|
|
40
|
+
.get("/:id", zValidator("param", idParam, onInvalid), (c) => {
|
|
41
|
+
if (deps === undefined)
|
|
42
|
+
return unavailable(c);
|
|
43
|
+
const template = getTemplate(deps.service.db, c.req.valid("param").id);
|
|
44
|
+
return template === undefined
|
|
45
|
+
? designRefused(c, {
|
|
46
|
+
reason: "not-found",
|
|
47
|
+
message: "This design template no longer exists. Open Templates → Poster templates to choose another.",
|
|
48
|
+
})
|
|
49
|
+
: c.json({ ...template, sample: deps.samples?.state?.(template.id) ?? null });
|
|
50
|
+
})
|
|
51
|
+
.put("/:id", zValidator("param", idParam, onInvalid), async (c) => {
|
|
52
|
+
if (deps === undefined)
|
|
53
|
+
return unavailable(c);
|
|
54
|
+
const id = c.req.valid("param").id;
|
|
55
|
+
const body = await jsonBody(c);
|
|
56
|
+
const result = saveTemplate(deps.service, id, body);
|
|
57
|
+
if (!result.ok)
|
|
58
|
+
return designRefused(c, result);
|
|
59
|
+
const { template, saved, before } = result.value;
|
|
60
|
+
if (saved)
|
|
61
|
+
deps.templateChanged?.(id);
|
|
62
|
+
const asked = z
|
|
63
|
+
.object({
|
|
64
|
+
sample: z.enum(["make", "skip"]).optional(),
|
|
65
|
+
acknowledgedHigh: z.number().optional(),
|
|
66
|
+
})
|
|
67
|
+
.catch({})
|
|
68
|
+
.parse(body);
|
|
69
|
+
const sample = deps.samples === undefined || !saved
|
|
70
|
+
? null
|
|
71
|
+
: deps.samples.afterSave({
|
|
72
|
+
templateId: id,
|
|
73
|
+
version: template.headVersion,
|
|
74
|
+
before,
|
|
75
|
+
after: template.document,
|
|
76
|
+
sample: asked.sample ?? "skip",
|
|
77
|
+
acknowledgedHigh: asked.acknowledgedHigh ?? 0,
|
|
78
|
+
});
|
|
79
|
+
return c.json({
|
|
80
|
+
template,
|
|
81
|
+
saved,
|
|
82
|
+
sample: sample === null ? null : sample.ok ? sample.value : { refused: sample.message },
|
|
83
|
+
});
|
|
84
|
+
})
|
|
85
|
+
.delete("/:id", zValidator("param", idParam, onInvalid), (c) => {
|
|
86
|
+
if (deps === undefined)
|
|
87
|
+
return unavailable(c);
|
|
88
|
+
const result = trashDesignTemplate(deps.service, c.req.valid("param").id);
|
|
89
|
+
return result.ok
|
|
90
|
+
? c.body(null, 204)
|
|
91
|
+
: designRefused(c, {
|
|
92
|
+
reason: "not-found",
|
|
93
|
+
message: "This design template no longer exists. Open Templates → Poster templates to choose another.",
|
|
94
|
+
});
|
|
95
|
+
})
|
|
96
|
+
.post("/:id/quote", zValidator("param", idParam, onInvalid), async (c) => {
|
|
97
|
+
if (deps === undefined)
|
|
98
|
+
return unavailable(c);
|
|
99
|
+
const id = c.req.valid("param").id;
|
|
100
|
+
const body = await jsonBody(c);
|
|
101
|
+
// With a document: what saving it would cost the editor's sample (only a changed
|
|
102
|
+
// picture is paid). Without: what one piece from the newest version costs.
|
|
103
|
+
if (typeof body === "object" && body !== null && Object.keys(body).length > 0) {
|
|
104
|
+
const parsed = quoteBodySchema.safeParse(body);
|
|
105
|
+
if (!parsed.success)
|
|
106
|
+
return designRefused(c, {
|
|
107
|
+
reason: "invalid",
|
|
108
|
+
message: `The template can't be priced: ${parsed.error.issues[0]?.message ?? "a field is missing"}.`,
|
|
109
|
+
});
|
|
110
|
+
const template = getTemplate(deps.service.db, id);
|
|
111
|
+
if (template === undefined)
|
|
112
|
+
return designRefused(c, notFoundRefusal);
|
|
113
|
+
const sample = deps.samples?.state?.(id);
|
|
114
|
+
const sections = designAffectedSections(template.document, parsed.data.document);
|
|
115
|
+
const makesPicture = sampleNeedsPicture(sections) ||
|
|
116
|
+
sample === null ||
|
|
117
|
+
sample === undefined ||
|
|
118
|
+
sample.designId == null ||
|
|
119
|
+
sample.state === "failed";
|
|
120
|
+
const quote = makesPicture
|
|
121
|
+
? quoteDocument(deps.catalogue(), parsed.data.document)
|
|
122
|
+
: freeSample(deps.catalogue());
|
|
123
|
+
return c.json({ ...quote, sections, makesPicture });
|
|
124
|
+
}
|
|
125
|
+
const result = quoteTemplate(deps, id);
|
|
126
|
+
return result.ok ? c.json(result.value) : designRefused(c, result);
|
|
127
|
+
})
|
|
128
|
+
.post("/:id/sample", zValidator("param", idParam, onInvalid), async (c) => {
|
|
129
|
+
if (deps === undefined)
|
|
130
|
+
return unavailable(c);
|
|
131
|
+
const request = deps.samples?.request;
|
|
132
|
+
if (request === undefined)
|
|
133
|
+
return unavailable(c);
|
|
134
|
+
const parsed = sampleRequestSchema.safeParse(await jsonBody(c));
|
|
135
|
+
if (!parsed.success)
|
|
136
|
+
return designRefused(c, {
|
|
137
|
+
reason: "invalid",
|
|
138
|
+
message: "Say which version to make a sample of and the price you saw, then press Make sample.",
|
|
139
|
+
});
|
|
140
|
+
const result = request(c.req.valid("param").id, parsed.data.version, parsed.data.acknowledgedHigh, parsed.data.acknowledgedUnknown);
|
|
141
|
+
return result.ok ? c.json(result.value, 202) : designRefused(c, result);
|
|
142
|
+
})
|
|
143
|
+
.post("/:id/ready", zValidator("param", idParam, onInvalid), async (c) => {
|
|
144
|
+
if (deps === undefined)
|
|
145
|
+
return unavailable(c);
|
|
146
|
+
const id = c.req.valid("param").id;
|
|
147
|
+
const checks = deps.checks;
|
|
148
|
+
const result = await markTemplateReady(deps.service, id, await jsonBody(c), checks === undefined ? undefined : (doc, version) => checks(id, doc, version));
|
|
149
|
+
if (result.ok) {
|
|
150
|
+
deps.templateChanged?.(id);
|
|
151
|
+
return c.json(result.value);
|
|
152
|
+
}
|
|
153
|
+
return result.reason === "not-ready"
|
|
154
|
+
? problem(c, {
|
|
155
|
+
status: 409,
|
|
156
|
+
detail: result.message,
|
|
157
|
+
extensions: { reason: result.reason, checks: result.current },
|
|
158
|
+
})
|
|
159
|
+
: designRefused(c, result);
|
|
160
|
+
})
|
|
161
|
+
.post("/:id/make", zValidator("param", idParam, onInvalid), async (c) => {
|
|
162
|
+
if (deps === undefined)
|
|
163
|
+
return unavailable(c);
|
|
164
|
+
const result = makeFromTemplate(deps, c.req.valid("param").id, await jsonBody(c));
|
|
165
|
+
return result.ok ? c.json(result.value, 202) : designRefused(c, result);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { zValidator } from "@hono/zod-validator";
|
|
3
|
+
import { Hono } from "hono";
|
|
4
|
+
import { bodyLimit } from "hono/body-limit";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { castImageMaxBytes } from "../../slices/channels/images.js";
|
|
7
|
+
import { designFormats } from "../../slices/designs/model.js";
|
|
8
|
+
import { createDesign, getDesign, listDesignViews, setDesignHead, stepPicture, storeUploadedPicture, updateDesignRecord, } from "../../slices/designs/service.js";
|
|
9
|
+
import { trashDesign } from "../../slices/trash/designs.js";
|
|
10
|
+
import { idParam, idString } from "./ids.js";
|
|
11
|
+
import { onInvalid, problem } from "./problem.js";
|
|
12
|
+
import { jsonBody } from "./refusal.js";
|
|
13
|
+
const stepParam = idParam.extend({ stepId: idString });
|
|
14
|
+
const fileParam = idParam.extend({
|
|
15
|
+
file: z.string().regex(new RegExp(`^(?:${designFormats.join("|")})\\.(?:png|pdf)$`)),
|
|
16
|
+
});
|
|
17
|
+
const listQuery = z.object({ projectId: idString.optional() });
|
|
18
|
+
export const designStatuses = {
|
|
19
|
+
"not-found": 404,
|
|
20
|
+
invalid: 400,
|
|
21
|
+
changed: 409,
|
|
22
|
+
"mutation-reused": 409,
|
|
23
|
+
"not-an-image": 400,
|
|
24
|
+
"still-uploading": 409,
|
|
25
|
+
"upload-gone": 404,
|
|
26
|
+
"project-not-found": 404,
|
|
27
|
+
"channel-not-found": 404,
|
|
28
|
+
busy: 409,
|
|
29
|
+
"no-image-provider": 409,
|
|
30
|
+
"cost-changed": 409,
|
|
31
|
+
"missing-values": 400,
|
|
32
|
+
"not-ready": 409,
|
|
33
|
+
};
|
|
34
|
+
export function designRefused(c, result) {
|
|
35
|
+
return problem(c, {
|
|
36
|
+
status: designStatuses[result.reason],
|
|
37
|
+
detail: result.message,
|
|
38
|
+
extensions: {
|
|
39
|
+
reason: result.reason,
|
|
40
|
+
...(result.current === undefined
|
|
41
|
+
? {}
|
|
42
|
+
: result.reason === "cost-changed"
|
|
43
|
+
? { quote: result.current }
|
|
44
|
+
: { current: result.current }),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const unavailable = (c) => problem(c, {
|
|
49
|
+
status: 503,
|
|
50
|
+
detail: "Designs aren't available in this copy of Slopify. Restart Slopify; if it keeps happening, reinstall it.",
|
|
51
|
+
});
|
|
52
|
+
export function designRoutes(deps) {
|
|
53
|
+
return (new Hono()
|
|
54
|
+
.get("/", zValidator("query", listQuery, onInvalid), (c) => {
|
|
55
|
+
if (deps === undefined)
|
|
56
|
+
return unavailable(c);
|
|
57
|
+
return c.json({
|
|
58
|
+
designs: listDesignViews(deps.service.db, c.req.valid("query").projectId),
|
|
59
|
+
});
|
|
60
|
+
})
|
|
61
|
+
.post("/", async (c) => {
|
|
62
|
+
if (deps === undefined)
|
|
63
|
+
return unavailable(c);
|
|
64
|
+
const result = createDesign(deps.service, await jsonBody(c));
|
|
65
|
+
return result.ok ? c.json(result.value, 201) : designRefused(c, result);
|
|
66
|
+
})
|
|
67
|
+
// The picture's bytes are the body; the answer's sha256 starts a design (fromStepSha).
|
|
68
|
+
.post("/pictures", bodyLimit({
|
|
69
|
+
maxSize: castImageMaxBytes,
|
|
70
|
+
onError: (c) => designRefused(c, {
|
|
71
|
+
reason: "not-an-image",
|
|
72
|
+
message: `This picture is larger than ${String(castImageMaxBytes / 1024 / 1024)} MB. Save it smaller (for example as a JPEG) and upload it again.`,
|
|
73
|
+
}),
|
|
74
|
+
}), async (c) => {
|
|
75
|
+
if (deps === undefined)
|
|
76
|
+
return unavailable(c);
|
|
77
|
+
const result = storeUploadedPicture(deps.service, new Uint8Array(await c.req.arrayBuffer()));
|
|
78
|
+
return result.ok ? c.json(result.value, 201) : designRefused(c, result);
|
|
79
|
+
})
|
|
80
|
+
.get("/:id", zValidator("param", idParam, onInvalid), (c) => {
|
|
81
|
+
if (deps === undefined)
|
|
82
|
+
return unavailable(c);
|
|
83
|
+
const result = getDesign(deps.service, c.req.valid("param").id);
|
|
84
|
+
return result.ok ? c.json(result.value) : designRefused(c, result);
|
|
85
|
+
})
|
|
86
|
+
.put("/:id", zValidator("param", idParam, onInvalid), async (c) => {
|
|
87
|
+
if (deps === undefined)
|
|
88
|
+
return unavailable(c);
|
|
89
|
+
const result = updateDesignRecord(deps.service, c.req.valid("param").id, await jsonBody(c));
|
|
90
|
+
return result.ok ? c.json(result.value) : designRefused(c, result);
|
|
91
|
+
})
|
|
92
|
+
.delete("/:id", zValidator("param", idParam, onInvalid), (c) => {
|
|
93
|
+
if (deps === undefined)
|
|
94
|
+
return unavailable(c);
|
|
95
|
+
const id = c.req.valid("param").id;
|
|
96
|
+
const result = trashDesign(deps.service, id);
|
|
97
|
+
if (!result.ok)
|
|
98
|
+
return designRefused(c, {
|
|
99
|
+
reason: "not-found",
|
|
100
|
+
message: "This design no longer exists. Go back to Designs to choose another.",
|
|
101
|
+
});
|
|
102
|
+
deps.service.emit?.({ type: "design.changed", designId: id });
|
|
103
|
+
return c.body(null, 204);
|
|
104
|
+
})
|
|
105
|
+
// Quoting records nothing and starts nothing.
|
|
106
|
+
.post("/:id/quote", zValidator("param", idParam, onInvalid), async (c) => {
|
|
107
|
+
if (deps === undefined)
|
|
108
|
+
return unavailable(c);
|
|
109
|
+
const result = deps.runner.quoteEdit(c.req.valid("param").id, await jsonBody(c));
|
|
110
|
+
return result.ok ? c.json(result.value) : designRefused(c, result);
|
|
111
|
+
})
|
|
112
|
+
.post("/:id/artwork/quote", zValidator("param", idParam, onInvalid), (c) => {
|
|
113
|
+
if (deps === undefined)
|
|
114
|
+
return unavailable(c);
|
|
115
|
+
const result = deps.runner.quoteArtwork(c.req.valid("param").id);
|
|
116
|
+
return result.ok ? c.json(result.value) : designRefused(c, result);
|
|
117
|
+
})
|
|
118
|
+
.post("/:id/edit", zValidator("param", idParam, onInvalid), async (c) => {
|
|
119
|
+
if (deps === undefined)
|
|
120
|
+
return unavailable(c);
|
|
121
|
+
const result = deps.runner.edit(c.req.valid("param").id, await jsonBody(c));
|
|
122
|
+
return result.ok ? c.json(result.value, 202) : designRefused(c, result);
|
|
123
|
+
})
|
|
124
|
+
.post("/:id/artwork", zValidator("param", idParam, onInvalid), async (c) => {
|
|
125
|
+
if (deps === undefined)
|
|
126
|
+
return unavailable(c);
|
|
127
|
+
const result = deps.runner.artwork(c.req.valid("param").id, await jsonBody(c));
|
|
128
|
+
return result.ok ? c.json(result.value, 202) : designRefused(c, result);
|
|
129
|
+
})
|
|
130
|
+
.post("/:id/steps/:stepId/retry", zValidator("param", stepParam, onInvalid), async (c) => {
|
|
131
|
+
if (deps === undefined)
|
|
132
|
+
return unavailable(c);
|
|
133
|
+
const { id, stepId } = c.req.valid("param");
|
|
134
|
+
const result = deps.runner.retry(id, stepId, await jsonBody(c));
|
|
135
|
+
return result.ok ? c.json(result.value, 202) : designRefused(c, result);
|
|
136
|
+
})
|
|
137
|
+
.put("/:id/head", zValidator("param", idParam, onInvalid), async (c) => {
|
|
138
|
+
if (deps === undefined)
|
|
139
|
+
return unavailable(c);
|
|
140
|
+
const result = setDesignHead(deps.service, c.req.valid("param").id, await jsonBody(c));
|
|
141
|
+
return result.ok ? c.json(result.value) : designRefused(c, result);
|
|
142
|
+
})
|
|
143
|
+
// A version never changes, so the browser may keep it.
|
|
144
|
+
.get("/:id/steps/:stepId/picture", zValidator("param", stepParam, onInvalid), (c) => {
|
|
145
|
+
if (deps === undefined)
|
|
146
|
+
return unavailable(c);
|
|
147
|
+
const { id, stepId } = c.req.valid("param");
|
|
148
|
+
const picture = stepPicture(deps.service.db, id, stepId);
|
|
149
|
+
if (picture === undefined)
|
|
150
|
+
return designRefused(c, {
|
|
151
|
+
reason: "not-found",
|
|
152
|
+
message: "That version has no picture. Reload the design to see its versions.",
|
|
153
|
+
});
|
|
154
|
+
return c.body(new Uint8Array(picture.bytes), 200, {
|
|
155
|
+
"Content-Type": picture.mime,
|
|
156
|
+
"Cache-Control": "private, max-age=31536000, immutable",
|
|
157
|
+
"X-Content-Type-Options": "nosniff",
|
|
158
|
+
});
|
|
159
|
+
})
|
|
160
|
+
// Drawn on demand in a child ffmpeg (and the PDF worker), then served from the cache.
|
|
161
|
+
.get("/:id/files/:file", zValidator("param", fileParam, onInvalid), async (c) => {
|
|
162
|
+
if (deps === undefined)
|
|
163
|
+
return unavailable(c);
|
|
164
|
+
const { id, file } = c.req.valid("param");
|
|
165
|
+
const format = z.enum(designFormats).parse(file.slice(0, file.lastIndexOf(".")));
|
|
166
|
+
const type = file.endsWith(".pdf") ? "pdf" : "png";
|
|
167
|
+
const result = await deps.renderer.render(id, format, type, c.req.raw.signal);
|
|
168
|
+
if (!result.ok)
|
|
169
|
+
return designRefused(c, result);
|
|
170
|
+
const bytes = await readFile(result.value.path);
|
|
171
|
+
return c.body(new Uint8Array(bytes), 200, {
|
|
172
|
+
"Content-Type": result.value.mime,
|
|
173
|
+
"Content-Disposition": `attachment; filename="${result.value.name.replace(/[^\x20-\x7e]|["\\]/g, "_")}"; filename*=UTF-8''${encodeURIComponent(result.value.name)}`,
|
|
174
|
+
"Cache-Control": "no-store",
|
|
175
|
+
"X-Content-Type-Options": "nosniff",
|
|
176
|
+
});
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import { providerStatuses } from "../../slices/settings/readiness.js";
|
|
3
|
+
import { notTemplateSample } from "../../slices/template-studio/repo.js";
|
|
3
4
|
/**
|
|
4
5
|
* A deliberately boring, secret-free support bundle. It is JSON rather than a
|
|
5
6
|
* filesystem archive so it can be copied from a remote/local browser and is
|
|
@@ -13,7 +14,10 @@ export function diagnosticsRoutes(deps) {
|
|
|
13
14
|
hostCliStatus: deps.hostCliStatus,
|
|
14
15
|
host: deps.speechHost,
|
|
15
16
|
});
|
|
16
|
-
|
|
17
|
+
// The template studio's hidden samples are no projects of the person's.
|
|
18
|
+
const projectCount = deps.db
|
|
19
|
+
.prepare(`SELECT count(*) AS count FROM projects WHERE ${notTemplateSample()}`)
|
|
20
|
+
.get();
|
|
17
21
|
const schema = deps.db.prepare("SELECT max(version) AS version FROM schema_migrations").get();
|
|
18
22
|
c.header("Cache-Control", "no-store");
|
|
19
23
|
c.header("Content-Disposition", 'attachment; filename="slopify-diagnostics.json"');
|