@timeax/scaffold 0.0.1 → 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 +115 -14
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +115 -14
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +91 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -1
- package/dist/index.d.ts +84 -1
- package/dist/index.mjs +88 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
- package/readme.md +184 -46
- package/scripts/postpublish.mjs +72 -0
- package/scripts/prepublish.mjs +95 -0
- package/src/cli/main.ts +38 -0
- package/src/core/config-loader.ts +4 -3
- package/src/core/init-scaffold.ts +8 -3
- package/src/core/scan-structure.ts +71 -0
- 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/index.d.cts
CHANGED
|
@@ -305,6 +305,15 @@ interface ScaffoldConfig {
|
|
|
305
305
|
* runner / CLI.
|
|
306
306
|
*/
|
|
307
307
|
watch?: boolean;
|
|
308
|
+
/**
|
|
309
|
+
* Number of spaces per indent level in structure files.
|
|
310
|
+
* Default: 2.
|
|
311
|
+
*
|
|
312
|
+
* Examples:
|
|
313
|
+
* - 2 → "··entry"
|
|
314
|
+
* - 4 → "····entry"
|
|
315
|
+
*/
|
|
316
|
+
indentStep?: number;
|
|
308
317
|
}
|
|
309
318
|
/**
|
|
310
319
|
* Options when scanning an existing directory into a structure.txt tree.
|
|
@@ -336,6 +345,8 @@ interface ScanFromConfigOptions extends ScanStructureOptions {
|
|
|
336
345
|
scaffoldDir?: string;
|
|
337
346
|
}
|
|
338
347
|
|
|
348
|
+
declare const SCAFFOLD_ROOT_DIR = ".scaffold";
|
|
349
|
+
|
|
339
350
|
type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
|
|
340
351
|
interface LoggerOptions {
|
|
341
352
|
level?: LogLevel;
|
|
@@ -394,6 +405,49 @@ interface RunOptions {
|
|
|
394
405
|
*/
|
|
395
406
|
declare function runOnce(cwd: string, options?: RunOptions): Promise<void>;
|
|
396
407
|
|
|
408
|
+
interface LoadScaffoldConfigOptions {
|
|
409
|
+
/**
|
|
410
|
+
* Optional explicit scaffold directory path (absolute or relative to cwd).
|
|
411
|
+
* If provided, this overrides config.root for locating the scaffold folder.
|
|
412
|
+
*/
|
|
413
|
+
scaffoldDir?: string;
|
|
414
|
+
/**
|
|
415
|
+
* Optional explicit config file path (absolute or relative to cwd).
|
|
416
|
+
* If not provided, we look for config.* inside the scaffoldDir.
|
|
417
|
+
*/
|
|
418
|
+
configPath?: string;
|
|
419
|
+
}
|
|
420
|
+
interface LoadScaffoldConfigResult {
|
|
421
|
+
/**
|
|
422
|
+
* Parsed scaffold configuration.
|
|
423
|
+
*/
|
|
424
|
+
config: ScaffoldConfig;
|
|
425
|
+
/**
|
|
426
|
+
* Absolute path to the scaffold directory (where config & *.txt live).
|
|
427
|
+
*/
|
|
428
|
+
scaffoldDir: string;
|
|
429
|
+
/**
|
|
430
|
+
* Effective project root BASE where structures are applied.
|
|
431
|
+
* This is derived from config.root + config.base.
|
|
432
|
+
*/
|
|
433
|
+
projectRoot: string;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Load scaffold configuration based on CWD + optional overrides + config.root/base.
|
|
437
|
+
*
|
|
438
|
+
* Resolution rules:
|
|
439
|
+
* - configRoot:
|
|
440
|
+
* - Start from cwd.
|
|
441
|
+
* - Apply config.root (if defined) as a path relative to cwd.
|
|
442
|
+
* - scaffoldDir:
|
|
443
|
+
* - If options.scaffoldDir is provided → use it as-is (resolved from cwd).
|
|
444
|
+
* - Else → <configRoot>/scaffold.
|
|
445
|
+
* - projectRoot (base):
|
|
446
|
+
* - If config.base is defined → resolve relative to configRoot.
|
|
447
|
+
* - Else → configRoot.
|
|
448
|
+
*/
|
|
449
|
+
declare function loadScaffoldConfig(cwd: string, options?: LoadScaffoldConfigOptions): Promise<LoadScaffoldConfigResult>;
|
|
450
|
+
|
|
397
451
|
/**
|
|
398
452
|
* Generate a structure.txt-style tree from an existing directory.
|
|
399
453
|
*
|
|
@@ -435,5 +489,34 @@ declare function scanProjectFromConfig(cwd: string, options?: ScanFromConfigOpti
|
|
|
435
489
|
* structure files.
|
|
436
490
|
*/
|
|
437
491
|
declare function writeScannedStructuresFromConfig(cwd: string, options?: ScanFromConfigOptions): Promise<void>;
|
|
492
|
+
interface EnsureStructuresResult {
|
|
493
|
+
created: string[];
|
|
494
|
+
existing: string[];
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Ensure all structure files declared in the config exist.
|
|
498
|
+
*
|
|
499
|
+
* - Grouped mode: one file per group (group.structureFile || `${group.name}.txt`)
|
|
500
|
+
* - Single-root mode: config.structureFile || "structure.txt"
|
|
501
|
+
*
|
|
502
|
+
* Existing files are left untouched. Only missing files are created with
|
|
503
|
+
* a small header comment.
|
|
504
|
+
*/
|
|
505
|
+
declare function ensureStructureFilesFromConfig(cwd: string, options?: {
|
|
506
|
+
scaffoldDirOverride?: string;
|
|
507
|
+
}): Promise<EnsureStructuresResult>;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Convert a structure.txt content into a nested StructureEntry[].
|
|
511
|
+
*
|
|
512
|
+
* Rules:
|
|
513
|
+
* - Indentation is **indentStep** spaces per level (default: 2).
|
|
514
|
+
* - Indent must be a multiple of indentStep.
|
|
515
|
+
* - You cannot "skip" levels (no jumping from level 0 to 2 directly).
|
|
516
|
+
* - **Only directories can have children**:
|
|
517
|
+
* - If you indent under a file, an error is thrown.
|
|
518
|
+
* - Folders must end with "/" in the txt; paths are normalized to POSIX.
|
|
519
|
+
*/
|
|
520
|
+
declare function parseStructureText(text: string, indentStep?: number): StructureEntry[];
|
|
438
521
|
|
|
439
|
-
export { type BaseEntryOptions, type DirEntry, type FileEntry, type HookContext, type HookFilter, type RegularHookConfig, type RegularHookFn, type RegularHookKind, type RunOptions, type ScaffoldConfig, type ScanFromConfigOptions, type ScanFromConfigResult, type ScanStructureOptions, type StructureEntry, type StructureGroupConfig, type StubConfig, type StubHookConfig, type StubHookFn, type StubHookKind, runOnce, scanDirectoryToStructureText, scanProjectFromConfig, writeScannedStructuresFromConfig };
|
|
522
|
+
export { type BaseEntryOptions, type DirEntry, type EnsureStructuresResult, type FileEntry, type HookContext, type HookFilter, type LoadScaffoldConfigOptions, type LoadScaffoldConfigResult, type RegularHookConfig, type RegularHookFn, type RegularHookKind, type RunOptions, SCAFFOLD_ROOT_DIR, type ScaffoldConfig, type ScanFromConfigOptions, type ScanFromConfigResult, type ScanStructureOptions, type StructureEntry, type StructureGroupConfig, type StubConfig, type StubHookConfig, type StubHookFn, type StubHookKind, ensureStructureFilesFromConfig, loadScaffoldConfig, parseStructureText, runOnce, scanDirectoryToStructureText, scanProjectFromConfig, writeScannedStructuresFromConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -305,6 +305,15 @@ interface ScaffoldConfig {
|
|
|
305
305
|
* runner / CLI.
|
|
306
306
|
*/
|
|
307
307
|
watch?: boolean;
|
|
308
|
+
/**
|
|
309
|
+
* Number of spaces per indent level in structure files.
|
|
310
|
+
* Default: 2.
|
|
311
|
+
*
|
|
312
|
+
* Examples:
|
|
313
|
+
* - 2 → "··entry"
|
|
314
|
+
* - 4 → "····entry"
|
|
315
|
+
*/
|
|
316
|
+
indentStep?: number;
|
|
308
317
|
}
|
|
309
318
|
/**
|
|
310
319
|
* Options when scanning an existing directory into a structure.txt tree.
|
|
@@ -336,6 +345,8 @@ interface ScanFromConfigOptions extends ScanStructureOptions {
|
|
|
336
345
|
scaffoldDir?: string;
|
|
337
346
|
}
|
|
338
347
|
|
|
348
|
+
declare const SCAFFOLD_ROOT_DIR = ".scaffold";
|
|
349
|
+
|
|
339
350
|
type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
|
|
340
351
|
interface LoggerOptions {
|
|
341
352
|
level?: LogLevel;
|
|
@@ -394,6 +405,49 @@ interface RunOptions {
|
|
|
394
405
|
*/
|
|
395
406
|
declare function runOnce(cwd: string, options?: RunOptions): Promise<void>;
|
|
396
407
|
|
|
408
|
+
interface LoadScaffoldConfigOptions {
|
|
409
|
+
/**
|
|
410
|
+
* Optional explicit scaffold directory path (absolute or relative to cwd).
|
|
411
|
+
* If provided, this overrides config.root for locating the scaffold folder.
|
|
412
|
+
*/
|
|
413
|
+
scaffoldDir?: string;
|
|
414
|
+
/**
|
|
415
|
+
* Optional explicit config file path (absolute or relative to cwd).
|
|
416
|
+
* If not provided, we look for config.* inside the scaffoldDir.
|
|
417
|
+
*/
|
|
418
|
+
configPath?: string;
|
|
419
|
+
}
|
|
420
|
+
interface LoadScaffoldConfigResult {
|
|
421
|
+
/**
|
|
422
|
+
* Parsed scaffold configuration.
|
|
423
|
+
*/
|
|
424
|
+
config: ScaffoldConfig;
|
|
425
|
+
/**
|
|
426
|
+
* Absolute path to the scaffold directory (where config & *.txt live).
|
|
427
|
+
*/
|
|
428
|
+
scaffoldDir: string;
|
|
429
|
+
/**
|
|
430
|
+
* Effective project root BASE where structures are applied.
|
|
431
|
+
* This is derived from config.root + config.base.
|
|
432
|
+
*/
|
|
433
|
+
projectRoot: string;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Load scaffold configuration based on CWD + optional overrides + config.root/base.
|
|
437
|
+
*
|
|
438
|
+
* Resolution rules:
|
|
439
|
+
* - configRoot:
|
|
440
|
+
* - Start from cwd.
|
|
441
|
+
* - Apply config.root (if defined) as a path relative to cwd.
|
|
442
|
+
* - scaffoldDir:
|
|
443
|
+
* - If options.scaffoldDir is provided → use it as-is (resolved from cwd).
|
|
444
|
+
* - Else → <configRoot>/scaffold.
|
|
445
|
+
* - projectRoot (base):
|
|
446
|
+
* - If config.base is defined → resolve relative to configRoot.
|
|
447
|
+
* - Else → configRoot.
|
|
448
|
+
*/
|
|
449
|
+
declare function loadScaffoldConfig(cwd: string, options?: LoadScaffoldConfigOptions): Promise<LoadScaffoldConfigResult>;
|
|
450
|
+
|
|
397
451
|
/**
|
|
398
452
|
* Generate a structure.txt-style tree from an existing directory.
|
|
399
453
|
*
|
|
@@ -435,5 +489,34 @@ declare function scanProjectFromConfig(cwd: string, options?: ScanFromConfigOpti
|
|
|
435
489
|
* structure files.
|
|
436
490
|
*/
|
|
437
491
|
declare function writeScannedStructuresFromConfig(cwd: string, options?: ScanFromConfigOptions): Promise<void>;
|
|
492
|
+
interface EnsureStructuresResult {
|
|
493
|
+
created: string[];
|
|
494
|
+
existing: string[];
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Ensure all structure files declared in the config exist.
|
|
498
|
+
*
|
|
499
|
+
* - Grouped mode: one file per group (group.structureFile || `${group.name}.txt`)
|
|
500
|
+
* - Single-root mode: config.structureFile || "structure.txt"
|
|
501
|
+
*
|
|
502
|
+
* Existing files are left untouched. Only missing files are created with
|
|
503
|
+
* a small header comment.
|
|
504
|
+
*/
|
|
505
|
+
declare function ensureStructureFilesFromConfig(cwd: string, options?: {
|
|
506
|
+
scaffoldDirOverride?: string;
|
|
507
|
+
}): Promise<EnsureStructuresResult>;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Convert a structure.txt content into a nested StructureEntry[].
|
|
511
|
+
*
|
|
512
|
+
* Rules:
|
|
513
|
+
* - Indentation is **indentStep** spaces per level (default: 2).
|
|
514
|
+
* - Indent must be a multiple of indentStep.
|
|
515
|
+
* - You cannot "skip" levels (no jumping from level 0 to 2 directly).
|
|
516
|
+
* - **Only directories can have children**:
|
|
517
|
+
* - If you indent under a file, an error is thrown.
|
|
518
|
+
* - Folders must end with "/" in the txt; paths are normalized to POSIX.
|
|
519
|
+
*/
|
|
520
|
+
declare function parseStructureText(text: string, indentStep?: number): StructureEntry[];
|
|
438
521
|
|
|
439
|
-
export { type BaseEntryOptions, type DirEntry, type FileEntry, type HookContext, type HookFilter, type RegularHookConfig, type RegularHookFn, type RegularHookKind, type RunOptions, type ScaffoldConfig, type ScanFromConfigOptions, type ScanFromConfigResult, type ScanStructureOptions, type StructureEntry, type StructureGroupConfig, type StubConfig, type StubHookConfig, type StubHookFn, type StubHookKind, runOnce, scanDirectoryToStructureText, scanProjectFromConfig, writeScannedStructuresFromConfig };
|
|
522
|
+
export { type BaseEntryOptions, type DirEntry, type EnsureStructuresResult, type FileEntry, type HookContext, type HookFilter, type LoadScaffoldConfigOptions, type LoadScaffoldConfigResult, type RegularHookConfig, type RegularHookFn, type RegularHookKind, type RunOptions, SCAFFOLD_ROOT_DIR, type ScaffoldConfig, type ScanFromConfigOptions, type ScanFromConfigResult, type ScanStructureOptions, type StructureEntry, type StructureGroupConfig, type StubConfig, type StubHookConfig, type StubHookFn, type StubHookKind, ensureStructureFilesFromConfig, loadScaffoldConfig, parseStructureText, runOnce, scanDirectoryToStructureText, scanProjectFromConfig, writeScannedStructuresFromConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,8 @@ import { pathToFileURL } from 'url';
|
|
|
6
6
|
import { transform } from 'esbuild';
|
|
7
7
|
import { minimatch } from 'minimatch';
|
|
8
8
|
|
|
9
|
-
// src/
|
|
9
|
+
// src/schema/index.ts
|
|
10
|
+
var SCAFFOLD_ROOT_DIR = ".scaffold";
|
|
10
11
|
|
|
11
12
|
// src/util/logger.ts
|
|
12
13
|
var supportsColor = typeof process !== "undefined" && process.stdout && process.stdout.isTTY && process.env.NO_COLOR !== "1";
|
|
@@ -131,14 +132,14 @@ function toProjectRelativePath(projectRoot, absolutePath) {
|
|
|
131
132
|
var logger = defaultLogger.child("[config]");
|
|
132
133
|
async function loadScaffoldConfig(cwd, options = {}) {
|
|
133
134
|
const absCwd = path2.resolve(cwd);
|
|
134
|
-
const initialScaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(absCwd,
|
|
135
|
+
const initialScaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(absCwd, SCAFFOLD_ROOT_DIR);
|
|
135
136
|
const configPath = options.configPath ?? resolveConfigPath(initialScaffoldDir);
|
|
136
137
|
const config = await importConfig(configPath);
|
|
137
138
|
let configRoot = absCwd;
|
|
138
139
|
if (config.root) {
|
|
139
140
|
configRoot = path2.resolve(absCwd, config.root);
|
|
140
141
|
}
|
|
141
|
-
const scaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(configRoot,
|
|
142
|
+
const scaffoldDir = options.scaffoldDir ? path2.resolve(absCwd, options.scaffoldDir) : path2.join(configRoot, SCAFFOLD_ROOT_DIR);
|
|
142
143
|
const baseRoot = config.base ? path2.resolve(configRoot, config.base) : configRoot;
|
|
143
144
|
logger.debug(
|
|
144
145
|
`Loaded config: configRoot=${configRoot}, baseRoot=${baseRoot}, scaffoldDir=${scaffoldDir}`
|
|
@@ -203,14 +204,50 @@ async function importTsConfig(configPath) {
|
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
// src/core/structure-txt.ts
|
|
207
|
+
function stripInlineComment(content) {
|
|
208
|
+
let cutIndex = -1;
|
|
209
|
+
const len = content.length;
|
|
210
|
+
for (let i = 0; i < len; i++) {
|
|
211
|
+
const ch = content[i];
|
|
212
|
+
const prev = i > 0 ? content[i - 1] : "";
|
|
213
|
+
if (ch === "#") {
|
|
214
|
+
if (i === 0) continue;
|
|
215
|
+
if (prev === " " || prev === " ") {
|
|
216
|
+
cutIndex = i;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (ch === "/" && i + 1 < len && content[i + 1] === "/" && (prev === " " || prev === " ")) {
|
|
221
|
+
cutIndex = i;
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (cutIndex === -1) {
|
|
226
|
+
return content.trimEnd();
|
|
227
|
+
}
|
|
228
|
+
return content.slice(0, cutIndex).trimEnd();
|
|
229
|
+
}
|
|
206
230
|
function parseLine(line, lineNo) {
|
|
207
|
-
const match = line.match(/^(\s*)(
|
|
231
|
+
const match = line.match(/^(\s*)(.*)$/);
|
|
208
232
|
if (!match) return null;
|
|
209
233
|
const indentSpaces = match[1].length;
|
|
210
|
-
|
|
211
|
-
if (!rest
|
|
212
|
-
const
|
|
234
|
+
let rest = match[2];
|
|
235
|
+
if (!rest.trim()) return null;
|
|
236
|
+
const trimmedRest = rest.trimStart();
|
|
237
|
+
if (trimmedRest.startsWith("#") || trimmedRest.startsWith("//")) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
const stripped = stripInlineComment(rest);
|
|
241
|
+
const trimmed = stripped.trim();
|
|
242
|
+
if (!trimmed) return null;
|
|
243
|
+
const parts = trimmed.split(/\s+/);
|
|
244
|
+
if (!parts.length) return null;
|
|
213
245
|
const pathToken = parts[0];
|
|
246
|
+
if (pathToken.includes(":")) {
|
|
247
|
+
throw new Error(
|
|
248
|
+
`structure.txt: ":" is reserved for annotations (@stub:, @include:, etc). Invalid path "${pathToken}" on line ${lineNo}.`
|
|
249
|
+
);
|
|
250
|
+
}
|
|
214
251
|
let stub;
|
|
215
252
|
const include = [];
|
|
216
253
|
const exclude = [];
|
|
@@ -242,7 +279,7 @@ function parseLine(line, lineNo) {
|
|
|
242
279
|
exclude: exclude.length ? exclude : void 0
|
|
243
280
|
};
|
|
244
281
|
}
|
|
245
|
-
function parseStructureText(text) {
|
|
282
|
+
function parseStructureText(text, indentStep = 2) {
|
|
246
283
|
const lines = text.split(/\r?\n/);
|
|
247
284
|
const parsed = [];
|
|
248
285
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -252,15 +289,14 @@ function parseStructureText(text) {
|
|
|
252
289
|
}
|
|
253
290
|
const rootEntries = [];
|
|
254
291
|
const stack = [];
|
|
255
|
-
const INDENT_STEP = 2;
|
|
256
292
|
for (const p of parsed) {
|
|
257
293
|
const { indentSpaces, lineNo } = p;
|
|
258
|
-
if (indentSpaces %
|
|
294
|
+
if (indentSpaces % indentStep !== 0) {
|
|
259
295
|
throw new Error(
|
|
260
|
-
`structure.txt: Invalid indent on line ${lineNo}. Indent must be multiples of ${
|
|
296
|
+
`structure.txt: Invalid indent on line ${lineNo}. Indent must be multiples of ${indentStep} spaces.`
|
|
261
297
|
);
|
|
262
298
|
}
|
|
263
|
-
const level = indentSpaces /
|
|
299
|
+
const level = indentSpaces / indentStep;
|
|
264
300
|
if (level > stack.length) {
|
|
265
301
|
if (level !== stack.length + 1) {
|
|
266
302
|
throw new Error(
|
|
@@ -767,7 +803,46 @@ async function writeScannedStructuresFromConfig(cwd, options = {}) {
|
|
|
767
803
|
);
|
|
768
804
|
}
|
|
769
805
|
}
|
|
806
|
+
async function ensureStructureFilesFromConfig(cwd, options = {}) {
|
|
807
|
+
const { config, scaffoldDir } = await loadScaffoldConfig(cwd, {
|
|
808
|
+
scaffoldDir: options.scaffoldDirOverride
|
|
809
|
+
});
|
|
810
|
+
ensureDirSync(scaffoldDir);
|
|
811
|
+
const created = [];
|
|
812
|
+
const existing = [];
|
|
813
|
+
const seen = /* @__PURE__ */ new Set();
|
|
814
|
+
const ensureFile = (fileName) => {
|
|
815
|
+
if (!fileName) return;
|
|
816
|
+
const filePath = path2.join(scaffoldDir, fileName);
|
|
817
|
+
const key = path2.resolve(filePath);
|
|
818
|
+
if (seen.has(key)) return;
|
|
819
|
+
seen.add(key);
|
|
820
|
+
if (fs2.existsSync(filePath)) {
|
|
821
|
+
existing.push(filePath);
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
const header = `# ${fileName}
|
|
825
|
+
# Structure file for @timeax/scaffold
|
|
826
|
+
# Define your desired folders/files here.
|
|
827
|
+
`;
|
|
828
|
+
fs2.writeFileSync(filePath, header, "utf8");
|
|
829
|
+
created.push(filePath);
|
|
830
|
+
};
|
|
831
|
+
if (config.groups && config.groups.length > 0) {
|
|
832
|
+
for (const group of config.groups) {
|
|
833
|
+
const fileName = group.structureFile ?? `${group.name}.txt`;
|
|
834
|
+
ensureFile(fileName);
|
|
835
|
+
}
|
|
836
|
+
} else {
|
|
837
|
+
const fileName = config.structureFile ?? "structure.txt";
|
|
838
|
+
ensureFile(fileName);
|
|
839
|
+
}
|
|
840
|
+
logger4.debug(
|
|
841
|
+
`ensureStructureFilesFromConfig: created=${created.length}, existing=${existing.length}`
|
|
842
|
+
);
|
|
843
|
+
return { created, existing };
|
|
844
|
+
}
|
|
770
845
|
|
|
771
|
-
export { runOnce, scanDirectoryToStructureText, scanProjectFromConfig, writeScannedStructuresFromConfig };
|
|
846
|
+
export { SCAFFOLD_ROOT_DIR, ensureStructureFilesFromConfig, loadScaffoldConfig, parseStructureText, runOnce, scanDirectoryToStructureText, scanProjectFromConfig, writeScannedStructuresFromConfig };
|
|
772
847
|
//# sourceMappingURL=index.mjs.map
|
|
773
848
|
//# sourceMappingURL=index.mjs.map
|