@timeax/scaffold 0.0.2 → 0.0.3
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 +55 -14
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +55 -14
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +51 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -1
- package/dist/index.d.ts +68 -1
- package/dist/index.mjs +49 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/readme.md +150 -51
- package/src/core/config-loader.ts +4 -3
- package/src/core/init-scaffold.ts +8 -3
- package/src/core/structure-txt.ts +88 -15
- package/src/index.ts +3 -2
- package/src/schema/config.ts +10 -1
- package/src/schema/index.ts +1 -0
package/dist/cli.cjs
CHANGED
|
@@ -21,6 +21,9 @@ var os__default = /*#__PURE__*/_interopDefault(os);
|
|
|
21
21
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
22
22
|
var chokidar__default = /*#__PURE__*/_interopDefault(chokidar);
|
|
23
23
|
|
|
24
|
+
// src/schema/index.ts
|
|
25
|
+
var SCAFFOLD_ROOT_DIR = ".scaffold";
|
|
26
|
+
|
|
24
27
|
// src/util/logger.ts
|
|
25
28
|
var supportsColor = typeof process !== "undefined" && process.stdout && process.stdout.isTTY && process.env.NO_COLOR !== "1";
|
|
26
29
|
function wrap(code) {
|
|
@@ -144,14 +147,14 @@ function toProjectRelativePath(projectRoot, absolutePath) {
|
|
|
144
147
|
var logger = defaultLogger.child("[config]");
|
|
145
148
|
async function loadScaffoldConfig(cwd, options = {}) {
|
|
146
149
|
const absCwd = path2__default.default.resolve(cwd);
|
|
147
|
-
const initialScaffoldDir = options.scaffoldDir ? path2__default.default.resolve(absCwd, options.scaffoldDir) : path2__default.default.join(absCwd,
|
|
150
|
+
const initialScaffoldDir = options.scaffoldDir ? path2__default.default.resolve(absCwd, options.scaffoldDir) : path2__default.default.join(absCwd, SCAFFOLD_ROOT_DIR);
|
|
148
151
|
const configPath = options.configPath ?? resolveConfigPath(initialScaffoldDir);
|
|
149
152
|
const config = await importConfig(configPath);
|
|
150
153
|
let configRoot = absCwd;
|
|
151
154
|
if (config.root) {
|
|
152
155
|
configRoot = path2__default.default.resolve(absCwd, config.root);
|
|
153
156
|
}
|
|
154
|
-
const scaffoldDir = options.scaffoldDir ? path2__default.default.resolve(absCwd, options.scaffoldDir) : path2__default.default.join(configRoot,
|
|
157
|
+
const scaffoldDir = options.scaffoldDir ? path2__default.default.resolve(absCwd, options.scaffoldDir) : path2__default.default.join(configRoot, SCAFFOLD_ROOT_DIR);
|
|
155
158
|
const baseRoot = config.base ? path2__default.default.resolve(configRoot, config.base) : configRoot;
|
|
156
159
|
logger.debug(
|
|
157
160
|
`Loaded config: configRoot=${configRoot}, baseRoot=${baseRoot}, scaffoldDir=${scaffoldDir}`
|
|
@@ -216,14 +219,50 @@ async function importTsConfig(configPath) {
|
|
|
216
219
|
}
|
|
217
220
|
|
|
218
221
|
// src/core/structure-txt.ts
|
|
222
|
+
function stripInlineComment(content) {
|
|
223
|
+
let cutIndex = -1;
|
|
224
|
+
const len = content.length;
|
|
225
|
+
for (let i = 0; i < len; i++) {
|
|
226
|
+
const ch = content[i];
|
|
227
|
+
const prev = i > 0 ? content[i - 1] : "";
|
|
228
|
+
if (ch === "#") {
|
|
229
|
+
if (i === 0) continue;
|
|
230
|
+
if (prev === " " || prev === " ") {
|
|
231
|
+
cutIndex = i;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (ch === "/" && i + 1 < len && content[i + 1] === "/" && (prev === " " || prev === " ")) {
|
|
236
|
+
cutIndex = i;
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (cutIndex === -1) {
|
|
241
|
+
return content.trimEnd();
|
|
242
|
+
}
|
|
243
|
+
return content.slice(0, cutIndex).trimEnd();
|
|
244
|
+
}
|
|
219
245
|
function parseLine(line, lineNo) {
|
|
220
|
-
const match = line.match(/^(\s*)(
|
|
246
|
+
const match = line.match(/^(\s*)(.*)$/);
|
|
221
247
|
if (!match) return null;
|
|
222
248
|
const indentSpaces = match[1].length;
|
|
223
|
-
|
|
224
|
-
if (!rest
|
|
225
|
-
const
|
|
249
|
+
let rest = match[2];
|
|
250
|
+
if (!rest.trim()) return null;
|
|
251
|
+
const trimmedRest = rest.trimStart();
|
|
252
|
+
if (trimmedRest.startsWith("#") || trimmedRest.startsWith("//")) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
const stripped = stripInlineComment(rest);
|
|
256
|
+
const trimmed = stripped.trim();
|
|
257
|
+
if (!trimmed) return null;
|
|
258
|
+
const parts = trimmed.split(/\s+/);
|
|
259
|
+
if (!parts.length) return null;
|
|
226
260
|
const pathToken = parts[0];
|
|
261
|
+
if (pathToken.includes(":")) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
`structure.txt: ":" is reserved for annotations (@stub:, @include:, etc). Invalid path "${pathToken}" on line ${lineNo}.`
|
|
264
|
+
);
|
|
265
|
+
}
|
|
227
266
|
let stub;
|
|
228
267
|
const include = [];
|
|
229
268
|
const exclude = [];
|
|
@@ -255,7 +294,7 @@ function parseLine(line, lineNo) {
|
|
|
255
294
|
exclude: exclude.length ? exclude : void 0
|
|
256
295
|
};
|
|
257
296
|
}
|
|
258
|
-
function parseStructureText(text) {
|
|
297
|
+
function parseStructureText(text, indentStep = 2) {
|
|
259
298
|
const lines = text.split(/\r?\n/);
|
|
260
299
|
const parsed = [];
|
|
261
300
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -265,15 +304,14 @@ function parseStructureText(text) {
|
|
|
265
304
|
}
|
|
266
305
|
const rootEntries = [];
|
|
267
306
|
const stack = [];
|
|
268
|
-
const INDENT_STEP = 2;
|
|
269
307
|
for (const p of parsed) {
|
|
270
308
|
const { indentSpaces, lineNo } = p;
|
|
271
|
-
if (indentSpaces %
|
|
309
|
+
if (indentSpaces % indentStep !== 0) {
|
|
272
310
|
throw new Error(
|
|
273
|
-
`structure.txt: Invalid indent on line ${lineNo}. Indent must be multiples of ${
|
|
311
|
+
`structure.txt: Invalid indent on line ${lineNo}. Indent must be multiples of ${indentStep} spaces.`
|
|
274
312
|
);
|
|
275
313
|
}
|
|
276
|
-
const level = indentSpaces /
|
|
314
|
+
const level = indentSpaces / indentStep;
|
|
277
315
|
if (level > stack.length) {
|
|
278
316
|
if (level !== stack.length + 1) {
|
|
279
317
|
throw new Error(
|
|
@@ -896,7 +934,10 @@ const config: ScaffoldConfig = {
|
|
|
896
934
|
// base: 'src', // apply to <root>/src
|
|
897
935
|
// base: '..', // apply to parent of <root>
|
|
898
936
|
// base: '.',
|
|
899
|
-
|
|
937
|
+
|
|
938
|
+
// Number of spaces per indent level in structure files (default: 2).
|
|
939
|
+
// indentStep: 2,
|
|
940
|
+
|
|
900
941
|
// Cache file path, relative to base.
|
|
901
942
|
// cacheFile: '.scaffold-cache.json',
|
|
902
943
|
|
|
@@ -928,7 +969,7 @@ const config: ScaffoldConfig = {
|
|
|
928
969
|
|
|
929
970
|
export default config;
|
|
930
971
|
`;
|
|
931
|
-
var DEFAULT_STRUCTURE_TXT = `#
|
|
972
|
+
var DEFAULT_STRUCTURE_TXT = `# ${SCAFFOLD_ROOT_DIR}/structure.txt
|
|
932
973
|
# Example structure definition.
|
|
933
974
|
# - Indent with 2 spaces per level
|
|
934
975
|
# - Directories must end with "/"
|
|
@@ -940,7 +981,7 @@ var DEFAULT_STRUCTURE_TXT = `# scaffold/structure.txt
|
|
|
940
981
|
# index.ts
|
|
941
982
|
`;
|
|
942
983
|
async function initScaffold(cwd, options = {}) {
|
|
943
|
-
const scaffoldDirRel = options.scaffoldDir ??
|
|
984
|
+
const scaffoldDirRel = options.scaffoldDir ?? SCAFFOLD_ROOT_DIR;
|
|
944
985
|
const scaffoldDirAbs = path2__default.default.resolve(cwd, scaffoldDirRel);
|
|
945
986
|
const configFileName = options.configFileName ?? "config.ts";
|
|
946
987
|
const structureFileName = options.structureFileName ?? "structure.txt";
|