@artinstack/migrator 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/bundle-BfZqiKV_.d.ts +153 -0
- package/dist/chunk-2RWAXT6O.js +1 -0
- package/dist/chunk-2RWAXT6O.js.map +1 -0
- package/dist/chunk-FXXKLYO5.js +1076 -0
- package/dist/chunk-FXXKLYO5.js.map +1 -0
- package/dist/chunk-JKDRTL24.js +102 -0
- package/dist/chunk-JKDRTL24.js.map +1 -0
- package/dist/chunk-LKNIQQJO.js +1579 -0
- package/dist/chunk-LKNIQQJO.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +242 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index-DQNzrygx.d.ts +279 -0
- package/dist/index.d.ts +336 -0
- package/dist/index.js +376 -0
- package/dist/index.js.map +1 -0
- package/dist/normalizer/index.d.ts +23 -0
- package/dist/normalizer/index.js +20 -0
- package/dist/normalizer/index.js.map +1 -0
- package/dist/sinks/index.d.ts +3 -0
- package/dist/sinks/index.js +46 -0
- package/dist/sinks/index.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { f as NormalizedCategory, k as NormalizedTag, N as NormalizedAsset, i as NormalizedPortfolio, j as NormalizedPost, h as NormalizedPage, P as PortfolioMediaLink, b as EntityKey, g as NormalizedEntity, a as MigrationPlatform, E as EntityBundle, M as MigrationAdapter } from './bundle-BfZqiKV_.js';
|
|
2
|
+
import { Readable } from 'node:stream';
|
|
3
|
+
|
|
4
|
+
interface RewriteInlineImageRef {
|
|
5
|
+
originalSrc: string;
|
|
6
|
+
sourceAssetId?: string;
|
|
7
|
+
}
|
|
8
|
+
interface UploadedAssetRef {
|
|
9
|
+
targetId: string;
|
|
10
|
+
publicUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
interface RewriteInlineImagesOptions {
|
|
13
|
+
resolveAsset: (src: string) => RewriteInlineImageRef | undefined;
|
|
14
|
+
replaceWith: (ref: RewriteInlineImageRef, uploaded: UploadedAssetRef) => string;
|
|
15
|
+
}
|
|
16
|
+
interface RewriteInlineImagesResult {
|
|
17
|
+
html: string;
|
|
18
|
+
referencedSources: string[];
|
|
19
|
+
unresolved: string[];
|
|
20
|
+
}
|
|
21
|
+
/** Rewrite `<img src>` / `srcset` using uploaded asset targets supplied by the host sink. */
|
|
22
|
+
declare function rewriteInlineImages(html: string, options: RewriteInlineImagesOptions, uploadedBySourceId: Map<string, UploadedAssetRef>): RewriteInlineImagesResult;
|
|
23
|
+
|
|
24
|
+
interface CreatePostResult {
|
|
25
|
+
targetId: string;
|
|
26
|
+
publicPath: string;
|
|
27
|
+
}
|
|
28
|
+
interface CreatePageResult {
|
|
29
|
+
targetId: string;
|
|
30
|
+
publicPath: string;
|
|
31
|
+
}
|
|
32
|
+
interface UploadAssetInput {
|
|
33
|
+
asset: NormalizedAsset;
|
|
34
|
+
/** Byte stream from source URL or local file. Optional for metadata-only sinks. */
|
|
35
|
+
body?: Readable | ReadableStream<Uint8Array>;
|
|
36
|
+
contentLength?: number;
|
|
37
|
+
}
|
|
38
|
+
interface UploadAssetResult {
|
|
39
|
+
targetId: string;
|
|
40
|
+
publicUrl?: string;
|
|
41
|
+
}
|
|
42
|
+
interface MigrationRedirect {
|
|
43
|
+
fromPath: string;
|
|
44
|
+
toPath: string;
|
|
45
|
+
statusCode: number;
|
|
46
|
+
}
|
|
47
|
+
interface MigrationProgress {
|
|
48
|
+
stage: string;
|
|
49
|
+
progress: number;
|
|
50
|
+
message?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Host-implemented write surface (e.g. ArtInStack PlatformMigrationSink).
|
|
54
|
+
* This package defines the interface only — no Directus or platform imports.
|
|
55
|
+
*/
|
|
56
|
+
interface MigrationSink {
|
|
57
|
+
createCategory?(category: NormalizedCategory): Promise<{
|
|
58
|
+
targetId: string;
|
|
59
|
+
}>;
|
|
60
|
+
createTag?(tag: NormalizedTag): Promise<{
|
|
61
|
+
targetId: string;
|
|
62
|
+
}>;
|
|
63
|
+
uploadAsset(input: UploadAssetInput): Promise<UploadAssetResult>;
|
|
64
|
+
createPortfolio?(portfolio: NormalizedPortfolio): Promise<{
|
|
65
|
+
targetId: string;
|
|
66
|
+
}>;
|
|
67
|
+
createPost(post: NormalizedPost): Promise<CreatePostResult>;
|
|
68
|
+
createPage(page: NormalizedPage): Promise<CreatePageResult>;
|
|
69
|
+
linkPortfolioMedia?(link: PortfolioMediaLink): Promise<void>;
|
|
70
|
+
writeRedirect?(redirect: MigrationRedirect): Promise<void>;
|
|
71
|
+
reportProgress?(progress: MigrationProgress): Promise<void>;
|
|
72
|
+
/** Optional lookup for idempotent re-runs. */
|
|
73
|
+
findExisting?(key: EntityKey): Promise<string | undefined>;
|
|
74
|
+
}
|
|
75
|
+
interface ResolvedAssetStream {
|
|
76
|
+
body: Readable | ReadableStream<Uint8Array>;
|
|
77
|
+
contentLength?: number;
|
|
78
|
+
}
|
|
79
|
+
interface MigrationRunOptions {
|
|
80
|
+
sink: MigrationSink;
|
|
81
|
+
entities: AsyncIterable<NormalizedEntity>;
|
|
82
|
+
platform: MigrationPlatform;
|
|
83
|
+
/** Fetch source bytes before uploadAsset; omit for metadata-only sinks. */
|
|
84
|
+
resolveAssetStream?: (asset: NormalizedAsset) => Promise<ResolvedAssetStream | null>;
|
|
85
|
+
/** Rewrite post/page HTML after assets are uploaded. */
|
|
86
|
+
rewriteInlineImages?: RewriteInlineImagesOptions;
|
|
87
|
+
onEntityProcessed?: (key: EntityKey, result: "done" | "failed" | "skipped", error?: string) => void;
|
|
88
|
+
}
|
|
89
|
+
interface MigrationRunResult {
|
|
90
|
+
processed: number;
|
|
91
|
+
failed: number;
|
|
92
|
+
skipped: number;
|
|
93
|
+
}
|
|
94
|
+
declare const MIGRATION_WRITE_STAGES: readonly ["taxonomy", "assets", "portfolios", "content", "bindings", "redirects"];
|
|
95
|
+
type MigrationWriteStage = (typeof MIGRATION_WRITE_STAGES)[number];
|
|
96
|
+
|
|
97
|
+
declare function runMigration(options: MigrationRunOptions): Promise<MigrationRunResult>;
|
|
98
|
+
declare function runMigrationFromBundle(bundle: EntityBundle, options: MigrationRunOptions): Promise<MigrationRunResult>;
|
|
99
|
+
|
|
100
|
+
interface DuplicateSlugConflict {
|
|
101
|
+
entityType: "post" | "page";
|
|
102
|
+
slug: string;
|
|
103
|
+
sourceIds: string[];
|
|
104
|
+
}
|
|
105
|
+
interface MissingFeaturedImageConflict {
|
|
106
|
+
postSourceId: string;
|
|
107
|
+
featuredMediaSourceId: string;
|
|
108
|
+
reason: string;
|
|
109
|
+
}
|
|
110
|
+
interface StaleAssetUrlConflict {
|
|
111
|
+
sourceId: string;
|
|
112
|
+
url: string;
|
|
113
|
+
reason: string;
|
|
114
|
+
}
|
|
115
|
+
interface InvalidHtmlConflict {
|
|
116
|
+
entityType: "post" | "page";
|
|
117
|
+
sourceId: string;
|
|
118
|
+
issues: string[];
|
|
119
|
+
}
|
|
120
|
+
interface UnresolvedInlineImageConflict {
|
|
121
|
+
postOrPageSourceId: string;
|
|
122
|
+
src: string;
|
|
123
|
+
}
|
|
124
|
+
interface UnsupportedBlockConflict {
|
|
125
|
+
entityType: "post" | "page";
|
|
126
|
+
sourceId: string;
|
|
127
|
+
blockType: string;
|
|
128
|
+
blockId?: string;
|
|
129
|
+
}
|
|
130
|
+
interface RedirectLoopConflict {
|
|
131
|
+
fromPath: string;
|
|
132
|
+
toPath: string;
|
|
133
|
+
blocked: boolean;
|
|
134
|
+
}
|
|
135
|
+
interface ConflictReport {
|
|
136
|
+
duplicatePostSlugs: DuplicateSlugConflict[];
|
|
137
|
+
duplicatePageSlugs: DuplicateSlugConflict[];
|
|
138
|
+
missingFeaturedImages: MissingFeaturedImageConflict[];
|
|
139
|
+
staleAssetUrls: StaleAssetUrlConflict[];
|
|
140
|
+
invalidHtml: InvalidHtmlConflict[];
|
|
141
|
+
unresolvedInlineImages: UnresolvedInlineImageConflict[];
|
|
142
|
+
unsupportedBlocks: UnsupportedBlockConflict[];
|
|
143
|
+
redirectLoops: RedirectLoopConflict[];
|
|
144
|
+
}
|
|
145
|
+
declare function emptyConflictReport(): ConflictReport;
|
|
146
|
+
declare function analyzeConflicts(bundle: EntityBundle, options?: {
|
|
147
|
+
staleAssetUrls?: StaleAssetUrlConflict[];
|
|
148
|
+
redirectLoops?: RedirectLoopConflict[];
|
|
149
|
+
}): ConflictReport;
|
|
150
|
+
declare function hasBlockingConflicts(report: ConflictReport): boolean;
|
|
151
|
+
declare function hasWarnings(report: ConflictReport): boolean;
|
|
152
|
+
declare function buildRedirectMap(bundle: EntityBundle): {
|
|
153
|
+
fromPath: string;
|
|
154
|
+
toPath: string;
|
|
155
|
+
statusCode: number;
|
|
156
|
+
}[];
|
|
157
|
+
declare function detectRedirectLoops(redirects: {
|
|
158
|
+
fromPath: string;
|
|
159
|
+
toPath: string;
|
|
160
|
+
}[]): RedirectLoopConflict[];
|
|
161
|
+
|
|
162
|
+
type MigrationRunMode = "dry-run" | "export" | "sink" | "worker";
|
|
163
|
+
interface MigrationReport {
|
|
164
|
+
runId: string;
|
|
165
|
+
platform: MigrationPlatform;
|
|
166
|
+
mode: MigrationRunMode;
|
|
167
|
+
startedAt: string;
|
|
168
|
+
finishedAt: string;
|
|
169
|
+
summary: {
|
|
170
|
+
posts: number;
|
|
171
|
+
pages: number;
|
|
172
|
+
assets: number;
|
|
173
|
+
portfolios: number;
|
|
174
|
+
categories: number;
|
|
175
|
+
tags: number;
|
|
176
|
+
storageBytesEstimated?: number;
|
|
177
|
+
};
|
|
178
|
+
warnings: string[];
|
|
179
|
+
errors: string[];
|
|
180
|
+
conflicts: ConflictReport;
|
|
181
|
+
redirectMap: {
|
|
182
|
+
fromPath: string;
|
|
183
|
+
toPath: string;
|
|
184
|
+
statusCode: number;
|
|
185
|
+
}[];
|
|
186
|
+
}
|
|
187
|
+
declare function buildMigrationReport(input: {
|
|
188
|
+
platform: MigrationPlatform;
|
|
189
|
+
mode: MigrationRunMode;
|
|
190
|
+
bundle: EntityBundle;
|
|
191
|
+
conflicts: ConflictReport;
|
|
192
|
+
redirectMap: {
|
|
193
|
+
fromPath: string;
|
|
194
|
+
toPath: string;
|
|
195
|
+
statusCode: number;
|
|
196
|
+
}[];
|
|
197
|
+
startedAt: Date;
|
|
198
|
+
finishedAt?: Date;
|
|
199
|
+
storageBytesEstimated?: number;
|
|
200
|
+
warnings?: string[];
|
|
201
|
+
errors?: string[];
|
|
202
|
+
runId?: string;
|
|
203
|
+
}): MigrationReport;
|
|
204
|
+
|
|
205
|
+
interface WriteFilesystemOptions {
|
|
206
|
+
outDir: string;
|
|
207
|
+
bundle: EntityBundle;
|
|
208
|
+
conflicts?: ConflictReport;
|
|
209
|
+
report?: MigrationReport;
|
|
210
|
+
}
|
|
211
|
+
declare function writeFilesystemExport(options: WriteFilesystemOptions): Promise<void>;
|
|
212
|
+
declare function bundleToCombinedJson(bundle: EntityBundle): Record<string, unknown>;
|
|
213
|
+
|
|
214
|
+
/** Reference MigrationSink that accumulates entities and writes M0 JSON bundles. */
|
|
215
|
+
declare class FilesystemMigrationSink implements MigrationSink {
|
|
216
|
+
readonly bundle: EntityBundle;
|
|
217
|
+
readonly portfolioMediaLinks: PortfolioMediaLink[];
|
|
218
|
+
readonly redirects: MigrationRedirect[];
|
|
219
|
+
createCategory(category: NormalizedCategory): Promise<{
|
|
220
|
+
targetId: string;
|
|
221
|
+
}>;
|
|
222
|
+
createTag(tag: NormalizedTag): Promise<{
|
|
223
|
+
targetId: string;
|
|
224
|
+
}>;
|
|
225
|
+
uploadAsset(input: UploadAssetInput): Promise<UploadAssetResult>;
|
|
226
|
+
createPortfolio(portfolio: NormalizedPortfolio): Promise<{
|
|
227
|
+
targetId: string;
|
|
228
|
+
}>;
|
|
229
|
+
createPost(post: NormalizedPost): Promise<CreatePostResult>;
|
|
230
|
+
createPage(page: NormalizedPage): Promise<CreatePageResult>;
|
|
231
|
+
linkPortfolioMedia(link: PortfolioMediaLink): Promise<void>;
|
|
232
|
+
writeRedirect(redirect: MigrationRedirect): Promise<void>;
|
|
233
|
+
flush(options: WriteFilesystemOptions): Promise<void>;
|
|
234
|
+
}
|
|
235
|
+
declare function createFilesystemMigrationSink(): FilesystemMigrationSink;
|
|
236
|
+
/** Verify sink-produced M2M links match bundle-derived index. */
|
|
237
|
+
declare function portfolioMediaMatchesBundle(sink: FilesystemMigrationSink): boolean;
|
|
238
|
+
|
|
239
|
+
interface DryRunOptions {
|
|
240
|
+
adapter: MigrationAdapter;
|
|
241
|
+
input: unknown;
|
|
242
|
+
platform: MigrationPlatform;
|
|
243
|
+
offlineStorageEstimate?: boolean;
|
|
244
|
+
fetchFn?: typeof fetch;
|
|
245
|
+
}
|
|
246
|
+
interface DryRunResult {
|
|
247
|
+
bundle: EntityBundle;
|
|
248
|
+
conflicts: ConflictReport;
|
|
249
|
+
report: MigrationReport;
|
|
250
|
+
exitCode: 0 | 1 | 2;
|
|
251
|
+
}
|
|
252
|
+
declare function runDryRun(options: DryRunOptions): Promise<DryRunResult>;
|
|
253
|
+
|
|
254
|
+
declare const FALLBACK_ASSET_BYTES: number;
|
|
255
|
+
interface AssetSizeResult {
|
|
256
|
+
sourceId: string;
|
|
257
|
+
url: string;
|
|
258
|
+
bytes: number;
|
|
259
|
+
source: "head" | "fallback";
|
|
260
|
+
error?: string;
|
|
261
|
+
}
|
|
262
|
+
interface StorageEstimate {
|
|
263
|
+
totalBytes: number;
|
|
264
|
+
assets: AssetSizeResult[];
|
|
265
|
+
}
|
|
266
|
+
interface EstimateStorageOptions {
|
|
267
|
+
assets: NormalizedAsset[];
|
|
268
|
+
/** When true, skip network and use fallback for all assets. */
|
|
269
|
+
offline?: boolean;
|
|
270
|
+
fetchFn?: typeof fetch;
|
|
271
|
+
}
|
|
272
|
+
declare function estimateStorage(options: EstimateStorageOptions): Promise<StorageEstimate>;
|
|
273
|
+
declare function staleUrlsFromEstimate(estimate: StorageEstimate): {
|
|
274
|
+
sourceId: string;
|
|
275
|
+
url: string;
|
|
276
|
+
reason: string;
|
|
277
|
+
}[];
|
|
278
|
+
|
|
279
|
+
export { runMigration as A, runMigrationFromBundle as B, type ConflictReport as C, type DryRunOptions as D, staleUrlsFromEstimate as E, FALLBACK_ASSET_BYTES as F, writeFilesystemExport as G, MIGRATION_WRITE_STAGES as M, type RewriteInlineImageRef as R, type StorageEstimate as S, type UploadAssetInput as U, type WriteFilesystemOptions as W, type DryRunResult as a, FilesystemMigrationSink as b, type MigrationRedirect as c, type MigrationReport as d, type MigrationRunMode as e, type MigrationRunOptions as f, type MigrationRunResult as g, type MigrationSink as h, type MigrationWriteStage as i, type RewriteInlineImagesOptions as j, type RewriteInlineImagesResult as k, type UploadAssetResult as l, type UploadedAssetRef as m, analyzeConflicts as n, buildMigrationReport as o, buildRedirectMap as p, bundleToCombinedJson as q, createFilesystemMigrationSink as r, detectRedirectLoops as s, emptyConflictReport as t, estimateStorage as u, hasBlockingConflicts as v, hasWarnings as w, portfolioMediaMatchesBundle as x, rewriteInlineImages as y, runDryRun as z };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { M as MigrationAdapter, a as MigrationPlatform } from './bundle-BfZqiKV_.js';
|
|
2
|
+
export { A as AdapterContext, B as BundleCounts, E as EntityBundle, b as EntityKey, c as EntityType, d as MigrationCursor, N as NormalizedAsset, e as NormalizedAssetExif, f as NormalizedCategory, g as NormalizedEntity, h as NormalizedPage, i as NormalizedPortfolio, j as NormalizedPost, k as NormalizedTag, P as PortfolioMediaLink, l as PublishStatus, S as SourceMetadata, V as ValidationIssue, m as ValidationResult, n as bundleCounts, o as collectEntities, p as emptyBundle, q as entityKey } from './bundle-BfZqiKV_.js';
|
|
3
|
+
export { EntityState, MigrationCheckpoint, TrackedEntity, buildPortfolioMediaLinks, isTerminalState, shouldProcessEntity } from './normalizer/index.js';
|
|
4
|
+
export { C as ConflictReport, D as DryRunOptions, a as DryRunResult, F as FALLBACK_ASSET_BYTES, b as FilesystemMigrationSink, M as MIGRATION_WRITE_STAGES, c as MigrationRedirect, d as MigrationReport, e as MigrationRunMode, f as MigrationRunOptions, g as MigrationRunResult, h as MigrationSink, i as MigrationWriteStage, R as RewriteInlineImageRef, j as RewriteInlineImagesOptions, k as RewriteInlineImagesResult, S as StorageEstimate, U as UploadAssetInput, l as UploadAssetResult, m as UploadedAssetRef, W as WriteFilesystemOptions, n as analyzeConflicts, o as buildMigrationReport, p as buildRedirectMap, q as bundleToCombinedJson, r as createFilesystemMigrationSink, s as detectRedirectLoops, t as emptyConflictReport, u as estimateStorage, v as hasBlockingConflicts, w as hasWarnings, x as portfolioMediaMatchesBundle, y as rewriteInlineImages, z as runDryRun, A as runMigration, B as runMigrationFromBundle, E as staleUrlsFromEstimate, G as writeFilesystemExport } from './index-DQNzrygx.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import 'node:stream';
|
|
7
|
+
|
|
8
|
+
declare const wordpressAdapter: MigrationAdapter;
|
|
9
|
+
|
|
10
|
+
/** Flat relational dump (Folders / Albums / Images tables). */
|
|
11
|
+
interface SmugMugFlatFolder {
|
|
12
|
+
sourceId: string;
|
|
13
|
+
name: string;
|
|
14
|
+
parentSourceId?: string;
|
|
15
|
+
slug?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
}
|
|
18
|
+
interface SmugMugFlatAlbum {
|
|
19
|
+
sourceId: string;
|
|
20
|
+
name: string;
|
|
21
|
+
parentSourceId?: string;
|
|
22
|
+
slug?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
url?: string;
|
|
25
|
+
}
|
|
26
|
+
interface SmugMugFlatImage {
|
|
27
|
+
sourceId: string;
|
|
28
|
+
portfolioSourceId: string;
|
|
29
|
+
sort?: number;
|
|
30
|
+
fileName?: string;
|
|
31
|
+
originalUrl?: string;
|
|
32
|
+
caption?: string;
|
|
33
|
+
keywords?: string[];
|
|
34
|
+
exif?: {
|
|
35
|
+
iso?: number | string;
|
|
36
|
+
aperture?: number | string;
|
|
37
|
+
shutter?: string;
|
|
38
|
+
focalLength?: number | string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
interface SmugMugFlatExport {
|
|
42
|
+
exportVersion: string | number;
|
|
43
|
+
exportedAt?: string;
|
|
44
|
+
Folders: SmugMugFlatFolder[];
|
|
45
|
+
Albums: SmugMugFlatAlbum[];
|
|
46
|
+
Images: SmugMugFlatImage[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
declare const SMUGMUG_API_BASE = "https://api.smugmug.com/api/v2";
|
|
50
|
+
declare const SMUGMUG_OAUTH_ENDPOINTS: {
|
|
51
|
+
readonly requestToken: "https://api.smugmug.com/services/oauth/1.0a/getRequestToken";
|
|
52
|
+
readonly authorize: "https://api.smugmug.com/services/oauth/1.0a/authorize";
|
|
53
|
+
readonly accessToken: "https://api.smugmug.com/services/oauth/1.0a/getAccessToken";
|
|
54
|
+
};
|
|
55
|
+
declare const smugMugCredentialsSchema: z.ZodObject<{
|
|
56
|
+
consumerKey: z.ZodString;
|
|
57
|
+
consumerSecret: z.ZodString;
|
|
58
|
+
accessToken: z.ZodString;
|
|
59
|
+
accessTokenSecret: z.ZodString;
|
|
60
|
+
}, "strip", z.ZodTypeAny, {
|
|
61
|
+
consumerKey: string;
|
|
62
|
+
consumerSecret: string;
|
|
63
|
+
accessToken: string;
|
|
64
|
+
accessTokenSecret: string;
|
|
65
|
+
}, {
|
|
66
|
+
consumerKey: string;
|
|
67
|
+
consumerSecret: string;
|
|
68
|
+
accessToken: string;
|
|
69
|
+
accessTokenSecret: string;
|
|
70
|
+
}>;
|
|
71
|
+
type SmugMugCredentials = z.infer<typeof smugMugCredentialsSchema>;
|
|
72
|
+
declare const smugMugClientOptionsSchema: z.ZodObject<{
|
|
73
|
+
credentials: z.ZodObject<{
|
|
74
|
+
consumerKey: z.ZodString;
|
|
75
|
+
consumerSecret: z.ZodString;
|
|
76
|
+
accessToken: z.ZodString;
|
|
77
|
+
accessTokenSecret: z.ZodString;
|
|
78
|
+
}, "strip", z.ZodTypeAny, {
|
|
79
|
+
consumerKey: string;
|
|
80
|
+
consumerSecret: string;
|
|
81
|
+
accessToken: string;
|
|
82
|
+
accessTokenSecret: string;
|
|
83
|
+
}, {
|
|
84
|
+
consumerKey: string;
|
|
85
|
+
consumerSecret: string;
|
|
86
|
+
accessToken: string;
|
|
87
|
+
accessTokenSecret: string;
|
|
88
|
+
}>;
|
|
89
|
+
pageSize: z.ZodDefault<z.ZodNumber>;
|
|
90
|
+
maxRetries: z.ZodDefault<z.ZodNumber>;
|
|
91
|
+
retryBaseDelayMs: z.ZodDefault<z.ZodNumber>;
|
|
92
|
+
maxRetryDelayMs: z.ZodDefault<z.ZodNumber>;
|
|
93
|
+
requestIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
94
|
+
fetchImpl: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
|
|
95
|
+
}, "strip", z.ZodTypeAny, {
|
|
96
|
+
maxRetries: number;
|
|
97
|
+
retryBaseDelayMs: number;
|
|
98
|
+
maxRetryDelayMs: number;
|
|
99
|
+
requestIntervalMs: number;
|
|
100
|
+
credentials: {
|
|
101
|
+
consumerKey: string;
|
|
102
|
+
consumerSecret: string;
|
|
103
|
+
accessToken: string;
|
|
104
|
+
accessTokenSecret: string;
|
|
105
|
+
};
|
|
106
|
+
pageSize: number;
|
|
107
|
+
fetchImpl?: typeof fetch | undefined;
|
|
108
|
+
}, {
|
|
109
|
+
credentials: {
|
|
110
|
+
consumerKey: string;
|
|
111
|
+
consumerSecret: string;
|
|
112
|
+
accessToken: string;
|
|
113
|
+
accessTokenSecret: string;
|
|
114
|
+
};
|
|
115
|
+
maxRetries?: number | undefined;
|
|
116
|
+
retryBaseDelayMs?: number | undefined;
|
|
117
|
+
maxRetryDelayMs?: number | undefined;
|
|
118
|
+
requestIntervalMs?: number | undefined;
|
|
119
|
+
fetchImpl?: typeof fetch | undefined;
|
|
120
|
+
pageSize?: number | undefined;
|
|
121
|
+
}>;
|
|
122
|
+
type SmugMugClientOptions = z.input<typeof smugMugClientOptionsSchema>;
|
|
123
|
+
/** Build OAuth 1.0a HMAC-SHA1 signature for a SmugMug API request. */
|
|
124
|
+
declare function signSmugMugOAuthRequest(input: {
|
|
125
|
+
method: string;
|
|
126
|
+
url: string;
|
|
127
|
+
credentials: SmugMugCredentials;
|
|
128
|
+
oauthParams: Record<string, string>;
|
|
129
|
+
bodyParams?: Record<string, string>;
|
|
130
|
+
}): string;
|
|
131
|
+
declare function buildSmugMugAuthorizationHeader(input: {
|
|
132
|
+
method: string;
|
|
133
|
+
url: string;
|
|
134
|
+
credentials: SmugMugCredentials;
|
|
135
|
+
nonce?: string;
|
|
136
|
+
timestamp?: string;
|
|
137
|
+
bodyParams?: Record<string, string>;
|
|
138
|
+
}): string;
|
|
139
|
+
declare function readSmugMugCredentialsFromEnv(env?: Record<string, string | undefined>): SmugMugCredentials;
|
|
140
|
+
/** Signed SmugMug API client — recursively discovers folders, albums, and images. */
|
|
141
|
+
declare class SmugMugApiClient {
|
|
142
|
+
readonly credentials: SmugMugCredentials;
|
|
143
|
+
readonly pageSize: number;
|
|
144
|
+
readonly maxRetries: number;
|
|
145
|
+
readonly retryBaseDelayMs: number;
|
|
146
|
+
readonly maxRetryDelayMs: number;
|
|
147
|
+
readonly requestIntervalMs: number;
|
|
148
|
+
readonly fetchImpl: typeof fetch;
|
|
149
|
+
private lastRequestAt;
|
|
150
|
+
constructor(options: SmugMugClientOptions);
|
|
151
|
+
/** Validate credentials against `GET /user/!authuser`. */
|
|
152
|
+
validateCredentials(): Promise<{
|
|
153
|
+
nick?: string;
|
|
154
|
+
rootNodeUri: string;
|
|
155
|
+
}>;
|
|
156
|
+
/** Crawl the authenticated user's node tree into flat export tables for `parse-node.ts`. */
|
|
157
|
+
crawlExport(): Promise<SmugMugFlatExport>;
|
|
158
|
+
private getAuthUser;
|
|
159
|
+
private walkNode;
|
|
160
|
+
private collectAlbumImages;
|
|
161
|
+
private paginateNodes;
|
|
162
|
+
private paginateAlbumImages;
|
|
163
|
+
private paginate;
|
|
164
|
+
private requestJson;
|
|
165
|
+
private requestWithRetry;
|
|
166
|
+
private throttle;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
declare const smugmugAdapter: MigrationAdapter;
|
|
170
|
+
|
|
171
|
+
/** Squarespace JSON export shape for fixtures and static HTML snapshot migration. */
|
|
172
|
+
interface SquarespaceGalleryItem {
|
|
173
|
+
id?: string;
|
|
174
|
+
imageUrl: string;
|
|
175
|
+
altText?: string;
|
|
176
|
+
caption?: string;
|
|
177
|
+
}
|
|
178
|
+
interface SquarespaceBlock {
|
|
179
|
+
id?: string;
|
|
180
|
+
type: string;
|
|
181
|
+
html?: string;
|
|
182
|
+
value?: string;
|
|
183
|
+
imageUrl?: string;
|
|
184
|
+
altText?: string;
|
|
185
|
+
caption?: string;
|
|
186
|
+
url?: string;
|
|
187
|
+
label?: string;
|
|
188
|
+
embedHtml?: string;
|
|
189
|
+
items?: SquarespaceGalleryItem[];
|
|
190
|
+
}
|
|
191
|
+
interface SquarespacePage {
|
|
192
|
+
id: string;
|
|
193
|
+
title: string;
|
|
194
|
+
slug: string;
|
|
195
|
+
url?: string;
|
|
196
|
+
status?: "published" | "draft" | "scheduled";
|
|
197
|
+
isHomePage?: boolean;
|
|
198
|
+
seoTitle?: string;
|
|
199
|
+
seoDescription?: string;
|
|
200
|
+
contentCss?: string;
|
|
201
|
+
/** Pre-rendered snapshot when blocks[] is absent. */
|
|
202
|
+
contentHtml?: string;
|
|
203
|
+
blocks?: SquarespaceBlock[];
|
|
204
|
+
}
|
|
205
|
+
interface SquarespacePost {
|
|
206
|
+
id: string;
|
|
207
|
+
title: string;
|
|
208
|
+
slug: string;
|
|
209
|
+
url?: string;
|
|
210
|
+
excerpt?: string;
|
|
211
|
+
publishedAt?: string;
|
|
212
|
+
status?: "published" | "draft" | "scheduled";
|
|
213
|
+
categorySlugs?: string[];
|
|
214
|
+
tagSlugs?: string[];
|
|
215
|
+
featuredImageUrl?: string;
|
|
216
|
+
seoTitle?: string;
|
|
217
|
+
seoDescription?: string;
|
|
218
|
+
contentHtml?: string;
|
|
219
|
+
blocks?: SquarespaceBlock[];
|
|
220
|
+
}
|
|
221
|
+
interface SquarespaceCategory {
|
|
222
|
+
id: string;
|
|
223
|
+
name: string;
|
|
224
|
+
slug: string;
|
|
225
|
+
}
|
|
226
|
+
interface SquarespaceTag {
|
|
227
|
+
id: string;
|
|
228
|
+
name: string;
|
|
229
|
+
slug: string;
|
|
230
|
+
}
|
|
231
|
+
interface SquarespaceExport {
|
|
232
|
+
exportVersion: string | number;
|
|
233
|
+
exportedAt?: string;
|
|
234
|
+
site?: {
|
|
235
|
+
url?: string;
|
|
236
|
+
title?: string;
|
|
237
|
+
};
|
|
238
|
+
pages: SquarespacePage[];
|
|
239
|
+
posts?: SquarespacePost[];
|
|
240
|
+
categories?: SquarespaceCategory[];
|
|
241
|
+
tags?: SquarespaceTag[];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
declare const SQUARESPACE_JSON_FORMAT: "json-pretty";
|
|
245
|
+
declare const SQUARESPACE_JSON_FORMAT_COMPACT: "json";
|
|
246
|
+
type SquarespaceJsonFormat = typeof SQUARESPACE_JSON_FORMAT | typeof SQUARESPACE_JSON_FORMAT_COMPACT;
|
|
247
|
+
declare const squarespaceClientOptionsSchema: z.ZodObject<{
|
|
248
|
+
format: z.ZodDefault<z.ZodEnum<["json", "json-pretty"]>>;
|
|
249
|
+
maxRetries: z.ZodDefault<z.ZodNumber>;
|
|
250
|
+
retryBaseDelayMs: z.ZodDefault<z.ZodNumber>;
|
|
251
|
+
maxRetryDelayMs: z.ZodDefault<z.ZodNumber>;
|
|
252
|
+
requestIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
253
|
+
fetchImpl: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
|
|
254
|
+
}, "strip", z.ZodTypeAny, {
|
|
255
|
+
format: "json-pretty" | "json";
|
|
256
|
+
maxRetries: number;
|
|
257
|
+
retryBaseDelayMs: number;
|
|
258
|
+
maxRetryDelayMs: number;
|
|
259
|
+
requestIntervalMs: number;
|
|
260
|
+
fetchImpl?: typeof fetch | undefined;
|
|
261
|
+
}, {
|
|
262
|
+
format?: "json-pretty" | "json" | undefined;
|
|
263
|
+
maxRetries?: number | undefined;
|
|
264
|
+
retryBaseDelayMs?: number | undefined;
|
|
265
|
+
maxRetryDelayMs?: number | undefined;
|
|
266
|
+
requestIntervalMs?: number | undefined;
|
|
267
|
+
fetchImpl?: typeof fetch | undefined;
|
|
268
|
+
}>;
|
|
269
|
+
type SquarespaceClientOptions = z.input<typeof squarespaceClientOptionsSchema>;
|
|
270
|
+
interface SquarespaceCollectTarget {
|
|
271
|
+
/** Page or collection URL on the live Squarespace site (without format query). */
|
|
272
|
+
url: string;
|
|
273
|
+
/** `collection` paginates `items[]`; `page` fetches a single static page/item. */
|
|
274
|
+
kind?: "auto" | "page" | "collection";
|
|
275
|
+
isHomePage?: boolean;
|
|
276
|
+
}
|
|
277
|
+
/** Append Squarespace `?format=json-pretty` (or `json`) to a site URL. */
|
|
278
|
+
declare function buildJsonPrettyUrl(pageUrl: string, format?: SquarespaceJsonFormat): string;
|
|
279
|
+
/** Map one Squarespace `?format=json-pretty` response into export partials. */
|
|
280
|
+
declare function mapJsonPrettyWire(wire: unknown, context?: {
|
|
281
|
+
fetchedUrl?: string;
|
|
282
|
+
isHomePage?: boolean;
|
|
283
|
+
}): Partial<SquarespaceExport>;
|
|
284
|
+
/** Fetch json-pretty pages/collections and assemble a canonical export document. */
|
|
285
|
+
declare class SquarespaceCollectionClient {
|
|
286
|
+
readonly format: SquarespaceJsonFormat;
|
|
287
|
+
readonly maxRetries: number;
|
|
288
|
+
readonly retryBaseDelayMs: number;
|
|
289
|
+
readonly maxRetryDelayMs: number;
|
|
290
|
+
readonly requestIntervalMs: number;
|
|
291
|
+
readonly fetchImpl: typeof fetch;
|
|
292
|
+
private lastRequestAt;
|
|
293
|
+
constructor(options?: SquarespaceClientOptions);
|
|
294
|
+
buildJsonPrettyUrl(pageUrl: string): string;
|
|
295
|
+
fetchWire(url: string): Promise<unknown>;
|
|
296
|
+
collectExport(targets: SquarespaceCollectTarget[]): Promise<SquarespaceExport>;
|
|
297
|
+
private collectCollectionPages;
|
|
298
|
+
private requestWithRetry;
|
|
299
|
+
private throttle;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
declare const squarespaceAdapter: MigrationAdapter;
|
|
303
|
+
|
|
304
|
+
declare function getAdapter(platform: MigrationPlatform): MigrationAdapter;
|
|
305
|
+
|
|
306
|
+
interface HtmlToGrapesOptions {
|
|
307
|
+
/** Map source class names to Grapes component types. */
|
|
308
|
+
componentMap?: Record<string, string>;
|
|
309
|
+
}
|
|
310
|
+
interface GrapesStyleRule {
|
|
311
|
+
selectors: string[];
|
|
312
|
+
style: Record<string, string>;
|
|
313
|
+
}
|
|
314
|
+
interface GrapesComponent {
|
|
315
|
+
type: string;
|
|
316
|
+
tagName?: string;
|
|
317
|
+
attributes?: Record<string, string>;
|
|
318
|
+
classes?: string[];
|
|
319
|
+
components?: GrapesComponent[];
|
|
320
|
+
content?: string;
|
|
321
|
+
void?: boolean;
|
|
322
|
+
}
|
|
323
|
+
interface GrapesProjectSnapshot {
|
|
324
|
+
content: GrapesComponent[];
|
|
325
|
+
styles: GrapesStyleRule[];
|
|
326
|
+
contentHtml?: string;
|
|
327
|
+
contentCss?: string;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Cheerio HTML walk → Grapes `content` + root `styles`. */
|
|
331
|
+
declare function htmlToGrapes(html: string, options?: HtmlToGrapesOptions): GrapesProjectSnapshot;
|
|
332
|
+
|
|
333
|
+
/** Parse `<style>` blocks and class rules into Grapes root `styles[]`. */
|
|
334
|
+
declare function cssToStyles(css: string): GrapesStyleRule[];
|
|
335
|
+
|
|
336
|
+
export { type GrapesComponent, type GrapesProjectSnapshot, type GrapesStyleRule, type HtmlToGrapesOptions, MigrationAdapter, MigrationPlatform, SMUGMUG_API_BASE, SMUGMUG_OAUTH_ENDPOINTS, SQUARESPACE_JSON_FORMAT, SmugMugApiClient, type SmugMugClientOptions, type SmugMugCredentials, type SquarespaceClientOptions, type SquarespaceCollectTarget, SquarespaceCollectionClient, buildJsonPrettyUrl, buildSmugMugAuthorizationHeader, cssToStyles, getAdapter, htmlToGrapes, mapJsonPrettyWire, readSmugMugCredentialsFromEnv, signSmugMugOAuthRequest, smugMugCredentialsSchema, smugmugAdapter, squarespaceAdapter, wordpressAdapter };
|