emdash-emit 0.1.17 → 0.1.25

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 (216) hide show
  1. package/CHANGELOG.md +152 -0
  2. package/README.md +22 -11
  3. package/dist/cli/commands/new.d.ts.map +1 -1
  4. package/dist/cli/commands/new.js +30 -0
  5. package/dist/cli/commands/new.js.map +1 -1
  6. package/dist/cli/commands/pull.d.ts +2 -10
  7. package/dist/cli/commands/pull.d.ts.map +1 -1
  8. package/dist/cli/commands/pull.js +12 -30
  9. package/dist/cli/commands/pull.js.map +1 -1
  10. package/dist/cli/commands/status.d.ts.map +1 -1
  11. package/dist/cli/commands/status.js +7 -2
  12. package/dist/cli/commands/status.js.map +1 -1
  13. package/dist/client/api.d.ts +20 -0
  14. package/dist/client/api.d.ts.map +1 -1
  15. package/dist/client/api.js +89 -0
  16. package/dist/client/api.js.map +1 -1
  17. package/dist/client/auth.d.ts.map +1 -1
  18. package/dist/client/auth.js +2 -1
  19. package/dist/client/auth.js.map +1 -1
  20. package/dist/client/endpoints.d.ts +19 -0
  21. package/dist/client/endpoints.d.ts.map +1 -0
  22. package/dist/client/endpoints.js +69 -0
  23. package/dist/client/endpoints.js.map +1 -0
  24. package/dist/client/http.d.ts +4 -2
  25. package/dist/client/http.d.ts.map +1 -1
  26. package/dist/client/http.js.map +1 -1
  27. package/dist/client/lock.d.ts.map +1 -1
  28. package/dist/client/lock.js +4 -3
  29. package/dist/client/lock.js.map +1 -1
  30. package/dist/client/mapper.d.ts.map +1 -1
  31. package/dist/client/mapper.js +5 -3
  32. package/dist/client/mapper.js.map +1 -1
  33. package/dist/client/media-id.d.ts +2 -0
  34. package/dist/client/media-id.d.ts.map +1 -0
  35. package/dist/client/media-id.js +23 -0
  36. package/dist/client/media-id.js.map +1 -0
  37. package/dist/client/media.d.ts +8 -7
  38. package/dist/client/media.d.ts.map +1 -1
  39. package/dist/client/media.js +58 -17
  40. package/dist/client/media.js.map +1 -1
  41. package/dist/db/baseline.d.ts +38 -0
  42. package/dist/db/baseline.d.ts.map +1 -0
  43. package/dist/db/baseline.js +74 -0
  44. package/dist/db/baseline.js.map +1 -0
  45. package/dist/db/cache.d.ts +8 -2
  46. package/dist/db/cache.d.ts.map +1 -1
  47. package/dist/db/cache.js +24 -2
  48. package/dist/db/cache.js.map +1 -1
  49. package/dist/index.d.ts +4 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +4 -0
  52. package/dist/index.js.map +1 -1
  53. package/dist/mcp/tools/sync-new.d.ts.map +1 -1
  54. package/dist/mcp/tools/sync-new.js +42 -1
  55. package/dist/mcp/tools/sync-new.js.map +1 -1
  56. package/dist/mcp/tools/sync-pull.d.ts.map +1 -1
  57. package/dist/mcp/tools/sync-pull.js +15 -2
  58. package/dist/mcp/tools/sync-pull.js.map +1 -1
  59. package/dist/mcp/tools/sync-status.d.ts.map +1 -1
  60. package/dist/mcp/tools/sync-status.js +1 -0
  61. package/dist/mcp/tools/sync-status.js.map +1 -1
  62. package/dist/presentation/article_report.d.ts +40 -0
  63. package/dist/presentation/article_report.d.ts.map +1 -0
  64. package/dist/presentation/article_report.js +80 -0
  65. package/dist/presentation/article_report.js.map +1 -0
  66. package/dist/sync/bylines.d.ts.map +1 -1
  67. package/dist/sync/bylines.js +2 -1
  68. package/dist/sync/bylines.js.map +1 -1
  69. package/dist/sync/conflicts.js +1 -1
  70. package/dist/sync/conflicts.js.map +1 -1
  71. package/dist/sync/delete.d.ts +0 -5
  72. package/dist/sync/delete.d.ts.map +1 -1
  73. package/dist/sync/delete.js +5 -11
  74. package/dist/sync/delete.js.map +1 -1
  75. package/dist/sync/diff.d.ts.map +1 -1
  76. package/dist/sync/diff.js +13 -9
  77. package/dist/sync/diff.js.map +1 -1
  78. package/dist/sync/doctor.d.ts.map +1 -1
  79. package/dist/sync/doctor.js +11 -14
  80. package/dist/sync/doctor.js.map +1 -1
  81. package/dist/sync/guards.d.ts +5 -0
  82. package/dist/sync/guards.d.ts.map +1 -1
  83. package/dist/sync/guards.js +62 -1
  84. package/dist/sync/guards.js.map +1 -1
  85. package/dist/sync/media/body_scan.d.ts.map +1 -1
  86. package/dist/sync/media/body_scan.js +9 -3
  87. package/dist/sync/media/body_scan.js.map +1 -1
  88. package/dist/sync/media/companions.d.ts +2 -9
  89. package/dist/sync/media/companions.d.ts.map +1 -1
  90. package/dist/sync/media/companions.js +5 -23
  91. package/dist/sync/media/companions.js.map +1 -1
  92. package/dist/sync/media/mirror_item.d.ts.map +1 -1
  93. package/dist/sync/media/mirror_item.js +33 -21
  94. package/dist/sync/media/mirror_item.js.map +1 -1
  95. package/dist/sync/media/pull_article.d.ts.map +1 -1
  96. package/dist/sync/media/pull_article.js +3 -2
  97. package/dist/sync/media/pull_article.js.map +1 -1
  98. package/dist/sync/media/pull_library.d.ts.map +1 -1
  99. package/dist/sync/media/pull_library.js +16 -11
  100. package/dist/sync/media/pull_library.js.map +1 -1
  101. package/dist/sync/media/remote_index.d.ts.map +1 -1
  102. package/dist/sync/media/remote_index.js +2 -1
  103. package/dist/sync/media/remote_index.js.map +1 -1
  104. package/dist/sync/media/types.d.ts +4 -3
  105. package/dist/sync/media/types.d.ts.map +1 -1
  106. package/dist/sync/media/types.js.map +1 -1
  107. package/dist/sync/merge.d.ts +1 -1
  108. package/dist/sync/merge.d.ts.map +1 -1
  109. package/dist/sync/merge.js +50 -17
  110. package/dist/sync/merge.js.map +1 -1
  111. package/dist/sync/new.d.ts +11 -0
  112. package/dist/sync/new.d.ts.map +1 -1
  113. package/dist/sync/new.js +81 -4
  114. package/dist/sync/new.js.map +1 -1
  115. package/dist/sync/preflight.d.ts +10 -2
  116. package/dist/sync/preflight.d.ts.map +1 -1
  117. package/dist/sync/preflight.js +119 -17
  118. package/dist/sync/preflight.js.map +1 -1
  119. package/dist/sync/pull.d.ts +6 -44
  120. package/dist/sync/pull.d.ts.map +1 -1
  121. package/dist/sync/pull.js +154 -207
  122. package/dist/sync/pull.js.map +1 -1
  123. package/dist/sync/push/commit.d.ts +61 -0
  124. package/dist/sync/push/commit.d.ts.map +1 -0
  125. package/dist/sync/push/commit.js +258 -0
  126. package/dist/sync/push/commit.js.map +1 -0
  127. package/dist/sync/push/guards.d.ts +33 -0
  128. package/dist/sync/push/guards.d.ts.map +1 -0
  129. package/dist/sync/push/guards.js +110 -0
  130. package/dist/sync/push/guards.js.map +1 -0
  131. package/dist/sync/push/index.d.ts +9 -0
  132. package/dist/sync/push/index.d.ts.map +1 -0
  133. package/dist/sync/push/index.js +372 -0
  134. package/dist/sync/push/index.js.map +1 -0
  135. package/dist/sync/push/media_stage.d.ts +56 -0
  136. package/dist/sync/push/media_stage.d.ts.map +1 -0
  137. package/dist/sync/push/media_stage.js +338 -0
  138. package/dist/sync/push/media_stage.js.map +1 -0
  139. package/dist/sync/push/merge_stage.d.ts +37 -0
  140. package/dist/sync/push/merge_stage.d.ts.map +1 -0
  141. package/dist/sync/push/merge_stage.js +257 -0
  142. package/dist/sync/push/merge_stage.js.map +1 -0
  143. package/dist/sync/push/preflight_stage.d.ts +6 -0
  144. package/dist/sync/push/preflight_stage.d.ts.map +1 -0
  145. package/dist/sync/push/preflight_stage.js +40 -0
  146. package/dist/sync/push/preflight_stage.js.map +1 -0
  147. package/dist/sync/push/tax_audit.d.ts +24 -0
  148. package/dist/sync/push/tax_audit.d.ts.map +1 -0
  149. package/dist/sync/push/tax_audit.js +70 -0
  150. package/dist/sync/push/tax_audit.js.map +1 -0
  151. package/dist/sync/push/taxonomy_plan.d.ts +36 -0
  152. package/dist/sync/push/taxonomy_plan.d.ts.map +1 -0
  153. package/dist/sync/push/taxonomy_plan.js +136 -0
  154. package/dist/sync/push/taxonomy_plan.js.map +1 -0
  155. package/dist/sync/push/transport.d.ts +14 -0
  156. package/dist/sync/push/transport.d.ts.map +1 -0
  157. package/dist/sync/push/transport.js +74 -0
  158. package/dist/sync/push/transport.js.map +1 -0
  159. package/dist/sync/push/types.d.ts +62 -0
  160. package/dist/sync/push/types.d.ts.map +1 -0
  161. package/dist/sync/push/types.js +23 -0
  162. package/dist/sync/push/types.js.map +1 -0
  163. package/dist/sync/push.d.ts +2 -57
  164. package/dist/sync/push.d.ts.map +1 -1
  165. package/dist/sync/push.js +2 -1184
  166. package/dist/sync/push.js.map +1 -1
  167. package/dist/sync/status.d.ts +3 -0
  168. package/dist/sync/status.d.ts.map +1 -1
  169. package/dist/sync/status.js +18 -8
  170. package/dist/sync/status.js.map +1 -1
  171. package/dist/sync/taxonomies.d.ts.map +1 -1
  172. package/dist/sync/taxonomies.js +21 -9
  173. package/dist/sync/taxonomies.js.map +1 -1
  174. package/dist/sync/terms.d.ts.map +1 -1
  175. package/dist/sync/terms.js +2 -1
  176. package/dist/sync/terms.js.map +1 -1
  177. package/dist/sync/workspace/commit.d.ts +46 -0
  178. package/dist/sync/workspace/commit.d.ts.map +1 -0
  179. package/dist/sync/workspace/commit.js +85 -0
  180. package/dist/sync/workspace/commit.js.map +1 -0
  181. package/dist/sync/workspace/index.d.ts +42 -0
  182. package/dist/sync/workspace/index.d.ts.map +1 -0
  183. package/dist/sync/workspace/index.js +125 -0
  184. package/dist/sync/workspace/index.js.map +1 -0
  185. package/dist/utils/disk-spelling.d.ts +26 -0
  186. package/dist/utils/disk-spelling.d.ts.map +1 -0
  187. package/dist/utils/disk-spelling.js +51 -0
  188. package/dist/utils/disk-spelling.js.map +1 -0
  189. package/dist/utils/draft-revision.d.ts +15 -0
  190. package/dist/utils/draft-revision.d.ts.map +1 -0
  191. package/dist/utils/draft-revision.js +36 -0
  192. package/dist/utils/draft-revision.js.map +1 -0
  193. package/dist/utils/frontmatter.d.ts +21 -2
  194. package/dist/utils/frontmatter.d.ts.map +1 -1
  195. package/dist/utils/frontmatter.js +71 -10
  196. package/dist/utils/frontmatter.js.map +1 -1
  197. package/dist/utils/media-body-refs.d.ts +24 -0
  198. package/dist/utils/media-body-refs.d.ts.map +1 -1
  199. package/dist/utils/media-body-refs.js +51 -0
  200. package/dist/utils/media-body-refs.js.map +1 -1
  201. package/dist/utils/media-companion.d.ts +13 -0
  202. package/dist/utils/media-companion.d.ts.map +1 -0
  203. package/dist/utils/media-companion.js +42 -0
  204. package/dist/utils/media-companion.js.map +1 -0
  205. package/dist/utils/media-id.d.ts +46 -0
  206. package/dist/utils/media-id.d.ts.map +1 -0
  207. package/dist/utils/media-id.js +84 -0
  208. package/dist/utils/media-id.js.map +1 -0
  209. package/dist/utils/naming.d.ts.map +1 -1
  210. package/dist/utils/naming.js +3 -2
  211. package/dist/utils/naming.js.map +1 -1
  212. package/dist/utils/ulid.d.ts +31 -0
  213. package/dist/utils/ulid.d.ts.map +1 -0
  214. package/dist/utils/ulid.js +65 -0
  215. package/dist/utils/ulid.js.map +1 -0
  216. package/package.json +1 -1
@@ -40,7 +40,10 @@
40
40
  * form (`media/<storageKey>`) is still accepted wherever a local reference is read — workspaces built with it
41
41
  * are re-spelled on the next pull rather than reported as edits.
42
42
  */
43
+ import fs from 'node:fs';
44
+ import path from 'node:path';
43
45
  import { storageKeyToMarkdownRef } from './naming.js';
46
+ import { FENCE_POLICY, scanRawMediaReferences } from './media-refs.js';
44
47
  /** Canonical root-relative media route prefix EmDash writes into Portable Text image blocks. */
45
48
  export const MEDIA_FILE_ROUTE_PREFIX = '/_emdash/api/media/file/';
46
49
  /** Workspace-relative directory a mirrored asset lives in. */
@@ -174,6 +177,18 @@ export function storageKeyFromMirrorRef(rawPath, candidateStorageKeys) {
174
177
  }
175
178
  return null;
176
179
  }
180
+ /**
181
+ * Scans a Markdown article body for every media reference it carries.
182
+ *
183
+ * This is the workspace-contract entry point Layer 2 consumers (delete, doctor, media) call instead of
184
+ * reaching into each other: markdown images and HTML `<img>` tags anywhere in the body, including inside
185
+ * opaque `<!--ec:block ... -->` fences and legacy container lines such as `[dimage url="..." control=true]`.
186
+ * External `http(s)` and `data:` URLs are excluded because they name no local mirror. The fence policy is
187
+ * delegated to `utils/media-refs.ts` so the guard/diagnostic distinction stays declared in exactly one place.
188
+ */
189
+ export function scanArticleMediaReferences(bodyMarkdown, fencePolicy = FENCE_POLICY.guard) {
190
+ return scanRawMediaReferences(bodyMarkdown, fencePolicy);
191
+ }
177
192
  /**
178
193
  * Builds the `../../` depth an article at `articleRelPath` needs to reach `media/` from its own directory,
179
194
  * matching the prefix the draft-image guards already accept.
@@ -237,4 +252,40 @@ export function localizeArticleMediaRefs(body, options) {
237
252
  articleRelPath: options.preferLegacyRef ? undefined : options.articleRelPath,
238
253
  });
239
254
  }
255
+ /**
256
+ * Detects whether a document body carries any depth-free `media/<storageKey>` references.
257
+ *
258
+ * Used by pull to preserve the depth-free spelling for articles that already carry it, because the cache
259
+ * records exactly those bytes — re-spelling an untouched file would report a media rewrite nobody made. Once a
260
+ * document carries the article-relative form (or no local ref at all), the article-relative spelling takes over.
261
+ */
262
+ export function carriesDepthFreeMediaRef(content) {
263
+ for (const rawLine of content.split('\n')) {
264
+ const match = rawLine.trim().match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
265
+ if (!match)
266
+ continue;
267
+ const ref = match[2].trim();
268
+ // A depth-free `media/...` reference is the legacy spelling; anything carrying `../` already migrated.
269
+ if (isLocalMediaRef(ref) && ref.startsWith('media/'))
270
+ return true;
271
+ }
272
+ return false;
273
+ }
274
+ /**
275
+ * Reports whether any local copy of an article still carries the depth-free spelling, deciding which form a
276
+ * re-pull must reproduce. A genuinely new article has no local copy, so it gets the article-relative form.
277
+ */
278
+ export function shouldPreferLegacyRef(workspaceRoot, existingRelPaths) {
279
+ for (const relPath of existingRelPaths) {
280
+ try {
281
+ if (carriesDepthFreeMediaRef(fs.readFileSync(path.join(workspaceRoot, relPath), 'utf8'))) {
282
+ return true;
283
+ }
284
+ }
285
+ catch {
286
+ // Ignore unreadable files
287
+ }
288
+ }
289
+ return false;
290
+ }
240
291
  //# sourceMappingURL=media-body-refs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"media-body-refs.js","sourceRoot":"","sources":["../../src/utils/media-body-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,gGAAgG;AAChG,MAAM,CAAC,MAAM,uBAAuB,GAAG,0BAA0B,CAAC;AAElE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAEzC,MAAM,yBAAyB,GAAG,kCAAkC,CAAC;AAErE,gFAAgF;AAChF,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AAErE;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AAErE,2GAA2G;AAC3G,MAAM,4BAA4B,GAAwB,IAAI,GAAG,EAAE,CAAC;AAEpE,2FAA2F;AAC3F,MAAM,UAAU,0BAA0B,CAAC,GAAW;IACpD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,0BAA0B,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;AAClD,CAAC;AAED,qFAAqF;AACrF,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,IAAI,KAAK,IAAI,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAAY,EACZ,OAIC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc;QACnC,CAAC,CAAC,GAAG,wBAAwB,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,gBAAgB,EAAE;QAC1E,CAAC,CAAC,gBAAgB,CAAC;IACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,eAAe,GAAG,gCAAgC,CAAC;IAEzD,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,mFAAmF;QACnF,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAEjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,0GAA0G;QAC1G,yGAAyG;QACzG,sGAAsG;QACtG,MAAM,UAAU,GACd,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACpC,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,4BAA4B,CAAC,CAAC;QAClE,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,UAAU,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAE7E,MAAM,SAAS,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,oBAAsC;IAEtC,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,uGAAuG;IACvG,8EAA8E;IAC9E,MAAM,SAAS,GAAG,CAAC,GAAG,oBAAoB,CAAC,CAAC;IAC5C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5E,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,GAAG,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,4GAA4G;IAC5G,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAC5D,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,GAAG,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,QAAQ,CAAC;YAAE,OAAO,GAAG,CAAC;IAC5D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,cAAsB;IAC7D,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,iGAAiG;AACjG,SAAS,aAAa,CACpB,IAAY,EACZ,MAAc,EACd,EAAsC;IAEtC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,MAAM,eAAe,GAAG,6BAA6B,CAAC;IACtD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACjF,IAAI,CAAC,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,mBAAmB,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,gEAAgE;QACxG,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACrE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1C,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAY,EACZ,OAMC;IAED,2GAA2G;IAC3G,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC;IACrE,MAAM,WAAW,GAAG,GAAG,wBAAwB,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,gBAAgB,EAAE,CAAC;IAE7F,+FAA+F;IAC/F,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC;IAC9E,IAAI,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/D,2GAA2G;IAC3G,wGAAwG;IACxG,8FAA8F;IAC9F,OAAO,yBAAyB,CAAC,IAAI,EAAE;QACrC,QAAQ;QACR,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,cAAc,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc;KAC7E,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"media-body-refs.js","sourceRoot":"","sources":["../../src/utils/media-body-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAwB,MAAM,iBAAiB,CAAC;AAE7F,gGAAgG;AAChG,MAAM,CAAC,MAAM,uBAAuB,GAAG,0BAA0B,CAAC;AAElE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAEzC,MAAM,yBAAyB,GAAG,kCAAkC,CAAC;AAErE,gFAAgF;AAChF,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AAErE;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AAErE,2GAA2G;AAC3G,MAAM,4BAA4B,GAAwB,IAAI,GAAG,EAAE,CAAC;AAEpE,2FAA2F;AAC3F,MAAM,UAAU,0BAA0B,CAAC,GAAW;IACpD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,0BAA0B,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;AAClD,CAAC;AAED,qFAAqF;AACrF,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,IAAI,KAAK,IAAI,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAAY,EACZ,OAIC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc;QACnC,CAAC,CAAC,GAAG,wBAAwB,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,gBAAgB,EAAE;QAC1E,CAAC,CAAC,gBAAgB,CAAC;IACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,eAAe,GAAG,gCAAgC,CAAC;IAEzD,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,mFAAmF;QACnF,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAEjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,0GAA0G;QAC1G,yGAAyG;QACzG,sGAAsG;QACtG,MAAM,UAAU,GACd,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACpC,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,4BAA4B,CAAC,CAAC;QAClE,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,UAAU,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAE7E,MAAM,SAAS,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,oBAAsC;IAEtC,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,uGAAuG;IACvG,8EAA8E;IAC9E,MAAM,SAAS,GAAG,CAAC,GAAG,oBAAoB,CAAC,CAAC;IAC5C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5E,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,GAAG,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,4GAA4G;IAC5G,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAC5D,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,GAAG,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,QAAQ,CAAC;YAAE,OAAO,GAAG,CAAC;IAC5D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CACxC,YAAoB,EACpB,WAAW,GAAoB,YAAY,CAAC,KAAK;IAEjD,OAAO,sBAAsB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AAC3D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,cAAsB;IAC7D,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,iGAAiG;AACjG,SAAS,aAAa,CACpB,IAAY,EACZ,MAAc,EACd,EAAsC;IAEtC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,MAAM,eAAe,GAAG,6BAA6B,CAAC;IACtD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACjF,IAAI,CAAC,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,mBAAmB,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,gEAAgE;QACxG,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACrE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1C,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAY,EACZ,OAMC;IAED,2GAA2G;IAC3G,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC;IACrE,MAAM,WAAW,GAAG,GAAG,wBAAwB,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,gBAAgB,EAAE,CAAC;IAE7F,+FAA+F;IAC/F,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC;IAC9E,IAAI,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/D,2GAA2G;IAC3G,wGAAwG;IACxG,8FAA8F;IAC9F,OAAO,yBAAyB,CAAC,IAAI,EAAE;QACrC,QAAQ;QACR,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,cAAc,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc;KAC7E,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACjE,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,uGAAuG;QACvG,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,aAAqB,EAAE,gBAA0B;IACrF,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,wBAAwB,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;gBACzF,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Recovers a storageKey from a media record's metadata map or companion YAML document.
3
+ *
4
+ * EmDash media records have two identifier spaces: the D1 primary key (`id`) and the R2 object key
5
+ * (`storageKey`). Modern companions record both fields explicitly, but older mirrors — or records
6
+ * written before Emit persisted the field — carry no `storageKey:` key at all, yet their `url:` is the
7
+ * canonical `/_emdash/api/media/file/<storageKey>` route, which is confirmed metadata written from the
8
+ * server response and not an inference from a body reference. Absolute and root-relative forms are both
9
+ * accepted because either can appear depending on how the record was mirrored. `legacy_*` residue is
10
+ * never read here: it backs no real record, so it must not serve as verification evidence.
11
+ */
12
+ export declare function storageKeyFromMediaMeta(doc: Record<string, unknown>): string | undefined;
13
+ //# sourceMappingURL=media-companion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-companion.d.ts","sourceRoot":"","sources":["../../src/utils/media-companion.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAOxF"}
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ /**
23
+ * Recovers a storageKey from a media record's metadata map or companion YAML document.
24
+ *
25
+ * EmDash media records have two identifier spaces: the D1 primary key (`id`) and the R2 object key
26
+ * (`storageKey`). Modern companions record both fields explicitly, but older mirrors — or records
27
+ * written before Emit persisted the field — carry no `storageKey:` key at all, yet their `url:` is the
28
+ * canonical `/_emdash/api/media/file/<storageKey>` route, which is confirmed metadata written from the
29
+ * server response and not an inference from a body reference. Absolute and root-relative forms are both
30
+ * accepted because either can appear depending on how the record was mirrored. `legacy_*` residue is
31
+ * never read here: it backs no real record, so it must not serve as verification evidence.
32
+ */
33
+ export function storageKeyFromMediaMeta(doc) {
34
+ if (typeof doc.storageKey === 'string' && doc.storageKey.trim()) {
35
+ return doc.storageKey.trim();
36
+ }
37
+ if (typeof doc.url !== 'string' || !doc.url.trim())
38
+ return undefined;
39
+ const match = doc.url.match(/(?:^|\/)media\/file\/([^?#]+)/);
40
+ return match ? match[1] : undefined;
41
+ }
42
+ //# sourceMappingURL=media-companion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-companion.js","sourceRoot":"","sources":["../../src/utils/media-companion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAA4B;IAClE,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QAChE,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC;IACrE,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC7D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * EmDash media record primary key (D1 database record ID).
3
+ * Always a 26-character canonical Crockford Base32 ULID.
4
+ */
5
+ export type MediaRecordId = string & {
6
+ readonly __brand: 'MediaRecordId';
7
+ };
8
+ /**
9
+ * EmDash public R2 storage key (object key on Cloudflare R2).
10
+ * Formatted as `<ulid>.<ext>` or `<ulid1>.<ulid2>.<ext>`.
11
+ */
12
+ export type StorageKey = string & {
13
+ readonly __brand: 'StorageKey';
14
+ };
15
+ /**
16
+ * Unvalidated cast kept only for call sites that have already proven the value is a record id through
17
+ * confirmed metadata (a `media_state` row written by Emit, or a companion YAML `id:`). New code should go
18
+ * through `toMediaRecordId`, which refuses anything that is not a canonical ULID.
19
+ */
20
+ export declare function asMediaRecordId(value: string): MediaRecordId;
21
+ /**
22
+ * Unvalidated cast for storage keys, mirroring `asMediaRecordId`: the brand is granted without checking the
23
+ * key shape. During gradual adoption it is used where a value already flows from a source Emit trusts (an
24
+ * upload target, a cached `media_state` row) and strict validation would abort otherwise-safe pushes; those
25
+ * sites are scheduled to move to `toStorageKey` in a later pass. New code should prefer `toStorageKey`.
26
+ */
27
+ export declare function asStorageKey(value: string): StorageKey;
28
+ export declare function isMediaRecordId(value: unknown): value is MediaRecordId;
29
+ /**
30
+ * Validates and normalizes a raw value into a `StorageKey`.
31
+ *
32
+ * A storageKey is the R2 object key that a canonical body URL addresses: exactly one path segment ending in
33
+ * a known image extension, with ULID-shaped segments (`<ulid>.<ext>` or `<ulid1>.<ulid2>.<ext>`). Migrated
34
+ * corpora also carry path-shaped keys (`uploads/2026/11/sample.png`), which are accepted as-is because they
35
+ * are the key the server itself reports. Returns null for anything with no usable key at all — an empty or
36
+ * whitespace-only value, a multi-segment value that is not a plain key, or a key carrying no extension Emit
37
+ * recognizes as media.
38
+ */
39
+ export declare function toStorageKey(value: unknown): StorageKey | null;
40
+ /**
41
+ * Validates a raw value and returns it as a `MediaRecordId`, or null when it is not a canonical 26-character
42
+ * ULID. Unlike `asMediaRecordId`, this never trusts the caller: the brand is only granted to values that are
43
+ * provably record ids, so a storageKey-shaped or truncated value cannot be laundered into one.
44
+ */
45
+ export declare function toMediaRecordId(value: unknown): MediaRecordId | null;
46
+ //# sourceMappingURL=media-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-id.d.ts","sourceRoot":"","sources":["../../src/utils/media-id.ts"],"names":[],"mappings":"AAwBA;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAE3E;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAErE;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEtD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAEtE;AAKD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAY9D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAGpE"}
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { isCanonicalUlid } from './ulid.js';
23
+ /**
24
+ * Unvalidated cast kept only for call sites that have already proven the value is a record id through
25
+ * confirmed metadata (a `media_state` row written by Emit, or a companion YAML `id:`). New code should go
26
+ * through `toMediaRecordId`, which refuses anything that is not a canonical ULID.
27
+ */
28
+ export function asMediaRecordId(value) {
29
+ return value;
30
+ }
31
+ /**
32
+ * Unvalidated cast for storage keys, mirroring `asMediaRecordId`: the brand is granted without checking the
33
+ * key shape. During gradual adoption it is used where a value already flows from a source Emit trusts (an
34
+ * upload target, a cached `media_state` row) and strict validation would abort otherwise-safe pushes; those
35
+ * sites are scheduled to move to `toStorageKey` in a later pass. New code should prefer `toStorageKey`.
36
+ */
37
+ export function asStorageKey(value) {
38
+ return value;
39
+ }
40
+ export function isMediaRecordId(value) {
41
+ return isCanonicalUlid(value);
42
+ }
43
+ /** Image extensions a storageKey may carry, matching the mirror naming rule. */
44
+ const STORAGE_KEY_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp', '.avif', '.svg']);
45
+ /**
46
+ * Validates and normalizes a raw value into a `StorageKey`.
47
+ *
48
+ * A storageKey is the R2 object key that a canonical body URL addresses: exactly one path segment ending in
49
+ * a known image extension, with ULID-shaped segments (`<ulid>.<ext>` or `<ulid1>.<ulid2>.<ext>`). Migrated
50
+ * corpora also carry path-shaped keys (`uploads/2026/11/sample.png`), which are accepted as-is because they
51
+ * are the key the server itself reports. Returns null for anything with no usable key at all — an empty or
52
+ * whitespace-only value, a multi-segment value that is not a plain key, or a key carrying no extension Emit
53
+ * recognizes as media.
54
+ */
55
+ export function toStorageKey(value) {
56
+ if (typeof value !== 'string')
57
+ return null;
58
+ const trimmed = value.trim();
59
+ if (!trimmed)
60
+ return null;
61
+ if (/[?#]/.test(trimmed))
62
+ return null;
63
+ const segments = trimmed.replace(/\\/g, '/').split('/');
64
+ if (segments.some((segment) => !segment))
65
+ return null;
66
+ const last = segments[segments.length - 1];
67
+ const extMatch = last.match(/\.[A-Za-z0-9]+$/);
68
+ if (!extMatch)
69
+ return null;
70
+ if (!STORAGE_KEY_EXTENSIONS.has(extMatch[0].toLowerCase()))
71
+ return null;
72
+ return trimmed;
73
+ }
74
+ /**
75
+ * Validates a raw value and returns it as a `MediaRecordId`, or null when it is not a canonical 26-character
76
+ * ULID. Unlike `asMediaRecordId`, this never trusts the caller: the brand is only granted to values that are
77
+ * provably record ids, so a storageKey-shaped or truncated value cannot be laundered into one.
78
+ */
79
+ export function toMediaRecordId(value) {
80
+ if (!isCanonicalUlid(value))
81
+ return null;
82
+ return value.trim().toUpperCase();
83
+ }
84
+ //# sourceMappingURL=media-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-id.js","sourceRoot":"","sources":["../../src/utils/media-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAc5C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAsB,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,gFAAgF;AAChF,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpG;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,OAAqB,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAQ,KAAgB,CAAC,IAAI,EAAE,CAAC,WAAW,EAAmB,CAAC;AACjE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/utils/naming.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAgC,GACzC,MAAM,CA+BR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAmBzE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAoC,GAC7C,MAAM,GAAG,IAAI,CAyBf;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW7E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAC/B,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/E"}
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/utils/naming.ts"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAgC,GACzC,MAAM,CA+BR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAmBzE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAoC,GAC7C,MAAM,GAAG,IAAI,CAyBf;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW7E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAC/B,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/E"}
@@ -20,6 +20,7 @@
20
20
  * SOFTWARE.
21
21
  */
22
22
  import path from 'node:path';
23
+ import { extractFilenameUlid } from './ulid.js';
23
24
  /**
24
25
  * Default maximum UTF-8 byte length for the title portion in generated filenames.
25
26
  * Standard article filename: <yyyyMMdd_ (9B)><ulid (26B)>-<title (<=120B)>.md (3B) = <=158B,
@@ -174,9 +175,9 @@ export function collisionSuffixedMarkdownRef(markdownRef, mediaId) {
174
175
  */
175
176
  export function extractUlidFromFilename(filenameOrPath) {
176
177
  const baseWithoutDate = stripDatePrefix(filenameOrPath);
177
- const match = baseWithoutDate.match(/^([0-9A-Za-z_-]{26})(?:-|\.|$)/);
178
+ const match = extractFilenameUlid(baseWithoutDate);
178
179
  if (match)
179
- return match[1];
180
+ return match;
180
181
  const firstHyphen = baseWithoutDate.indexOf('-');
181
182
  const candidate = firstHyphen !== -1 ? baseWithoutDate.slice(0, firstHyphen) : baseWithoutDate;
182
183
  if (candidate.length === 26) {
@@ -1 +1 @@
1
- {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/utils/naming.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/utils/naming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Canonical 26-character Crockford Base32 pattern for ULIDs:
3
+ * Excludes I, L, O, and U to prevent human transcription errors.
4
+ */
5
+ export declare const CANONICAL_ULID_PATTERN = "[0-9A-HJ-NP-Z]{26}";
6
+ /**
7
+ * Case-insensitive regular expression validating a 26-character canonical ULID string.
8
+ */
9
+ export declare const CANONICAL_ULID_REGEX: RegExp;
10
+ /**
11
+ * Case-sensitive (uppercase only) regular expression validating a 26-character canonical ULID string.
12
+ */
13
+ export declare const CANONICAL_ULID_EXACT_REGEX: RegExp;
14
+ /**
15
+ * Global matcher for finding 26-character canonical ULIDs within URLs, storageKeys, or filenames.
16
+ */
17
+ export declare const CANONICAL_ULID_GLOBAL_REGEX: RegExp;
18
+ /**
19
+ * Reports whether a value is a valid 26-character canonical Crockford Base32 ULID.
20
+ */
21
+ export declare function isCanonicalUlid(value: unknown): value is string;
22
+ /**
23
+ * Normalizes a string to uppercase canonical ULID if valid, or returns null.
24
+ */
25
+ export declare function toCanonicalUlid(value: unknown): string | null;
26
+ /**
27
+ * Extracts a 26-character ID from a filename stem.
28
+ * Preserves permissive naming rules ([0-9A-Za-z_-]{26}) for legacy compatibility (EMIT naming.ts:203).
29
+ */
30
+ export declare function extractFilenameUlid(filename: string): string | null;
31
+ //# sourceMappingURL=ulid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ulid.d.ts","sourceRoot":"","sources":["../../src/utils/ulid.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAA0B,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,0BAA0B,QAAyB,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,2BAA2B,QAAyB,CAAC;AAElE;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAG/D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAInE"}
@@ -0,0 +1,65 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ /**
23
+ * Canonical 26-character Crockford Base32 pattern for ULIDs:
24
+ * Excludes I, L, O, and U to prevent human transcription errors.
25
+ */
26
+ export const CANONICAL_ULID_PATTERN = '[0-9A-HJ-NP-Z]{26}';
27
+ /**
28
+ * Case-insensitive regular expression validating a 26-character canonical ULID string.
29
+ */
30
+ export const CANONICAL_ULID_REGEX = /^[0-9A-HJ-NP-Z]{26}$/i;
31
+ /**
32
+ * Case-sensitive (uppercase only) regular expression validating a 26-character canonical ULID string.
33
+ */
34
+ export const CANONICAL_ULID_EXACT_REGEX = /^[0-9A-HJ-NP-Z]{26}$/;
35
+ /**
36
+ * Global matcher for finding 26-character canonical ULIDs within URLs, storageKeys, or filenames.
37
+ */
38
+ export const CANONICAL_ULID_GLOBAL_REGEX = /[0-9A-HJ-NP-Z]{26}/gi;
39
+ /**
40
+ * Reports whether a value is a valid 26-character canonical Crockford Base32 ULID.
41
+ */
42
+ export function isCanonicalUlid(value) {
43
+ if (typeof value !== 'string')
44
+ return false;
45
+ return CANONICAL_ULID_REGEX.test(value.trim());
46
+ }
47
+ /**
48
+ * Normalizes a string to uppercase canonical ULID if valid, or returns null.
49
+ */
50
+ export function toCanonicalUlid(value) {
51
+ if (typeof value !== 'string')
52
+ return null;
53
+ const trimmed = value.trim();
54
+ return CANONICAL_ULID_REGEX.test(trimmed) ? trimmed.toUpperCase() : null;
55
+ }
56
+ /**
57
+ * Extracts a 26-character ID from a filename stem.
58
+ * Preserves permissive naming rules ([0-9A-Za-z_-]{26}) for legacy compatibility (EMIT naming.ts:203).
59
+ */
60
+ export function extractFilenameUlid(filename) {
61
+ const baseWithoutDate = filename.replace(/^\d{8}_/, '');
62
+ const match = baseWithoutDate.match(/^([0-9A-Za-z_-]{26})(?:-|\.|$)/);
63
+ return match ? match[1] : null;
64
+ }
65
+ //# sourceMappingURL=ulid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ulid.js","sourceRoot":"","sources":["../../src/utils/ulid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AAE5D;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,sBAAsB,CAAC;AAEjE;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAAsB,CAAC;AAElE;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACtE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emdash-emit",
3
- "version": "0.1.17",
3
+ "version": "0.1.25",
4
4
  "description": "AI-First Local Workspace & Sync Tool for EmDash (Cloudflare Workers + D1)",
5
5
  "author": "hiroaki <45134003+aroooy@users.noreply.github.com>",
6
6
  "license": "MIT",