Skip to content

Commit 02a462f

Browse files
committed
refactor: wip
1 parent ec356e0 commit 02a462f

10 files changed

Lines changed: 81 additions & 34 deletions

File tree

testing/test-utils/src/lib/utils/execute-process.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** THIS IS A COPY OF THE UTILS PACKAGE AND TESTED THERE **/
12
import { execFile } from 'node:child_process';
23
import { promisify } from 'node:util';
34

tools/zod2md-jsdocs/src/lib/generators/configuration/generator.int.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,18 @@ describe('configurationGenerator', () => {
1313
let tree: Tree;
1414
const testProjectName = 'test-app';
1515
const loggerInfoSpy = vi.spyOn(logger, 'info');
16+
1617
beforeEach(() => {
1718
tree = createTreeWithEmptyWorkspace();
1819
addProjectConfiguration(tree, 'test-app', {
1920
root: 'test-app',
2021
});
2122
});
23+
2224
afterEach(() => {
2325
tree.delete(testProjectName);
2426
});
27+
2528
it('should skip config creation if skipConfig is used', async () => {
2629
await configurationGenerator(tree, {
2730
project: testProjectName,
@@ -38,6 +41,7 @@ describe('configurationGenerator', () => {
3841
).toBeNull();
3942
expect(loggerInfoSpy).toHaveBeenCalledWith('Skip config file creation');
4043
});
44+
4145
it('should skip formatting', async () => {
4246
await configurationGenerator(tree, {
4347
project: testProjectName,

tools/zod2md-jsdocs/src/lib/generators/configuration/tsconfig.unit.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ describe('addZod2MdTransformToTsConfig', () => {
1212
testProjectName,
1313
DEFAULT_ZOD2MD_CONFIG_FILE_NAME,
1414
);
15+
1516
beforeEach(() => {
1617
tree = createTreeWithEmptyWorkspace();
1718
tree.write(
@@ -39,6 +40,7 @@ describe('addZod2MdTransformToTsConfig', () => {
3940
`,
4041
);
4142
});
43+
4244
it('should fail on missing tsconfig.json', () => {
4345
tree.delete(tsconfigLibPath);
4446
expect(() =>
@@ -48,6 +50,7 @@ describe('addZod2MdTransformToTsConfig', () => {
4850
}),
4951
).toThrow('No config tsconfig.json file exists.');
5052
});
53+
5154
it('should update tsconfig.lib.json with transform', () => {
5255
tree.write(
5356
tsconfigLibPath,
@@ -73,6 +76,7 @@ describe('addZod2MdTransformToTsConfig', () => {
7376
}),
7477
);
7578
});
79+
7680
it('should skip creation if config already configured', () => {
7781
expect(() =>
7882
addZod2MdTransformToTsConfig(tree, testProjectName, {

tools/zod2md-jsdocs/src/lib/generators/configuration/utils.unit.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,50 @@ describe('formatArrayToJSArray', () => {
1212
plugin2()]"
1313
`);
1414
});
15+
1516
it('should return empty array as JS for empty items', () => {
1617
expect(formatArrayToJSArray([])).toMatchInlineSnapshot('"[]"');
1718
});
19+
1820
it('should return undefined for undefined values', () => {
1921
expect(formatArrayToJSArray(undefined)).toBeUndefined();
2022
});
2123
});
24+
2225
describe('formatArrayToLinesOfJsString', () => {
2326
it('should return lines as JS', () => {
2427
expect(formatArrayToLinesOfJsString([`import plugin from "../nx-plugin";`]))
2528
.toMatchInlineSnapshot(`
2629
"import plugin from "../nx-plugin";"
2730
`);
2831
});
32+
2933
it('should return lines as JS with normalized quotes', () => {
3034
expect(
3135
formatArrayToLinesOfJsString([
3236
`import { CoreConfig } from '@zod2md/models';`,
3337
`import plugin from "../mx-plugin";`,
3438
]),
3539
).toMatchInlineSnapshot(`
36-
"import { CoreConfig } from "@zod2md/models";
37-
import plugin from "../mx-plugin";"
38-
`);
40+
"import { CoreConfig } from "@zod2md/models";
41+
import plugin from "../mx-plugin";"
42+
`);
3943
});
44+
4045
it('should return undefined for empty items', () => {
4146
expect(formatArrayToLinesOfJsString([])).toBeUndefined();
4247
});
48+
4349
it('should return undefined for nullish values', () => {
4450
expect(formatArrayToLinesOfJsString()).toBeUndefined();
4551
});
4652
});
53+
4754
describe('normalizeItemOrArray', () => {
4855
it('should turn string into string array', () => {
4956
expect(normalizeItemOrArray('myPlugin()')).toStrictEqual(['myPlugin()']);
5057
});
58+
5159
it('should keep string array', () => {
5260
expect(normalizeItemOrArray('myPlugin()')).toStrictEqual(['myPlugin()']);
5361
});

tools/zod2md-jsdocs/src/lib/generators/configuration/zod2md-config.ts

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,30 +52,38 @@ export function readDefaultExportObject<
5252
ts.ScriptTarget.Latest,
5353
true,
5454
);
55-
let result: Record<string, unknown> | null = null;
56-
source.forEachChild(node => {
55+
const matchingNode = source.getChildren().find(node => {
5756
if (!ts.isExportAssignment(node)) {
58-
return;
57+
return false;
5958
}
6059
const expr = ts.isSatisfiesExpression?.(node.expression)
6160
? node.expression.expression
6261
: node.expression;
63-
if (!ts.isObjectLiteralExpression(expr)) {
64-
return;
65-
}
66-
result = expr.properties.reduce<Record<string, string>>((acc, prop) => {
67-
if (
68-
ts.isPropertyAssignment(prop) &&
69-
ts.isIdentifier(prop.name) &&
70-
ts.isStringLiteral(prop.initializer)
71-
) {
72-
return {
73-
...acc,
74-
[prop.name.text]: prop.initializer.text,
75-
};
76-
}
77-
return acc;
78-
}, {});
62+
return ts.isObjectLiteralExpression(expr);
7963
});
64+
const result =
65+
matchingNode && ts.isExportAssignment(matchingNode)
66+
? (() => {
67+
const expr = ts.isSatisfiesExpression?.(matchingNode.expression)
68+
? matchingNode.expression.expression
69+
: matchingNode.expression;
70+
if (!ts.isObjectLiteralExpression(expr)) {
71+
return null;
72+
}
73+
return expr.properties.reduce<Record<string, string>>((acc, prop) => {
74+
if (
75+
ts.isPropertyAssignment(prop) &&
76+
ts.isIdentifier(prop.name) &&
77+
ts.isStringLiteral(prop.initializer)
78+
) {
79+
return {
80+
...acc,
81+
[prop.name.text]: prop.initializer.text,
82+
};
83+
}
84+
return acc;
85+
}, {});
86+
})()
87+
: null;
8088
return result as T | null;
8189
}

tools/zod2md-jsdocs/src/lib/generators/configuration/zod2md-config.unit.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ describe('generateZod2MdConfig options', () => {
99
const testProjectName = 'test-app';
1010
const generateFilesSpy = vi.spyOn(devKit, 'generateFiles');
1111
const loggerWarnSpy = vi.spyOn(devKit.logger, 'warn');
12+
1213
beforeEach(() => {
1314
tree = createTreeWithEmptyWorkspace();
1415
devKit.addProjectConfiguration(tree, testProjectName, {
1516
root: 'test-app',
1617
});
1718
});
19+
1820
afterEach(() => {
1921
generateFilesSpy.mockReset();
2022
});
23+
2124
it('should create zod2md.config.ts with options', () => {
2225
generateZod2MdConfig(tree, testProjectName, {
2326
entry: 'test-app/src/main.ts',
@@ -37,10 +40,12 @@ describe('generateZod2MdConfig options', () => {
3740
}),
3841
);
3942
});
43+
4044
it('should call generateFilesSpy', () => {
4145
generateZod2MdConfig(tree, testProjectName);
4246
expect(generateFilesSpy).toHaveBeenCalledOnce();
4347
});
48+
4449
it('should skip creation if config already exists', () => {
4550
tree.write(path.join(testProjectName, 'zod2md.config.js'), '');
4651
generateZod2MdConfig(tree, testProjectName);
@@ -52,6 +57,7 @@ describe('generateZod2MdConfig options', () => {
5257
),
5358
);
5459
});
60+
5561
it('should use correct templates', () => {
5662
generateZod2MdConfig(tree, testProjectName);
5763
expect(generateFilesSpy).toHaveBeenCalledWith(
@@ -70,6 +76,7 @@ describe('generateZod2MdConfig options', () => {
7076
expect.any(Object),
7177
);
7278
});
79+
7380
it('should use correct testProjectName', () => {
7481
generateZod2MdConfig(tree, testProjectName);
7582
expect(generateFilesSpy).toHaveBeenCalledWith(
@@ -79,6 +86,7 @@ describe('generateZod2MdConfig options', () => {
7986
expect.any(Object),
8087
);
8188
});
89+
8290
it('should use default options', () => {
8391
generateZod2MdConfig(tree, testProjectName);
8492
expect(generateFilesSpy).toHaveBeenCalledWith(

tools/zod2md-jsdocs/src/lib/generators/sync-zod2md-setup/sync-zod2md-setup.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,15 +213,19 @@ function formatIssues(issues: readonly SyncIssue[]): string | undefined {
213213
if (issues.length === 0) {
214214
return undefined;
215215
}
216-
const grouped = issues.reduce<
217-
Record<SyncIssue['type'], readonly SyncIssue[]>
218-
>(
219-
(acc, issue) => ({
220-
...acc,
221-
[issue.type]: [...(acc[issue.type] ?? []), issue],
222-
}),
223-
{} as Record<SyncIssue['type'], readonly SyncIssue[]>,
224-
);
216+
const grouped: Record<SyncIssue['type'], readonly SyncIssue[]> =
217+
issues.reduce<Record<SyncIssue['type'], readonly SyncIssue[]>>(
218+
(acc, issue) => ({
219+
...acc,
220+
[issue.type]: [...(acc[issue.type] ?? []), issue],
221+
}),
222+
{
223+
[missingTsconfig]: [],
224+
[missingTarget]: [],
225+
[missingBuildDeps]: [],
226+
[missingTsPlugin]: [],
227+
},
228+
);
225229
return [
226230
grouped[missingTsconfig]?.length
227231
? `Missing tsconfig in:\n${grouped[missingTsconfig]

tools/zod2md-jsdocs/src/lib/generators/sync-zod2md-setup/sync-zod2md-setup.unit.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('sync-zod2md-setup generator', () => {
3535
},
3636
tags: [],
3737
};
38+
3839
beforeEach(async () => {
3940
tree = await generateWorkspaceAndProject({
4041
name: 'test',
@@ -67,13 +68,15 @@ describe('sync-zod2md-setup generator', () => {
6768
},
6869
}));
6970
});
71+
7072
it('should pass if missing zod2md.config', async () => {
7173
tree.delete(zod2mdConfigPath);
7274
await expect(syncZod2mdSetupGenerator(tree)).resolves.toStrictEqual({
7375
outOfSyncMessage: undefined,
7476
});
7577
expect(tree.exists(zod2mdConfigPath)).toBeFalse();
7678
});
79+
7780
it('should fail if missing tsconfig file', async () => {
7881
tree.delete(`${projectRoot}/tsconfig.json`);
7982
tree.delete(`${projectRoot}/tsconfig.lib.json`);
@@ -83,6 +86,7 @@ describe('sync-zod2md-setup generator', () => {
8386
});
8487
expect(tree.exists(`${projectRoot}/zod2md.config.ts`)).toBeTrue();
8588
});
89+
8690
it('should fail if missing "zod2md" target in project config', async () => {
8791
updateJson(tree, `${projectRoot}/project.json`, config => ({
8892
...config,
@@ -125,6 +129,7 @@ describe('sync-zod2md-setup generator', () => {
125129
});
126130
expect(tree.exists(`${projectRoot}/zod2md.config.ts`)).toBeTrue();
127131
});
132+
128133
it('should fail if missing "dependsOn" targets in build target', async () => {
129134
updateJson(tree, `${projectRoot}/project.json`, config => ({
130135
...config,
@@ -161,6 +166,7 @@ describe('sync-zod2md-setup generator', () => {
161166
});
162167
expect(tree.exists(`${projectRoot}/zod2md.config.ts`)).toBeTrue();
163168
});
169+
164170
it('should fail if missing Zod2Md TypeScript plugin configuration', async () => {
165171
updateJson(tree, `${projectRoot}/tsconfig.lib.json`, config => ({
166172
...config,
@@ -176,11 +182,13 @@ describe('sync-zod2md-setup generator', () => {
176182
});
177183
expect(tree.exists(`${projectRoot}/zod2md.config.ts`)).toBeTrue();
178184
});
185+
179186
it('should pass if zod2md setup is correct', async () => {
180187
await expect(syncZod2mdSetupGenerator(tree)).resolves.toStrictEqual({
181188
outOfSyncMessage: undefined,
182189
});
183190
});
191+
184192
it('should not duplicate dependencies when they exist as objects', async () => {
185193
const objectFormDependsOn = [
186194
'^build',

tools/zod2md-jsdocs/src/lib/transformers/transformers.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { PluginConfig, TransformerExtras } from 'ts-patch';
2-
import type * as ts from 'typescript';
3-
import tsInstance from 'typescript';
2+
import * as ts from 'typescript';
43

54
export function generateJSDocComment(
65
typeName: string,
@@ -28,7 +27,7 @@ export function annotateTypeDefinitions(
2827
'Please configure it in your tsconfig.json plugins section.',
2928
);
3029
}
31-
const tsLib = extras?.ts ?? tsInstance;
30+
const tsLib = extras?.ts ?? ts;
3231
return (context: ts.TransformationContext) => {
3332
const visitor = (node: ts.Node): ts.Node => {
3433
if (

tools/zod2md-jsdocs/src/lib/transformers/transformers.unit.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ describe('generateJSDocComment', () => {
1717
"
1818
`);
1919
});
20+
2021
it('should use type name in description', () => {
2122
const result = generateJSDocComment('SchemaName123', 'https://example.com');
2223
expect(result).toContain('Type Definition: `SchemaName123`');
2324
});
25+
2426
it('should convert type name to lowercase in the link anchor', () => {
2527
const result = generateJSDocComment('SchemaName123', 'https://example.com');
2628
expect(result).toContain('#schemaname123');
2729
});
30+
2831
it('should baseUrl in the link', () => {
2932
const result = generateJSDocComment('Schema', 'https://example.com');
3033
expect(result).toContain('https://example.com#');

0 commit comments

Comments
 (0)