@see-ms/converter 1.0.0 → 1.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/README.md +244 -202
- package/dist/cli.mjs +2792 -457
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +246 -12
- package/dist/index.mjs +2783 -356
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ConversionOptions, FieldMapping, CollectionMapping, CMSManifest, StrapiSchema } from '@see-ms/types';
|
|
2
|
-
export { ConversionOptions } from '@see-ms/types';
|
|
1
|
+
import { ConversionOptions, SeeMSConfig, SharedComponent, ConversionReport, FieldMapping, CollectionMapping, CMSManifest, StrapiSchema } from '@see-ms/types';
|
|
2
|
+
export { ConversionOptions, ConversionReport, SeeMSConfig, SharedComponent } from '@see-ms/types';
|
|
3
|
+
import { CheerioAPI, Cheerio } from 'cheerio';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Main conversion logic
|
|
@@ -7,14 +8,120 @@ export { ConversionOptions } from '@see-ms/types';
|
|
|
7
8
|
|
|
8
9
|
declare function convertWebflowExport(options: ConversionOptions): Promise<void>;
|
|
9
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Boilerplate cloning and setup utilities
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Setup boilerplate in output directory
|
|
16
|
+
*/
|
|
17
|
+
type ProjectTarget = 'nuxt' | 'astro-vue';
|
|
18
|
+
declare function setupBoilerplate(boilerplateSource: string | undefined, outputDir: string, target?: ProjectTarget): Promise<void>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* File system utilities for copying Webflow assets
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
interface AssetPaths {
|
|
25
|
+
css: string[];
|
|
26
|
+
images: string[];
|
|
27
|
+
fonts: string[];
|
|
28
|
+
js: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Scan Webflow export directory for assets
|
|
32
|
+
*/
|
|
33
|
+
declare function scanAssets(webflowDir: string): Promise<AssetPaths>;
|
|
34
|
+
|
|
35
|
+
interface PageRouteInfo {
|
|
36
|
+
sourcePath: string;
|
|
37
|
+
pageId: string;
|
|
38
|
+
route: string;
|
|
39
|
+
outputPath: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ConversionAnalysis {
|
|
43
|
+
inputDir: string;
|
|
44
|
+
pages: PageRouteInfo[];
|
|
45
|
+
assets: Awaited<ReturnType<typeof scanAssets>>;
|
|
46
|
+
componentCandidates: SharedComponent[];
|
|
47
|
+
warnings: string[];
|
|
48
|
+
}
|
|
49
|
+
declare function analyzeWebflowExport(inputDir: string, config?: SeeMSConfig): Promise<ConversionAnalysis>;
|
|
50
|
+
declare function createConversionReport(input: {
|
|
51
|
+
analysis: ConversionAnalysis;
|
|
52
|
+
provider: "strapi" | "contentful" | "sanity";
|
|
53
|
+
stages: ConversionReport["stages"];
|
|
54
|
+
components: SharedComponent[];
|
|
55
|
+
fields: number;
|
|
56
|
+
collections: number;
|
|
57
|
+
schemas: number;
|
|
58
|
+
seedPages: number;
|
|
59
|
+
warnings?: string[];
|
|
60
|
+
}): ConversionReport;
|
|
61
|
+
declare function writeConversionReport(outputDir: string, report: ConversionReport): Promise<void>;
|
|
62
|
+
declare function renderReportMarkdown(report: ConversionReport): string;
|
|
63
|
+
|
|
64
|
+
declare function mergeConfig(base?: SeeMSConfig, override?: SeeMSConfig): SeeMSConfig;
|
|
65
|
+
declare function loadSeeMSConfig(configPath?: string): Promise<SeeMSConfig>;
|
|
66
|
+
declare function writeSeeMSConfig(outputDir: string, config: SeeMSConfig): Promise<void>;
|
|
67
|
+
declare function normalizeConfig(config?: SeeMSConfig): SeeMSConfig;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Strapi Complete Setup Script
|
|
71
|
+
* Installs schemas, uploads images, and seeds content - all in one command
|
|
72
|
+
*/
|
|
73
|
+
interface SetupOptions {
|
|
74
|
+
projectDir: string;
|
|
75
|
+
strapiDir: string;
|
|
76
|
+
strapiUrl?: string;
|
|
77
|
+
apiToken?: string;
|
|
78
|
+
ignoreSavedToken?: boolean;
|
|
79
|
+
scaffold?: boolean;
|
|
80
|
+
scaffoldOptions?: StrapiScaffoldOptions;
|
|
81
|
+
}
|
|
82
|
+
interface StrapiScaffoldOptions {
|
|
83
|
+
strapiDir: string;
|
|
84
|
+
packageManager?: "npm" | "pnpm" | "yarn";
|
|
85
|
+
install?: boolean;
|
|
86
|
+
run?: boolean;
|
|
87
|
+
gitInit?: boolean;
|
|
88
|
+
typescript?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Main setup function
|
|
92
|
+
* Exported for use by CLI and direct execution
|
|
93
|
+
*/
|
|
94
|
+
declare function completeSetup(options: SetupOptions): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Scaffold a new Strapi project using the official Strapi create CLI.
|
|
97
|
+
*/
|
|
98
|
+
declare function scaffoldStrapiProject(options: StrapiScaffoldOptions): Promise<void>;
|
|
99
|
+
|
|
10
100
|
/**
|
|
11
101
|
* Auto-detection of editable fields from Vue components
|
|
102
|
+
* Enhanced with universal detection, expanded collection keywords, and data-cms attributes
|
|
12
103
|
*/
|
|
13
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Detection options
|
|
107
|
+
*/
|
|
108
|
+
interface DetectionOptions {
|
|
109
|
+
/** Custom collection classes to detect */
|
|
110
|
+
collectionClasses?: string[];
|
|
111
|
+
/** Minimum items for collection detection */
|
|
112
|
+
collectionMin?: number;
|
|
113
|
+
/** Enable universal detection (default: true) */
|
|
114
|
+
universalDetection?: boolean;
|
|
115
|
+
/** Selectors to ignore */
|
|
116
|
+
ignoreSelectors?: string[];
|
|
117
|
+
/** Classes to ignore */
|
|
118
|
+
ignoreClasses?: string[];
|
|
119
|
+
}
|
|
14
120
|
/**
|
|
15
121
|
* Detect editable fields from Vue template content
|
|
122
|
+
* Universal detection: finds ALL text, images, and links
|
|
16
123
|
*/
|
|
17
|
-
declare function detectEditableFields(templateHtml: string): {
|
|
124
|
+
declare function detectEditableFields(templateHtml: string, options?: DetectionOptions): {
|
|
18
125
|
fields: Record<string, FieldMapping>;
|
|
19
126
|
collections: Record<string, CollectionMapping>;
|
|
20
127
|
};
|
|
@@ -23,12 +130,33 @@ declare function detectEditableFields(templateHtml: string): {
|
|
|
23
130
|
* Manifest generation
|
|
24
131
|
*/
|
|
25
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Manifest generation options
|
|
135
|
+
*/
|
|
136
|
+
interface ManifestOptions {
|
|
137
|
+
/** Custom collection classes to detect */
|
|
138
|
+
collectionClasses?: string[];
|
|
139
|
+
/** Mapping of collection class names to display names */
|
|
140
|
+
collectionNames?: Record<string, string>;
|
|
141
|
+
/** Shared components extracted during conversion */
|
|
142
|
+
sharedComponents?: SharedComponent[];
|
|
143
|
+
/** Directory containing extracted shared Vue components */
|
|
144
|
+
componentsDir?: string;
|
|
145
|
+
/** Selectors to ignore during field detection */
|
|
146
|
+
ignoreSelectors?: string[];
|
|
147
|
+
/** Classes to ignore during field detection */
|
|
148
|
+
ignoreClasses?: string[];
|
|
149
|
+
/** CMS provider */
|
|
150
|
+
provider?: 'strapi' | 'contentful' | 'sanity';
|
|
151
|
+
/** Route lookup by page id */
|
|
152
|
+
pageRoutes?: Record<string, string>;
|
|
153
|
+
}
|
|
26
154
|
/**
|
|
27
155
|
* Generate CMS manifest from analyzed pages
|
|
28
156
|
*/
|
|
29
|
-
declare function generateManifest(pagesDir: string): Promise<CMSManifest>;
|
|
157
|
+
declare function generateManifest(pagesDir: string, options?: ManifestOptions): Promise<CMSManifest>;
|
|
30
158
|
/**
|
|
31
|
-
* Read manifest from file
|
|
159
|
+
* Read manifest from file (from public directory)
|
|
32
160
|
*/
|
|
33
161
|
declare function readManifest(outputDir: string): Promise<CMSManifest>;
|
|
34
162
|
|
|
@@ -43,26 +171,132 @@ declare function generateSchemas(_manifestPath: string, _cmsType: string): Promi
|
|
|
43
171
|
* Transform CMS manifest to Strapi schemas
|
|
44
172
|
*/
|
|
45
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Link component schema for Strapi
|
|
176
|
+
* This is a shared component that represents a link with URL and text
|
|
177
|
+
*/
|
|
178
|
+
declare const LINK_COMPONENT_SCHEMA: {
|
|
179
|
+
collectionName: string;
|
|
180
|
+
info: {
|
|
181
|
+
displayName: string;
|
|
182
|
+
icon: string;
|
|
183
|
+
description: string;
|
|
184
|
+
};
|
|
185
|
+
options: {};
|
|
186
|
+
attributes: {
|
|
187
|
+
url: {
|
|
188
|
+
type: "string";
|
|
189
|
+
required: boolean;
|
|
190
|
+
};
|
|
191
|
+
text: {
|
|
192
|
+
type: "string";
|
|
193
|
+
required: boolean;
|
|
194
|
+
};
|
|
195
|
+
newTab: {
|
|
196
|
+
type: "boolean";
|
|
197
|
+
default: boolean;
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
};
|
|
46
201
|
/**
|
|
47
202
|
* Transform entire manifest to Strapi schemas
|
|
203
|
+
* Returns content type schemas and optionally the link component schema
|
|
48
204
|
*/
|
|
49
205
|
declare function manifestToSchemas(manifest: CMSManifest): Record<string, StrapiSchema>;
|
|
206
|
+
/**
|
|
207
|
+
* Get the link component schema if needed
|
|
208
|
+
*/
|
|
209
|
+
declare function getLinkComponentSchema(manifest: CMSManifest): typeof LINK_COMPONENT_SCHEMA | null;
|
|
50
210
|
|
|
51
211
|
/**
|
|
52
|
-
*
|
|
212
|
+
* Transform static Vue files to use reactive content from Strapi
|
|
53
213
|
*/
|
|
214
|
+
|
|
54
215
|
/**
|
|
55
|
-
*
|
|
216
|
+
* Transform all Vue pages in a directory
|
|
56
217
|
*/
|
|
57
|
-
declare function
|
|
218
|
+
declare function transformAllVuePages(pagesDir: string, manifest: CMSManifest, options?: {
|
|
219
|
+
target?: "nuxt" | "astro-vue";
|
|
220
|
+
}): Promise<void>;
|
|
58
221
|
|
|
59
222
|
/**
|
|
60
|
-
*
|
|
223
|
+
* Component Extractor
|
|
224
|
+
* Detects reused HTML sections across pages and extracts them as Vue components
|
|
61
225
|
*/
|
|
62
226
|
|
|
63
227
|
/**
|
|
64
|
-
*
|
|
228
|
+
* Parsed page with its HTML content
|
|
229
|
+
*/
|
|
230
|
+
interface ParsedPage {
|
|
231
|
+
name: string;
|
|
232
|
+
filePath: string;
|
|
233
|
+
sourcePath: string;
|
|
234
|
+
$: CheerioAPI;
|
|
235
|
+
sections: SectionInfo[];
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Information about a section in a page
|
|
239
|
+
*/
|
|
240
|
+
interface SectionInfo {
|
|
241
|
+
/** CSS selector for the section */
|
|
242
|
+
selector: string;
|
|
243
|
+
/** Structural fingerprint (hash of DOM structure) */
|
|
244
|
+
fingerprint: string;
|
|
245
|
+
/** Exact-ish HTML fingerprint with normalized volatile attributes */
|
|
246
|
+
exactFingerprint: string;
|
|
247
|
+
/** Cheerio element reference */
|
|
248
|
+
$element: Cheerio<any>;
|
|
249
|
+
/** Original HTML content */
|
|
250
|
+
html: string;
|
|
251
|
+
/** Suggested component name */
|
|
252
|
+
suggestedName: string;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Extracted component ready to be written
|
|
256
|
+
*/
|
|
257
|
+
interface ExtractedComponent {
|
|
258
|
+
name: string;
|
|
259
|
+
selector: string;
|
|
260
|
+
pages: string[];
|
|
261
|
+
html: string;
|
|
262
|
+
fingerprint: string;
|
|
263
|
+
confidence: "high" | "medium" | "low";
|
|
264
|
+
reason: string;
|
|
265
|
+
role?: "shared-section" | "collection-item";
|
|
266
|
+
collectionName?: string;
|
|
267
|
+
collectionStorage?: "collection-type" | "page-repeatable" | "global-repeatable";
|
|
268
|
+
contentMode?: "shared-global" | "per-page" | "auto";
|
|
269
|
+
}
|
|
270
|
+
interface ComponentExtractionOptions {
|
|
271
|
+
match?: "exact" | "structure";
|
|
272
|
+
minOccurrences?: number;
|
|
273
|
+
minPages?: number;
|
|
274
|
+
minSectionSize?: number;
|
|
275
|
+
writeConfidence?: "high" | "medium" | "low";
|
|
276
|
+
include?: string[];
|
|
277
|
+
exclude?: string[];
|
|
278
|
+
rules?: Array<{
|
|
279
|
+
name: string;
|
|
280
|
+
selector: string;
|
|
281
|
+
role?: "shared-section" | "collection-item";
|
|
282
|
+
collectionName?: string;
|
|
283
|
+
collectionStorage?: "collection-type" | "page-repeatable" | "global-repeatable";
|
|
284
|
+
contentMode?: "shared-global" | "per-page" | "auto";
|
|
285
|
+
minOccurrences?: number;
|
|
286
|
+
minPages?: number;
|
|
287
|
+
}>;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Parse all HTML files in a directory
|
|
291
|
+
*/
|
|
292
|
+
declare function parseAllPages(inputDir: string, options?: Pick<ComponentExtractionOptions, "minSectionSize">): Promise<ParsedPage[]>;
|
|
293
|
+
/**
|
|
294
|
+
* Find shared sections across pages (appear in 2+ pages with similar structure)
|
|
295
|
+
*/
|
|
296
|
+
declare function findSharedSections(pages: ParsedPage[], options?: Pick<ComponentExtractionOptions, "match" | "minOccurrences" | "minPages" | "include" | "exclude" | "rules">): ExtractedComponent[];
|
|
297
|
+
/**
|
|
298
|
+
* Main entry point: extract shared components from HTML pages
|
|
65
299
|
*/
|
|
66
|
-
declare function
|
|
300
|
+
declare function extractSharedComponents(inputDir: string, outputDir: string, options?: ComponentExtractionOptions): Promise<SharedComponent[]>;
|
|
67
301
|
|
|
68
|
-
export { convertWebflowExport, detectEditableFields, generateManifest, generateSchemas, manifestToSchemas, readManifest, setupBoilerplate, transformAllVuePages };
|
|
302
|
+
export { LINK_COMPONENT_SCHEMA, analyzeWebflowExport, completeSetup, convertWebflowExport, createConversionReport, detectEditableFields, extractSharedComponents, findSharedSections, generateManifest, generateSchemas, getLinkComponentSchema, loadSeeMSConfig, manifestToSchemas, mergeConfig, normalizeConfig, parseAllPages, readManifest, renderReportMarkdown, scaffoldStrapiProject, setupBoilerplate, transformAllVuePages, writeConversionReport, writeSeeMSConfig };
|