@artinstack/migrator 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle-uAAHehbv.d.ts +23 -0
- package/dist/chunk-CIOYDRY5.js +851 -0
- package/dist/chunk-CIOYDRY5.js.map +1 -0
- package/dist/chunk-EXYXTAZM.js +91 -0
- package/dist/chunk-EXYXTAZM.js.map +1 -0
- package/dist/{chunk-XKWWXKP3.js → chunk-IPYHS5R2.js} +157 -87
- package/dist/chunk-IPYHS5R2.js.map +1 -0
- package/dist/{chunk-Q6M5JEL3.js → chunk-XQVKA54A.js} +150 -6
- package/dist/chunk-XQVKA54A.js.map +1 -0
- package/dist/chunk-XYP3VYDH.js +159 -0
- package/dist/chunk-XYP3VYDH.js.map +1 -0
- package/dist/cli/index.js +4 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +8 -87
- package/dist/index.js +29 -353
- package/dist/index.js.map +1 -1
- package/dist/lib/index.d.ts +14 -4
- package/dist/lib/index.js +7 -3
- package/dist/normalizer/index.d.ts +4 -2
- package/dist/rewrite-inline-images-DPoxyzVC.d.ts +21 -0
- package/dist/sinks/index.d.ts +262 -3
- package/dist/sinks/index.js +5 -3
- package/dist/transformers/index.d.ts +157 -0
- package/dist/transformers/index.js +32 -0
- package/dist/transformers/index.js.map +1 -0
- package/dist/{bundle-DfM_jKbq.d.ts → types-DWOP8Dcy.d.ts} +1 -21
- package/package.json +5 -1
- package/dist/chunk-2PNSVE5Y.js +0 -67
- package/dist/chunk-2PNSVE5Y.js.map +0 -1
- package/dist/chunk-Q6M5JEL3.js.map +0 -1
- package/dist/chunk-XKWWXKP3.js.map +0 -1
- package/dist/index-D88mjcF5.d.ts +0 -279
package/dist/sinks/index.d.ts
CHANGED
|
@@ -1,3 +1,262 @@
|
|
|
1
|
-
|
|
2
|
-
import '
|
|
3
|
-
import '
|
|
1
|
+
import { d as NormalizedCategory, e as NormalizedTag, b as NormalizedAsset, c as NormalizedPortfolio, N as NormalizedPost, a as NormalizedPage, P as PortfolioMediaLink, E as EntityKey, f as NormalizedEntity, g as MigrationPlatform, M as MigrationAdapter } from '../types-DWOP8Dcy.js';
|
|
2
|
+
import { Readable } from 'node:stream';
|
|
3
|
+
import { a as RewriteInlineImagesOptions } from '../rewrite-inline-images-DPoxyzVC.js';
|
|
4
|
+
export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-DPoxyzVC.js';
|
|
5
|
+
import { E as EntityBundle } from '../bundle-uAAHehbv.js';
|
|
6
|
+
|
|
7
|
+
interface CreatePostResult {
|
|
8
|
+
targetId: string;
|
|
9
|
+
publicPath: string;
|
|
10
|
+
}
|
|
11
|
+
interface CreatePageResult {
|
|
12
|
+
targetId: string;
|
|
13
|
+
publicPath: string;
|
|
14
|
+
}
|
|
15
|
+
interface UploadAssetInput {
|
|
16
|
+
asset: NormalizedAsset;
|
|
17
|
+
/** Byte stream from source URL or local file. Optional for metadata-only sinks. */
|
|
18
|
+
body?: Readable | ReadableStream<Uint8Array>;
|
|
19
|
+
contentLength?: number;
|
|
20
|
+
}
|
|
21
|
+
interface UploadAssetResult {
|
|
22
|
+
targetId: string;
|
|
23
|
+
publicUrl?: string;
|
|
24
|
+
}
|
|
25
|
+
interface MigrationRedirect {
|
|
26
|
+
fromPath: string;
|
|
27
|
+
toPath: string;
|
|
28
|
+
statusCode: number;
|
|
29
|
+
}
|
|
30
|
+
interface MigrationProgress {
|
|
31
|
+
stage: string;
|
|
32
|
+
progress: number;
|
|
33
|
+
message?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Host-implemented write surface (e.g. ArtInStack PlatformMigrationSink).
|
|
37
|
+
* This package defines the interface only — no Directus or platform imports.
|
|
38
|
+
*/
|
|
39
|
+
interface MigrationSink {
|
|
40
|
+
createCategory?(category: NormalizedCategory): Promise<{
|
|
41
|
+
targetId: string;
|
|
42
|
+
}>;
|
|
43
|
+
createTag?(tag: NormalizedTag): Promise<{
|
|
44
|
+
targetId: string;
|
|
45
|
+
}>;
|
|
46
|
+
uploadAsset(input: UploadAssetInput): Promise<UploadAssetResult>;
|
|
47
|
+
createPortfolio?(portfolio: NormalizedPortfolio): Promise<{
|
|
48
|
+
targetId: string;
|
|
49
|
+
}>;
|
|
50
|
+
createPost(post: NormalizedPost): Promise<CreatePostResult>;
|
|
51
|
+
createPage(page: NormalizedPage): Promise<CreatePageResult>;
|
|
52
|
+
linkPortfolioMedia?(link: PortfolioMediaLink): Promise<void>;
|
|
53
|
+
writeRedirect?(redirect: MigrationRedirect): Promise<void>;
|
|
54
|
+
reportProgress?(progress: MigrationProgress): Promise<void>;
|
|
55
|
+
/** Optional lookup for idempotent re-runs. */
|
|
56
|
+
findExisting?(key: EntityKey): Promise<string | undefined>;
|
|
57
|
+
}
|
|
58
|
+
interface ResolvedAssetStream {
|
|
59
|
+
body: Readable | ReadableStream<Uint8Array>;
|
|
60
|
+
contentLength?: number;
|
|
61
|
+
}
|
|
62
|
+
interface MigrationRunOptions {
|
|
63
|
+
sink: MigrationSink;
|
|
64
|
+
entities: AsyncIterable<NormalizedEntity>;
|
|
65
|
+
platform: MigrationPlatform;
|
|
66
|
+
/** Fetch source bytes before uploadAsset; omit for metadata-only sinks. */
|
|
67
|
+
resolveAssetStream?: (asset: NormalizedAsset) => Promise<ResolvedAssetStream | null>;
|
|
68
|
+
/** Rewrite post/page HTML after assets are uploaded. */
|
|
69
|
+
rewriteInlineImages?: RewriteInlineImagesOptions;
|
|
70
|
+
onEntityProcessed?: (key: EntityKey, result: "done" | "failed" | "skipped", error?: string) => void;
|
|
71
|
+
}
|
|
72
|
+
interface MigrationRunResult {
|
|
73
|
+
processed: number;
|
|
74
|
+
failed: number;
|
|
75
|
+
skipped: number;
|
|
76
|
+
}
|
|
77
|
+
declare const MIGRATION_WRITE_STAGES: readonly ["taxonomy", "assets", "portfolios", "content", "bindings", "redirects"];
|
|
78
|
+
type MigrationWriteStage = (typeof MIGRATION_WRITE_STAGES)[number];
|
|
79
|
+
|
|
80
|
+
declare function runMigration(options: MigrationRunOptions): Promise<MigrationRunResult>;
|
|
81
|
+
declare function runMigrationFromBundle(bundle: EntityBundle, options: MigrationRunOptions): Promise<MigrationRunResult>;
|
|
82
|
+
|
|
83
|
+
interface DuplicateSlugConflict {
|
|
84
|
+
entityType: "post" | "page";
|
|
85
|
+
slug: string;
|
|
86
|
+
sourceIds: string[];
|
|
87
|
+
}
|
|
88
|
+
interface MissingFeaturedImageConflict {
|
|
89
|
+
postSourceId: string;
|
|
90
|
+
featuredMediaSourceId: string;
|
|
91
|
+
reason: string;
|
|
92
|
+
}
|
|
93
|
+
interface StaleAssetUrlConflict {
|
|
94
|
+
sourceId: string;
|
|
95
|
+
url: string;
|
|
96
|
+
reason: string;
|
|
97
|
+
}
|
|
98
|
+
interface InvalidHtmlConflict {
|
|
99
|
+
entityType: "post" | "page";
|
|
100
|
+
sourceId: string;
|
|
101
|
+
issues: string[];
|
|
102
|
+
}
|
|
103
|
+
interface UnresolvedInlineImageConflict {
|
|
104
|
+
postOrPageSourceId: string;
|
|
105
|
+
src: string;
|
|
106
|
+
}
|
|
107
|
+
interface UnsupportedBlockConflict {
|
|
108
|
+
entityType: "post" | "page";
|
|
109
|
+
sourceId: string;
|
|
110
|
+
blockType: string;
|
|
111
|
+
blockId?: string;
|
|
112
|
+
}
|
|
113
|
+
interface RedirectLoopConflict {
|
|
114
|
+
fromPath: string;
|
|
115
|
+
toPath: string;
|
|
116
|
+
blocked: boolean;
|
|
117
|
+
}
|
|
118
|
+
interface ConflictReport {
|
|
119
|
+
duplicatePostSlugs: DuplicateSlugConflict[];
|
|
120
|
+
duplicatePageSlugs: DuplicateSlugConflict[];
|
|
121
|
+
missingFeaturedImages: MissingFeaturedImageConflict[];
|
|
122
|
+
staleAssetUrls: StaleAssetUrlConflict[];
|
|
123
|
+
invalidHtml: InvalidHtmlConflict[];
|
|
124
|
+
unresolvedInlineImages: UnresolvedInlineImageConflict[];
|
|
125
|
+
unsupportedBlocks: UnsupportedBlockConflict[];
|
|
126
|
+
redirectLoops: RedirectLoopConflict[];
|
|
127
|
+
}
|
|
128
|
+
declare function emptyConflictReport(): ConflictReport;
|
|
129
|
+
declare function analyzeConflicts(bundle: EntityBundle, options?: {
|
|
130
|
+
staleAssetUrls?: StaleAssetUrlConflict[];
|
|
131
|
+
redirectLoops?: RedirectLoopConflict[];
|
|
132
|
+
}): ConflictReport;
|
|
133
|
+
declare function hasBlockingConflicts(report: ConflictReport): boolean;
|
|
134
|
+
declare function hasWarnings(report: ConflictReport): boolean;
|
|
135
|
+
declare function buildRedirectMap(bundle: EntityBundle): {
|
|
136
|
+
fromPath: string;
|
|
137
|
+
toPath: string;
|
|
138
|
+
statusCode: number;
|
|
139
|
+
}[];
|
|
140
|
+
declare function detectRedirectLoops(redirects: {
|
|
141
|
+
fromPath: string;
|
|
142
|
+
toPath: string;
|
|
143
|
+
}[]): RedirectLoopConflict[];
|
|
144
|
+
|
|
145
|
+
type MigrationRunMode = "dry-run" | "export" | "sink" | "worker";
|
|
146
|
+
interface MigrationReport {
|
|
147
|
+
runId: string;
|
|
148
|
+
platform: MigrationPlatform;
|
|
149
|
+
mode: MigrationRunMode;
|
|
150
|
+
startedAt: string;
|
|
151
|
+
finishedAt: string;
|
|
152
|
+
summary: {
|
|
153
|
+
posts: number;
|
|
154
|
+
pages: number;
|
|
155
|
+
assets: number;
|
|
156
|
+
portfolios: number;
|
|
157
|
+
categories: number;
|
|
158
|
+
tags: number;
|
|
159
|
+
storageBytesEstimated?: number;
|
|
160
|
+
};
|
|
161
|
+
warnings: string[];
|
|
162
|
+
errors: string[];
|
|
163
|
+
conflicts: ConflictReport;
|
|
164
|
+
redirectMap: {
|
|
165
|
+
fromPath: string;
|
|
166
|
+
toPath: string;
|
|
167
|
+
statusCode: number;
|
|
168
|
+
}[];
|
|
169
|
+
}
|
|
170
|
+
declare function buildMigrationReport(input: {
|
|
171
|
+
platform: MigrationPlatform;
|
|
172
|
+
mode: MigrationRunMode;
|
|
173
|
+
bundle: EntityBundle;
|
|
174
|
+
conflicts: ConflictReport;
|
|
175
|
+
redirectMap: {
|
|
176
|
+
fromPath: string;
|
|
177
|
+
toPath: string;
|
|
178
|
+
statusCode: number;
|
|
179
|
+
}[];
|
|
180
|
+
startedAt: Date;
|
|
181
|
+
finishedAt?: Date;
|
|
182
|
+
storageBytesEstimated?: number;
|
|
183
|
+
warnings?: string[];
|
|
184
|
+
errors?: string[];
|
|
185
|
+
runId?: string;
|
|
186
|
+
}): MigrationReport;
|
|
187
|
+
|
|
188
|
+
interface WriteFilesystemOptions {
|
|
189
|
+
outDir: string;
|
|
190
|
+
bundle: EntityBundle;
|
|
191
|
+
conflicts?: ConflictReport;
|
|
192
|
+
report?: MigrationReport;
|
|
193
|
+
}
|
|
194
|
+
declare function writeFilesystemExport(options: WriteFilesystemOptions): Promise<void>;
|
|
195
|
+
declare function bundleToCombinedJson(bundle: EntityBundle): Record<string, unknown>;
|
|
196
|
+
|
|
197
|
+
/** Reference MigrationSink that accumulates entities and writes M0 JSON bundles. */
|
|
198
|
+
declare class FilesystemMigrationSink implements MigrationSink {
|
|
199
|
+
readonly bundle: EntityBundle;
|
|
200
|
+
readonly portfolioMediaLinks: PortfolioMediaLink[];
|
|
201
|
+
readonly redirects: MigrationRedirect[];
|
|
202
|
+
createCategory(category: NormalizedCategory): Promise<{
|
|
203
|
+
targetId: string;
|
|
204
|
+
}>;
|
|
205
|
+
createTag(tag: NormalizedTag): Promise<{
|
|
206
|
+
targetId: string;
|
|
207
|
+
}>;
|
|
208
|
+
uploadAsset(input: UploadAssetInput): Promise<UploadAssetResult>;
|
|
209
|
+
createPortfolio(portfolio: NormalizedPortfolio): Promise<{
|
|
210
|
+
targetId: string;
|
|
211
|
+
}>;
|
|
212
|
+
createPost(post: NormalizedPost): Promise<CreatePostResult>;
|
|
213
|
+
createPage(page: NormalizedPage): Promise<CreatePageResult>;
|
|
214
|
+
linkPortfolioMedia(link: PortfolioMediaLink): Promise<void>;
|
|
215
|
+
writeRedirect(redirect: MigrationRedirect): Promise<void>;
|
|
216
|
+
flush(options: WriteFilesystemOptions): Promise<void>;
|
|
217
|
+
}
|
|
218
|
+
declare function createFilesystemMigrationSink(): FilesystemMigrationSink;
|
|
219
|
+
/** Verify sink-produced M2M links match bundle-derived index. */
|
|
220
|
+
declare function portfolioMediaMatchesBundle(sink: FilesystemMigrationSink): boolean;
|
|
221
|
+
|
|
222
|
+
interface DryRunOptions {
|
|
223
|
+
adapter: MigrationAdapter;
|
|
224
|
+
input: unknown;
|
|
225
|
+
platform: MigrationPlatform;
|
|
226
|
+
offlineStorageEstimate?: boolean;
|
|
227
|
+
fetchFn?: typeof fetch;
|
|
228
|
+
}
|
|
229
|
+
interface DryRunResult {
|
|
230
|
+
bundle: EntityBundle;
|
|
231
|
+
conflicts: ConflictReport;
|
|
232
|
+
report: MigrationReport;
|
|
233
|
+
exitCode: 0 | 1 | 2;
|
|
234
|
+
}
|
|
235
|
+
declare function runDryRun(options: DryRunOptions): Promise<DryRunResult>;
|
|
236
|
+
|
|
237
|
+
declare const FALLBACK_ASSET_BYTES: number;
|
|
238
|
+
interface AssetSizeResult {
|
|
239
|
+
sourceId: string;
|
|
240
|
+
url: string;
|
|
241
|
+
bytes: number;
|
|
242
|
+
source: "head" | "fallback";
|
|
243
|
+
error?: string;
|
|
244
|
+
}
|
|
245
|
+
interface StorageEstimate {
|
|
246
|
+
totalBytes: number;
|
|
247
|
+
assets: AssetSizeResult[];
|
|
248
|
+
}
|
|
249
|
+
interface EstimateStorageOptions {
|
|
250
|
+
assets: NormalizedAsset[];
|
|
251
|
+
/** When true, skip network and use fallback for all assets. */
|
|
252
|
+
offline?: boolean;
|
|
253
|
+
fetchFn?: typeof fetch;
|
|
254
|
+
}
|
|
255
|
+
declare function estimateStorage(options: EstimateStorageOptions): Promise<StorageEstimate>;
|
|
256
|
+
declare function staleUrlsFromEstimate(estimate: StorageEstimate): {
|
|
257
|
+
sourceId: string;
|
|
258
|
+
url: string;
|
|
259
|
+
reason: string;
|
|
260
|
+
}[];
|
|
261
|
+
|
|
262
|
+
export { type ConflictReport, type DryRunOptions, type DryRunResult, FALLBACK_ASSET_BYTES, FilesystemMigrationSink, MIGRATION_WRITE_STAGES, type MigrationRedirect, type MigrationReport, type MigrationRunMode, type MigrationRunOptions, type MigrationRunResult, type MigrationSink, type MigrationWriteStage, RewriteInlineImagesOptions, type StorageEstimate, type UploadAssetInput, type UploadAssetResult, type WriteFilesystemOptions, analyzeConflicts, buildMigrationReport, buildRedirectMap, bundleToCombinedJson, createFilesystemMigrationSink, detectRedirectLoops, emptyConflictReport, estimateStorage, hasBlockingConflicts, hasWarnings, portfolioMediaMatchesBundle, runDryRun, runMigration, runMigrationFromBundle, staleUrlsFromEstimate, writeFilesystemExport };
|
package/dist/sinks/index.js
CHANGED
|
@@ -13,15 +13,17 @@ import {
|
|
|
13
13
|
hasBlockingConflicts,
|
|
14
14
|
hasWarnings,
|
|
15
15
|
portfolioMediaMatchesBundle,
|
|
16
|
-
rewriteInlineImages,
|
|
17
16
|
runDryRun,
|
|
18
17
|
runMigration,
|
|
19
18
|
runMigrationFromBundle,
|
|
20
19
|
staleUrlsFromEstimate,
|
|
21
20
|
writeFilesystemExport
|
|
22
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-IPYHS5R2.js";
|
|
23
22
|
import "../chunk-HI7JHWZU.js";
|
|
24
|
-
import
|
|
23
|
+
import {
|
|
24
|
+
rewriteInlineImages
|
|
25
|
+
} from "../chunk-EXYXTAZM.js";
|
|
26
|
+
import "../chunk-XYP3VYDH.js";
|
|
25
27
|
export {
|
|
26
28
|
FALLBACK_ASSET_BYTES,
|
|
27
29
|
FilesystemMigrationSink,
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { l as ValidationResult } from '../types-DWOP8Dcy.js';
|
|
3
|
+
export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, U as UploadedAssetRef, r as rewriteInlineImages } from '../rewrite-inline-images-DPoxyzVC.js';
|
|
4
|
+
|
|
5
|
+
type LayoutKind = "section" | "row" | "column";
|
|
6
|
+
/** Map OSS-2 `data-layout` markers to Grapes component types (host may override). */
|
|
7
|
+
interface LayoutTypeMap {
|
|
8
|
+
section?: string;
|
|
9
|
+
row?: string;
|
|
10
|
+
column?: string;
|
|
11
|
+
}
|
|
12
|
+
interface HtmlToGrapesOptions {
|
|
13
|
+
/** Map source class names to Grapes component types. */
|
|
14
|
+
componentMap?: Record<string, string>;
|
|
15
|
+
/** Map HTML tag names to Grapes component types (e.g. `h2` → `heading`). */
|
|
16
|
+
tagMap?: Record<string, string>;
|
|
17
|
+
/** Map `data-layout` section/row/column markers to Grapes component types. */
|
|
18
|
+
layoutTypeMap?: LayoutTypeMap;
|
|
19
|
+
}
|
|
20
|
+
interface GrapesStyleRule {
|
|
21
|
+
selectors: string[];
|
|
22
|
+
style: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
interface GrapesComponent {
|
|
25
|
+
type: string;
|
|
26
|
+
tagName?: string;
|
|
27
|
+
attributes?: Record<string, string>;
|
|
28
|
+
classes?: string[];
|
|
29
|
+
components?: GrapesComponent[];
|
|
30
|
+
content?: string;
|
|
31
|
+
void?: boolean;
|
|
32
|
+
}
|
|
33
|
+
interface GrapesProjectSnapshot {
|
|
34
|
+
content: GrapesComponent[];
|
|
35
|
+
styles: GrapesStyleRule[];
|
|
36
|
+
contentHtml?: string;
|
|
37
|
+
contentCss?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Cheerio HTML walk → Grapes `content` + root `styles`. */
|
|
41
|
+
declare function htmlToGrapes(html: string, options?: HtmlToGrapesOptions): GrapesProjectSnapshot;
|
|
42
|
+
|
|
43
|
+
/** ProseMirror / Tiptap mark (inline formatting). */
|
|
44
|
+
interface TiptapMark {
|
|
45
|
+
type: string;
|
|
46
|
+
attrs?: Record<string, string>;
|
|
47
|
+
}
|
|
48
|
+
/** ProseMirror / Tiptap node — text nodes use `text`; others use `content`. */
|
|
49
|
+
interface TiptapNode {
|
|
50
|
+
type: string;
|
|
51
|
+
attrs?: Record<string, unknown>;
|
|
52
|
+
content?: TiptapNode[];
|
|
53
|
+
marks?: TiptapMark[];
|
|
54
|
+
text?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Root Tiptap document (`content_json` shape). */
|
|
57
|
+
interface TiptapDoc {
|
|
58
|
+
type: "doc";
|
|
59
|
+
content: TiptapNode[];
|
|
60
|
+
}
|
|
61
|
+
interface HtmlToTiptapOptions {
|
|
62
|
+
/**
|
|
63
|
+
* Unwrap OSS-2 `data-layout` scaffolding (section/row/column divs) into prose blocks.
|
|
64
|
+
* @default true
|
|
65
|
+
*/
|
|
66
|
+
unwrapLayoutMarkers?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Cheerio HTML walk → Tiptap / ProseMirror `doc` JSON for blog `content_json`. */
|
|
70
|
+
declare function htmlToTiptap(html: string, options?: HtmlToTiptapOptions): TiptapDoc;
|
|
71
|
+
|
|
72
|
+
/** Parse `<style>` blocks and class rules into Grapes root `styles[]`. */
|
|
73
|
+
declare function cssToStyles(css: string): GrapesStyleRule[];
|
|
74
|
+
|
|
75
|
+
declare const grapesStyleRuleSchema: z.ZodObject<{
|
|
76
|
+
selectors: z.ZodArray<z.ZodString, "many">;
|
|
77
|
+
style: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
78
|
+
}, "strip", z.ZodTypeAny, {
|
|
79
|
+
style: Record<string, string>;
|
|
80
|
+
selectors: string[];
|
|
81
|
+
}, {
|
|
82
|
+
style: Record<string, string>;
|
|
83
|
+
selectors: string[];
|
|
84
|
+
}>;
|
|
85
|
+
declare const grapesComponentSchema: z.ZodType<GrapesComponent>;
|
|
86
|
+
declare const grapesProjectSnapshotSchema: z.ZodObject<{
|
|
87
|
+
content: z.ZodArray<z.ZodType<GrapesComponent, z.ZodTypeDef, GrapesComponent>, "many">;
|
|
88
|
+
styles: z.ZodArray<z.ZodObject<{
|
|
89
|
+
selectors: z.ZodArray<z.ZodString, "many">;
|
|
90
|
+
style: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
91
|
+
}, "strip", z.ZodTypeAny, {
|
|
92
|
+
style: Record<string, string>;
|
|
93
|
+
selectors: string[];
|
|
94
|
+
}, {
|
|
95
|
+
style: Record<string, string>;
|
|
96
|
+
selectors: string[];
|
|
97
|
+
}>, "many">;
|
|
98
|
+
contentHtml: z.ZodOptional<z.ZodString>;
|
|
99
|
+
contentCss: z.ZodOptional<z.ZodString>;
|
|
100
|
+
}, "strip", z.ZodTypeAny, {
|
|
101
|
+
content: GrapesComponent[];
|
|
102
|
+
styles: {
|
|
103
|
+
style: Record<string, string>;
|
|
104
|
+
selectors: string[];
|
|
105
|
+
}[];
|
|
106
|
+
contentHtml?: string | undefined;
|
|
107
|
+
contentCss?: string | undefined;
|
|
108
|
+
}, {
|
|
109
|
+
content: GrapesComponent[];
|
|
110
|
+
styles: {
|
|
111
|
+
style: Record<string, string>;
|
|
112
|
+
selectors: string[];
|
|
113
|
+
}[];
|
|
114
|
+
contentHtml?: string | undefined;
|
|
115
|
+
contentCss?: string | undefined;
|
|
116
|
+
}>;
|
|
117
|
+
interface ValidateGrapesProjectSnapshotOptions {
|
|
118
|
+
/** When set, every component `type` in the tree must be in this allowlist. */
|
|
119
|
+
allowedComponentTypes?: string[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Opt-in structural check for a Grapes project snapshot (not a full Grapes editor project file).
|
|
123
|
+
* Does not validate host-specific component registries unless `allowedComponentTypes` is passed.
|
|
124
|
+
*/
|
|
125
|
+
declare function validateGrapesProjectSnapshot(snapshot: unknown, options?: ValidateGrapesProjectSnapshotOptions): ValidationResult;
|
|
126
|
+
|
|
127
|
+
declare const tiptapMarkSchema: z.ZodObject<{
|
|
128
|
+
type: z.ZodString;
|
|
129
|
+
attrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
130
|
+
}, "strip", z.ZodTypeAny, {
|
|
131
|
+
type: string;
|
|
132
|
+
attrs?: Record<string, string> | undefined;
|
|
133
|
+
}, {
|
|
134
|
+
type: string;
|
|
135
|
+
attrs?: Record<string, string> | undefined;
|
|
136
|
+
}>;
|
|
137
|
+
declare const tiptapNodeSchema: z.ZodType<TiptapNode>;
|
|
138
|
+
declare const tiptapDocSchema: z.ZodObject<{
|
|
139
|
+
type: z.ZodLiteral<"doc">;
|
|
140
|
+
content: z.ZodArray<z.ZodType<TiptapNode, z.ZodTypeDef, TiptapNode>, "many">;
|
|
141
|
+
}, "strip", z.ZodTypeAny, {
|
|
142
|
+
type: "doc";
|
|
143
|
+
content: TiptapNode[];
|
|
144
|
+
}, {
|
|
145
|
+
type: "doc";
|
|
146
|
+
content: TiptapNode[];
|
|
147
|
+
}>;
|
|
148
|
+
interface ValidateTiptapDocOptions {
|
|
149
|
+
/** When set, every node `type` in the tree must be in this allowlist. */
|
|
150
|
+
allowedNodeTypes?: string[];
|
|
151
|
+
/** When set, every mark `type` must be in this allowlist. */
|
|
152
|
+
allowedMarkTypes?: string[];
|
|
153
|
+
}
|
|
154
|
+
/** Opt-in structural check for a Tiptap / ProseMirror document. */
|
|
155
|
+
declare function validateTiptapDoc(doc: unknown, options?: ValidateTiptapDocOptions): ValidationResult;
|
|
156
|
+
|
|
157
|
+
export { type GrapesComponent, type GrapesProjectSnapshot, type GrapesStyleRule, type HtmlToGrapesOptions, type HtmlToTiptapOptions, type LayoutKind, type LayoutTypeMap, type TiptapDoc, type TiptapMark, type TiptapNode, type ValidateGrapesProjectSnapshotOptions, type ValidateTiptapDocOptions, cssToStyles, grapesComponentSchema, grapesProjectSnapshotSchema, grapesStyleRuleSchema, htmlToGrapes, htmlToTiptap, tiptapDocSchema, tiptapMarkSchema, tiptapNodeSchema, validateGrapesProjectSnapshot, validateTiptapDoc };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cssToStyles,
|
|
3
|
+
grapesComponentSchema,
|
|
4
|
+
grapesProjectSnapshotSchema,
|
|
5
|
+
grapesStyleRuleSchema,
|
|
6
|
+
htmlToGrapes,
|
|
7
|
+
htmlToTiptap,
|
|
8
|
+
tiptapDocSchema,
|
|
9
|
+
tiptapMarkSchema,
|
|
10
|
+
tiptapNodeSchema,
|
|
11
|
+
validateGrapesProjectSnapshot,
|
|
12
|
+
validateTiptapDoc
|
|
13
|
+
} from "../chunk-CIOYDRY5.js";
|
|
14
|
+
import {
|
|
15
|
+
rewriteInlineImages
|
|
16
|
+
} from "../chunk-EXYXTAZM.js";
|
|
17
|
+
import "../chunk-XYP3VYDH.js";
|
|
18
|
+
export {
|
|
19
|
+
cssToStyles,
|
|
20
|
+
grapesComponentSchema,
|
|
21
|
+
grapesProjectSnapshotSchema,
|
|
22
|
+
grapesStyleRuleSchema,
|
|
23
|
+
htmlToGrapes,
|
|
24
|
+
htmlToTiptap,
|
|
25
|
+
rewriteInlineImages,
|
|
26
|
+
tiptapDocSchema,
|
|
27
|
+
tiptapMarkSchema,
|
|
28
|
+
tiptapNodeSchema,
|
|
29
|
+
validateGrapesProjectSnapshot,
|
|
30
|
+
validateTiptapDoc
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -130,24 +130,4 @@ interface EntityKey {
|
|
|
130
130
|
}
|
|
131
131
|
declare function entityKey(entity: NormalizedEntity, platform: MigrationPlatform): EntityKey;
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
posts: NormalizedPost[];
|
|
135
|
-
pages: NormalizedPage[];
|
|
136
|
-
media: NormalizedAsset[];
|
|
137
|
-
portfolios: NormalizedPortfolio[];
|
|
138
|
-
categories: NormalizedCategory[];
|
|
139
|
-
tags: NormalizedTag[];
|
|
140
|
-
}
|
|
141
|
-
declare function emptyBundle(): EntityBundle;
|
|
142
|
-
declare function collectEntities(entities: AsyncIterable<NormalizedEntity>): Promise<EntityBundle>;
|
|
143
|
-
interface BundleCounts {
|
|
144
|
-
posts: number;
|
|
145
|
-
pages: number;
|
|
146
|
-
assets: number;
|
|
147
|
-
portfolios: number;
|
|
148
|
-
categories: number;
|
|
149
|
-
tags: number;
|
|
150
|
-
}
|
|
151
|
-
declare function bundleCounts(bundle: EntityBundle): BundleCounts;
|
|
152
|
-
|
|
153
|
-
export { type AdapterContext as A, type BundleCounts as B, type EntityBundle as E, type MigrationAdapter as M, type NormalizedAsset as N, type PortfolioMediaLink as P, type SourceMetadata as S, type ValidationResult as V, type MigrationPlatform as a, type EntityKey as b, type EntityType as c, type MigrationCursor as d, type NormalizedAssetExif as e, type NormalizedCategory as f, type NormalizedEntity as g, type NormalizedPage as h, type NormalizedPortfolio as i, type NormalizedPost as j, type NormalizedTag as k, type PublishStatus as l, type ValidationIssue as m, bundleCounts as n, collectEntities as o, emptyBundle as p, entityKey as q };
|
|
133
|
+
export { type AdapterContext as A, type EntityKey as E, type MigrationAdapter as M, type NormalizedPost as N, type PortfolioMediaLink as P, type SourceMetadata as S, type ValidationIssue as V, type NormalizedPage as a, type NormalizedAsset as b, type NormalizedPortfolio as c, type NormalizedCategory as d, type NormalizedTag as e, type NormalizedEntity as f, type MigrationPlatform as g, type EntityType as h, type MigrationCursor as i, type NormalizedAssetExif as j, type PublishStatus as k, type ValidationResult as l, entityKey as m };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artinstack/migrator",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Stateless content normalizer and migration framework — WordPress, SmugMug, Squarespace → platform-agnostic schema",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ArtInStack",
|
|
@@ -46,6 +46,10 @@
|
|
|
46
46
|
"./lib": {
|
|
47
47
|
"types": "./dist/lib/index.d.ts",
|
|
48
48
|
"import": "./dist/lib/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./transformers": {
|
|
51
|
+
"types": "./dist/transformers/index.d.ts",
|
|
52
|
+
"import": "./dist/transformers/index.js"
|
|
49
53
|
}
|
|
50
54
|
},
|
|
51
55
|
"bin": {
|
package/dist/chunk-2PNSVE5Y.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
// src/lib/content-asset-urls.ts
|
|
2
|
-
import * as cheerio from "cheerio";
|
|
3
|
-
var ASSET_URL_PARAM_PATTERN = /\b(?:src|image|url)\s*=\s*["']([^"']+)["']/gi;
|
|
4
|
-
var IMAGE_EXTENSION_PATTERN = /\.(?:jpe?g|png|gif|webp|avif|svg)(?:[?#]|$)/i;
|
|
5
|
-
var WP_UPLOADS_PATTERN = /\/wp-content\/uploads\//i;
|
|
6
|
-
function extractImgTagSrcs(content) {
|
|
7
|
-
if (!content.trim()) return [];
|
|
8
|
-
const $ = cheerio.load(content, { xml: false });
|
|
9
|
-
const srcs = [];
|
|
10
|
-
$("img[src]").each((_, el) => {
|
|
11
|
-
const src = $(el).attr("src")?.trim();
|
|
12
|
-
if (src) srcs.push(src);
|
|
13
|
-
});
|
|
14
|
-
return srcs;
|
|
15
|
-
}
|
|
16
|
-
function discoverRawImgSrcs(content) {
|
|
17
|
-
return extractImgTagSrcs(content).filter((src) => !src.startsWith("data:"));
|
|
18
|
-
}
|
|
19
|
-
function normalizeAssetUrl(raw) {
|
|
20
|
-
const trimmed = raw.trim();
|
|
21
|
-
if (!trimmed || trimmed.startsWith("data:")) return void 0;
|
|
22
|
-
if (trimmed.startsWith("//")) return `https:${trimmed}`;
|
|
23
|
-
return trimmed;
|
|
24
|
-
}
|
|
25
|
-
function isLikelyImageUrl(url) {
|
|
26
|
-
if (!url || url.startsWith("data:")) return false;
|
|
27
|
-
if (url.startsWith("/")) {
|
|
28
|
-
return WP_UPLOADS_PATTERN.test(url) || IMAGE_EXTENSION_PATTERN.test(url);
|
|
29
|
-
}
|
|
30
|
-
if (!/^https?:\/\//i.test(url)) return false;
|
|
31
|
-
if (WP_UPLOADS_PATTERN.test(url)) return true;
|
|
32
|
-
try {
|
|
33
|
-
const pathname = new URL(url).pathname;
|
|
34
|
-
return IMAGE_EXTENSION_PATTERN.test(pathname);
|
|
35
|
-
} catch {
|
|
36
|
-
return IMAGE_EXTENSION_PATTERN.test(url);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function discoverContentAssetUrls(content) {
|
|
40
|
-
if (!content.trim()) return [];
|
|
41
|
-
const urls = /* @__PURE__ */ new Set();
|
|
42
|
-
for (const raw of extractImgTagSrcs(content)) {
|
|
43
|
-
const normalized = normalizeAssetUrl(raw);
|
|
44
|
-
if (normalized && isLikelyImageUrl(normalized)) {
|
|
45
|
-
urls.add(normalized);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
for (const match of content.matchAll(ASSET_URL_PARAM_PATTERN)) {
|
|
49
|
-
const normalized = normalizeAssetUrl(match[1] ?? "");
|
|
50
|
-
if (normalized && isLikelyImageUrl(normalized)) {
|
|
51
|
-
urls.add(normalized);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return [...urls];
|
|
55
|
-
}
|
|
56
|
-
function extractInlineImageSrcs(content) {
|
|
57
|
-
return discoverContentAssetUrls(content);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export {
|
|
61
|
-
discoverRawImgSrcs,
|
|
62
|
-
normalizeAssetUrl,
|
|
63
|
-
isLikelyImageUrl,
|
|
64
|
-
discoverContentAssetUrls,
|
|
65
|
-
extractInlineImageSrcs
|
|
66
|
-
};
|
|
67
|
-
//# sourceMappingURL=chunk-2PNSVE5Y.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/content-asset-urls.ts"],"sourcesContent":["import * as cheerio from \"cheerio\";\n\n/** Builder-agnostic attribute names that commonly hold image URLs in post_content. */\nconst ASSET_URL_PARAM_PATTERN =\n /\\b(?:src|image|url)\\s*=\\s*[\"']([^\"']+)[\"']/gi;\n\nconst IMAGE_EXTENSION_PATTERN = /\\.(?:jpe?g|png|gif|webp|avif|svg)(?:[?#]|$)/i;\nconst WP_UPLOADS_PATTERN = /\\/wp-content\\/uploads\\//i;\n\nfunction extractImgTagSrcs(content: string): string[] {\n if (!content.trim()) return [];\n const $ = cheerio.load(content, { xml: false });\n const srcs: string[] = [];\n $(\"img[src]\").each((_, el) => {\n const src = $(el).attr(\"src\")?.trim();\n if (src) srcs.push(src);\n });\n return srcs;\n}\n\n/** All `<img src>` values (including those not ingested as vault assets). */\nexport function discoverRawImgSrcs(content: string): string[] {\n return extractImgTagSrcs(content).filter((src) => !src.startsWith(\"data:\"));\n}\n\n/** Normalize protocol-relative and trim; skip data URIs. */\nexport function normalizeAssetUrl(raw: string): string | undefined {\n const trimmed = raw.trim();\n if (!trimmed || trimmed.startsWith(\"data:\")) return undefined;\n if (trimmed.startsWith(\"//\")) return `https:${trimmed}`;\n return trimmed;\n}\n\n/** Heuristic: URL likely points at a raster/vector image asset, not a page link. */\nexport function isLikelyImageUrl(url: string): boolean {\n if (!url || url.startsWith(\"data:\")) return false;\n\n if (url.startsWith(\"/\")) {\n return WP_UPLOADS_PATTERN.test(url) || IMAGE_EXTENSION_PATTERN.test(url);\n }\n\n if (!/^https?:\\/\\//i.test(url)) return false;\n\n if (WP_UPLOADS_PATTERN.test(url)) return true;\n\n try {\n const pathname = new URL(url).pathname;\n return IMAGE_EXTENSION_PATTERN.test(pathname);\n } catch {\n return IMAGE_EXTENSION_PATTERN.test(url);\n }\n}\n\n/**\n * Generic content-discovery pass: collect image URLs from HTML `<img>` tags and\n * common shortcode/builder attributes (`src=`, `image=`, `url=`) without parsing\n * builder-specific structure (Tatsu, Elementor, etc.).\n */\nexport function discoverContentAssetUrls(content: string): string[] {\n if (!content.trim()) return [];\n\n const urls = new Set<string>();\n\n for (const raw of extractImgTagSrcs(content)) {\n const normalized = normalizeAssetUrl(raw);\n if (normalized && isLikelyImageUrl(normalized)) {\n urls.add(normalized);\n }\n }\n\n for (const match of content.matchAll(ASSET_URL_PARAM_PATTERN)) {\n const normalized = normalizeAssetUrl(match[1] ?? \"\");\n if (normalized && isLikelyImageUrl(normalized)) {\n urls.add(normalized);\n }\n }\n\n return [...urls];\n}\n\n/** @deprecated Use discoverContentAssetUrls — kept for call-site clarity during transition. */\nexport function extractInlineImageSrcs(content: string): string[] {\n return discoverContentAssetUrls(content);\n}\n"],"mappings":";AAAA,YAAY,aAAa;AAGzB,IAAM,0BACJ;AAEF,IAAM,0BAA0B;AAChC,IAAM,qBAAqB;AAE3B,SAAS,kBAAkB,SAA2B;AACpD,MAAI,CAAC,QAAQ,KAAK,EAAG,QAAO,CAAC;AAC7B,QAAM,IAAY,aAAK,SAAS,EAAE,KAAK,MAAM,CAAC;AAC9C,QAAM,OAAiB,CAAC;AACxB,IAAE,UAAU,EAAE,KAAK,CAAC,GAAG,OAAO;AAC5B,UAAM,MAAM,EAAE,EAAE,EAAE,KAAK,KAAK,GAAG,KAAK;AACpC,QAAI,IAAK,MAAK,KAAK,GAAG;AAAA,EACxB,CAAC;AACD,SAAO;AACT;AAGO,SAAS,mBAAmB,SAA2B;AAC5D,SAAO,kBAAkB,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,WAAW,OAAO,CAAC;AAC5E;AAGO,SAAS,kBAAkB,KAAiC;AACjE,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,CAAC,WAAW,QAAQ,WAAW,OAAO,EAAG,QAAO;AACpD,MAAI,QAAQ,WAAW,IAAI,EAAG,QAAO,SAAS,OAAO;AACrD,SAAO;AACT;AAGO,SAAS,iBAAiB,KAAsB;AACrD,MAAI,CAAC,OAAO,IAAI,WAAW,OAAO,EAAG,QAAO;AAE5C,MAAI,IAAI,WAAW,GAAG,GAAG;AACvB,WAAO,mBAAmB,KAAK,GAAG,KAAK,wBAAwB,KAAK,GAAG;AAAA,EACzE;AAEA,MAAI,CAAC,gBAAgB,KAAK,GAAG,EAAG,QAAO;AAEvC,MAAI,mBAAmB,KAAK,GAAG,EAAG,QAAO;AAEzC,MAAI;AACF,UAAM,WAAW,IAAI,IAAI,GAAG,EAAE;AAC9B,WAAO,wBAAwB,KAAK,QAAQ;AAAA,EAC9C,QAAQ;AACN,WAAO,wBAAwB,KAAK,GAAG;AAAA,EACzC;AACF;AAOO,SAAS,yBAAyB,SAA2B;AAClE,MAAI,CAAC,QAAQ,KAAK,EAAG,QAAO,CAAC;AAE7B,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,OAAO,kBAAkB,OAAO,GAAG;AAC5C,UAAM,aAAa,kBAAkB,GAAG;AACxC,QAAI,cAAc,iBAAiB,UAAU,GAAG;AAC9C,WAAK,IAAI,UAAU;AAAA,IACrB;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ,SAAS,uBAAuB,GAAG;AAC7D,UAAM,aAAa,kBAAkB,MAAM,CAAC,KAAK,EAAE;AACnD,QAAI,cAAc,iBAAiB,UAAU,GAAG;AAC9C,WAAK,IAAI,UAAU;AAAA,IACrB;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,IAAI;AACjB;AAGO,SAAS,uBAAuB,SAA2B;AAChE,SAAO,yBAAyB,OAAO;AACzC;","names":[]}
|