@timeax/scaffold 0.0.3 → 0.0.5
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/.vscode/settings.json +12 -0
- package/dist/ast.cjs +438 -0
- package/dist/ast.cjs.map +1 -0
- package/dist/ast.d.cts +152 -0
- package/dist/ast.d.ts +152 -0
- package/dist/ast.mjs +433 -0
- package/dist/ast.mjs.map +1 -0
- package/package.json +9 -3
- package/readme.md +215 -110
- package/src/ast/format.ts +262 -0
- package/src/ast/index.ts +2 -0
- package/src/ast/parser.ts +593 -0
- package/src/core/format.ts +87 -0
- package/src/core/init-scaffold.ts +126 -88
- package/src/core/runner.ts +74 -66
- package/src/core/structure-txt.ts +196 -222
- package/src/core/watcher.ts +87 -79
- package/src/schema/config.ts +198 -154
- package/test/format-roundtrip.spec.ts +20 -0
- package/test/format.spec.ts +104 -0
- package/test/parser-diagnostics.spec.ts +86 -0
- package/test/parser-tree.spec.ts +102 -0
- package/tsup.config.ts +61 -43
- package/vitest.config.ts +9 -0
- package/dist/cli.cjs +0 -1182
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.mjs +0 -1171
- package/dist/cli.mjs.map +0 -1
- package/dist/index.cjs +0 -864
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs +0 -848
- package/dist/index.mjs.map +0 -1
package/dist/ast.d.cts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
type AstMode = 'strict' | 'loose';
|
|
2
|
+
type DiagnosticSeverity = 'info' | 'warning' | 'error';
|
|
3
|
+
interface Diagnostic {
|
|
4
|
+
line: number;
|
|
5
|
+
column?: number;
|
|
6
|
+
message: string;
|
|
7
|
+
severity: DiagnosticSeverity;
|
|
8
|
+
code?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* How a physical line in the text was classified.
|
|
12
|
+
*/
|
|
13
|
+
type LineKind = 'blank' | 'comment' | 'entry';
|
|
14
|
+
interface StructureAstLine {
|
|
15
|
+
index: number;
|
|
16
|
+
lineNo: number;
|
|
17
|
+
raw: string;
|
|
18
|
+
kind: LineKind;
|
|
19
|
+
indentSpaces: number;
|
|
20
|
+
content: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* AST node base for structure entries.
|
|
24
|
+
*/
|
|
25
|
+
interface AstNodeBase {
|
|
26
|
+
type: 'dir' | 'file';
|
|
27
|
+
/** The last segment name, e.g. "schema/" or "index.ts". */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Depth level (0 = root, 1 = child of root, etc.). */
|
|
30
|
+
depth: number;
|
|
31
|
+
/** 1-based source line number. */
|
|
32
|
+
line: number;
|
|
33
|
+
/** Normalized POSIX path from root, e.g. "src/schema/index.ts" or "src/schema/". */
|
|
34
|
+
path: string;
|
|
35
|
+
/** Stub annotation, if any. */
|
|
36
|
+
stub?: string;
|
|
37
|
+
/** Include glob patterns, if any. */
|
|
38
|
+
include?: string[];
|
|
39
|
+
/** Exclude glob patterns, if any. */
|
|
40
|
+
exclude?: string[];
|
|
41
|
+
/** Parent node; null for roots. */
|
|
42
|
+
parent: DirNode | null;
|
|
43
|
+
}
|
|
44
|
+
interface DirNode extends AstNodeBase {
|
|
45
|
+
type: 'dir';
|
|
46
|
+
children: AstNode[];
|
|
47
|
+
}
|
|
48
|
+
interface FileNode extends AstNodeBase {
|
|
49
|
+
type: 'file';
|
|
50
|
+
children?: undefined;
|
|
51
|
+
}
|
|
52
|
+
type AstNode = DirNode | FileNode;
|
|
53
|
+
interface AstOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Spaces per indent level.
|
|
56
|
+
* Default: 2.
|
|
57
|
+
*/
|
|
58
|
+
indentStep?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Parser mode:
|
|
61
|
+
* - "strict": mismatched indentation / impossible structures are errors.
|
|
62
|
+
* - "loose" : tries to recover from bad indentation, demotes some issues to warnings.
|
|
63
|
+
*
|
|
64
|
+
* Default: "loose".
|
|
65
|
+
*/
|
|
66
|
+
mode?: AstMode;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Full AST result: nodes + per-line meta + diagnostics.
|
|
70
|
+
*/
|
|
71
|
+
interface StructureAst {
|
|
72
|
+
/** Root-level nodes (depth 0). */
|
|
73
|
+
rootNodes: AstNode[];
|
|
74
|
+
/** All lines as seen in the source file. */
|
|
75
|
+
lines: StructureAstLine[];
|
|
76
|
+
/** Collected diagnostics (errors + warnings + infos). */
|
|
77
|
+
diagnostics: Diagnostic[];
|
|
78
|
+
/** Resolved options used by the parser. */
|
|
79
|
+
options: Required<AstOptions>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Main entry: parse a structure text into an AST tree with diagnostics.
|
|
83
|
+
*
|
|
84
|
+
* - Does NOT throw on parse errors.
|
|
85
|
+
* - Always returns something (even if diagnostics contain errors).
|
|
86
|
+
* - In "loose" mode, attempts to repair:
|
|
87
|
+
* - odd/misaligned indentation → snapped via relative depth rules with warnings.
|
|
88
|
+
* - large indent jumps → treated as "one level deeper" with warnings.
|
|
89
|
+
* - children under files → attached to nearest viable ancestor with warnings.
|
|
90
|
+
*/
|
|
91
|
+
declare function parseStructureAst(text: string, opts?: AstOptions): StructureAst;
|
|
92
|
+
declare function mapThrough(content: string): number;
|
|
93
|
+
/**
|
|
94
|
+
* Extracts the inline comment portion (if any) from the content area (no leading indent).
|
|
95
|
+
*/
|
|
96
|
+
declare function extractInlineCommentParts(content: string): {
|
|
97
|
+
contentWithoutComment: string;
|
|
98
|
+
inlineComment: string | null;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
interface FormatOptions {
|
|
102
|
+
/**
|
|
103
|
+
* Spaces per indent level for re-printing entries.
|
|
104
|
+
* Defaults to 2.
|
|
105
|
+
*/
|
|
106
|
+
indentStep?: number;
|
|
107
|
+
/**
|
|
108
|
+
* Parser mode to use for the AST.
|
|
109
|
+
* - "loose": attempt to repair mis-indents / bad parents (default).
|
|
110
|
+
* - "strict": report issues as errors, less repair.
|
|
111
|
+
*/
|
|
112
|
+
mode?: AstMode;
|
|
113
|
+
/**
|
|
114
|
+
* Normalize newlines to the dominant style in the original text (LF vs CRLF).
|
|
115
|
+
* Defaults to true.
|
|
116
|
+
*/
|
|
117
|
+
normalizeNewlines?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Trim trailing whitespace on non-entry lines (comments / blanks).
|
|
120
|
+
* Defaults to true.
|
|
121
|
+
*/
|
|
122
|
+
trimTrailingWhitespace?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Whether to normalize annotation ordering and spacing:
|
|
125
|
+
* name @stub:... @include:... @exclude:...
|
|
126
|
+
* Defaults to true.
|
|
127
|
+
*/
|
|
128
|
+
normalizeAnnotations?: boolean;
|
|
129
|
+
}
|
|
130
|
+
interface FormatResult {
|
|
131
|
+
/** Formatted text. */
|
|
132
|
+
text: string;
|
|
133
|
+
/** Underlying AST that was used. */
|
|
134
|
+
ast: StructureAst;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Smart formatter for scaffold structure files.
|
|
138
|
+
*
|
|
139
|
+
* - Uses the loose AST parser (parseStructureAst) to understand structure.
|
|
140
|
+
* - Auto-fixes indentation based on tree depth (indentStep).
|
|
141
|
+
* - Keeps **all** blank lines and full-line comments in place.
|
|
142
|
+
* - Preserves inline comments (# / //) on entry lines.
|
|
143
|
+
* - Canonicalizes annotation order (stub → include → exclude) if enabled.
|
|
144
|
+
*
|
|
145
|
+
* It does **not** throw on invalid input:
|
|
146
|
+
* - parseStructureAst always returns an AST + diagnostics.
|
|
147
|
+
* - If something is catastrophically off (entry/node counts mismatch),
|
|
148
|
+
* it falls back to a minimal normalization pass.
|
|
149
|
+
*/
|
|
150
|
+
declare function formatStructureText(text: string, options?: FormatOptions): FormatResult;
|
|
151
|
+
|
|
152
|
+
export { type AstMode, type AstNode, type AstOptions, type Diagnostic, type DiagnosticSeverity, type DirNode, type FileNode, type FormatOptions, type FormatResult, type LineKind, type StructureAst, type StructureAstLine, extractInlineCommentParts, formatStructureText, mapThrough, parseStructureAst };
|
package/dist/ast.d.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
type AstMode = 'strict' | 'loose';
|
|
2
|
+
type DiagnosticSeverity = 'info' | 'warning' | 'error';
|
|
3
|
+
interface Diagnostic {
|
|
4
|
+
line: number;
|
|
5
|
+
column?: number;
|
|
6
|
+
message: string;
|
|
7
|
+
severity: DiagnosticSeverity;
|
|
8
|
+
code?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* How a physical line in the text was classified.
|
|
12
|
+
*/
|
|
13
|
+
type LineKind = 'blank' | 'comment' | 'entry';
|
|
14
|
+
interface StructureAstLine {
|
|
15
|
+
index: number;
|
|
16
|
+
lineNo: number;
|
|
17
|
+
raw: string;
|
|
18
|
+
kind: LineKind;
|
|
19
|
+
indentSpaces: number;
|
|
20
|
+
content: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* AST node base for structure entries.
|
|
24
|
+
*/
|
|
25
|
+
interface AstNodeBase {
|
|
26
|
+
type: 'dir' | 'file';
|
|
27
|
+
/** The last segment name, e.g. "schema/" or "index.ts". */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Depth level (0 = root, 1 = child of root, etc.). */
|
|
30
|
+
depth: number;
|
|
31
|
+
/** 1-based source line number. */
|
|
32
|
+
line: number;
|
|
33
|
+
/** Normalized POSIX path from root, e.g. "src/schema/index.ts" or "src/schema/". */
|
|
34
|
+
path: string;
|
|
35
|
+
/** Stub annotation, if any. */
|
|
36
|
+
stub?: string;
|
|
37
|
+
/** Include glob patterns, if any. */
|
|
38
|
+
include?: string[];
|
|
39
|
+
/** Exclude glob patterns, if any. */
|
|
40
|
+
exclude?: string[];
|
|
41
|
+
/** Parent node; null for roots. */
|
|
42
|
+
parent: DirNode | null;
|
|
43
|
+
}
|
|
44
|
+
interface DirNode extends AstNodeBase {
|
|
45
|
+
type: 'dir';
|
|
46
|
+
children: AstNode[];
|
|
47
|
+
}
|
|
48
|
+
interface FileNode extends AstNodeBase {
|
|
49
|
+
type: 'file';
|
|
50
|
+
children?: undefined;
|
|
51
|
+
}
|
|
52
|
+
type AstNode = DirNode | FileNode;
|
|
53
|
+
interface AstOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Spaces per indent level.
|
|
56
|
+
* Default: 2.
|
|
57
|
+
*/
|
|
58
|
+
indentStep?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Parser mode:
|
|
61
|
+
* - "strict": mismatched indentation / impossible structures are errors.
|
|
62
|
+
* - "loose" : tries to recover from bad indentation, demotes some issues to warnings.
|
|
63
|
+
*
|
|
64
|
+
* Default: "loose".
|
|
65
|
+
*/
|
|
66
|
+
mode?: AstMode;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Full AST result: nodes + per-line meta + diagnostics.
|
|
70
|
+
*/
|
|
71
|
+
interface StructureAst {
|
|
72
|
+
/** Root-level nodes (depth 0). */
|
|
73
|
+
rootNodes: AstNode[];
|
|
74
|
+
/** All lines as seen in the source file. */
|
|
75
|
+
lines: StructureAstLine[];
|
|
76
|
+
/** Collected diagnostics (errors + warnings + infos). */
|
|
77
|
+
diagnostics: Diagnostic[];
|
|
78
|
+
/** Resolved options used by the parser. */
|
|
79
|
+
options: Required<AstOptions>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Main entry: parse a structure text into an AST tree with diagnostics.
|
|
83
|
+
*
|
|
84
|
+
* - Does NOT throw on parse errors.
|
|
85
|
+
* - Always returns something (even if diagnostics contain errors).
|
|
86
|
+
* - In "loose" mode, attempts to repair:
|
|
87
|
+
* - odd/misaligned indentation → snapped via relative depth rules with warnings.
|
|
88
|
+
* - large indent jumps → treated as "one level deeper" with warnings.
|
|
89
|
+
* - children under files → attached to nearest viable ancestor with warnings.
|
|
90
|
+
*/
|
|
91
|
+
declare function parseStructureAst(text: string, opts?: AstOptions): StructureAst;
|
|
92
|
+
declare function mapThrough(content: string): number;
|
|
93
|
+
/**
|
|
94
|
+
* Extracts the inline comment portion (if any) from the content area (no leading indent).
|
|
95
|
+
*/
|
|
96
|
+
declare function extractInlineCommentParts(content: string): {
|
|
97
|
+
contentWithoutComment: string;
|
|
98
|
+
inlineComment: string | null;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
interface FormatOptions {
|
|
102
|
+
/**
|
|
103
|
+
* Spaces per indent level for re-printing entries.
|
|
104
|
+
* Defaults to 2.
|
|
105
|
+
*/
|
|
106
|
+
indentStep?: number;
|
|
107
|
+
/**
|
|
108
|
+
* Parser mode to use for the AST.
|
|
109
|
+
* - "loose": attempt to repair mis-indents / bad parents (default).
|
|
110
|
+
* - "strict": report issues as errors, less repair.
|
|
111
|
+
*/
|
|
112
|
+
mode?: AstMode;
|
|
113
|
+
/**
|
|
114
|
+
* Normalize newlines to the dominant style in the original text (LF vs CRLF).
|
|
115
|
+
* Defaults to true.
|
|
116
|
+
*/
|
|
117
|
+
normalizeNewlines?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Trim trailing whitespace on non-entry lines (comments / blanks).
|
|
120
|
+
* Defaults to true.
|
|
121
|
+
*/
|
|
122
|
+
trimTrailingWhitespace?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Whether to normalize annotation ordering and spacing:
|
|
125
|
+
* name @stub:... @include:... @exclude:...
|
|
126
|
+
* Defaults to true.
|
|
127
|
+
*/
|
|
128
|
+
normalizeAnnotations?: boolean;
|
|
129
|
+
}
|
|
130
|
+
interface FormatResult {
|
|
131
|
+
/** Formatted text. */
|
|
132
|
+
text: string;
|
|
133
|
+
/** Underlying AST that was used. */
|
|
134
|
+
ast: StructureAst;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Smart formatter for scaffold structure files.
|
|
138
|
+
*
|
|
139
|
+
* - Uses the loose AST parser (parseStructureAst) to understand structure.
|
|
140
|
+
* - Auto-fixes indentation based on tree depth (indentStep).
|
|
141
|
+
* - Keeps **all** blank lines and full-line comments in place.
|
|
142
|
+
* - Preserves inline comments (# / //) on entry lines.
|
|
143
|
+
* - Canonicalizes annotation order (stub → include → exclude) if enabled.
|
|
144
|
+
*
|
|
145
|
+
* It does **not** throw on invalid input:
|
|
146
|
+
* - parseStructureAst always returns an AST + diagnostics.
|
|
147
|
+
* - If something is catastrophically off (entry/node counts mismatch),
|
|
148
|
+
* it falls back to a minimal normalization pass.
|
|
149
|
+
*/
|
|
150
|
+
declare function formatStructureText(text: string, options?: FormatOptions): FormatResult;
|
|
151
|
+
|
|
152
|
+
export { type AstMode, type AstNode, type AstOptions, type Diagnostic, type DiagnosticSeverity, type DirNode, type FileNode, type FormatOptions, type FormatResult, type LineKind, type StructureAst, type StructureAstLine, extractInlineCommentParts, formatStructureText, mapThrough, parseStructureAst };
|