@deskwork/studio 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/components/scrapbook-item.d.ts +20 -0
  2. package/dist/components/scrapbook-item.d.ts.map +1 -1
  3. package/dist/components/scrapbook-item.js +21 -2
  4. package/dist/components/scrapbook-item.js.map +1 -1
  5. package/dist/lib/entry-resolver.d.ts +19 -6
  6. package/dist/lib/entry-resolver.d.ts.map +1 -1
  7. package/dist/lib/entry-resolver.js +40 -33
  8. package/dist/lib/entry-resolver.js.map +1 -1
  9. package/dist/pages/dashboard/affordances.d.ts.map +1 -1
  10. package/dist/pages/dashboard/affordances.js +13 -1
  11. package/dist/pages/dashboard/affordances.js.map +1 -1
  12. package/dist/pages/dashboard/affordances.ts +13 -1
  13. package/dist/pages/review-scrapbook-drawer.d.ts.map +1 -1
  14. package/dist/pages/review-scrapbook-drawer.js +10 -1
  15. package/dist/pages/review-scrapbook-drawer.js.map +1 -1
  16. package/dist/pages/review-scrapbook-drawer.ts +11 -1
  17. package/dist/pages/scrapbook/dispatch.d.ts +50 -0
  18. package/dist/pages/scrapbook/dispatch.d.ts.map +1 -0
  19. package/dist/pages/scrapbook/dispatch.js +104 -0
  20. package/dist/pages/scrapbook/dispatch.js.map +1 -0
  21. package/dist/pages/scrapbook/image-readers.d.ts +24 -0
  22. package/dist/pages/scrapbook/image-readers.d.ts.map +1 -0
  23. package/dist/pages/scrapbook/image-readers.js +135 -0
  24. package/dist/pages/scrapbook/image-readers.js.map +1 -0
  25. package/dist/pages/scrapbook/index.d.ts +21 -0
  26. package/dist/pages/scrapbook/index.d.ts.map +1 -0
  27. package/dist/pages/scrapbook/index.js +96 -0
  28. package/dist/pages/scrapbook/index.js.map +1 -0
  29. package/dist/pages/scrapbook/render.d.ts +68 -0
  30. package/dist/pages/scrapbook/render.d.ts.map +1 -0
  31. package/dist/pages/scrapbook/render.js +315 -0
  32. package/dist/pages/scrapbook/render.js.map +1 -0
  33. package/dist/pages/scrapbook/text-helpers.d.ts +40 -0
  34. package/dist/pages/scrapbook/text-helpers.d.ts.map +1 -0
  35. package/dist/pages/scrapbook/text-helpers.js +92 -0
  36. package/dist/pages/scrapbook/text-helpers.js.map +1 -0
  37. package/dist/pages/scrapbook/types.d.ts +26 -0
  38. package/dist/pages/scrapbook/types.d.ts.map +1 -0
  39. package/dist/pages/scrapbook/types.js +12 -0
  40. package/dist/pages/scrapbook/types.js.map +1 -0
  41. package/dist/pages/scrapbook.d.ts +8 -8
  42. package/dist/pages/scrapbook.d.ts.map +1 -1
  43. package/dist/pages/scrapbook.js +8 -600
  44. package/dist/pages/scrapbook.js.map +1 -1
  45. package/dist/pages/scrapbook.ts +11 -660
  46. package/dist/routes/api.d.ts.map +1 -1
  47. package/dist/routes/api.js +111 -2
  48. package/dist/routes/api.js.map +1 -1
  49. package/dist/routes/entry-annotation-body.d.ts +29 -0
  50. package/dist/routes/entry-annotation-body.d.ts.map +1 -1
  51. package/dist/routes/entry-annotation-body.js +80 -0
  52. package/dist/routes/entry-annotation-body.js.map +1 -1
  53. package/dist/routes/scrapbook-file.d.ts +1 -1
  54. package/dist/routes/scrapbook-file.js +1 -1
  55. package/dist/routes/scrapbook-mutation-dispatch.d.ts +29 -0
  56. package/dist/routes/scrapbook-mutation-dispatch.d.ts.map +1 -0
  57. package/dist/routes/scrapbook-mutation-dispatch.js +63 -0
  58. package/dist/routes/scrapbook-mutation-dispatch.js.map +1 -0
  59. package/dist/routes/scrapbook-mutation-envelope.d.ts +93 -0
  60. package/dist/routes/scrapbook-mutation-envelope.d.ts.map +1 -0
  61. package/dist/routes/scrapbook-mutation-envelope.js +147 -0
  62. package/dist/routes/scrapbook-mutation-envelope.js.map +1 -0
  63. package/dist/routes/scrapbook-mutations.d.ts +25 -7
  64. package/dist/routes/scrapbook-mutations.d.ts.map +1 -1
  65. package/dist/routes/scrapbook-mutations.js +67 -92
  66. package/dist/routes/scrapbook-mutations.js.map +1 -1
  67. package/dist/server.d.ts.map +1 -1
  68. package/dist/server.js +16 -2
  69. package/dist/server.js.map +1 -1
  70. package/package.json +2 -2
  71. package/dist/pages/review.d.ts +0 -68
  72. package/dist/pages/review.d.ts.map +0 -1
  73. package/dist/pages/review.js +0 -561
  74. package/dist/pages/review.js.map +0 -1
  75. package/dist/pages/review.ts +0 -710
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Mutation-envelope parsing for the studio scrapbook routes.
3
+ *
4
+ * Lives next to `scrapbook-mutations.ts`; extracted (#191) to keep the
5
+ * route file under the project's 300–500 line cap. The single
6
+ * responsibility is:
7
+ *
8
+ * 1. Validate the request envelope (`site`, `entryId | slug`, `secret?`).
9
+ * 2. Validate `entryId` against the UUID regex BEFORE filesystem access
10
+ * (the scrapbook-file route's same pattern, landed in v0.15.0
11
+ * commit `14ffbe7`).
12
+ * 3. Resolve the absolute scrapbook directory for whichever addressing
13
+ * mode the request used. Both modes route through
14
+ * `scrapbookDirForEntry`: entry-id mode reads the sidecar to get
15
+ * the bound `{ uuid, slug }`; slug mode synthesizes `{ slug }`
16
+ * (no id) and lets the entry-aware resolver fall back to its
17
+ * internal slug-template path. Post-#192 this is a single code
18
+ * path with no public slug-template entry point.
19
+ *
20
+ * The envelope is a discriminated union (`mode: 'entry' | 'slug'`); call
21
+ * sites narrow without `as` casts.
22
+ */
23
+ import { scrapbookDirForEntry } from '@deskwork/core/scrapbook';
24
+ import { readSidecar } from '@deskwork/core/sidecar';
25
+ // ---------------------------------------------------------------------------
26
+ // UUID validation
27
+ // ---------------------------------------------------------------------------
28
+ /**
29
+ * Mirrors the UUID regex enforced on entry creation and used by the
30
+ * scrapbook-file route. Rejects malformed `entryId` before it reaches
31
+ * the filesystem — `readSidecar` composes its path as
32
+ * `<projectRoot>/.deskwork/entries/<entryId>.json`, and `node:path`'s
33
+ * join collapses `..` segments, so an unvalidated `entryId` could probe
34
+ * arbitrary on-disk locations.
35
+ */
36
+ export const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
37
+ export function isEnvelopeError(v) {
38
+ return 'error' in v;
39
+ }
40
+ // ---------------------------------------------------------------------------
41
+ // JSON envelope check
42
+ // ---------------------------------------------------------------------------
43
+ /**
44
+ * Validate the common `{ site, entryId? | slug?, secret? }` envelope for
45
+ * JSON-body routes. Returns a typed object or an `EnvelopeError` that
46
+ * the caller propagates directly. The site existence check is here so
47
+ * every mutation 404s on unknown sites the same way the read endpoint
48
+ * does.
49
+ *
50
+ * `entryId` is preferred when both are present. UUID validation runs
51
+ * BEFORE filesystem access for the same reason as the scrapbook-file
52
+ * route — see the UUID_RE comment above.
53
+ */
54
+ export function checkJsonEnvelope(ctx, body) {
55
+ const site = body.site;
56
+ if (typeof site !== 'string' || site.length === 0) {
57
+ return { error: 'site is required', status: 400 };
58
+ }
59
+ if (!(site in ctx.config.sites)) {
60
+ return { error: `unknown site: ${site}`, status: 404 };
61
+ }
62
+ const secretRaw = body.secret;
63
+ if (secretRaw !== undefined && typeof secretRaw !== 'boolean') {
64
+ return { error: 'secret must be a boolean when provided', status: 400 };
65
+ }
66
+ const secret = secretRaw === true;
67
+ const entryId = body.entryId;
68
+ if (entryId !== undefined) {
69
+ if (typeof entryId !== 'string' || entryId.length === 0) {
70
+ return {
71
+ error: 'entryId must be a non-empty string when provided',
72
+ status: 400,
73
+ };
74
+ }
75
+ if (!UUID_RE.test(entryId)) {
76
+ return { error: 'invalid entryId', status: 400 };
77
+ }
78
+ return { mode: 'entry', site, entryId, secret };
79
+ }
80
+ // Back-compat slug-template fallback. To be removed in #192 once all
81
+ // callers send entryId.
82
+ const slug = body.slug;
83
+ if (typeof slug !== 'string' || slug.length === 0) {
84
+ return { error: 'entryId or slug is required', status: 400 };
85
+ }
86
+ return { mode: 'slug', site, slug, secret };
87
+ }
88
+ // ---------------------------------------------------------------------------
89
+ // Multipart envelope check
90
+ // ---------------------------------------------------------------------------
91
+ /**
92
+ * Same shape as `checkJsonEnvelope` but reads from a `FormData` instance.
93
+ * Used by the upload route, which speaks multipart for binary file
94
+ * payloads. The semantics match — `entryId` preferred, `slug` is the
95
+ * deprecation-window fallback, UUID validation up-front.
96
+ *
97
+ * Note: the multipart `secret` field arrives as the literal string
98
+ * `"true"` (form fields are always strings); we normalize it here so
99
+ * the rest of the pipeline doesn't have to special-case form-vs-json.
100
+ */
101
+ export function checkFormEnvelope(ctx, form) {
102
+ const site = form.get('site');
103
+ if (typeof site !== 'string' || site.length === 0) {
104
+ return { error: 'site is required', status: 400 };
105
+ }
106
+ if (!(site in ctx.config.sites)) {
107
+ return { error: `unknown site: ${site}`, status: 404 };
108
+ }
109
+ const secretField = form.get('secret');
110
+ const secret = typeof secretField === 'string' && secretField === 'true';
111
+ const entryIdField = form.get('entryId');
112
+ if (typeof entryIdField === 'string' && entryIdField.length > 0) {
113
+ if (!UUID_RE.test(entryIdField)) {
114
+ return { error: 'invalid entryId', status: 400 };
115
+ }
116
+ return { mode: 'entry', site, entryId: entryIdField, secret };
117
+ }
118
+ const slug = form.get('slug');
119
+ if (typeof slug !== 'string' || slug.length === 0) {
120
+ return { error: 'entryId or slug is required', status: 400 };
121
+ }
122
+ return { mode: 'slug', site, slug, secret };
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Directory resolution
126
+ // ---------------------------------------------------------------------------
127
+ /**
128
+ * Resolve the absolute scrapbook directory for a parsed envelope. Both
129
+ * modes go through `scrapbookDirForEntry`:
130
+ * - entry-id mode reads the sidecar and passes `{ id, slug }` so the
131
+ * resolver hits the index lookup (refactor-proof binding).
132
+ * - slug mode passes `{ slug }` only; the resolver still goes through
133
+ * `findEntryFile`, which falls back to its private slug-template
134
+ * path when no id binding exists. Post-#192 this is the only code
135
+ * path; the public `scrapbookDir(slug)` was retired.
136
+ *
137
+ * Throws on lookup / resolution failure; the caller maps the error
138
+ * message onto the right HTTP status via `statusForError`.
139
+ */
140
+ export async function resolveScrapbookDir(ctx, env) {
141
+ if (env.mode === 'entry') {
142
+ const entry = await readSidecar(ctx.projectRoot, env.entryId);
143
+ return scrapbookDirForEntry(ctx.projectRoot, ctx.config, env.site, { id: entry.uuid, slug: entry.slug });
144
+ }
145
+ return scrapbookDirForEntry(ctx.projectRoot, ctx.config, env.site, { slug: env.slug });
146
+ }
147
+ //# sourceMappingURL=scrapbook-mutation-envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrapbook-mutation-envelope.js","sourceRoot":"","sources":["../../src/routes/scrapbook-mutation-envelope.ts"],"names":[],"mappings":"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"}
@@ -10,15 +10,33 @@
10
10
  * Phase 16d retrofitted only the read path. v0.4.1 closes the gap
11
11
  * (issue #21).
12
12
  *
13
+ * Two addressing modes (#191, unified post-#192):
14
+ * - **Entry-id mode** (preferred): `{ site, entryId, ... }` — looks up
15
+ * the entry's sidecar, derives the scrapbook dir from the artifact's
16
+ * parent directory via `scrapbookDirForEntry`, mutates there. Same
17
+ * code path the read endpoints use; refactor-proof for projects whose
18
+ * feature-doc layout doesn't match the kebab-case slug template.
19
+ * - **Slug mode** (back-compat fallback): `{ site, slug, ... }` —
20
+ * accepted for back-compat with older clients. Post-#192, slug mode
21
+ * also routes through `scrapbookDirForEntry`: passing `{ slug }`
22
+ * without an id triggers the resolver's internal slug-template
23
+ * fallback, so the public mutation surface is unified on the
24
+ * entry-aware code path. The legacy `scrapbookDir(slug)` and the
25
+ * slug-template CRUD primitives are no longer exported from
26
+ * `@deskwork/core/scrapbook`.
27
+ *
28
+ * Companion modules (#191 split, to keep this file under the project's
29
+ * 300–500 line cap):
30
+ * - `scrapbook-mutation-envelope.ts` — JSON / form envelope parsing,
31
+ * UUID validation, dir resolution.
32
+ * - `scrapbook-mutation-dispatch.ts` — per-mode dispatch helpers
33
+ * (entry-aware vs. slug-template), one per route verb.
34
+ *
13
35
  * Design notes:
14
36
  * - Path resolution + traversal protection runs through
15
- * `@deskwork/core/scrapbook` helpers (`scrapbookFilePath` etc.).
16
- * Those throw on `..` sequences, absolute paths, and any filename
17
- * that escapes the scrapbook dir; we surface those as 400.
18
- * - The client speaks `{ site, slug, filename, body }` for save/create,
19
- * `{ site, slug, oldName, newName }` for rename, `{ site, slug,
20
- * filename }` for delete, multipart `{ site, slug, file }` for
21
- * upload. Endpoints accept those exact field names.
37
+ * `@deskwork/core/scrapbook` helpers. Those throw on `..` sequences,
38
+ * absolute paths, and any filename that escapes the scrapbook dir;
39
+ * we surface those as 400.
22
40
  * - We never log file contents on save / upload (privacy). Logging
23
41
  * filename + slug is fine but kept silent here — the studio's
24
42
  * console is the operator's, not a server log.
@@ -1 +1 @@
1
- {"version":3,"file":"scrapbook-mutations.d.ts","sourceRoot":"","sources":["../../src/routes/scrapbook-mutations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAc5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA0F9C,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAqSvE"}
1
+ {"version":3,"file":"scrapbook-mutations.d.ts","sourceRoot":"","sources":["../../src/routes/scrapbook-mutations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAgE9C,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAyMvE"}
@@ -10,15 +10,33 @@
10
10
  * Phase 16d retrofitted only the read path. v0.4.1 closes the gap
11
11
  * (issue #21).
12
12
  *
13
+ * Two addressing modes (#191, unified post-#192):
14
+ * - **Entry-id mode** (preferred): `{ site, entryId, ... }` — looks up
15
+ * the entry's sidecar, derives the scrapbook dir from the artifact's
16
+ * parent directory via `scrapbookDirForEntry`, mutates there. Same
17
+ * code path the read endpoints use; refactor-proof for projects whose
18
+ * feature-doc layout doesn't match the kebab-case slug template.
19
+ * - **Slug mode** (back-compat fallback): `{ site, slug, ... }` —
20
+ * accepted for back-compat with older clients. Post-#192, slug mode
21
+ * also routes through `scrapbookDirForEntry`: passing `{ slug }`
22
+ * without an id triggers the resolver's internal slug-template
23
+ * fallback, so the public mutation surface is unified on the
24
+ * entry-aware code path. The legacy `scrapbookDir(slug)` and the
25
+ * slug-template CRUD primitives are no longer exported from
26
+ * `@deskwork/core/scrapbook`.
27
+ *
28
+ * Companion modules (#191 split, to keep this file under the project's
29
+ * 300–500 line cap):
30
+ * - `scrapbook-mutation-envelope.ts` — JSON / form envelope parsing,
31
+ * UUID validation, dir resolution.
32
+ * - `scrapbook-mutation-dispatch.ts` — per-mode dispatch helpers
33
+ * (entry-aware vs. slug-template), one per route verb.
34
+ *
13
35
  * Design notes:
14
36
  * - Path resolution + traversal protection runs through
15
- * `@deskwork/core/scrapbook` helpers (`scrapbookFilePath` etc.).
16
- * Those throw on `..` sequences, absolute paths, and any filename
17
- * that escapes the scrapbook dir; we surface those as 400.
18
- * - The client speaks `{ site, slug, filename, body }` for save/create,
19
- * `{ site, slug, oldName, newName }` for rename, `{ site, slug,
20
- * filename }` for delete, multipart `{ site, slug, file }` for
21
- * upload. Endpoints accept those exact field names.
37
+ * `@deskwork/core/scrapbook` helpers. Those throw on `..` sequences,
38
+ * absolute paths, and any filename that escapes the scrapbook dir;
39
+ * we surface those as 400.
22
40
  * - We never log file contents on save / upload (privacy). Logging
23
41
  * filename + slug is fine but kept silent here — the studio's
24
42
  * console is the operator's, not a server log.
@@ -28,34 +46,14 @@
28
46
  * so the client UI can flash a useful message.
29
47
  */
30
48
  import { Hono } from 'hono';
31
- import { classify, createScrapbookMarkdown, deleteScrapbookFile, renameScrapbookFile, saveScrapbookFile, writeScrapbookUpload, } from '@deskwork/core/scrapbook';
49
+ import { classify } from '@deskwork/core/scrapbook';
32
50
  import { existsSync, mkdirSync, renameSync, statSync } from 'node:fs';
33
51
  import { dirname } from 'node:path';
34
- import { scrapbookFilePath } from '@deskwork/core/scrapbook';
35
- /**
36
- * Validate the common `{ site, slug, secret? }` envelope. Returns a
37
- * typed object or a 400/404 Response that the caller propagates
38
- * directly. The site existence check is here so every mutation 404s
39
- * on unknown sites the same way the read endpoint does.
40
- */
41
- function checkEnvelope(ctx, body) {
42
- const site = body.site;
43
- const slug = body.slug;
44
- if (typeof site !== 'string' || site.length === 0) {
45
- return { error: 'site is required', status: 400 };
46
- }
47
- if (typeof slug !== 'string' || slug.length === 0) {
48
- return { error: 'slug is required', status: 400 };
49
- }
50
- if (!(site in ctx.config.sites)) {
51
- return { error: `unknown site: ${site}`, status: 404 };
52
- }
53
- const secretRaw = body.secret;
54
- if (secretRaw !== undefined && typeof secretRaw !== 'boolean') {
55
- return { error: 'secret must be a boolean when provided', status: 400 };
56
- }
57
- return { site, slug, secret: secretRaw === true };
58
- }
52
+ import { checkFormEnvelope, checkJsonEnvelope, isEnvelopeError, } from "./scrapbook-mutation-envelope.js";
53
+ import { createDispatch, deleteDispatch, renameInPlace, resolveCrossSectionPaths, saveDispatch, uploadDispatch, } from "./scrapbook-mutation-dispatch.js";
54
+ // ---------------------------------------------------------------------------
55
+ // Helpers
56
+ // ---------------------------------------------------------------------------
59
57
  /**
60
58
  * Map a core-helper error message onto the right HTTP status. The core
61
59
  * helpers throw plain `Error` with descriptive text; we keep the text
@@ -91,16 +89,17 @@ async function readJson(c) {
91
89
  export function createScrapbookMutationsRouter(ctx) {
92
90
  const app = new Hono();
93
91
  // POST /api/dev/scrapbook/save
94
- // Body: { site, slug, filename, body }
95
- // Behavior: write `body` to <contentDir>/<slug>/scrapbook/<filename>.
96
- // Creates the file if missing (delegates to create when absent so the
97
- // operator's first save lands rather than 404'ing).
92
+ // Body (entry mode): { site, entryId, filename, body, secret? }
93
+ // Body (slug mode): { site, slug, filename, body, secret? }
94
+ // Behavior: write `body` to <scrapbook-dir>/<filename>. Creates the
95
+ // file if missing (delegates to create when absent so the operator's
96
+ // first save lands rather than 404'ing).
98
97
  app.post('/save', async (c) => {
99
98
  const parsed = await readJson(c);
100
99
  if (!parsed.ok)
101
100
  return c.json({ error: parsed.error }, parsed.status);
102
- const env = checkEnvelope(ctx, parsed.value);
103
- if ('error' in env)
101
+ const env = checkJsonEnvelope(ctx, parsed.value);
102
+ if (isEnvelopeError(env))
104
103
  return c.json({ error: env.error }, env.status);
105
104
  const filename = parsed.value.filename;
106
105
  const bodyText = parsed.value.body;
@@ -112,22 +111,7 @@ export function createScrapbookMutationsRouter(ctx) {
112
111
  }
113
112
  let item;
114
113
  try {
115
- // Resolve to test for existence. If absent, create-then-return.
116
- const abs = scrapbookFilePath(ctx.projectRoot, ctx.config, env.site, env.slug, filename, { secret: env.secret });
117
- if (!existsSync(abs)) {
118
- // Only `.md` files can be created by the create helper, but
119
- // save's contract is "write whatever was sent". For non-md
120
- // files that don't yet exist, fall through to upload semantics.
121
- if (filename.endsWith('.md')) {
122
- item = createScrapbookMarkdown(ctx.projectRoot, ctx.config, env.site, env.slug, filename, bodyText, { secret: env.secret });
123
- }
124
- else {
125
- item = writeScrapbookUpload(ctx.projectRoot, ctx.config, env.site, env.slug, filename, Buffer.from(bodyText, 'utf-8'), { secret: env.secret });
126
- }
127
- }
128
- else {
129
- item = saveScrapbookFile(ctx.projectRoot, ctx.config, env.site, env.slug, filename, bodyText, { secret: env.secret });
130
- }
114
+ item = await saveDispatch(ctx, env, filename, bodyText);
131
115
  }
132
116
  catch (err) {
133
117
  const reason = err instanceof Error ? err.message : String(err);
@@ -136,7 +120,8 @@ export function createScrapbookMutationsRouter(ctx) {
136
120
  return c.json({ item }, 200);
137
121
  });
138
122
  // POST /api/dev/scrapbook/rename
139
- // Body: { site, slug, oldName, newName, secret?, toSecret? }
123
+ // Body (entry mode): { site, entryId, oldName, newName, secret?, toSecret? }
124
+ // Body (slug mode): { site, slug, oldName, newName, secret?, toSecret? }
140
125
  //
141
126
  // Two modes:
142
127
  // - In-place rename: secret = source location (defaults to false);
@@ -153,8 +138,8 @@ export function createScrapbookMutationsRouter(ctx) {
153
138
  const parsed = await readJson(c);
154
139
  if (!parsed.ok)
155
140
  return c.json({ error: parsed.error }, parsed.status);
156
- const env = checkEnvelope(ctx, parsed.value);
157
- if ('error' in env)
141
+ const env = checkJsonEnvelope(ctx, parsed.value);
142
+ if (isEnvelopeError(env))
158
143
  return c.json({ error: env.error }, env.status);
159
144
  const oldName = parsed.value.oldName;
160
145
  const newName = parsed.value.newName;
@@ -172,15 +157,13 @@ export function createScrapbookMutationsRouter(ctx) {
172
157
  let item;
173
158
  try {
174
159
  if (toSecret === env.secret) {
175
- item = renameScrapbookFile(ctx.projectRoot, ctx.config, env.site, env.slug, oldName, newName, { secret: env.secret });
160
+ item = await renameInPlace(ctx, env, oldName, newName);
176
161
  }
177
162
  else {
178
- // Cross-section move. Use the path-resolver to compute the
179
- // source and destination absolute paths under the right
180
- // sub-roots (and let the resolver enforce traversal guards).
163
+ // Cross-section move. Resolve src + dst absolute paths under the
164
+ // right sub-roots and let the resolver enforce traversal guards.
181
165
  // Then physically rename across the two paths.
182
- const srcAbs = scrapbookFilePath(ctx.projectRoot, ctx.config, env.site, env.slug, oldName, { secret: env.secret });
183
- const dstAbs = scrapbookFilePath(ctx.projectRoot, ctx.config, env.site, env.slug, newName, { secret: toSecret });
166
+ const { srcAbs, dstAbs } = await resolveCrossSectionPaths(ctx, env, oldName, newName, toSecret);
184
167
  if (!existsSync(srcAbs)) {
185
168
  return c.json({ error: `file not found: "${oldName}"` }, 404);
186
169
  }
@@ -208,21 +191,22 @@ export function createScrapbookMutationsRouter(ctx) {
208
191
  return c.json({ item }, 200);
209
192
  });
210
193
  // POST /api/dev/scrapbook/delete
211
- // Body: { site, slug, filename }
194
+ // Body (entry mode): { site, entryId, filename, secret? }
195
+ // Body (slug mode): { site, slug, filename, secret? }
212
196
  // Behavior: unlink the file. 404 if missing.
213
197
  app.post('/delete', async (c) => {
214
198
  const parsed = await readJson(c);
215
199
  if (!parsed.ok)
216
200
  return c.json({ error: parsed.error }, parsed.status);
217
- const env = checkEnvelope(ctx, parsed.value);
218
- if ('error' in env)
201
+ const env = checkJsonEnvelope(ctx, parsed.value);
202
+ if (isEnvelopeError(env))
219
203
  return c.json({ error: env.error }, env.status);
220
204
  const filename = parsed.value.filename;
221
205
  if (typeof filename !== 'string' || filename.length === 0) {
222
206
  return c.json({ error: 'filename is required' }, 400);
223
207
  }
224
208
  try {
225
- deleteScrapbookFile(ctx.projectRoot, ctx.config, env.site, env.slug, filename, { secret: env.secret });
209
+ await deleteDispatch(ctx, env, filename);
226
210
  }
227
211
  catch (err) {
228
212
  const reason = err instanceof Error ? err.message : String(err);
@@ -231,14 +215,15 @@ export function createScrapbookMutationsRouter(ctx) {
231
215
  return c.json({ ok: true }, 200);
232
216
  });
233
217
  // POST /api/dev/scrapbook/create
234
- // Body: { site, slug, filename, body? }
218
+ // Body (entry mode): { site, entryId, filename, body?, secret? }
219
+ // Body (slug mode): { site, slug, filename, body?, secret? }
235
220
  // Behavior: create a new markdown file. 409 if it already exists.
236
221
  app.post('/create', async (c) => {
237
222
  const parsed = await readJson(c);
238
223
  if (!parsed.ok)
239
224
  return c.json({ error: parsed.error }, parsed.status);
240
- const env = checkEnvelope(ctx, parsed.value);
241
- if ('error' in env)
225
+ const env = checkJsonEnvelope(ctx, parsed.value);
226
+ if (isEnvelopeError(env))
242
227
  return c.json({ error: env.error }, env.status);
243
228
  const filename = parsed.value.filename;
244
229
  const bodyText = parsed.value.body ?? '';
@@ -250,7 +235,7 @@ export function createScrapbookMutationsRouter(ctx) {
250
235
  }
251
236
  let item;
252
237
  try {
253
- item = createScrapbookMarkdown(ctx.projectRoot, ctx.config, env.site, env.slug, filename, bodyText, { secret: env.secret });
238
+ item = await createDispatch(ctx, env, filename, bodyText);
254
239
  }
255
240
  catch (err) {
256
241
  const reason = err instanceof Error ? err.message : String(err);
@@ -259,12 +244,12 @@ export function createScrapbookMutationsRouter(ctx) {
259
244
  return c.json({ item }, 200);
260
245
  });
261
246
  // POST /api/dev/scrapbook/upload
262
- // Multipart body: { site, slug, file, secret? }
263
- // Behavior: save the uploaded file (binary-safe) at
264
- // <contentDir>/<slug>/scrapbook/<file.name>, or under
265
- // `scrapbook/secret/` when the `secret` form field is the literal
266
- // string "true". 409 if it already exists — operator must rename
267
- // or delete first.
247
+ // Multipart body (entry mode): { site, entryId, file, secret? }
248
+ // Multipart body (slug mode): { site, slug, file, secret? }
249
+ // Behavior: save the uploaded file (binary-safe) at the scrapbook dir,
250
+ // or under `scrapbook/secret/` when the `secret` form field is the
251
+ // literal string "true". 409 if it already exists — operator must
252
+ // rename or delete first.
268
253
  app.post('/upload', async (c) => {
269
254
  let form;
270
255
  try {
@@ -273,20 +258,10 @@ export function createScrapbookMutationsRouter(ctx) {
273
258
  catch {
274
259
  return c.json({ error: 'invalid multipart body' }, 400);
275
260
  }
276
- const site = form.get('site');
277
- const slug = form.get('slug');
261
+ const env = checkFormEnvelope(ctx, form);
262
+ if (isEnvelopeError(env))
263
+ return c.json({ error: env.error }, env.status);
278
264
  const file = form.get('file');
279
- const secretField = form.get('secret');
280
- const secret = typeof secretField === 'string' && secretField === 'true';
281
- if (typeof site !== 'string' || site.length === 0) {
282
- return c.json({ error: 'site is required' }, 400);
283
- }
284
- if (typeof slug !== 'string' || slug.length === 0) {
285
- return c.json({ error: 'slug is required' }, 400);
286
- }
287
- if (!(site in ctx.config.sites)) {
288
- return c.json({ error: `unknown site: ${site}` }, 404);
289
- }
290
265
  if (!(file instanceof File)) {
291
266
  return c.json({ error: 'file is required (multipart)' }, 400);
292
267
  }
@@ -297,7 +272,7 @@ export function createScrapbookMutationsRouter(ctx) {
297
272
  let item;
298
273
  try {
299
274
  const buf = Buffer.from(await file.arrayBuffer());
300
- item = writeScrapbookUpload(ctx.projectRoot, ctx.config, site, slug, filename, buf, { secret });
275
+ item = await uploadDispatch(ctx, env, filename, buf);
301
276
  }
302
277
  catch (err) {
303
278
  const reason = err instanceof Error ? err.message : String(err);
@@ -1 +1 @@
1
- {"version":3,"file":"scrapbook-mutations.js","sourceRoot":"","sources":["../../src/routes/scrapbook-mutations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scrapbook-mutations.js","sourceRoot":"","sources":["../../src/routes/scrapbook-mutations.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAwBtE,UAAU,OAAO;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qEAAqE;IACrE,WAAW,EAAE,OAAO,CAAC;CACtB;AAKD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CA8CpD;AAkFD,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAuNlD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAwBtE,UAAU,OAAO;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qEAAqE;IACrE,WAAW,EAAE,OAAO,CAAC;CACtB;AAKD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CA8CpD;AAkFD,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAyOlD"}
package/dist/server.js CHANGED
@@ -43,7 +43,7 @@ import { renderShortformReviewPage } from "./pages/shortform-review.js";
43
43
  import { renderEntryReviewPage } from "./pages/entry-review.js";
44
44
  import { renderShortformPage } from "./pages/shortform.js";
45
45
  import { renderHelpPage } from "./pages/help.js";
46
- import { renderScrapbookPage } from "./pages/scrapbook.js";
46
+ import { renderScrapbookPage, ScrapbookPageError } from "./pages/scrapbook.js";
47
47
  import { renderContentTopLevel, renderContentProject, } from "./pages/content.js";
48
48
  import { renderStudioIndex } from "./pages/index.js";
49
49
  import { detectTailscale } from "./tailscale.js";
@@ -286,6 +286,11 @@ export function createApp(ctx) {
286
286
  app.get('/dev/scrapbook/:site/:path{.+}', async (c) => {
287
287
  const site = c.req.param('site');
288
288
  const path = decodeURIComponent(c.req.param('path'));
289
+ // #205: when the request carries `?entryId=<uuid>`, resolve the
290
+ // listing via `scrapbookDirForEntry` (matching the entry-aware
291
+ // mutation API). Slug-template addressing remains the fallback for
292
+ // legacy callers and ad-hoc paths.
293
+ const entryId = c.req.query('entryId');
289
294
  const overridden = await runTemplateOverride(ctx, 'scrapbook', [
290
295
  ctx,
291
296
  site,
@@ -293,7 +298,16 @@ export function createApp(ctx) {
293
298
  ]);
294
299
  if (overridden !== null)
295
300
  return c.html(overridden);
296
- return c.html(renderScrapbookPage(ctx, site, path));
301
+ try {
302
+ const html = await renderScrapbookPage(ctx, site, path, entryId !== undefined && entryId.length > 0 ? { entryId } : {});
303
+ return c.html(html);
304
+ }
305
+ catch (e) {
306
+ if (e instanceof ScrapbookPageError) {
307
+ return c.json({ error: e.message }, e.status);
308
+ }
309
+ throw e;
310
+ }
297
311
  });
298
312
  // Read-only binary endpoint for scrapbook files. Used by the
299
313
  // shared scrapbook-item renderer (`components/scrapbook-item.ts`)