@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.
@@ -0,0 +1,102 @@
1
+ // test/parser-tree.spec.ts
2
+ import {describe, it, expect} from 'vitest';
3
+ import {parseStructureAst} from '../src/ast';
4
+
5
+ describe('parseStructureAst tree shape', () => {
6
+ it('builds a simple nested tree', () => {
7
+ const text = [
8
+ 'src/',
9
+ ' schema/',
10
+ ' index.ts',
11
+ ' field.ts',
12
+ ].join('\n');
13
+
14
+ const ast = parseStructureAst(text, {indentStep: 2, mode: 'loose'});
15
+
16
+ expect(ast.rootNodes).toHaveLength(1);
17
+ const src = ast.rootNodes[0];
18
+ if (src.type !== 'dir') throw new Error('src should be dir');
19
+ expect(src.name).toBe('src/');
20
+
21
+ const schema = src.children[0];
22
+ expect(schema.type).toBe('dir');
23
+ expect(schema.name).toBe('schema/');
24
+
25
+ const files = (schema as any).children;
26
+ expect(files.map((n: any) => n.name)).toEqual(['index.ts', 'field.ts']);
27
+ });
28
+
29
+ it('normalizes over-indented children under same parent in loose mode', () => {
30
+ const text = [
31
+ 'src/',
32
+ ' index.ts',
33
+ '',
34
+ ' schema/',
35
+ ' index.ts',
36
+ ' field.ts',
37
+ ].join('\n');
38
+
39
+ const ast = parseStructureAst(text, {indentStep: 2, mode: 'loose'});
40
+
41
+ const src = ast.rootNodes[0]!;
42
+ if (src.type !== 'dir') throw new Error('src should be dir');
43
+
44
+ const names = src.children.map((c) => c.name);
45
+ expect(names).toEqual(['index.ts', 'schema/']);
46
+
47
+ const schema = src.children[1]!;
48
+ if (schema.type !== 'dir') throw new Error('schema should be dir');
49
+
50
+ expect(schema.children.map((c) => c.name)).toEqual(['index.ts', 'field.ts']);
51
+ });
52
+
53
+ it('parses stub/include/exclude annotations onto nodes', () => {
54
+ const text = [
55
+ 'src/ @stub:root',
56
+ ' pages/ @stub:page @include:pages/** @exclude:pages/legacy/**',
57
+ ' home.tsx',
58
+ ].join('\n');
59
+
60
+ const ast = parseStructureAst(text, {indentStep: 2, mode: 'loose'});
61
+
62
+ const src = ast.rootNodes[0]!;
63
+ if (src.type !== 'dir') throw new Error('src should be dir');
64
+ expect(src.stub).toBe('root');
65
+
66
+ const pages = src.children[0]!;
67
+ if (pages.type !== 'dir') throw new Error('pages should be dir');
68
+ expect(pages.stub).toBe('page');
69
+ expect(pages.include).toEqual(['pages/**']);
70
+ expect(pages.exclude).toEqual(['pages/legacy/**']);
71
+ });
72
+
73
+ it('escalates certain diagnostics in strict mode', () => {
74
+ const text = [
75
+ 'src/',
76
+ ' schema/',
77
+ ' index.ts', // bad decrease (4 -> 3)
78
+ ].join('\n');
79
+
80
+ const loose = parseStructureAst(text, {indentStep: 2, mode: 'loose'});
81
+ const strict = parseStructureAst(text, {indentStep: 2, mode: 'strict'});
82
+
83
+ const looseDiag = loose.diagnostics.find((d) => d.code === 'indent-misaligned');
84
+ const strictDiag = strict.diagnostics.find((d) => d.code === 'indent-misaligned');
85
+
86
+ expect(looseDiag?.severity).toBe<'warning' | 'error'>('warning');
87
+ expect(strictDiag?.severity).toBe<'warning' | 'error'>('error');
88
+ });
89
+
90
+ it('reports indent-tabs when tabs are used in indentation', () => {
91
+ const text = [
92
+ 'src/',
93
+ '\tschema/',
94
+ ].join('\n');
95
+
96
+ const ast = parseStructureAst(text, {indentStep: 2, mode: 'loose'});
97
+
98
+ const diag = ast.diagnostics.find((d) => d.code === 'indent-tabs');
99
+ expect(diag).toBeDefined();
100
+ expect(diag?.line).toBe(2);
101
+ });
102
+ });
package/tsup.config.ts CHANGED
@@ -1,48 +1,66 @@
1
1
  // tsup.config.ts
2
- import { defineConfig } from 'tsup';
2
+ import {defineConfig} from 'tsup';
3
3
 
4
4
  export default defineConfig([
5
- // Library build (@timeax/scaffold import)
6
- {
7
- entry: ['src/index.ts'],
8
- outDir: 'dist',
9
- format: ['esm', 'cjs'],
10
- dts: true,
11
- sourcemap: true,
12
- clean: true,
13
- target: 'node18',
14
- platform: 'node',
15
- treeshake: true,
16
- splitting: false, // small lib, keep it simple
17
- outExtension({ format }) {
18
- return {
19
- // ESM .mjs, CJS .cjs
20
- js: format === 'esm' ? '.mjs' : '.cjs',
21
- };
22
- },
23
- },
5
+ {
6
+ entry: ['src/index.ts'],
7
+ outDir: 'dist',
8
+ format: ['esm', 'cjs'],
9
+ dts: true,
10
+ sourcemap: true,
11
+ clean: true,
12
+ target: 'node18',
13
+ platform: 'node',
14
+ treeshake: true,
15
+ splitting: false, // small lib, keep it simple
16
+ outExtension({format}) {
17
+ return {
18
+ // ESM → .mjs, CJS → .cjs
19
+ js: format === 'esm' ? '.mjs' : '.cjs',
20
+ };
21
+ },
22
+ },
24
23
 
25
- // CLI build (scaffold command)
26
- {
27
- entry: {
28
- cli: 'src/cli/main.ts',
29
- },
30
- outDir: 'dist',
31
- format: ['esm', 'cjs'],
32
- dts: false,
33
- sourcemap: true,
34
- clean: false, // don't blow away the lib build
35
- target: 'node18',
36
- platform: 'node',
37
- treeshake: true,
38
- splitting: false,
39
- outExtension({ format }) {
40
- return {
41
- js: format === 'esm' ? '.mjs' : '.cjs',
42
- };
43
- },
44
- banner: {
45
- js: '#!/usr/bin/env node',
46
- },
47
- },
24
+ // CLI build (scaffold command)
25
+ {
26
+ entry: {
27
+ cli: 'src/cli/main.ts',
28
+ },
29
+ outDir: 'dist',
30
+ format: ['esm', 'cjs'],
31
+ dts: false,
32
+ sourcemap: true,
33
+ clean: false, // don't blow away the lib build
34
+ target: 'node18',
35
+ platform: 'node',
36
+ treeshake: true,
37
+ splitting: false,
38
+ outExtension({format}) {
39
+ return {
40
+ js: format === 'esm' ? '.mjs' : '.cjs',
41
+ };
42
+ },
43
+ banner: {
44
+ js: '#!/usr/bin/env node',
45
+ },
46
+ },
47
+ {
48
+ entry: {
49
+ ast: "src/ast/index.ts",
50
+ },
51
+ outDir: "dist",
52
+ format: ['esm', 'cjs'],
53
+ dts: true,
54
+ sourcemap: true,
55
+ clean: false,
56
+ target: 'node18',
57
+ platform: 'node',
58
+ treeshake: true,
59
+ splitting: false,
60
+ outExtension({format}) {
61
+ return {
62
+ js: format === 'esm' ? '.mjs' : '.cjs',
63
+ };
64
+ },
65
+ }
48
66
  ]);
@@ -0,0 +1,9 @@
1
+ // vitest.config.ts
2
+ import {defineConfig} from 'vitest/config';
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ // adjust these to your actual structure
7
+ include: ['test/**/*.spec.ts', 'tests/**/*.spec.ts'],
8
+ },
9
+ });