@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.mjs CHANGED
@@ -10,6 +10,9 @@ import { transform } from 'esbuild';
10
10
  import { minimatch } from 'minimatch';
11
11
  import chokidar from 'chokidar';
12
12
 
13
+ // src/schema/index.ts
14
+ var SCAFFOLD_ROOT_DIR = ".scaffold";
15
+
13
16
  // src/util/logger.ts
14
17
  var supportsColor = typeof process !== "undefined" && process.stdout && process.stdout.isTTY && process.env.NO_COLOR !== "1";
15
18
  function wrap(code) {
@@ -133,14 +136,14 @@ function toProjectRelativePath(projectRoot, absolutePath) {
133
136
  var logger = defaultLogger.child("[config]");
134
137
  async function loadScaffoldConfig(cwd, options = {}) {
135
138
  const absCwd = path2.resolve(cwd);
136
- const initialScaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(absCwd, "scaffold");
139
+ const initialScaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(absCwd, SCAFFOLD_ROOT_DIR);
137
140
  const configPath = options.configPath ?? resolveConfigPath(initialScaffoldDir);
138
141
  const config = await importConfig(configPath);
139
142
  let configRoot = absCwd;
140
143
  if (config.root) {
141
144
  configRoot = path2.resolve(absCwd, config.root);
142
145
  }
143
- const scaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(configRoot, "scaffold");
146
+ const scaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(configRoot, SCAFFOLD_ROOT_DIR);
144
147
  const baseRoot = config.base ? path2.resolve(configRoot, config.base) : configRoot;
145
148
  logger.debug(
146
149
  `Loaded config: configRoot=${configRoot}, baseRoot=${baseRoot}, scaffoldDir=${scaffoldDir}`
@@ -205,14 +208,50 @@ async function importTsConfig(configPath) {
205
208
  }
206
209
 
207
210
  // src/core/structure-txt.ts
211
+ function stripInlineComment(content) {
212
+ let cutIndex = -1;
213
+ const len = content.length;
214
+ for (let i = 0; i < len; i++) {
215
+ const ch = content[i];
216
+ const prev = i > 0 ? content[i - 1] : "";
217
+ if (ch === "#") {
218
+ if (i === 0) continue;
219
+ if (prev === " " || prev === " ") {
220
+ cutIndex = i;
221
+ break;
222
+ }
223
+ }
224
+ if (ch === "/" && i + 1 < len && content[i + 1] === "/" && (prev === " " || prev === " ")) {
225
+ cutIndex = i;
226
+ break;
227
+ }
228
+ }
229
+ if (cutIndex === -1) {
230
+ return content.trimEnd();
231
+ }
232
+ return content.slice(0, cutIndex).trimEnd();
233
+ }
208
234
  function parseLine(line, lineNo) {
209
- const match = line.match(/^(\s*)(.+)$/);
235
+ const match = line.match(/^(\s*)(.*)$/);
210
236
  if (!match) return null;
211
237
  const indentSpaces = match[1].length;
212
- const rest = match[2].trim();
213
- if (!rest || rest.startsWith("#")) return null;
214
- const parts = rest.split(/\s+/);
238
+ let rest = match[2];
239
+ if (!rest.trim()) return null;
240
+ const trimmedRest = rest.trimStart();
241
+ if (trimmedRest.startsWith("#") || trimmedRest.startsWith("//")) {
242
+ return null;
243
+ }
244
+ const stripped = stripInlineComment(rest);
245
+ const trimmed = stripped.trim();
246
+ if (!trimmed) return null;
247
+ const parts = trimmed.split(/\s+/);
248
+ if (!parts.length) return null;
215
249
  const pathToken = parts[0];
250
+ if (pathToken.includes(":")) {
251
+ throw new Error(
252
+ `structure.txt: ":" is reserved for annotations (@stub:, @include:, etc). Invalid path "${pathToken}" on line ${lineNo}.`
253
+ );
254
+ }
216
255
  let stub;
217
256
  const include = [];
218
257
  const exclude = [];
@@ -244,7 +283,7 @@ function parseLine(line, lineNo) {
244
283
  exclude: exclude.length ? exclude : void 0
245
284
  };
246
285
  }
247
- function parseStructureText(text) {
286
+ function parseStructureText(text, indentStep = 2) {
248
287
  const lines = text.split(/\r?\n/);
249
288
  const parsed = [];
250
289
  for (let i = 0; i < lines.length; i++) {
@@ -254,15 +293,14 @@ function parseStructureText(text) {
254
293
  }
255
294
  const rootEntries = [];
256
295
  const stack = [];
257
- const INDENT_STEP = 2;
258
296
  for (const p of parsed) {
259
297
  const { indentSpaces, lineNo } = p;
260
- if (indentSpaces % INDENT_STEP !== 0) {
298
+ if (indentSpaces % indentStep !== 0) {
261
299
  throw new Error(
262
- `structure.txt: Invalid indent on line ${lineNo}. Indent must be multiples of ${INDENT_STEP} spaces.`
300
+ `structure.txt: Invalid indent on line ${lineNo}. Indent must be multiples of ${indentStep} spaces.`
263
301
  );
264
302
  }
265
- const level = indentSpaces / INDENT_STEP;
303
+ const level = indentSpaces / indentStep;
266
304
  if (level > stack.length) {
267
305
  if (level !== stack.length + 1) {
268
306
  throw new Error(
@@ -885,7 +923,10 @@ const config: ScaffoldConfig = {
885
923
  // base: 'src', // apply to <root>/src
886
924
  // base: '..', // apply to parent of <root>
887
925
  // base: '.',
888
-
926
+
927
+ // Number of spaces per indent level in structure files (default: 2).
928
+ // indentStep: 2,
929
+
889
930
  // Cache file path, relative to base.
890
931
  // cacheFile: '.scaffold-cache.json',
891
932
 
@@ -917,7 +958,7 @@ const config: ScaffoldConfig = {
917
958
 
918
959
  export default config;
919
960
  `;
920
- var DEFAULT_STRUCTURE_TXT = `# scaffold/structure.txt
961
+ var DEFAULT_STRUCTURE_TXT = `# ${SCAFFOLD_ROOT_DIR}/structure.txt
921
962
  # Example structure definition.
922
963
  # - Indent with 2 spaces per level
923
964
  # - Directories must end with "/"
@@ -929,7 +970,7 @@ var DEFAULT_STRUCTURE_TXT = `# scaffold/structure.txt
929
970
  # index.ts
930
971
  `;
931
972
  async function initScaffold(cwd, options = {}) {
932
- const scaffoldDirRel = options.scaffoldDir ?? "scaffold";
973
+ const scaffoldDirRel = options.scaffoldDir ?? SCAFFOLD_ROOT_DIR;
933
974
  const scaffoldDirAbs = path2.resolve(cwd, scaffoldDirRel);
934
975
  const configFileName = options.configFileName ?? "config.ts";
935
976
  const structureFileName = options.structureFileName ?? "structure.txt";