@cparra/apexdocs 3.0.0-alpha.9 → 3.0.0-rc.0

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.
Files changed (82) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +442 -325
  3. package/dist/cli/generate.js +295 -205
  4. package/dist/index.d.ts +15 -17
  5. package/examples/markdown/docs/miscellaneous/Url.md +10 -8
  6. package/examples/markdown/force-app/classes/Url.cls +3 -1
  7. package/examples/markdown-jsconfig/.forceignore +12 -0
  8. package/examples/markdown-jsconfig/apexdocs.config.mjs +21 -0
  9. package/examples/markdown-jsconfig/config/project-scratch-def.json +5 -0
  10. package/examples/markdown-jsconfig/docs/index.md +12 -0
  11. package/examples/markdown-jsconfig/docs/miscellaneous/Url.md +315 -0
  12. package/examples/markdown-jsconfig/force-app/classes/Url.cls +196 -0
  13. package/examples/markdown-jsconfig/package-lock.json +665 -0
  14. package/examples/markdown-jsconfig/package.json +15 -0
  15. package/examples/markdown-jsconfig/sfdx-project.json +12 -0
  16. package/examples/open-api/config/project-scratch-def.json +13 -0
  17. package/examples/open-api/docs/openapi.json +582 -0
  18. package/examples/{force-app → open-api/force-app}/main/default/classes/SampleClass.cls +1 -0
  19. package/examples/open-api/package-lock.json +724 -0
  20. package/examples/open-api/package.json +20 -0
  21. package/examples/open-api/sfdx-project.json +12 -0
  22. package/examples/vitepress/apexdocs.config.ts +7 -2
  23. package/examples/vitepress/docs/index.md +11 -11
  24. package/examples/vitepress/docs/miscellaneous/BaseClass.md +1 -1
  25. package/examples/vitepress/docs/miscellaneous/MultiInheritanceClass.md +2 -2
  26. package/examples/vitepress/docs/miscellaneous/SampleException.md +1 -1
  27. package/examples/vitepress/docs/miscellaneous/SampleInterface.md +6 -6
  28. package/examples/vitepress/docs/miscellaneous/Url.md +3 -3
  29. package/examples/vitepress/docs/sample-enums/SampleEnum.md +3 -3
  30. package/examples/vitepress/docs/samplegroup/SampleClass.md +5 -5
  31. package/examples/vitepress/force-app/main/default/classes/SampleClass.cls +1 -1
  32. package/package.json +2 -2
  33. package/src/application/Apexdocs.ts +39 -7
  34. package/src/application/__tests__/apex-file-reader.spec.ts +0 -17
  35. package/src/application/file-writer.ts +37 -15
  36. package/src/application/generators/markdown.ts +10 -39
  37. package/src/application/generators/openapi.ts +22 -6
  38. package/src/cli/args.ts +4 -1
  39. package/src/cli/commands/markdown.ts +1 -3
  40. package/src/cli/commands/openapi.ts +36 -0
  41. package/src/core/markdown/__test__/generating-class-docs.spec.ts +1 -129
  42. package/src/core/markdown/__test__/generating-docs.spec.ts +111 -0
  43. package/src/core/markdown/__test__/generating-enum-docs.spec.ts +0 -64
  44. package/src/core/markdown/__test__/generating-interface-docs.spec.ts +0 -64
  45. package/src/core/markdown/adapters/documentables.ts +0 -1
  46. package/src/core/markdown/generate-docs.ts +2 -5
  47. package/src/core/markdown/reflection/__test__/filter-scope.spec.ts +306 -0
  48. package/src/core/markdown/reflection/reflect-source.ts +51 -50
  49. package/src/core/openApiSettings.ts +41 -0
  50. package/src/core/openapi/__tests__/open-api-docs-processor.spec.ts +2 -2
  51. package/src/core/openapi/open-api-docs-processor.ts +8 -4
  52. package/src/core/openapi/open-api.ts +5 -1
  53. package/src/core/openapi/openapi-type-file.ts +1 -1
  54. package/src/core/openapi/parser.ts +1 -15
  55. package/src/core/openapi/transpiler.ts +0 -5
  56. package/src/core/parse-apex-metadata.ts +21 -5
  57. package/src/core/shared/types.d.ts +18 -17
  58. package/src/index.ts +23 -10
  59. package/src/test-helpers/SettingsBuilder.ts +2 -6
  60. package/examples/force-app/main/default/classes/AnotherInterface.cls +0 -16
  61. package/examples/force-app/main/default/classes/EscapedAnnotations.cls +0 -5
  62. package/examples/force-app/main/default/classes/GrandparentClass.cls +0 -5
  63. package/examples/force-app/main/default/classes/GroupedClass.cls +0 -8
  64. package/examples/force-app/main/default/classes/InterfaceWithInheritance.cls +0 -1
  65. package/examples/force-app/main/default/classes/MemberGrouping.cls +0 -17
  66. package/examples/force-app/main/default/classes/ParentClass.cls +0 -16
  67. package/examples/force-app/main/default/classes/SampleClass.cls-meta.xml +0 -5
  68. package/examples/force-app/main/default/classes/SampleClassWithoutModifier.cls +0 -9
  69. package/examples/force-app/main/default/classes/SampleInterface.cls +0 -16
  70. package/src/core/settings.ts +0 -56
  71. /package/examples/{force-app → open-api/force-app}/main/default/classes/ChildClass.cls +0 -0
  72. /package/examples/{force-app → open-api/force-app}/main/default/restapi/SampleRestResource.cls +0 -0
  73. /package/examples/{force-app → open-api/force-app}/main/default/restapi/SampleRestResourceToSkip.cls +0 -0
  74. /package/examples/{force-app → open-api/force-app}/main/default/restapi/SampleRestResourceWithInnerClass.cls +0 -0
  75. /package/examples/{force-app → open-api/force-app}/main/default/restapi/SampleRestResourceWithoutApexDocs.cls +0 -0
  76. /package/examples/{force-app → open-api/force-app}/main/default/restapi/references/Reference1.cls +0 -0
  77. /package/examples/{force-app → open-api/force-app}/main/default/restapi/references/Reference2.cls +0 -0
  78. /package/examples/{force-app → open-api/force-app}/main/default/restapi/references/Reference3.cls +0 -0
  79. /package/examples/{force-app → open-api/force-app}/main/default/restapi/references/Reference4.cls +0 -0
  80. /package/examples/{force-app → open-api/force-app}/main/default/restapi/references/Reference5.cls +0 -0
  81. /package/examples/{force-app → open-api/force-app}/main/default/restapi/references/Reference6.cls +0 -0
  82. /package/examples/{force-app → open-api/force-app}/main/default/restapi/references/Reference7.cls +0 -0
@@ -0,0 +1,306 @@
1
+ import { ParsedFile } from '../../../shared/types';
2
+ import { ClassMirror, EnumMirror, InterfaceMirror, reflect } from '@cparra/apex-reflection';
3
+ import { filterScope } from '../filter-scope';
4
+
5
+ function parsedFileFromRawString(raw: string): ParsedFile {
6
+ const { error, typeMirror } = reflect(raw);
7
+ if (error) {
8
+ throw new Error(error.message);
9
+ }
10
+
11
+ return {
12
+ source: {
13
+ filePath: 'test.cls',
14
+ name: typeMirror!.name,
15
+ type: typeMirror!.type_name,
16
+ },
17
+ type: typeMirror!,
18
+ };
19
+ }
20
+
21
+ describe('When filtering scope', () => {
22
+ it('filters out files with the @ignore annotation', () => {
23
+ const properties: [string, number][] = [
24
+ [
25
+ `
26
+ /**
27
+ * @ignore
28
+ */
29
+ global class MyClass {}
30
+ `,
31
+ 0,
32
+ ],
33
+ ['global class MyClass {}', 1],
34
+ ];
35
+
36
+ for (const [input, expected] of properties) {
37
+ const parsedFile = parsedFileFromRawString(input);
38
+
39
+ const result = filterScope(['global'], [parsedFile]);
40
+
41
+ expect(result).toHaveLength(expected);
42
+ }
43
+ });
44
+
45
+ describe('when scoping a class', () => {
46
+ it('filters out methods tagged with @ignore', () => {
47
+ const properties: [string, number][] = [
48
+ [
49
+ `
50
+ global class MyClass {
51
+ /**
52
+ * @ignore
53
+ */
54
+ global void myMethod() {}
55
+ }
56
+ `,
57
+ 0,
58
+ ],
59
+ [
60
+ `
61
+ global class MyClass {
62
+ global void myMethod() {}
63
+ }
64
+ `,
65
+ 1,
66
+ ],
67
+ ];
68
+
69
+ for (const [input, expected] of properties) {
70
+ const parsedFile = parsedFileFromRawString(input);
71
+
72
+ const result = filterScope(['global'], [parsedFile]);
73
+
74
+ expect((result[0].type as ClassMirror).methods).toHaveLength(expected);
75
+ }
76
+ });
77
+
78
+ it('filters out properties tagged with @ignore', () => {
79
+ const properties: [string, number][] = [
80
+ [
81
+ `
82
+ global class MyClass {
83
+ /**
84
+ * @ignore
85
+ */
86
+ global Integer myProperty { get; set; }
87
+ }
88
+ `,
89
+ 0,
90
+ ],
91
+ [
92
+ `
93
+ global class MyClass {
94
+ global Integer myProperty { get; set; }
95
+ }
96
+ `,
97
+ 1,
98
+ ],
99
+ ];
100
+
101
+ for (const [input, expected] of properties) {
102
+ const parsedFile = parsedFileFromRawString(input);
103
+
104
+ const result = filterScope(['global'], [parsedFile]);
105
+
106
+ expect((result[0].type as ClassMirror).properties).toHaveLength(expected);
107
+ }
108
+ });
109
+
110
+ it('filters out fields tagged with @ignore', () => {
111
+ const properties: [string, number][] = [
112
+ [
113
+ `
114
+ global class MyClass {
115
+ /**
116
+ * @ignore
117
+ */
118
+ global Integer myField;
119
+ }
120
+ `,
121
+ 0,
122
+ ],
123
+ [
124
+ `
125
+ global class MyClass {
126
+ global Integer myField;
127
+ }
128
+ `,
129
+ 1,
130
+ ],
131
+ ];
132
+
133
+ for (const [input, expected] of properties) {
134
+ const parsedFile = parsedFileFromRawString(input);
135
+
136
+ const result = filterScope(['global'], [parsedFile]);
137
+
138
+ expect((result[0].type as ClassMirror).fields).toHaveLength(expected);
139
+ }
140
+ });
141
+
142
+ it('filters out inner classes tagged with @ignore', () => {
143
+ const properties: [string, number][] = [
144
+ [
145
+ `
146
+ global class MyClass {
147
+ /**
148
+ * @ignore
149
+ */
150
+ global class InnerClass {}
151
+ }
152
+ `,
153
+ 0,
154
+ ],
155
+ [
156
+ `
157
+ global class MyClass {
158
+ global class InnerClass {}
159
+ }
160
+ `,
161
+ 1,
162
+ ],
163
+ ];
164
+
165
+ for (const [input, expected] of properties) {
166
+ const parsedFile = parsedFileFromRawString(input);
167
+
168
+ const result = filterScope(['global'], [parsedFile]);
169
+
170
+ expect((result[0].type as ClassMirror).classes).toHaveLength(expected);
171
+ }
172
+ });
173
+
174
+ it('filters out inner interfaces tagged with @ignore', () => {
175
+ const properties: [string, number][] = [
176
+ [
177
+ `
178
+ global class MyClass {
179
+ /**
180
+ * @ignore
181
+ */
182
+ global interface InnerInterface {}
183
+ }
184
+ `,
185
+ 0,
186
+ ],
187
+ [
188
+ `
189
+ global class MyClass {
190
+ global interface InnerInterface {}
191
+ }
192
+ `,
193
+ 1,
194
+ ],
195
+ ];
196
+
197
+ for (const [input, expected] of properties) {
198
+ const parsedFile = parsedFileFromRawString(input);
199
+
200
+ const result = filterScope(['global'], [parsedFile]);
201
+
202
+ expect((result[0].type as ClassMirror).interfaces).toHaveLength(expected);
203
+ }
204
+ });
205
+
206
+ it('filters out inner enums tagged with @ignore', () => {
207
+ const properties: [string, number][] = [
208
+ [
209
+ `
210
+ global class MyClass {
211
+ /**
212
+ * @ignore
213
+ */
214
+ global enum InnerEnum {}
215
+ }
216
+ `,
217
+ 0,
218
+ ],
219
+ [
220
+ `
221
+ global class MyClass {
222
+ global enum InnerEnum {}
223
+ }
224
+ `,
225
+ 1,
226
+ ],
227
+ ];
228
+
229
+ for (const [input, expected] of properties) {
230
+ const parsedFile = parsedFileFromRawString(input);
231
+
232
+ const result = filterScope(['global'], [parsedFile]);
233
+
234
+ expect((result[0].type as ClassMirror).enums).toHaveLength(expected);
235
+ }
236
+ });
237
+ });
238
+
239
+ describe('when scoping an interface', () => {
240
+ it('filters out methods tagged with @ignore', () => {
241
+ const properties: [string, number][] = [
242
+ [
243
+ `
244
+ global interface MyInterface {
245
+ /**
246
+ * @ignore
247
+ */
248
+ void myMethod();
249
+ }
250
+ `,
251
+ 0,
252
+ ],
253
+ [
254
+ `
255
+ global interface MyInterface {
256
+ void myMethod();
257
+ }
258
+ `,
259
+ 1,
260
+ ],
261
+ ];
262
+
263
+ for (const [input, expected] of properties) {
264
+ const parsedFile = parsedFileFromRawString(input);
265
+
266
+ const result = filterScope(['global'], [parsedFile]);
267
+
268
+ expect((result[0].type as InterfaceMirror).methods).toHaveLength(expected);
269
+ }
270
+ });
271
+ });
272
+
273
+ describe('when scoping an enum', () => {
274
+ it('never filters out enum values, even if tagged with @ignore', () => {
275
+ const properties: [string, number][] = [
276
+ [
277
+ `
278
+ global enum MyEnum {
279
+ /**
280
+ * @ignore
281
+ */
282
+ VALUE
283
+ }
284
+ `,
285
+ 1,
286
+ ],
287
+ [
288
+ `
289
+ global enum MyEnum {
290
+ VALUE
291
+ }
292
+ `,
293
+ 1,
294
+ ],
295
+ ];
296
+
297
+ for (const [input, expected] of properties) {
298
+ const parsedFile = parsedFileFromRawString(input);
299
+
300
+ const result = filterScope(['global'], [parsedFile]);
301
+
302
+ expect((result[0].type as EnumMirror).values).toHaveLength(expected);
303
+ }
304
+ });
305
+ });
306
+ });
@@ -1,13 +1,13 @@
1
1
  import { ParsedFile, UnparsedSourceFile } from '../../shared/types';
2
- //import * as E from 'fp-ts/Either';
3
2
  import * as TE from 'fp-ts/TaskEither';
3
+ import * as E from 'fp-ts/Either';
4
4
  import * as T from 'fp-ts/Task';
5
5
  import * as A from 'fp-ts/lib/Array';
6
- import { reflect as mirrorReflection, Type } from '@cparra/apex-reflection';
6
+ import { Annotation, reflect as mirrorReflection, Type } from '@cparra/apex-reflection';
7
7
  import { pipe } from 'fp-ts/function';
8
8
  import * as O from 'fp-ts/Option';
9
9
  import { parseApexMetadata } from '../../parse-apex-metadata';
10
- import { ParsingError } from '@cparra/apex-reflection/index';
10
+ import { ParsingError } from '@cparra/apex-reflection';
11
11
  import { apply } from '#utils/fp';
12
12
  import { Semigroup } from 'fp-ts/Semigroup';
13
13
 
@@ -37,20 +37,20 @@ async function reflectAsync(rawSource: string): Promise<Type> {
37
37
  });
38
38
  }
39
39
 
40
- export function myPipeSeq(apexBundles: UnparsedSourceFile[]) {
40
+ export function reflectBundles(apexBundles: UnparsedSourceFile[]) {
41
41
  const semiGroupReflectionError: Semigroup<ReflectionErrors> = {
42
42
  concat: (x, y) => new ReflectionErrors([...x.errors, ...y.errors]),
43
43
  };
44
44
  const Ap = TE.getApplicativeTaskValidation(T.ApplyPar, semiGroupReflectionError);
45
45
 
46
- return pipe(apexBundles, A.traverse(Ap)(myPipe));
46
+ return pipe(apexBundles, A.traverse(Ap)(reflectBundle));
47
47
  }
48
48
 
49
- function myPipe(apexBundle: UnparsedSourceFile): TE.TaskEither<ReflectionErrors, ParsedFile> {
49
+ function reflectBundle(apexBundle: UnparsedSourceFile): TE.TaskEither<ReflectionErrors, ParsedFile> {
50
50
  const convertToParsedFile: (typeMirror: Type) => ParsedFile = apply(toParsedFile, apexBundle.filePath);
51
- const withMetadata: (parsedFile: ParsedFile) => ParsedFile = apply(addMetadata, apexBundle.metadataContent);
51
+ const withMetadata = apply(addMetadata, apexBundle.metadataContent);
52
52
 
53
- return pipe(apexBundle, reflectAsTask, TE.map(convertToParsedFile), TE.map(withMetadata));
53
+ return pipe(apexBundle, reflectAsTask, TE.map(convertToParsedFile), TE.flatMap(withMetadata));
54
54
  }
55
55
 
56
56
  function reflectAsTask(apexBundle: UnparsedSourceFile): TE.TaskEither<ReflectionErrors, Type> {
@@ -72,51 +72,52 @@ function toParsedFile(filePath: string, typeMirror: Type): ParsedFile {
72
72
  };
73
73
  }
74
74
 
75
- function addMetadata(rawMetadataContent: string | null, parsedFile: ParsedFile) {
76
- return {
77
- ...parsedFile,
78
- type: addFileMetadataToTypeAnnotation(parsedFile.type, rawMetadataContent),
79
- };
75
+ function addMetadata(
76
+ rawMetadataContent: string | null,
77
+ parsedFile: ParsedFile,
78
+ ): TE.TaskEither<ReflectionErrors, ParsedFile> {
79
+ return TE.fromEither(
80
+ pipe(
81
+ parsedFile.type,
82
+ (type) => addFileMetadataToTypeAnnotation(type, rawMetadataContent),
83
+ E.map((type) => ({ ...parsedFile, type })),
84
+ E.mapLeft((error) => errorToReflectionErrors(error, parsedFile.source.filePath)),
85
+ ),
86
+ );
80
87
  }
81
88
 
82
- // TODO: Not Async below
83
-
84
- // export function reflectSourceCode(apexBundles: UnparsedSourceFile[]) {
85
- // return apexBundles.map(reflectSourceBody);
86
- // }
87
- //
88
- // function reflectSourceBody(apexBundle: UnparsedSourceFile): E.Either<ReflectionError, ParsedFile> {
89
- // const { filePath, content: input, metadataContent: metadata } = apexBundle;
90
- // const result = mirrorReflection(input);
91
- // return result.error
92
- // ? E.left(new ReflectionError(filePath, result.error.message))
93
- // : E.right({
94
- // source: {
95
- // filePath,
96
- // name: result.typeMirror!.name,
97
- // type: result.typeMirror!.type_name,
98
- // },
99
- // type: addFileMetadataToTypeAnnotation(result.typeMirror!, metadata),
100
- // });
101
- // }
102
-
103
- function addFileMetadataToTypeAnnotation(type: Type, metadata: string | null): Type {
89
+ function errorToReflectionErrors(error: Error, filePath: string): ReflectionErrors {
90
+ return new ReflectionErrors([new ReflectionError(filePath, error.message)]);
91
+ }
92
+
93
+ function addFileMetadataToTypeAnnotation(type: Type, metadata: string | null): E.Either<Error, Type> {
94
+ const concatAnnotationToType = apply(concatAnnotations, type);
95
+
104
96
  return pipe(
105
97
  O.fromNullable(metadata),
106
- O.map((metadata) => {
107
- // TODO: Do we need to error check this, as it is coming from an external library?
108
- // Or maybe what we do is return the Either from the parse-apex-metadata function?
109
- const metadataParams = parseApexMetadata(metadata);
110
- metadataParams.forEach((value, key) => {
111
- const declaration = `${key}: ${value}`;
112
- type.annotations.push({
113
- rawDeclaration: declaration,
114
- name: declaration,
115
- type: declaration,
116
- });
117
- });
118
- return type;
119
- }),
120
- O.getOrElse(() => type),
98
+ O.map(concatAnnotationToType),
99
+ O.getOrElse(() => E.right(type)),
121
100
  );
122
101
  }
102
+
103
+ function concatAnnotations(type: Type, metadataInput: string): E.Either<Error, Type> {
104
+ return pipe(
105
+ metadataInput,
106
+ parseApexMetadata,
107
+ E.map((metadataMap) => ({
108
+ ...type,
109
+ annotations: [...type.annotations, ...mapToAnnotations(metadataMap)],
110
+ })),
111
+ );
112
+ }
113
+
114
+ function mapToAnnotations(metadata: Map<string, string>): Annotation[] {
115
+ return Array.from(metadata.entries()).map(([key, value]) => {
116
+ const declaration = `${key}: ${value}`;
117
+ return {
118
+ name: declaration,
119
+ type: declaration,
120
+ rawDeclaration: declaration,
121
+ };
122
+ });
123
+ }
@@ -0,0 +1,41 @@
1
+ export interface SettingsConfig {
2
+ sourceDirectory: string;
3
+ outputDir: string;
4
+ openApiFileName: string;
5
+ namespace?: string;
6
+ openApiTitle?: string;
7
+ version: string;
8
+ }
9
+
10
+ export class OpenApiSettings {
11
+ private static instance: OpenApiSettings;
12
+
13
+ private constructor(public config: SettingsConfig) {}
14
+
15
+ public static build(config: SettingsConfig) {
16
+ OpenApiSettings.instance = new OpenApiSettings(config);
17
+ }
18
+
19
+ public static getInstance(): OpenApiSettings {
20
+ if (!OpenApiSettings.instance) {
21
+ throw new Error('Settings has not been initialized');
22
+ }
23
+ return OpenApiSettings.instance;
24
+ }
25
+
26
+ public getOpenApiTitle(): string | undefined {
27
+ return this.config.openApiTitle;
28
+ }
29
+
30
+ public getNamespace(): string | undefined {
31
+ return this.config.namespace;
32
+ }
33
+
34
+ public openApiFileName(): string {
35
+ return this.config.openApiFileName;
36
+ }
37
+
38
+ public getVersion(): string {
39
+ return this.config.version;
40
+ }
41
+ }
@@ -1,12 +1,12 @@
1
1
  import { OpenApiDocsProcessor } from '../open-api-docs-processor';
2
- import { Settings } from '../../settings';
2
+ import { OpenApiSettings } from '../../openApiSettings';
3
3
  import { SettingsBuilder } from '../../../test-helpers/SettingsBuilder';
4
4
  import { DocCommentBuilder } from '../../../test-helpers/DocCommentBuilder';
5
5
  import { AnnotationBuilder } from '../../../test-helpers/AnnotationBuilder';
6
6
  import { ClassMirrorBuilder } from '../../../test-helpers/ClassMirrorBuilder';
7
7
 
8
8
  beforeEach(() => {
9
- Settings.build(new SettingsBuilder().build());
9
+ OpenApiSettings.build(new SettingsBuilder().build());
10
10
  });
11
11
 
12
12
  it('should add a path based on the @UrlResource annotation on the class', function () {
@@ -2,7 +2,7 @@ import { FileContainer } from './file-container';
2
2
  import { ClassMirror, Type } from '@cparra/apex-reflection';
3
3
  import { Logger } from '#utils/logger';
4
4
  import { OpenApi } from './open-api';
5
- import { Settings } from '../settings';
5
+ import { OpenApiSettings } from '../openApiSettings';
6
6
  import { MethodParser } from './parsers/MethodParser';
7
7
  import { camel2title } from '#utils/string-utils';
8
8
  import { createOpenApiFile } from './openapi-type-file';
@@ -13,11 +13,15 @@ export class OpenApiDocsProcessor {
13
13
 
14
14
  constructor() {
15
15
  this._fileContainer = new FileContainer();
16
- const title = Settings.getInstance().getOpenApiTitle();
16
+ const title = OpenApiSettings.getInstance().getOpenApiTitle();
17
17
  if (!title) {
18
18
  throw Error('No OpenApi title was provided.');
19
19
  }
20
- this.openApiModel = new OpenApi(title, '1.0.0', Settings.getInstance().getNamespace());
20
+ this.openApiModel = new OpenApi(
21
+ title,
22
+ OpenApiSettings.getInstance().getVersion(),
23
+ OpenApiSettings.getInstance().getNamespace(),
24
+ );
21
25
  }
22
26
 
23
27
  fileBuilder(): FileContainer {
@@ -66,7 +70,7 @@ export class OpenApiDocsProcessor {
66
70
  }
67
71
 
68
72
  onAfterProcess: ((types: Type[]) => void) | undefined = () => {
69
- const page = createOpenApiFile(Settings.getInstance().openApiFileName(), this.openApiModel);
73
+ const page = createOpenApiFile(OpenApiSettings.getInstance().openApiFileName(), this.openApiModel);
70
74
  this._fileContainer.pushFile(page);
71
75
  };
72
76
 
@@ -15,7 +15,11 @@ export class OpenApi {
15
15
  servers: ServerObject[];
16
16
  components?: ComponentsObject;
17
17
 
18
- constructor(title: string, version: string, private namespace?: string) {
18
+ constructor(
19
+ title: string,
20
+ version: string,
21
+ private namespace?: string,
22
+ ) {
19
23
  this.info = {
20
24
  title: title,
21
25
  version: version,
@@ -4,7 +4,7 @@ import { OpenApiPageData } from '../shared/types';
4
4
  export function createOpenApiFile(fileName: string, openApiModel: OpenApi): OpenApiPageData {
5
5
  const content = JSON.stringify({ ...openApiModel, namespace: undefined }, null, 2);
6
6
  return {
7
- outputDocPath: '',
7
+ outputDocPath: `${fileName}.json`,
8
8
  content,
9
9
  frontmatter: null,
10
10
  group: null,
@@ -1,5 +1,4 @@
1
1
  import { ClassMirror, InterfaceMirror, ReflectionResult, Type } from '@cparra/apex-reflection';
2
- import { parseApexMetadata } from '../parse-apex-metadata';
3
2
  import { Logger } from '#utils/logger';
4
3
  import { UnparsedSourceFile } from '../shared/types';
5
4
 
@@ -16,20 +15,7 @@ export class RawBodyParser implements TypeParser {
16
15
  const types = this.typeBundles
17
16
  .map((currentBundle) => {
18
17
  Logger.log(`Parsing file: ${currentBundle.filePath}`);
19
- const result = reflect(currentBundle);
20
- if (!!result.typeMirror && !!currentBundle.metadataContent) {
21
- // If successful and there is a metadata file
22
- const metadataParams = parseApexMetadata(currentBundle.metadataContent);
23
- metadataParams.forEach((value, key) => {
24
- const declaration = `${key}: ${value}`;
25
- result.typeMirror?.annotations.push({
26
- rawDeclaration: declaration,
27
- name: declaration,
28
- type: declaration,
29
- });
30
- });
31
- }
32
- return result;
18
+ return reflect(currentBundle);
33
19
  })
34
20
  .filter((reflectionResult) => {
35
21
  return reflectionResult.typeMirror;
@@ -1,5 +1,4 @@
1
1
  import { Type } from '@cparra/apex-reflection';
2
- import { Settings } from '../settings';
3
2
  import { OpenApiDocsProcessor } from './open-api-docs-processor';
4
3
 
5
4
  export default class Transpiler {
@@ -10,10 +9,6 @@ export default class Transpiler {
10
9
  return 0;
11
10
  });
12
11
 
13
- if (Settings.getInstance().indexOnly) {
14
- return;
15
- }
16
-
17
12
  sortedTypes.forEach((currentType) => {
18
13
  processor.onProcess(currentType);
19
14
  });
@@ -1,13 +1,29 @@
1
1
  import { XMLParser } from 'fast-xml-parser';
2
+ import * as E from 'fp-ts/Either';
3
+ import { pipe } from 'fp-ts/function';
4
+
5
+ type ApexMetadata = {
6
+ ApexClass: ApexClassMetadata;
7
+ };
8
+
9
+ type ApexClassMetadata = {
10
+ apiVersion: string;
11
+ status?: string;
12
+ };
2
13
 
3
14
  export function parseApexMetadata(input: string) {
4
- const map = new Map<string, string>();
5
- const xml = new XMLParser().parse(input);
15
+ return pipe(input, parse, E.map(toMap));
16
+ }
6
17
 
7
- map.set('apiVersion', xml.ApexClass.apiVersion ?? '');
18
+ function parse(input: string): E.Either<Error, ApexMetadata> {
19
+ return E.tryCatch(() => new XMLParser().parse(input), E.toError);
20
+ }
8
21
 
9
- if (xml.ApexClass.status) {
10
- map.set('status', xml.ApexClass.status);
22
+ function toMap(metadata: ApexMetadata): Map<string, string> {
23
+ const map = new Map<string, string>();
24
+ map.set('apiVersion', String(metadata.ApexClass.apiVersion));
25
+ if (metadata.ApexClass.status) {
26
+ map.set('status', String(metadata.ApexClass.status));
11
27
  }
12
28
 
13
29
  return map;