@reverso/scanner 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.
Files changed (58) hide show
  1. package/README.md +45 -0
  2. package/dist/index.d.ts +40 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +45 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/output/index.d.ts +6 -0
  7. package/dist/output/index.d.ts.map +1 -0
  8. package/dist/output/index.js +6 -0
  9. package/dist/output/index.js.map +1 -0
  10. package/dist/output/json-writer.d.ts +32 -0
  11. package/dist/output/json-writer.d.ts.map +1 -0
  12. package/dist/output/json-writer.js +169 -0
  13. package/dist/output/json-writer.js.map +1 -0
  14. package/dist/output/types-writer.d.ts +24 -0
  15. package/dist/output/types-writer.d.ts.map +1 -0
  16. package/dist/output/types-writer.js +209 -0
  17. package/dist/output/types-writer.js.map +1 -0
  18. package/dist/parser/ast-parser.d.ts +79 -0
  19. package/dist/parser/ast-parser.d.ts.map +1 -0
  20. package/dist/parser/ast-parser.js +201 -0
  21. package/dist/parser/ast-parser.js.map +1 -0
  22. package/dist/parser/attribute-extractor.d.ts +29 -0
  23. package/dist/parser/attribute-extractor.d.ts.map +1 -0
  24. package/dist/parser/attribute-extractor.js +204 -0
  25. package/dist/parser/attribute-extractor.js.map +1 -0
  26. package/dist/parser/index.d.ts +7 -0
  27. package/dist/parser/index.d.ts.map +1 -0
  28. package/dist/parser/index.js +7 -0
  29. package/dist/parser/index.js.map +1 -0
  30. package/dist/parser/jsx-walker.d.ts +31 -0
  31. package/dist/parser/jsx-walker.d.ts.map +1 -0
  32. package/dist/parser/jsx-walker.js +103 -0
  33. package/dist/parser/jsx-walker.js.map +1 -0
  34. package/dist/scanner.d.ts +101 -0
  35. package/dist/scanner.d.ts.map +1 -0
  36. package/dist/scanner.js +204 -0
  37. package/dist/scanner.js.map +1 -0
  38. package/dist/schema/generator.d.ts +22 -0
  39. package/dist/schema/generator.d.ts.map +1 -0
  40. package/dist/schema/generator.js +176 -0
  41. package/dist/schema/generator.js.map +1 -0
  42. package/dist/schema/index.d.ts +6 -0
  43. package/dist/schema/index.d.ts.map +1 -0
  44. package/dist/schema/index.js +6 -0
  45. package/dist/schema/index.js.map +1 -0
  46. package/dist/schema/normalizer.d.ts +45 -0
  47. package/dist/schema/normalizer.d.ts.map +1 -0
  48. package/dist/schema/normalizer.js +165 -0
  49. package/dist/schema/normalizer.js.map +1 -0
  50. package/dist/watch/index.d.ts +5 -0
  51. package/dist/watch/index.d.ts.map +1 -0
  52. package/dist/watch/index.js +5 -0
  53. package/dist/watch/index.js.map +1 -0
  54. package/dist/watch/watcher.d.ts +82 -0
  55. package/dist/watch/watcher.d.ts.map +1 -0
  56. package/dist/watch/watcher.js +141 -0
  57. package/dist/watch/watcher.js.map +1 -0
  58. package/package.json +62 -0
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Walks through JSX elements in a source file to find data-reverso markers.
3
+ */
4
+ import { SyntaxKind, } from 'ts-morph';
5
+ import { extractAttributes, getElementTextContent, hasReversoMarker, } from './attribute-extractor.js';
6
+ /**
7
+ * Walk through all JSX elements in a source file and detect fields.
8
+ */
9
+ export function walkJsxElements(sourceFile, options = {}) {
10
+ const fields = [];
11
+ const filePath = sourceFile.getFilePath();
12
+ // Get all JSX opening elements
13
+ const openingElements = sourceFile.getDescendantsOfKind(SyntaxKind.JsxOpeningElement);
14
+ for (const element of openingElements) {
15
+ const field = processElement(element, filePath, options);
16
+ if (field) {
17
+ fields.push(field);
18
+ }
19
+ }
20
+ // Get all self-closing JSX elements
21
+ const selfClosingElements = sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement);
22
+ for (const element of selfClosingElements) {
23
+ const field = processElement(element, filePath, options);
24
+ if (field) {
25
+ fields.push(field);
26
+ }
27
+ }
28
+ return fields;
29
+ }
30
+ /**
31
+ * Process a single JSX element and extract field data.
32
+ */
33
+ function processElement(element, filePath, options) {
34
+ // Check if element has the data-reverso marker
35
+ if (!hasReversoMarker(element)) {
36
+ return null;
37
+ }
38
+ // Extract attributes
39
+ const extracted = extractAttributes(element);
40
+ if (!extracted) {
41
+ return null;
42
+ }
43
+ // Get position info
44
+ const startLineNumber = element.getStartLineNumber();
45
+ const startLinePos = element.getStartLinePos();
46
+ const start = element.getStart();
47
+ const column = start - startLinePos;
48
+ // Get element tag name
49
+ const tagName = element.getTagNameNode().getText();
50
+ // Build the field object
51
+ const field = {
52
+ path: extracted.path,
53
+ attributes: extracted.raw,
54
+ file: filePath,
55
+ line: startLineNumber,
56
+ column,
57
+ element: tagName,
58
+ };
59
+ // Get text content if requested
60
+ if (options.includeTextContent !== false) {
61
+ const textContent = getElementTextContent(element);
62
+ if (textContent) {
63
+ field.textContent = textContent;
64
+ }
65
+ }
66
+ return field;
67
+ }
68
+ /**
69
+ * Find all unique paths in a list of detected fields.
70
+ */
71
+ export function getUniquePaths(fields) {
72
+ const paths = new Set();
73
+ for (const field of fields) {
74
+ paths.add(field.path);
75
+ }
76
+ return Array.from(paths).sort();
77
+ }
78
+ /**
79
+ * Group fields by their path.
80
+ */
81
+ export function groupFieldsByPath(fields) {
82
+ const grouped = new Map();
83
+ for (const field of fields) {
84
+ const existing = grouped.get(field.path) ?? [];
85
+ existing.push(field);
86
+ grouped.set(field.path, existing);
87
+ }
88
+ return grouped;
89
+ }
90
+ /**
91
+ * Check for duplicate paths (same path in multiple places).
92
+ */
93
+ export function findDuplicatePaths(fields) {
94
+ const grouped = groupFieldsByPath(fields);
95
+ const duplicates = new Map();
96
+ for (const [path, pathFields] of grouped) {
97
+ if (pathFields.length > 1) {
98
+ duplicates.set(path, pathFields);
99
+ }
100
+ }
101
+ return duplicates;
102
+ }
103
+ //# sourceMappingURL=jsx-walker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-walker.js","sourceRoot":"","sources":["../../src/parser/jsx-walker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Main Scanner class that orchestrates parsing, schema generation, and output.
3
+ */
4
+ import { type ProjectSchema, type ScanOptions, type ScanResult, type SchemaDiff } from '@reverso/core';
5
+ /**
6
+ * Scanner options.
7
+ */
8
+ export interface ScannerOptions {
9
+ /** Source directory to scan */
10
+ srcDir?: string;
11
+ /** Output directory for schema files */
12
+ outputDir?: string;
13
+ /** Glob patterns to include */
14
+ include?: string[];
15
+ /** Glob patterns to exclude */
16
+ exclude?: string[];
17
+ /** TypeScript config file path */
18
+ tsConfigFilePath?: string;
19
+ /** Watch mode */
20
+ watch?: boolean;
21
+ /** Watch debounce delay in milliseconds */
22
+ watchDebounce?: number;
23
+ /** Generate TypeScript types */
24
+ generateTypes?: boolean;
25
+ /** Pretty print JSON output */
26
+ prettyPrint?: boolean;
27
+ }
28
+ /**
29
+ * Scan event types.
30
+ */
31
+ export type ScanEventType = 'start' | 'complete' | 'error' | 'change';
32
+ /**
33
+ * Scan event data.
34
+ */
35
+ export interface ScanEvent {
36
+ type: ScanEventType;
37
+ schema?: ProjectSchema;
38
+ diff?: SchemaDiff;
39
+ error?: Error;
40
+ changedFile?: string;
41
+ }
42
+ /**
43
+ * Scan event handler.
44
+ */
45
+ export type ScanEventHandler = (event: ScanEvent) => void;
46
+ /**
47
+ * Main Scanner class.
48
+ */
49
+ export declare class Scanner {
50
+ private parser;
51
+ private watcher;
52
+ private options;
53
+ private currentSchema;
54
+ private eventHandlers;
55
+ constructor(options?: ScannerOptions);
56
+ /**
57
+ * Subscribe to scan events.
58
+ */
59
+ on(handler: ScanEventHandler): () => void;
60
+ /**
61
+ * Emit an event to all handlers.
62
+ */
63
+ private emit;
64
+ /**
65
+ * Run a full scan of the source directory.
66
+ */
67
+ scan(): Promise<ScanResult>;
68
+ /**
69
+ * Start watching for file changes.
70
+ */
71
+ startWatch(): Promise<void>;
72
+ /**
73
+ * Stop watching for file changes.
74
+ */
75
+ stopWatch(): Promise<void>;
76
+ /**
77
+ * Handle a file watch event.
78
+ */
79
+ private handleWatchEvent;
80
+ /**
81
+ * Get the current schema.
82
+ */
83
+ getSchema(): ProjectSchema | null;
84
+ /**
85
+ * Check if watch mode is active.
86
+ */
87
+ isWatching(): boolean;
88
+ /**
89
+ * Clear cached data.
90
+ */
91
+ clear(): void;
92
+ }
93
+ /**
94
+ * Create a new scanner instance.
95
+ */
96
+ export declare function createScanner(options?: ScannerOptions): Scanner;
97
+ /**
98
+ * Run a one-time scan.
99
+ */
100
+ export declare function scan(options: ScanOptions): Promise<ScanResult>;
101
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAavB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+BAA+B;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAE1D;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,aAAa,CAAoC;gBAE7C,OAAO,GAAE,cAAmB;IAsBxC;;OAEG;IACH,EAAE,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAOzC;;OAEG;IACH,OAAO,CAAC,IAAI;IAUZ;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IA8DjC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBjC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAOhC;;OAEG;YACW,gBAAgB;IAiB9B;;OAEG;IACH,SAAS,IAAI,aAAa,GAAG,IAAI;IAIjC;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAEnE;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAUpE"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Main Scanner class that orchestrates parsing, schema generation, and output.
3
+ */
4
+ import { resolve } from 'node:path';
5
+ import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_INCLUDE_PATTERNS, DEFAULT_OUTPUT_DIR, DEFAULT_SRC_DIR, } from '@reverso/core';
6
+ import { compareSchemas, readJsonSchema, writeJsonSchema, writeTypesFile, } from './output/index.js';
7
+ import { createParser } from './parser/index.js';
8
+ import { generateSchema, updateSchemaMeta } from './schema/index.js';
9
+ import { createWatcher } from './watch/index.js';
10
+ /**
11
+ * Main Scanner class.
12
+ */
13
+ export class Scanner {
14
+ parser;
15
+ watcher = null;
16
+ options;
17
+ currentSchema = null;
18
+ eventHandlers = new Set();
19
+ constructor(options = {}) {
20
+ this.options = {
21
+ srcDir: options.srcDir ?? DEFAULT_SRC_DIR,
22
+ outputDir: options.outputDir ?? DEFAULT_OUTPUT_DIR,
23
+ include: options.include ?? [...DEFAULT_INCLUDE_PATTERNS],
24
+ exclude: options.exclude ?? [...DEFAULT_EXCLUDE_PATTERNS],
25
+ tsConfigFilePath: options.tsConfigFilePath ?? '',
26
+ watch: options.watch ?? false,
27
+ watchDebounce: options.watchDebounce ?? 300,
28
+ generateTypes: options.generateTypes ?? true,
29
+ prettyPrint: options.prettyPrint ?? true,
30
+ };
31
+ // Create parser
32
+ this.parser = createParser({
33
+ srcDir: resolve(this.options.srcDir),
34
+ include: this.options.include,
35
+ exclude: this.options.exclude,
36
+ tsConfigFilePath: this.options.tsConfigFilePath || undefined,
37
+ });
38
+ }
39
+ /**
40
+ * Subscribe to scan events.
41
+ */
42
+ on(handler) {
43
+ this.eventHandlers.add(handler);
44
+ return () => {
45
+ this.eventHandlers.delete(handler);
46
+ };
47
+ }
48
+ /**
49
+ * Emit an event to all handlers.
50
+ */
51
+ emit(event) {
52
+ for (const handler of this.eventHandlers) {
53
+ try {
54
+ handler(event);
55
+ }
56
+ catch (error) {
57
+ console.error('Error in scan event handler:', error);
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * Run a full scan of the source directory.
63
+ */
64
+ async scan() {
65
+ this.emit({ type: 'start' });
66
+ try {
67
+ // Parse all files
68
+ const parseResult = await this.parser.parseAll();
69
+ // Generate schema
70
+ let schema = generateSchema(parseResult.fields, {
71
+ includeSourceInfo: true,
72
+ includeDefaults: true,
73
+ sort: true,
74
+ });
75
+ // Update metadata
76
+ const filesWithMarkers = new Set(parseResult.fields.map((f) => f.file)).size;
77
+ schema = updateSchemaMeta(schema, {
78
+ srcDir: this.options.srcDir,
79
+ filesScanned: parseResult.fileResults.length,
80
+ filesWithMarkers,
81
+ scanDuration: parseResult.duration,
82
+ });
83
+ // Compare with existing schema
84
+ const existingSchema = await readJsonSchema({
85
+ outputDir: resolve(this.options.outputDir),
86
+ });
87
+ const diff = compareSchemas(existingSchema, schema);
88
+ // Write output files
89
+ const outputDir = resolve(this.options.outputDir);
90
+ await writeJsonSchema(schema, {
91
+ outputDir,
92
+ pretty: this.options.prettyPrint,
93
+ });
94
+ if (this.options.generateTypes) {
95
+ await writeTypesFile(schema, {
96
+ outputDir,
97
+ includeComments: true,
98
+ });
99
+ }
100
+ // Store current schema
101
+ this.currentSchema = schema;
102
+ // Emit complete event
103
+ this.emit({ type: 'complete', schema, diff });
104
+ return {
105
+ schema,
106
+ files: parseResult.fileResults,
107
+ errors: parseResult.errors,
108
+ success: parseResult.errors.length === 0,
109
+ };
110
+ }
111
+ catch (error) {
112
+ const err = error instanceof Error ? error : new Error(String(error));
113
+ this.emit({ type: 'error', error: err });
114
+ throw err;
115
+ }
116
+ }
117
+ /**
118
+ * Start watching for file changes.
119
+ */
120
+ async startWatch() {
121
+ if (this.watcher) {
122
+ return;
123
+ }
124
+ // Run initial scan
125
+ await this.scan();
126
+ // Create watcher
127
+ this.watcher = createWatcher({
128
+ srcDir: resolve(this.options.srcDir),
129
+ include: this.options.include,
130
+ exclude: this.options.exclude,
131
+ debounce: this.options.watchDebounce,
132
+ onEvent: (event) => this.handleWatchEvent(event),
133
+ onError: (error) => this.emit({ type: 'error', error }),
134
+ onReady: () => { },
135
+ });
136
+ this.watcher.start();
137
+ }
138
+ /**
139
+ * Stop watching for file changes.
140
+ */
141
+ async stopWatch() {
142
+ if (this.watcher) {
143
+ await this.watcher.stop();
144
+ this.watcher = null;
145
+ }
146
+ }
147
+ /**
148
+ * Handle a file watch event.
149
+ */
150
+ async handleWatchEvent(event) {
151
+ try {
152
+ this.emit({ type: 'change', changedFile: event.path });
153
+ if (event.type === 'unlink') {
154
+ // File was deleted, remove from parser and rescan
155
+ this.parser.removeFile(event.path);
156
+ }
157
+ // Rescan all files
158
+ await this.scan();
159
+ }
160
+ catch (error) {
161
+ const err = error instanceof Error ? error : new Error(String(error));
162
+ this.emit({ type: 'error', error: err });
163
+ }
164
+ }
165
+ /**
166
+ * Get the current schema.
167
+ */
168
+ getSchema() {
169
+ return this.currentSchema;
170
+ }
171
+ /**
172
+ * Check if watch mode is active.
173
+ */
174
+ isWatching() {
175
+ return this.watcher?.isRunning() ?? false;
176
+ }
177
+ /**
178
+ * Clear cached data.
179
+ */
180
+ clear() {
181
+ this.parser.clear();
182
+ this.currentSchema = null;
183
+ }
184
+ }
185
+ /**
186
+ * Create a new scanner instance.
187
+ */
188
+ export function createScanner(options = {}) {
189
+ return new Scanner(options);
190
+ }
191
+ /**
192
+ * Run a one-time scan.
193
+ */
194
+ export async function scan(options) {
195
+ const scanner = createScanner({
196
+ srcDir: options.srcDir,
197
+ include: options.include,
198
+ exclude: options.exclude,
199
+ watch: false,
200
+ generateTypes: true,
201
+ });
202
+ return scanner.scan();
203
+ }
204
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Schema generator that converts detected fields into a structured schema.
3
+ */
4
+ import { type DetectedField, type FieldSchema, type ProjectSchema, type SchemaGeneratorOptions } from '@reverso/core';
5
+ /**
6
+ * Generate a complete project schema from detected fields.
7
+ */
8
+ export declare function generateSchema(fields: DetectedField[], options?: SchemaGeneratorOptions): ProjectSchema;
9
+ /**
10
+ * Convert a DetectedField to a FieldSchema.
11
+ */
12
+ export declare function convertToFieldSchema(field: DetectedField, options?: SchemaGeneratorOptions): FieldSchema;
13
+ /**
14
+ * Update schema metadata with scan information.
15
+ */
16
+ export declare function updateSchemaMeta(schema: ProjectSchema, meta: {
17
+ srcDir: string;
18
+ filesScanned: number;
19
+ filesWithMarkers: number;
20
+ scanDuration: number;
21
+ }): ProjectSchema;
22
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/schema/generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,WAAW,EAGhB,KAAK,aAAa,EAElB,KAAK,sBAAsB,EAM5B,MAAM,eAAe,CAAC;AAEvB;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,GAAE,sBAA2B,GACnC,aAAa,CA2Ef;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,sBAA2B,GACnC,WAAW,CAgHb;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB,GACA,aAAa,CAKf"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Schema generator that converts detected fields into a structured schema.
3
+ */
4
+ import { DEFAULT_FIELD_TYPE, SCHEMA_VERSION, formatLabel, groupPathsBySection, isValidFieldType, parsePath, } from '@reverso/core';
5
+ /**
6
+ * Generate a complete project schema from detected fields.
7
+ */
8
+ export function generateSchema(fields, options = {}) {
9
+ const startTime = performance.now();
10
+ // Group fields by page and section
11
+ const grouped = groupPathsBySection(fields.map((f) => f.path));
12
+ // Build pages
13
+ const pages = [];
14
+ for (const [pageSlug, sections] of grouped) {
15
+ const pageSections = [];
16
+ let order = 0;
17
+ for (const [sectionSlug, paths] of sections) {
18
+ // Get fields for this section
19
+ const sectionFields = fields.filter((f) => {
20
+ const parsed = parsePath(f.path);
21
+ return parsed.page === pageSlug && parsed.section === sectionSlug;
22
+ });
23
+ // Convert to FieldSchema
24
+ const fieldSchemas = sectionFields.map((f) => convertToFieldSchema(f, options));
25
+ // Check if this is a repeater section
26
+ const isRepeater = paths.some((p) => p.includes('.$'));
27
+ const section = {
28
+ slug: sectionSlug,
29
+ name: formatLabel(sectionSlug),
30
+ fields: options.sort
31
+ ? fieldSchemas.sort((a, b) => a.path.localeCompare(b.path))
32
+ : fieldSchemas,
33
+ isRepeater,
34
+ order: order++,
35
+ };
36
+ pageSections.push(section);
37
+ }
38
+ // Sort sections if requested
39
+ const sortedSections = options.sort
40
+ ? pageSections.sort((a, b) => a.slug.localeCompare(b.slug))
41
+ : pageSections;
42
+ const page = {
43
+ slug: pageSlug,
44
+ name: formatLabel(pageSlug),
45
+ sections: sortedSections,
46
+ fieldCount: sortedSections.reduce((sum, s) => sum + s.fields.length, 0),
47
+ sourceFiles: [
48
+ ...new Set(fields.filter((f) => parsePath(f.path).page === pageSlug).map((f) => f.file)),
49
+ ],
50
+ };
51
+ pages.push(page);
52
+ }
53
+ // Sort pages if requested
54
+ const sortedPages = options.sort ? pages.sort((a, b) => a.slug.localeCompare(b.slug)) : pages;
55
+ const duration = performance.now() - startTime;
56
+ return {
57
+ version: SCHEMA_VERSION,
58
+ generatedAt: new Date().toISOString(),
59
+ pages: sortedPages,
60
+ pageCount: sortedPages.length,
61
+ totalFields: fields.length,
62
+ meta: {
63
+ srcDir: '',
64
+ filesScanned: 0,
65
+ filesWithMarkers: 0,
66
+ scanDuration: duration,
67
+ },
68
+ };
69
+ }
70
+ /**
71
+ * Convert a DetectedField to a FieldSchema.
72
+ */
73
+ export function convertToFieldSchema(field, options = {}) {
74
+ const defaultType = options.defaultFieldType ?? DEFAULT_FIELD_TYPE;
75
+ // Get the type from attributes, validate it
76
+ let fieldType = defaultType;
77
+ if (field.attributes.type) {
78
+ const typeAttr = field.attributes.type;
79
+ if (isValidFieldType(typeAttr)) {
80
+ fieldType = typeAttr;
81
+ }
82
+ }
83
+ const schema = {
84
+ path: field.path,
85
+ type: fieldType,
86
+ file: options.includeSourceInfo !== false ? field.file : field.file,
87
+ line: field.line,
88
+ column: field.column,
89
+ element: field.element,
90
+ };
91
+ // Add optional attributes
92
+ if (field.attributes.label) {
93
+ schema.label = field.attributes.label;
94
+ }
95
+ else {
96
+ // Generate label from path
97
+ const parsed = parsePath(field.path);
98
+ const fieldName = parsed.repeaterField ?? parsed.field;
99
+ schema.label = formatLabel(fieldName);
100
+ }
101
+ if (field.attributes.placeholder) {
102
+ schema.placeholder = field.attributes.placeholder;
103
+ }
104
+ if (field.attributes.required !== undefined) {
105
+ schema.required = field.attributes.required === 'true' || field.attributes.required === '';
106
+ }
107
+ if (field.attributes.validation) {
108
+ schema.validation = field.attributes.validation;
109
+ }
110
+ if (field.attributes.options) {
111
+ schema.options = field.attributes.options;
112
+ }
113
+ if (field.attributes.condition) {
114
+ schema.condition = field.attributes.condition;
115
+ }
116
+ if (field.attributes.help) {
117
+ schema.help = field.attributes.help;
118
+ }
119
+ if (field.attributes.min !== undefined) {
120
+ const num = Number(field.attributes.min);
121
+ if (!Number.isNaN(num)) {
122
+ schema.min = num;
123
+ }
124
+ }
125
+ if (field.attributes.max !== undefined) {
126
+ const num = Number(field.attributes.max);
127
+ if (!Number.isNaN(num)) {
128
+ schema.max = num;
129
+ }
130
+ }
131
+ if (field.attributes.step !== undefined) {
132
+ const num = Number(field.attributes.step);
133
+ if (!Number.isNaN(num)) {
134
+ schema.step = num;
135
+ }
136
+ }
137
+ if (field.attributes.accept) {
138
+ schema.accept = field.attributes.accept;
139
+ }
140
+ if (field.attributes.multiple !== undefined) {
141
+ schema.multiple = field.attributes.multiple === 'true' || field.attributes.multiple === '';
142
+ }
143
+ if (field.attributes.rows !== undefined) {
144
+ const num = Number(field.attributes.rows);
145
+ if (!Number.isNaN(num)) {
146
+ schema.rows = num;
147
+ }
148
+ }
149
+ if (field.attributes.width !== undefined) {
150
+ const num = Number(field.attributes.width);
151
+ if (!Number.isNaN(num) && num >= 1 && num <= 12) {
152
+ schema.width = num;
153
+ }
154
+ }
155
+ if (field.attributes.readonly !== undefined) {
156
+ schema.readonly = field.attributes.readonly === 'true' || field.attributes.readonly === '';
157
+ }
158
+ if (field.attributes.hidden !== undefined) {
159
+ schema.hidden = field.attributes.hidden === 'true' || field.attributes.hidden === '';
160
+ }
161
+ // Include default content from JSX
162
+ if (options.includeDefaults !== false && field.textContent) {
163
+ schema.defaultContent = field.textContent;
164
+ }
165
+ return schema;
166
+ }
167
+ /**
168
+ * Update schema metadata with scan information.
169
+ */
170
+ export function updateSchemaMeta(schema, meta) {
171
+ return {
172
+ ...schema,
173
+ meta,
174
+ };
175
+ }
176
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/schema/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Schema exports for @reverso/scanner
3
+ */
4
+ export { generateSchema, convertToFieldSchema, updateSchemaMeta, } from './generator.js';
5
+ export { normalizeFieldPath, normalizeFields, sortSectionFields, sortPageSections, sortSchemaPages, ensureLabels, deduplicateFields, mergeFields, reorderSections, validateSchemaStructure, } from './normalizer.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,uBAAuB,GACxB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Schema exports for @reverso/scanner
3
+ */
4
+ export { generateSchema, convertToFieldSchema, updateSchemaMeta, } from './generator.js';
5
+ export { normalizeFieldPath, normalizeFields, sortSectionFields, sortPageSections, sortSchemaPages, ensureLabels, deduplicateFields, mergeFields, reorderSections, validateSchemaStructure, } from './normalizer.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,uBAAuB,GACxB,MAAM,iBAAiB,CAAC"}