emdash-emit 0.1.14 → 0.1.16
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/CHANGELOG.md +96 -1
- package/README.md +259 -188
- package/dist/bin/emit.d.ts.map +1 -1
- package/dist/bin/emit.js +2 -0
- package/dist/bin/emit.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +6 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/media.d.ts +4 -0
- package/dist/cli/commands/media.d.ts.map +1 -0
- package/dist/cli/commands/media.js +128 -0
- package/dist/cli/commands/media.js.map +1 -0
- package/dist/cli/commands/pull.d.ts +32 -0
- package/dist/cli/commands/pull.d.ts.map +1 -1
- package/dist/cli/commands/pull.js +136 -9
- package/dist/cli/commands/pull.js.map +1 -1
- package/dist/cli/commands/push.d.ts.map +1 -1
- package/dist/cli/commands/push.js +18 -0
- package/dist/cli/commands/push.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +16 -5
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/client/media.d.ts.map +1 -1
- package/dist/client/media.js +16 -5
- package/dist/client/media.js.map +1 -1
- package/dist/db/cache.d.ts +19 -4
- package/dist/db/cache.d.ts.map +1 -1
- package/dist/db/cache.js +127 -16
- package/dist/db/cache.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +7 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/sync-doctor.d.ts.map +1 -1
- package/dist/mcp/tools/sync-doctor.js +12 -0
- package/dist/mcp/tools/sync-doctor.js.map +1 -1
- package/dist/mcp/tools/sync-media-search.d.ts +4 -0
- package/dist/mcp/tools/sync-media-search.d.ts.map +1 -0
- package/dist/mcp/tools/sync-media-search.js +102 -0
- package/dist/mcp/tools/sync-media-search.js.map +1 -0
- package/dist/mcp/tools/sync-pull.d.ts.map +1 -1
- package/dist/mcp/tools/sync-pull.js +85 -13
- package/dist/mcp/tools/sync-pull.js.map +1 -1
- package/dist/mcp/tools/sync-push.d.ts.map +1 -1
- package/dist/mcp/tools/sync-push.js +5 -0
- package/dist/mcp/tools/sync-push.js.map +1 -1
- package/dist/mcp/tools/sync-status.d.ts.map +1 -1
- package/dist/mcp/tools/sync-status.js +6 -2
- package/dist/mcp/tools/sync-status.js.map +1 -1
- package/dist/sync/delete.d.ts +2 -1
- package/dist/sync/delete.d.ts.map +1 -1
- package/dist/sync/delete.js +6 -19
- package/dist/sync/delete.js.map +1 -1
- package/dist/sync/diff.d.ts.map +1 -1
- package/dist/sync/diff.js +18 -2
- package/dist/sync/diff.js.map +1 -1
- package/dist/sync/doctor.d.ts +27 -1
- package/dist/sync/doctor.d.ts.map +1 -1
- package/dist/sync/doctor.js +309 -26
- package/dist/sync/doctor.js.map +1 -1
- package/dist/sync/guards.d.ts +45 -0
- package/dist/sync/guards.d.ts.map +1 -0
- package/dist/sync/guards.js +236 -0
- package/dist/sync/guards.js.map +1 -0
- package/dist/sync/media/body_scan.d.ts +15 -0
- package/dist/sync/media/body_scan.d.ts.map +1 -0
- package/dist/sync/media/body_scan.js +132 -0
- package/dist/sync/media/body_scan.js.map +1 -0
- package/dist/sync/media/companions.d.ts +32 -0
- package/dist/sync/media/companions.d.ts.map +1 -0
- package/dist/sync/media/companions.js +260 -0
- package/dist/sync/media/companions.js.map +1 -0
- package/dist/sync/media/index.d.ts +9 -0
- package/dist/sync/media/index.d.ts.map +1 -0
- package/dist/sync/media/index.js +9 -0
- package/dist/sync/media/index.js.map +1 -0
- package/dist/sync/media/mirror_item.d.ts +27 -0
- package/dist/sync/media/mirror_item.d.ts.map +1 -0
- package/dist/sync/media/mirror_item.js +207 -0
- package/dist/sync/media/mirror_item.js.map +1 -0
- package/dist/sync/media/naming_mirror.d.ts +36 -0
- package/dist/sync/media/naming_mirror.d.ts.map +1 -0
- package/dist/sync/media/naming_mirror.js +143 -0
- package/dist/sync/media/naming_mirror.js.map +1 -0
- package/dist/sync/media/pull_article.d.ts +37 -0
- package/dist/sync/media/pull_article.d.ts.map +1 -0
- package/dist/sync/media/pull_article.js +273 -0
- package/dist/sync/media/pull_article.js.map +1 -0
- package/dist/sync/media/pull_library.d.ts +12 -0
- package/dist/sync/media/pull_library.d.ts.map +1 -0
- package/dist/sync/media/pull_library.js +255 -0
- package/dist/sync/media/pull_library.js.map +1 -0
- package/dist/sync/media/remote_index.d.ts +49 -0
- package/dist/sync/media/remote_index.d.ts.map +1 -0
- package/dist/sync/media/remote_index.js +241 -0
- package/dist/sync/media/remote_index.js.map +1 -0
- package/dist/sync/media/types.d.ts +237 -0
- package/dist/sync/media/types.d.ts.map +1 -0
- package/dist/sync/media/types.js +11 -0
- package/dist/sync/media/types.js.map +1 -0
- package/dist/sync/media.d.ts +1 -74
- package/dist/sync/media.d.ts.map +1 -1
- package/dist/sync/media.js +1 -592
- package/dist/sync/media.js.map +1 -1
- package/dist/sync/orchestrator.d.ts +23 -0
- package/dist/sync/orchestrator.d.ts.map +1 -1
- package/dist/sync/orchestrator.js +85 -1
- package/dist/sync/orchestrator.js.map +1 -1
- package/dist/sync/preflight.d.ts +1 -1
- package/dist/sync/preflight.d.ts.map +1 -1
- package/dist/sync/preflight.js +129 -17
- package/dist/sync/preflight.js.map +1 -1
- package/dist/sync/pull.d.ts +19 -0
- package/dist/sync/pull.d.ts.map +1 -1
- package/dist/sync/pull.js +169 -15
- package/dist/sync/pull.js.map +1 -1
- package/dist/sync/push.d.ts +7 -0
- package/dist/sync/push.d.ts.map +1 -1
- package/dist/sync/push.js +37 -10
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/status.d.ts +4 -0
- package/dist/sync/status.d.ts.map +1 -1
- package/dist/sync/status.js +68 -4
- package/dist/sync/status.js.map +1 -1
- package/dist/utils/config.d.ts +25 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +28 -2
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +15 -4
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/media-body-refs.d.ts +81 -0
- package/dist/utils/media-body-refs.d.ts.map +1 -0
- package/dist/utils/media-body-refs.js +240 -0
- package/dist/utils/media-body-refs.js.map +1 -0
- package/dist/utils/media-refs.d.ts +44 -0
- package/dist/utils/media-refs.d.ts.map +1 -0
- package/dist/utils/media-refs.js +101 -0
- package/dist/utils/media-refs.js.map +1 -0
- package/dist/utils/naming.d.ts +31 -0
- package/dist/utils/naming.d.ts.map +1 -1
- package/dist/utils/naming.js +58 -0
- package/dist/utils/naming.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
import { toRootRelativeMediaUrl } from '../../client/media.js';
|
|
5
|
+
import { MEDIA_FILE_ROUTE_PREFIX } from '../../utils/media-refs.js';
|
|
6
|
+
import { storageKeyToMarkdownRef } from '../../utils/naming.js';
|
|
7
|
+
export function buildMediaMetaDoc(item, origin, existingMeta) {
|
|
8
|
+
const storageKey = (typeof item.storageKey === 'string' && item.storageKey ? item.storageKey : undefined) ??
|
|
9
|
+
(typeof existingMeta?.storageKey === 'string' && existingMeta.storageKey
|
|
10
|
+
? existingMeta.storageKey
|
|
11
|
+
: '');
|
|
12
|
+
const canonicalUrl = item.url ||
|
|
13
|
+
(storageKey
|
|
14
|
+
? `${MEDIA_FILE_ROUTE_PREFIX}${storageKey}`
|
|
15
|
+
: typeof existingMeta?.url === 'string'
|
|
16
|
+
? existingMeta.url
|
|
17
|
+
: '');
|
|
18
|
+
const rootRelativeUrl = canonicalUrl
|
|
19
|
+
? toRootRelativeMediaUrl(canonicalUrl, storageKey, origin)
|
|
20
|
+
: '';
|
|
21
|
+
const resolvedAlt = item.alt !== undefined && item.alt !== null && item.alt !== ''
|
|
22
|
+
? item.alt
|
|
23
|
+
: typeof existingMeta?.alt === 'string'
|
|
24
|
+
? existingMeta.alt
|
|
25
|
+
: '';
|
|
26
|
+
const resolvedCaption = item.caption !== undefined && item.caption !== null && item.caption !== ''
|
|
27
|
+
? item.caption
|
|
28
|
+
: typeof existingMeta?.caption === 'string'
|
|
29
|
+
? existingMeta.caption
|
|
30
|
+
: '';
|
|
31
|
+
const resolvedContentHash = typeof item.contentHash === 'string' && item.contentHash
|
|
32
|
+
? item.contentHash
|
|
33
|
+
: typeof existingMeta?.contentHash === 'string' && existingMeta.contentHash
|
|
34
|
+
? existingMeta.contentHash
|
|
35
|
+
: null;
|
|
36
|
+
return {
|
|
37
|
+
id: item.id,
|
|
38
|
+
filename: item.filename,
|
|
39
|
+
mimeType: item.mimeType,
|
|
40
|
+
size: item.size,
|
|
41
|
+
width: item.width ?? (typeof existingMeta?.width === 'number' ? existingMeta.width : null),
|
|
42
|
+
height: item.height ?? (typeof existingMeta?.height === 'number' ? existingMeta.height : null),
|
|
43
|
+
alt: resolvedAlt,
|
|
44
|
+
caption: resolvedCaption,
|
|
45
|
+
storageKey,
|
|
46
|
+
contentHash: resolvedContentHash,
|
|
47
|
+
status: item.status ?? (typeof existingMeta?.status === 'string' ? existingMeta.status : 'ready'),
|
|
48
|
+
url: rootRelativeUrl,
|
|
49
|
+
createdAt: item.createdAt || (typeof existingMeta?.createdAt === 'string' ? existingMeta.createdAt : ''),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Recovers the storageKey a companion YAML actually refers to. Older mirrors — most visibly the ones
|
|
54
|
+
* written before Emit persisted the field — carry no `storageKey:` key at all, yet their `url:` is the
|
|
55
|
+
* canonical `/_emdash/api/media/file/<storageKey>` route, which is confirmed metadata written from the
|
|
56
|
+
* server response and not an inference from a body reference. Absolute and root-relative forms are both
|
|
57
|
+
* accepted because either can appear depending on how the record was mirrored. `legacy_*` residue is
|
|
58
|
+
* never read here: it backs no real record, so it must not serve as verification evidence.
|
|
59
|
+
*/
|
|
60
|
+
export function storageKeyFromMediaMeta(doc) {
|
|
61
|
+
if (typeof doc.storageKey === 'string' && doc.storageKey.trim()) {
|
|
62
|
+
return doc.storageKey.trim();
|
|
63
|
+
}
|
|
64
|
+
if (typeof doc.url !== 'string' || !doc.url.trim())
|
|
65
|
+
return undefined;
|
|
66
|
+
const match = doc.url.match(/(?:^|\/)media\/file\/([^?#]+)/);
|
|
67
|
+
return match ? match[1] : undefined;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Indexes every locally mirrored media asset (`media/<markdownRef>.yaml`, plus legacy companion names) so a body
|
|
71
|
+
* storageKey that the canonical id lookup failed to resolve can be re-checked against confirmed local
|
|
72
|
+
* metadata instead of being declared missing. Leftover `legacy_*` residue is skipped because it backs
|
|
73
|
+
* no real record. The result maps each ULID found in a mirror (record id or storageKey) to its entry,
|
|
74
|
+
* which is what lets Emit tell "the record exists under a different id" apart from "no record exists".
|
|
75
|
+
*/
|
|
76
|
+
export function collectLocalMediaMirrorCandidates(mediaDir) {
|
|
77
|
+
const byUlid = new Map();
|
|
78
|
+
if (!fs.existsSync(mediaDir))
|
|
79
|
+
return byUlid;
|
|
80
|
+
for (const file of fs.readdirSync(mediaDir)) {
|
|
81
|
+
if (!file.endsWith('.yaml') || file.startsWith('legacy_'))
|
|
82
|
+
continue;
|
|
83
|
+
let doc = null;
|
|
84
|
+
try {
|
|
85
|
+
doc = yaml.load(fs.readFileSync(path.join(mediaDir, file), 'utf8'));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (!doc)
|
|
91
|
+
continue;
|
|
92
|
+
const storageKey = storageKeyFromMediaMeta(doc);
|
|
93
|
+
const stem = file.replace(/\.yaml$/, '');
|
|
94
|
+
const idMatch = stem.replace(/^\d{8}_/, '').match(/^([0-9A-HJ-NP-Z]{26})/i);
|
|
95
|
+
const docId = typeof doc.id === 'string' && /^[0-9A-HJ-NP-Z]{26}$/i.test(doc.id.trim())
|
|
96
|
+
? doc.id.trim().toUpperCase()
|
|
97
|
+
: undefined;
|
|
98
|
+
const mediaId = docId || (idMatch ? idMatch[1].toUpperCase() : '');
|
|
99
|
+
if (!mediaId)
|
|
100
|
+
continue;
|
|
101
|
+
const candidate = { mediaId, storageKey, metaFile: file };
|
|
102
|
+
if (!byUlid.has(mediaId))
|
|
103
|
+
byUlid.set(mediaId, candidate);
|
|
104
|
+
for (const ulid of storageKey?.matchAll(/[0-9A-HJ-NP-Z]{26}/gi) ?? []) {
|
|
105
|
+
const key = ulid[0].toUpperCase();
|
|
106
|
+
if (!byUlid.has(key))
|
|
107
|
+
byUlid.set(key, candidate);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return byUlid;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Builds a local mirror index mapping storageKey -> LocalMirrorEntry.
|
|
114
|
+
*
|
|
115
|
+
* Driven by cache `media_state` (status 'ready' or 'uploaded') when available.
|
|
116
|
+
* Resolves companion YAML metadata (filename, alt, caption) strictly from companion YAML,
|
|
117
|
+
* never by filename guessing. If companion YAML is absent, metadata is null.
|
|
118
|
+
*
|
|
119
|
+
* For cache-less workspaces, scans `media/*.yaml` and recovers storageKey via storageKeyFromMediaMeta.
|
|
120
|
+
* Leftover `legacy_*` residue is strictly ignored.
|
|
121
|
+
*/
|
|
122
|
+
export function collectLocalMirrorIndex(workspaceRoot, cache) {
|
|
123
|
+
const index = new Map();
|
|
124
|
+
const mediaDir = path.join(workspaceRoot, 'media');
|
|
125
|
+
if (cache) {
|
|
126
|
+
const states = cache.listMediaStates();
|
|
127
|
+
for (const record of states) {
|
|
128
|
+
if (record.status !== 'ready' && record.status !== 'uploaded')
|
|
129
|
+
continue;
|
|
130
|
+
if (!record.storageKey)
|
|
131
|
+
continue;
|
|
132
|
+
let stem;
|
|
133
|
+
if (record.markdownRef) {
|
|
134
|
+
stem = path.basename(record.markdownRef);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
stem = storageKeyToMarkdownRef(record.storageKey) || record.storageKey;
|
|
138
|
+
}
|
|
139
|
+
let filename = null;
|
|
140
|
+
let alt = null;
|
|
141
|
+
let caption = null;
|
|
142
|
+
const yamlPath = path.join(mediaDir, `${stem}.yaml`);
|
|
143
|
+
let loadedDoc = null;
|
|
144
|
+
if (fs.existsSync(yamlPath)) {
|
|
145
|
+
try {
|
|
146
|
+
loadedDoc = yaml.load(fs.readFileSync(yamlPath, 'utf8'));
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
loadedDoc = null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (record.workspacePath) {
|
|
153
|
+
const altYamlPath = path.join(workspaceRoot, record.workspacePath.replace(/\.[^.]+$/, '.yaml'));
|
|
154
|
+
if (fs.existsSync(altYamlPath)) {
|
|
155
|
+
try {
|
|
156
|
+
loadedDoc = yaml.load(fs.readFileSync(altYamlPath, 'utf8'));
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
loadedDoc = null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (loadedDoc) {
|
|
164
|
+
filename =
|
|
165
|
+
typeof loadedDoc.filename === 'string' && loadedDoc.filename ? loadedDoc.filename : null;
|
|
166
|
+
alt = typeof loadedDoc.alt === 'string' && loadedDoc.alt ? loadedDoc.alt : null;
|
|
167
|
+
caption =
|
|
168
|
+
typeof loadedDoc.caption === 'string' && loadedDoc.caption ? loadedDoc.caption : null;
|
|
169
|
+
}
|
|
170
|
+
else if (fs.existsSync(mediaDir)) {
|
|
171
|
+
// Fallback: search for any companion that confirms this storageKey or mediaId
|
|
172
|
+
for (const f of fs.readdirSync(mediaDir)) {
|
|
173
|
+
if (!f.endsWith('.yaml') || f.startsWith('legacy_'))
|
|
174
|
+
continue;
|
|
175
|
+
try {
|
|
176
|
+
const candidate = yaml.load(fs.readFileSync(path.join(mediaDir, f), 'utf8'));
|
|
177
|
+
if (candidate &&
|
|
178
|
+
(storageKeyFromMediaMeta(candidate) === record.storageKey ||
|
|
179
|
+
(candidate.id && String(candidate.id).toUpperCase() === record.mediaId))) {
|
|
180
|
+
filename =
|
|
181
|
+
typeof candidate.filename === 'string' && candidate.filename
|
|
182
|
+
? candidate.filename
|
|
183
|
+
: null;
|
|
184
|
+
alt = typeof candidate.alt === 'string' && candidate.alt ? candidate.alt : null;
|
|
185
|
+
caption =
|
|
186
|
+
typeof candidate.caption === 'string' && candidate.caption
|
|
187
|
+
? candidate.caption
|
|
188
|
+
: null;
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch { }
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
let localPath = null;
|
|
196
|
+
if (record.workspacePath && fs.existsSync(path.join(workspaceRoot, record.workspacePath))) {
|
|
197
|
+
localPath = record.workspacePath;
|
|
198
|
+
}
|
|
199
|
+
else if (fs.existsSync(mediaDir)) {
|
|
200
|
+
const files = fs.readdirSync(mediaDir);
|
|
201
|
+
for (const f of files) {
|
|
202
|
+
if (f.replace(/\.[^.]+$/, '') === stem && !f.endsWith('.yaml')) {
|
|
203
|
+
localPath = path.posix.join('media', f);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
index.set(record.storageKey, {
|
|
209
|
+
mediaId: record.mediaId,
|
|
210
|
+
storageKey: record.storageKey,
|
|
211
|
+
localPath,
|
|
212
|
+
filename,
|
|
213
|
+
alt,
|
|
214
|
+
caption,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return index;
|
|
218
|
+
}
|
|
219
|
+
// Cache-less fallback
|
|
220
|
+
if (fs.existsSync(mediaDir)) {
|
|
221
|
+
const files = fs.readdirSync(mediaDir);
|
|
222
|
+
for (const file of files) {
|
|
223
|
+
if (!file.endsWith('.yaml') || file.startsWith('legacy_'))
|
|
224
|
+
continue;
|
|
225
|
+
let doc = null;
|
|
226
|
+
try {
|
|
227
|
+
doc = yaml.load(fs.readFileSync(path.join(mediaDir, file), 'utf8'));
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (!doc)
|
|
233
|
+
continue;
|
|
234
|
+
const storageKey = storageKeyFromMediaMeta(doc);
|
|
235
|
+
if (!storageKey)
|
|
236
|
+
continue;
|
|
237
|
+
const stem = file.replace(/\.yaml$/, '');
|
|
238
|
+
const docId = typeof doc.id === 'string' && /^[0-9A-HJ-NP-Z]{26}$/i.test(doc.id.trim())
|
|
239
|
+
? doc.id.trim().toUpperCase()
|
|
240
|
+
: '';
|
|
241
|
+
let binaryPath = null;
|
|
242
|
+
for (const f of files) {
|
|
243
|
+
if (f !== file && f.replace(/\.[^.]+$/, '') === stem && !f.endsWith('.yaml')) {
|
|
244
|
+
binaryPath = path.posix.join('media', f);
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
index.set(storageKey, {
|
|
249
|
+
mediaId: docId,
|
|
250
|
+
storageKey,
|
|
251
|
+
localPath: binaryPath,
|
|
252
|
+
filename: typeof doc.filename === 'string' && doc.filename ? doc.filename : null,
|
|
253
|
+
alt: typeof doc.alt === 'string' && doc.alt ? doc.alt : null,
|
|
254
|
+
caption: typeof doc.caption === 'string' && doc.caption ? doc.caption : null,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return index;
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=companions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companions.js","sourceRoot":"","sources":["../../../src/sync/media/companions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAQhE,MAAM,UAAU,iBAAiB,CAC/B,IAAqB,EACrB,MAAc,EACd,YAA6C;IAE7C,MAAM,UAAU,GACd,CAAC,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,CAAC,OAAO,YAAY,EAAE,UAAU,KAAK,QAAQ,IAAI,YAAY,CAAC,UAAU;YACtE,CAAC,CAAC,YAAY,CAAC,UAAU;YACzB,CAAC,CAAC,EAAE,CAAC,CAAC;IACV,MAAM,YAAY,GAChB,IAAI,CAAC,GAAG;QACR,CAAC,UAAU;YACT,CAAC,CAAC,GAAG,uBAAuB,GAAG,UAAU,EAAE;YAC3C,CAAC,CAAC,OAAO,YAAY,EAAE,GAAG,KAAK,QAAQ;gBACrC,CAAC,CAAC,YAAY,CAAC,GAAG;gBAClB,CAAC,CAAC,EAAE,CAAC,CAAC;IACZ,MAAM,eAAe,GAAG,YAAY;QAClC,CAAC,CAAC,sBAAsB,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC;QAC1D,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,WAAW,GACf,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE;QAC5D,CAAC,CAAC,IAAI,CAAC,GAAG;QACV,CAAC,CAAC,OAAO,YAAY,EAAE,GAAG,KAAK,QAAQ;YACrC,CAAC,CAAC,YAAY,CAAC,GAAG;YAClB,CAAC,CAAC,EAAE,CAAC;IACX,MAAM,eAAe,GACnB,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,EAAE;QACxE,CAAC,CAAC,IAAI,CAAC,OAAO;QACd,CAAC,CAAC,OAAO,YAAY,EAAE,OAAO,KAAK,QAAQ;YACzC,CAAC,CAAC,YAAY,CAAC,OAAO;YACtB,CAAC,CAAC,EAAE,CAAC;IACX,MAAM,mBAAmB,GACvB,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW;QACtD,CAAC,CAAC,IAAI,CAAC,WAAW;QAClB,CAAC,CAAC,OAAO,YAAY,EAAE,WAAW,KAAK,QAAQ,IAAI,YAAY,CAAC,WAAW;YACzE,CAAC,CAAC,YAAY,CAAC,WAAW;YAC1B,CAAC,CAAC,IAAI,CAAC;IAEb,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,YAAY,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1F,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,YAAY,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9F,GAAG,EAAE,WAAW;QAChB,OAAO,EAAE,eAAe;QACxB,UAAU;QACV,WAAW,EAAE,mBAAmB;QAChC,MAAM,EACJ,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,YAAY,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3F,GAAG,EAAE,eAAe;QACpB,SAAS,EACP,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,YAAY,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;KAChG,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;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;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iCAAiC,CAC/C,QAAgB;IAEhB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqC,CAAC;IAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,MAAM,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS;QACpE,IAAI,GAAG,GAAmC,IAAI,CAAC;QAC/C,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAGjE,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,UAAU,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5E,MAAM,KAAK,GACT,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YACvE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;YAC7B,CAAC,CAAC,SAAS,CAAC;QAChB,MAAM,OAAO,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,SAAS,GAA8B,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACrF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,QAAQ,CAAC,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC;YACtE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CACrC,aAAqB,EACrB,KAAqB;IAErB,MAAM,KAAK,GAAqB,IAAI,GAAG,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;QACvC,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;YAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;gBAAE,SAAS;YACxE,IAAI,CAAC,MAAM,CAAC,UAAU;gBAAE,SAAS;YAEjC,IAAI,IAAY,CAAC;YACjB,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC3C,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,uBAAuB,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC;YACzE,CAAC;YAED,IAAI,QAAQ,GAAkB,IAAI,CAAC;YACnC,IAAI,GAAG,GAAkB,IAAI,CAAC;YAC9B,IAAI,OAAO,GAAkB,IAAI,CAAC;YAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;YACrD,IAAI,SAAS,GAAmC,IAAI,CAAC;YAErD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACH,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAG/C,CAAC;gBACX,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBAChC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAC3B,aAAa,EACb,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAClD,CAAC;gBACF,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC/B,IAAI,CAAC;wBACH,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAGlD,CAAC;oBACX,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS,GAAG,IAAI,CAAC;oBACnB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,QAAQ;oBACN,OAAO,SAAS,CAAC,QAAQ,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC3F,GAAG,GAAG,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChF,OAAO;oBACL,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1F,CAAC;iBAAM,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,8EAA8E;gBAC9E,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;wBAAE,SAAS;oBAC9D,IAAI,CAAC;wBACH,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAGnE,CAAC;wBACT,IACE,SAAS;4BACT,CAAC,uBAAuB,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,UAAU;gCACvD,CAAC,SAAS,CAAC,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,EAC1E,CAAC;4BACD,QAAQ;gCACN,OAAO,SAAS,CAAC,QAAQ,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ;oCAC1D,CAAC,CAAC,SAAS,CAAC,QAAQ;oCACpB,CAAC,CAAC,IAAI,CAAC;4BACX,GAAG,GAAG,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;4BAChF,OAAO;gCACL,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ,IAAI,SAAS,CAAC,OAAO;oCACxD,CAAC,CAAC,SAAS,CAAC,OAAO;oCACnB,CAAC,CAAC,IAAI,CAAC;4BACX,MAAM;wBACR,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;gBACZ,CAAC;YACH,CAAC;YAED,IAAI,SAAS,GAAkB,IAAI,CAAC;YACpC,IAAI,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;gBAC1F,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC;YACnC,CAAC;iBAAM,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;oBACtB,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC/D,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;wBACxC,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YAED,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE;gBAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,SAAS;gBACT,QAAQ;gBACR,GAAG;gBACH,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,sBAAsB;IACtB,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,SAAS;YACpE,IAAI,GAAG,GAAmC,IAAI,CAAC;YAC/C,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAGjE,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG;gBAAE,SAAS;YAEnB,MAAM,UAAU,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,UAAU;gBAAE,SAAS;YAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACzC,MAAM,KAAK,GACT,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;gBACvE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;gBAC7B,CAAC,CAAC,EAAE,CAAC;YAET,IAAI,UAAU,GAAkB,IAAI,CAAC;YACrC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC7E,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;oBACzC,MAAM;gBACR,CAAC;YACH,CAAC;YAED,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE;gBACpB,OAAO,EAAE,KAAK;gBACd,UAAU;gBACV,SAAS,EAAE,UAAU;gBACrB,QAAQ,EAAE,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;gBAChF,GAAG,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;gBAC5D,OAAO,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;aAC7E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './naming_mirror.js';
|
|
3
|
+
export * from './companions.js';
|
|
4
|
+
export * from './body_scan.js';
|
|
5
|
+
export * from './mirror_item.js';
|
|
6
|
+
export * from './pull_article.js';
|
|
7
|
+
export * from './pull_library.js';
|
|
8
|
+
export * from './remote_index.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/media/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './naming_mirror.js';
|
|
3
|
+
export * from './companions.js';
|
|
4
|
+
export * from './body_scan.js';
|
|
5
|
+
export * from './mirror_item.js';
|
|
6
|
+
export * from './pull_article.js';
|
|
7
|
+
export * from './pull_library.js';
|
|
8
|
+
export * from './remote_index.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sync/media/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CacheDatabase } from '../../db/cache.js';
|
|
2
|
+
import type { EmDashMediaItem, PromoteDraftMediaOptions, PromotedMediaFile } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Persists YAML companion metadata and downloads the binary file for a single media item.
|
|
5
|
+
*/
|
|
6
|
+
export declare function syncSingleMediaItem(options: {
|
|
7
|
+
item: EmDashMediaItem;
|
|
8
|
+
mediaDir: string;
|
|
9
|
+
origin: string;
|
|
10
|
+
token: string;
|
|
11
|
+
downloadFiles: boolean;
|
|
12
|
+
fetchFn: typeof fetch;
|
|
13
|
+
cache?: CacheDatabase;
|
|
14
|
+
}): Promise<{
|
|
15
|
+
downloaded: boolean;
|
|
16
|
+
skipped: boolean;
|
|
17
|
+
baseName: string;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Promotes a local draft image from media/drafts/<name> into the canonical
|
|
21
|
+
* media/<markdownRef>.<ext> location alongside its matching media/<markdownRef>.yaml companion, where
|
|
22
|
+
* markdownRef is derived from the storageKey the article body will reference. Returns both the workspace-relative
|
|
23
|
+
* path of the promoted binary and the shared `media/<markdownRef>` stem, so the caller can record the mirror in
|
|
24
|
+
* `media_state.markdown_ref`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function promoteDraftMediaFile(options: PromoteDraftMediaOptions): PromotedMediaFile;
|
|
27
|
+
//# sourceMappingURL=mirror_item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror_item.d.ts","sourceRoot":"","sources":["../../../src/sync/media/mirror_item.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAQvD,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/F;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE;IACjD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,KAAK,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmKvE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAyD1F"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
import { MEDIA_FILE_ROUTE_PREFIX } from '../../utils/media-refs.js';
|
|
5
|
+
import { buildMediaMetaDoc } from './companions.js';
|
|
6
|
+
import { cleanupDuplicateMediaFilesForId, mediaMirrorNames, moveFileSafe, } from './naming_mirror.js';
|
|
7
|
+
/**
|
|
8
|
+
* Persists YAML companion metadata and downloads the binary file for a single media item.
|
|
9
|
+
*/
|
|
10
|
+
export async function syncSingleMediaItem(options) {
|
|
11
|
+
const { item, mediaDir, origin, token, downloadFiles, fetchFn, cache } = options;
|
|
12
|
+
const names = mediaMirrorNames(item, mediaDir);
|
|
13
|
+
const baseName = names.markdownRef;
|
|
14
|
+
const yamlPath = path.join(mediaDir, `${baseName}.yaml`);
|
|
15
|
+
// Read any existing companion for this record id first, whatever stem it currently occupies. The
|
|
16
|
+
// storageKey-named companion is the expected location; the legacy stems are where an older workspace still
|
|
17
|
+
// holds the same asset. `legacy_<storageKey>.yaml` is skipped unconditionally: it carries a matching ULID
|
|
18
|
+
// but fabricates its metadata from a file route, so it must never seed a real record.
|
|
19
|
+
let existingMeta = null;
|
|
20
|
+
let existingMetaPath = null;
|
|
21
|
+
const mediaFiles = fs.readdirSync(mediaDir);
|
|
22
|
+
const companionCandidates = [yamlPath];
|
|
23
|
+
for (const legacy of names.legacyBaseNames) {
|
|
24
|
+
companionCandidates.push(path.join(mediaDir, `${legacy}.yaml`));
|
|
25
|
+
}
|
|
26
|
+
for (const candidate of companionCandidates) {
|
|
27
|
+
if (!fs.existsSync(candidate))
|
|
28
|
+
continue;
|
|
29
|
+
try {
|
|
30
|
+
existingMeta = yaml.load(fs.readFileSync(candidate, 'utf8'));
|
|
31
|
+
existingMetaPath = candidate;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
existingMeta = null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!existingMeta) {
|
|
39
|
+
const matchingYaml = mediaFiles.find((f) => f.endsWith('.yaml') &&
|
|
40
|
+
!f.startsWith('legacy_') &&
|
|
41
|
+
f !== path.basename(yamlPath) &&
|
|
42
|
+
(f.includes(`_${item.id}-`) || f.startsWith(`${item.id}-`)));
|
|
43
|
+
if (matchingYaml) {
|
|
44
|
+
try {
|
|
45
|
+
existingMeta = yaml.load(fs.readFileSync(path.join(mediaDir, matchingYaml), 'utf8'));
|
|
46
|
+
existingMetaPath = path.join(mediaDir, matchingYaml);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
existingMeta = null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// 1. Write YAML metadata under the storageKey-derived stem
|
|
54
|
+
const metaDoc = buildMediaMetaDoc(item, origin, existingMeta);
|
|
55
|
+
fs.writeFileSync(yamlPath, yaml.dump(metaDoc, { indent: 2, quotingType: '"', forceQuotes: false, lineWidth: -1 }), 'utf8');
|
|
56
|
+
let downloaded = false;
|
|
57
|
+
let skipped = false;
|
|
58
|
+
// 2. Download binary file if enabled and url is present
|
|
59
|
+
const canonicalDownloadPath = item.url || (item.storageKey ? `${MEDIA_FILE_ROUTE_PREFIX}${item.storageKey}` : '');
|
|
60
|
+
const fileExt = names.ext || (item.mimeType.includes('png') ? '.png' : '.jpg');
|
|
61
|
+
const targetFilePath = path.join(mediaDir, `${baseName}${fileExt}`);
|
|
62
|
+
// Rename an existing mirror into the new name before considering a download, so migrating a workspace
|
|
63
|
+
// costs no bandwidth. Size must match: a same-stem file of a different size is not this asset.
|
|
64
|
+
if (!fs.existsSync(targetFilePath)) {
|
|
65
|
+
const candidates = names.legacyBaseNames
|
|
66
|
+
.map((legacy) => path.join(mediaDir, `${legacy}${fileExt}`))
|
|
67
|
+
.concat(mediaFiles
|
|
68
|
+
.filter((f) => !f.endsWith('.yaml') &&
|
|
69
|
+
!f.startsWith('legacy_') &&
|
|
70
|
+
(f.includes(`_${item.id}-`) || f.startsWith(`${item.id}-`)))
|
|
71
|
+
.map((f) => path.join(mediaDir, f)));
|
|
72
|
+
for (const candidate of candidates) {
|
|
73
|
+
if (candidate === targetFilePath || !fs.existsSync(candidate))
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
const stat = fs.statSync(candidate);
|
|
77
|
+
if (stat.size === item.size) {
|
|
78
|
+
moveFileSafe(candidate, targetFilePath);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch { }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (downloadFiles && canonicalDownloadPath) {
|
|
86
|
+
let shouldDownload = true;
|
|
87
|
+
if (fs.existsSync(targetFilePath)) {
|
|
88
|
+
const stat = fs.statSync(targetFilePath);
|
|
89
|
+
if (stat.size === item.size) {
|
|
90
|
+
shouldDownload = false;
|
|
91
|
+
skipped = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (shouldDownload) {
|
|
95
|
+
try {
|
|
96
|
+
const downloadUrl = new URL(canonicalDownloadPath, origin).toString();
|
|
97
|
+
const fileRes = await fetchFn(downloadUrl, {
|
|
98
|
+
headers: {
|
|
99
|
+
Authorization: `Bearer ${token}`,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
if (fileRes.ok) {
|
|
103
|
+
const buffer = Buffer.from(await fileRes.arrayBuffer());
|
|
104
|
+
fs.writeFileSync(targetFilePath, buffer);
|
|
105
|
+
downloaded = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Ignore individual download failures
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Register the mirrored asset in media_state. Before storageKey naming, only the push/upload path wrote
|
|
114
|
+
// this table, so a pulled workspace had no index at all and every lookup fell back to scanning YAML. With
|
|
115
|
+
// the mirror name no longer carrying the record id, that index is what makes a body reference resolvable
|
|
116
|
+
// without re-reading thousands of companions.
|
|
117
|
+
if (cache && item.storageKey) {
|
|
118
|
+
const mirrorUrl = typeof metaDoc.url === 'string' && metaDoc.url
|
|
119
|
+
? metaDoc.url
|
|
120
|
+
: `${MEDIA_FILE_ROUTE_PREFIX}${item.storageKey}`;
|
|
121
|
+
cache.saveMediaState({
|
|
122
|
+
localHash: `media-record:${item.id}`,
|
|
123
|
+
mediaId: item.id,
|
|
124
|
+
storageKey: item.storageKey,
|
|
125
|
+
url: mirrorUrl,
|
|
126
|
+
workspacePath: path.posix.join('media', `${baseName}${fileExt}`),
|
|
127
|
+
markdownRef: path.posix.join('media', baseName),
|
|
128
|
+
status: 'ready',
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// Drop the companion this asset occupied under a legacy stem. Done after the binary rename so an
|
|
132
|
+
// interrupted run never leaves a record whose metadata and bytes disagree about the name.
|
|
133
|
+
if (existingMetaPath && existingMetaPath !== yamlPath && fs.existsSync(existingMetaPath)) {
|
|
134
|
+
try {
|
|
135
|
+
fs.unlinkSync(existingMetaPath);
|
|
136
|
+
}
|
|
137
|
+
catch { }
|
|
138
|
+
}
|
|
139
|
+
for (const legacy of names.legacyBaseNames) {
|
|
140
|
+
const legacyYaml = path.join(mediaDir, `${legacy}.yaml`);
|
|
141
|
+
if (legacyYaml !== yamlPath && fs.existsSync(legacyYaml)) {
|
|
142
|
+
try {
|
|
143
|
+
fs.unlinkSync(legacyYaml);
|
|
144
|
+
}
|
|
145
|
+
catch { }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Clean up any duplicate files with the same media ID but a different datePrefix/baseName
|
|
149
|
+
cleanupDuplicateMediaFilesForId(mediaDir, item.id, baseName);
|
|
150
|
+
return { downloaded, skipped, baseName };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Promotes a local draft image from media/drafts/<name> into the canonical
|
|
154
|
+
* media/<markdownRef>.<ext> location alongside its matching media/<markdownRef>.yaml companion, where
|
|
155
|
+
* markdownRef is derived from the storageKey the article body will reference. Returns both the workspace-relative
|
|
156
|
+
* path of the promoted binary and the shared `media/<markdownRef>` stem, so the caller can record the mirror in
|
|
157
|
+
* `media_state.markdown_ref`.
|
|
158
|
+
*/
|
|
159
|
+
export function promoteDraftMediaFile(options) {
|
|
160
|
+
const { workspaceRoot, origin, draftAbsPath, item, removeDraft = true } = options;
|
|
161
|
+
const mediaDir = path.join(workspaceRoot, 'media');
|
|
162
|
+
fs.mkdirSync(mediaDir, { recursive: true });
|
|
163
|
+
const ext = path.extname(item.filename) ||
|
|
164
|
+
path.extname(draftAbsPath) ||
|
|
165
|
+
(item.mimeType.includes('png') ? '.png' : '.jpg');
|
|
166
|
+
const names = mediaMirrorNames({ ...item, filename: item.filename || path.basename(draftAbsPath) }, mediaDir);
|
|
167
|
+
const baseName = names.markdownRef;
|
|
168
|
+
const yamlPath = path.join(mediaDir, `${baseName}.yaml`);
|
|
169
|
+
let existingMeta = null;
|
|
170
|
+
if (fs.existsSync(yamlPath)) {
|
|
171
|
+
try {
|
|
172
|
+
existingMeta = yaml.load(fs.readFileSync(yamlPath, 'utf8'));
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
existingMeta = null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const metaDoc = buildMediaMetaDoc(item, origin, existingMeta);
|
|
179
|
+
fs.writeFileSync(yamlPath, yaml.dump(metaDoc, { indent: 2, quotingType: '"', forceQuotes: false, lineWidth: -1 }), 'utf8');
|
|
180
|
+
const targetFilePath = path.join(mediaDir, `${baseName}${ext}`);
|
|
181
|
+
if (fs.existsSync(draftAbsPath)) {
|
|
182
|
+
if (removeDraft) {
|
|
183
|
+
moveFileSafe(draftAbsPath, targetFilePath);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
fs.copyFileSync(draftAbsPath, targetFilePath);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Retire any earlier id-named mirror of the same record so one asset never occupies two names.
|
|
190
|
+
for (const legacy of names.legacyBaseNames) {
|
|
191
|
+
for (const suffix of [ext, '.yaml']) {
|
|
192
|
+
const legacyPath = path.join(mediaDir, `${legacy}${suffix}`);
|
|
193
|
+
if (legacyPath !== yamlPath && legacyPath !== targetFilePath && fs.existsSync(legacyPath)) {
|
|
194
|
+
try {
|
|
195
|
+
fs.unlinkSync(legacyPath);
|
|
196
|
+
}
|
|
197
|
+
catch { }
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
cleanupDuplicateMediaFilesForId(mediaDir, item.id, baseName);
|
|
202
|
+
return {
|
|
203
|
+
filePath: path.posix.join('media', `${baseName}${ext}`),
|
|
204
|
+
markdownRef: path.posix.join('media', baseName),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=mirror_item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror_item.js","sourceRoot":"","sources":["../../../src/sync/media/mirror_item.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type EmDashMediaItem, type MediaMirrorNames } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Moves a file from src to dest, falling back to copy + unlink when src and dest
|
|
4
|
+
* reside on different filesystems (`EXDEV`).
|
|
5
|
+
*/
|
|
6
|
+
export declare function moveFileSafe(src: string, dest: string): void;
|
|
7
|
+
/**
|
|
8
|
+
* Reads the media record id a mirror belongs to from its companion YAML, accepting both the storageKey-named
|
|
9
|
+
* stem and the legacy `<yyyyMMdd>_<id>-<name>` form. Returns `null` when no companion exists or it names no
|
|
10
|
+
* valid ULID, which is how Emit refuses to prune a file it cannot attribute to a record. A companion whose
|
|
11
|
+
* id is explicitly null (or any non-ULID value) proves the mirror backs no real record, so the stem's own
|
|
12
|
+
* leading characters are never trusted as an id — that fallback would let fabricated fixture ids reach
|
|
13
|
+
* record-keyed logic.
|
|
14
|
+
*/
|
|
15
|
+
export declare function mediaRecordIdForStem(mediaDir: string, stem: string): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Removes any stale duplicate files in `media/` that belong to the same 26-char `mediaId` but sit under a
|
|
18
|
+
* different stem — a leftover date-prefixed name from an earlier local promotion, for instance. Ownership is
|
|
19
|
+
* read from each file's companion YAML rather than from the filename, because a storageKey-named mirror
|
|
20
|
+
* carries no record id at all and must never be matched (or deleted) by a coincidental ULID prefix.
|
|
21
|
+
*/
|
|
22
|
+
export declare function cleanupDuplicateMediaFilesForId(mediaDir: string, mediaId: string, canonicalBaseName: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Resolves the storageKey-derived stem against the names already taken in `media/`. Two distinct keys can
|
|
25
|
+
* sanitize to the same basename — `a/sample.png` and `b/sample.png` both yield `sample` — and a second asset
|
|
26
|
+
* must never overwrite the first. A name already owned by this same record is reused as-is, so re-pulling is
|
|
27
|
+
* idempotent; any other collision gets the deterministic `<stem>--<mediaId>` suffix.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveMarkdownRefCollision(mediaDir: string, baseRef: string, item: EmDashMediaItem): string;
|
|
30
|
+
/**
|
|
31
|
+
* Computes the canonical mirror name for one remote media item. Falls back to the record-id based stem only
|
|
32
|
+
* when the storageKey carries no usable basename, so a malformed migrated key cannot produce an unnameable
|
|
33
|
+
* file. Pass `mediaDir` to resolve a stem collision against the mirrors already on disk.
|
|
34
|
+
*/
|
|
35
|
+
export declare function mediaMirrorNames(item: EmDashMediaItem, mediaDir?: string): MediaMirrorNames;
|
|
36
|
+
//# sourceMappingURL=naming_mirror.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming_mirror.d.ts","sourceRoot":"","sources":["../../../src/sync/media/naming_mirror.ts"],"names":[],"mappings":"AASA,OAAO,EAA2B,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElG;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAW5D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBlF;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,iBAAiB,EAAE,MAAM,GACxB,IAAI,CAwBN;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,GACpB,MAAM,CAgBR;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAkB3F"}
|