@timeax/scaffold 0.0.13 → 0.1.1
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/cli.cjs +12 -12
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +12 -12
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +12 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +12 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -7
- package/src/core/resolve-structure.ts +3 -2
- package/src/core/runner.ts +1 -1
- package/src/core/structure-txt.ts +8 -7
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timeax/scaffold",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"description": "A CLI tool that scaffolds project file structures based on a user-defined, type-safe configuration file.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"scaffold"
|
|
@@ -22,14 +22,24 @@
|
|
|
22
22
|
"types": "dist/index.d.ts",
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/index.d.mts",
|
|
27
|
+
"default": "./dist/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/index.d.cts",
|
|
31
|
+
"default": "./dist/index.cjs"
|
|
32
|
+
}
|
|
28
33
|
},
|
|
29
34
|
"./ast": {
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
"import": {
|
|
36
|
+
"types": "./dist/ast.d.mts",
|
|
37
|
+
"default": "./dist/ast.mjs"
|
|
38
|
+
},
|
|
39
|
+
"require": {
|
|
40
|
+
"types": "./dist/ast.d.cts",
|
|
41
|
+
"default": "./dist/ast.cjs"
|
|
42
|
+
}
|
|
33
43
|
}
|
|
34
44
|
},
|
|
35
45
|
"bin": {
|
|
@@ -15,6 +15,7 @@ const logger = defaultLogger.child('[structure]');
|
|
|
15
15
|
export function resolveGroupStructure(
|
|
16
16
|
scaffoldDir: string,
|
|
17
17
|
group: StructureGroupConfig,
|
|
18
|
+
config: ScaffoldConfig
|
|
18
19
|
): StructureEntry[] {
|
|
19
20
|
if (group.structure && group.structure.length) {
|
|
20
21
|
logger.debug(`Using inline structure for group "${group.name}"`);
|
|
@@ -33,7 +34,7 @@ export function resolveGroupStructure(
|
|
|
33
34
|
|
|
34
35
|
logger.debug(`Reading structure for group "${group.name}" from ${filePath}`);
|
|
35
36
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
36
|
-
return parseStructureText(raw);
|
|
37
|
+
return parseStructureText(fileName, raw, config.indentStep);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/**
|
|
@@ -60,5 +61,5 @@ export function resolveSingleStructure(
|
|
|
60
61
|
|
|
61
62
|
logger.debug(`Reading single structure from ${filePath}`);
|
|
62
63
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
63
|
-
return parseStructureText(raw);
|
|
64
|
+
return parseStructureText(fileName, raw, config.indentStep);
|
|
64
65
|
}
|
package/src/core/runner.ts
CHANGED
|
@@ -61,7 +61,7 @@ export async function runOnce(cwd: string, options: RunOptions = {}): Promise<vo
|
|
|
61
61
|
if (config.groups && config.groups.length > 0) {
|
|
62
62
|
for (const group of config.groups) {
|
|
63
63
|
const groupRootAbs = path.resolve(projectRoot, group.root);
|
|
64
|
-
const structure = resolveGroupStructure(scaffoldDir, group);
|
|
64
|
+
const structure = resolveGroupStructure(scaffoldDir, group, config);
|
|
65
65
|
|
|
66
66
|
const groupLogger = logger.child(`[group:${group.name}]`);
|
|
67
67
|
|
|
@@ -42,7 +42,7 @@ function stripInlineComment(content: string): string {
|
|
|
42
42
|
* - @include:pattern,pattern2
|
|
43
43
|
* - @exclude:pattern,pattern2
|
|
44
44
|
*/
|
|
45
|
-
function parseLine(line: string, lineNo: number): ParsedLine | null {
|
|
45
|
+
function parseLine(line: string, lineNo: number, fileName: string): ParsedLine | null {
|
|
46
46
|
const match = line.match(/^(\s*)(.*)$/);
|
|
47
47
|
if (!match) return null;
|
|
48
48
|
|
|
@@ -71,7 +71,7 @@ function parseLine(line: string, lineNo: number): ParsedLine | null {
|
|
|
71
71
|
// 🚫 Reserve ":" for annotations only – paths may not contain it.
|
|
72
72
|
if (pathToken.includes(':')) {
|
|
73
73
|
throw new Error(
|
|
74
|
-
|
|
74
|
+
`${fileName}: ":" is reserved for annotations (@stub:, @include:, etc). ` +
|
|
75
75
|
`Invalid path "${pathToken}" on line ${lineNo}.`,
|
|
76
76
|
);
|
|
77
77
|
}
|
|
@@ -128,6 +128,7 @@ function parseLine(line: string, lineNo: number): ParsedLine | null {
|
|
|
128
128
|
* - Folders must end with "/" in the txt; paths are normalized to POSIX.
|
|
129
129
|
*/
|
|
130
130
|
export function parseStructureText(
|
|
131
|
+
fileName: string,
|
|
131
132
|
text: string,
|
|
132
133
|
indentStep = 2,
|
|
133
134
|
): StructureEntry[] {
|
|
@@ -136,7 +137,7 @@ export function parseStructureText(
|
|
|
136
137
|
|
|
137
138
|
for (let i = 0; i < lines.length; i++) {
|
|
138
139
|
const lineNo = i + 1;
|
|
139
|
-
const p = parseLine(lines[i], lineNo);
|
|
140
|
+
const p = parseLine(lines[i], lineNo, fileName);
|
|
140
141
|
if (p) parsed.push(p);
|
|
141
142
|
}
|
|
142
143
|
|
|
@@ -155,7 +156,7 @@ export function parseStructureText(
|
|
|
155
156
|
|
|
156
157
|
if (indentSpaces % indentStep !== 0) {
|
|
157
158
|
throw new Error(
|
|
158
|
-
|
|
159
|
+
`${fileName}: Invalid indent on line ${lineNo}. ` +
|
|
159
160
|
`Indent must be multiples of ${indentStep} spaces.`,
|
|
160
161
|
);
|
|
161
162
|
}
|
|
@@ -167,7 +168,7 @@ export function parseStructureText(
|
|
|
167
168
|
// e.g. current stack depth 1, but line level=3 is invalid
|
|
168
169
|
if (level !== stack.length + 1) {
|
|
169
170
|
throw new Error(
|
|
170
|
-
|
|
171
|
+
`${fileName}: Invalid indentation on line ${lineNo}. ` +
|
|
171
172
|
`You cannot jump more than one level at a time. ` +
|
|
172
173
|
`Previous depth: ${stack.length}, this line depth: ${level}.`,
|
|
173
174
|
);
|
|
@@ -179,12 +180,12 @@ export function parseStructureText(
|
|
|
179
180
|
const parent = stack[level - 1]; // parent level is (level - 1)
|
|
180
181
|
if (!parent) {
|
|
181
182
|
throw new Error(
|
|
182
|
-
|
|
183
|
+
`${fileName}: Indented entry without a parent on line ${lineNo}.`,
|
|
183
184
|
);
|
|
184
185
|
}
|
|
185
186
|
if (!parent.isDir) {
|
|
186
187
|
throw new Error(
|
|
187
|
-
|
|
188
|
+
`${fileName}: Cannot indent under a file on line ${lineNo}. ` +
|
|
188
189
|
`Files cannot have children. Parent: "${parent.entry.path}".`,
|
|
189
190
|
);
|
|
190
191
|
}
|