@maplibre/maplibre-react-native 10.0.0-alpha.24 → 10.0.0-alpha.25

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 (62) hide show
  1. package/.husky/pre-commit +1 -1
  2. package/CHANGELOG.md +6 -0
  3. package/CONTRIBUTING.md +1 -1
  4. package/docs/Annotation.md +2 -11
  5. package/docs/BackgroundLayer.md +2 -1
  6. package/docs/Callout.md +2 -1
  7. package/docs/Camera.md +28 -29
  8. package/docs/CircleLayer.md +2 -1
  9. package/docs/FillExtrusionLayer.md +2 -1
  10. package/docs/FillLayer.md +2 -1
  11. package/docs/HeadingIndicator.md +2 -1
  12. package/docs/HeatmapLayer.md +2 -1
  13. package/docs/ImageSource.md +2 -1
  14. package/docs/Images.md +2 -1
  15. package/docs/Light.md +2 -1
  16. package/docs/LineLayer.md +2 -1
  17. package/docs/MapView.md +5 -4
  18. package/docs/MarkerView.md +2 -1
  19. package/docs/NativeUserLocation.md +2 -1
  20. package/docs/PointAnnotation.md +2 -1
  21. package/docs/RasterLayer.md +2 -1
  22. package/docs/RasterSource.md +2 -1
  23. package/docs/ShapeSource.md +2 -1
  24. package/docs/Style.md +2 -1
  25. package/docs/SymbolLayer.md +2 -1
  26. package/docs/UserLocation.md +2 -1
  27. package/docs/VectorSource.md +3 -2
  28. package/docs/coordinates.md +2 -1
  29. package/docs/docs.json +49 -88
  30. package/docs/location.md +2 -1
  31. package/docs/offlineManager.md +3 -2
  32. package/docs/snapshotManager.md +2 -1
  33. package/ios/RCTMLN/RCTMLNCamera.h +0 -3
  34. package/ios/RCTMLN/RCTMLNCamera.m +1 -1
  35. package/ios/RCTMLN/RCTMLNCameraManager.m +0 -3
  36. package/javascript/MLNModule.ts +9 -0
  37. package/javascript/Maplibre.ts +1 -1
  38. package/javascript/components/{annotations/Annotation.tsx → Annotation.tsx} +5 -5
  39. package/javascript/components/Camera.tsx +257 -388
  40. package/javascript/components/UserLocation.tsx +1 -1
  41. package/javascript/hooks/useNativeRef.ts +2 -1
  42. package/javascript/types/CameraMode.ts +6 -0
  43. package/package.json +7 -8
  44. package/scripts/codegen.ts +341 -0
  45. package/scripts/templates/MaplibreStyles.ts.ejs +8 -7
  46. package/scripts/templates/RCTMLNStyle.h.ejs +4 -3
  47. package/scripts/templates/RCTMLNStyle.m.ejs +11 -10
  48. package/scripts/templates/RCTMLNStyleFactory.java.ejs +12 -11
  49. package/scripts/templates/component.md.ejs +14 -12
  50. package/scripts/templates/index.d.ts.ejs +2 -1
  51. package/scripts/templates/styleMap.ts.ejs +2 -1
  52. package/scripts/utils/{DocJSONBuilder.js → DocJSONBuilder.ts} +133 -128
  53. package/scripts/utils/{JSDocNodeTree.js → JSDocNodeTree.ts} +14 -13
  54. package/scripts/utils/MarkdownBuilder.ts +44 -0
  55. package/scripts/utils/{template-globals.js → TemplateHelpers.ts} +65 -94
  56. package/scripts/utils/getNativeVersion.ts +53 -0
  57. package/tsconfig.json +2 -3
  58. package/docs/OfflineManager.md +0 -246
  59. package/scripts/download-style-spec.sh +0 -15
  60. package/scripts/generate-docs.js +0 -396
  61. package/scripts/utils/MarkdownBuilder.js +0 -37
  62. package/style-spec/v8.json +0 -6645
@@ -1,30 +1,32 @@
1
1
  <%
2
2
  const component = locals.component;
3
+ const helpers = locals.helpers;
3
4
  -%>
4
- <!-- This file was autogenerated from <%- component.name %>.js do not modify -->
5
+ <!-- DO NOT MODIFY! -->
6
+ <!-- This file is auto-generated from <%- component.filePath %> -->
5
7
  ## <MapLibreGL.<%- component.name %> />
6
- ### <%- replaceNewLine(component.description) %>
8
+ ### <%- helpers.replaceNewLine(component.description) %>
7
9
 
8
10
  <%_ if (component.props && component.props.length) { _%>
9
11
  ### props
10
12
  | Prop | Type | Default | Required | Description |
11
13
  | ---- | :--: | :-----: | :------: | :----------: |
12
- <%- propMarkdownTableRows(component) %>
14
+ <%- helpers.propMarkdownTableRows(component) %>
13
15
  <%_ } _%>
14
16
 
15
17
  <%_ if (component.methods && component.methods.length) { _%>
16
18
  ### methods
17
19
  <%_ for (let method of component.methods) { _%>
18
- #### <%- getMarkdownMethodSignature(method) %>
20
+ #### <%- helpers.getMarkdownMethodSignature(method) %>
19
21
 
20
- <%- replaceNewLine(method.description) %>
22
+ <%- helpers.replaceNewLine(method.description) %>
21
23
 
22
24
  ##### arguments
23
25
  | Name | Type | Required | Description |
24
26
  | ---- | :--: | :------: | :----------: |
25
- <%- methodMarkdownTableRow(method) %>
27
+ <%- helpers.methodMarkdownTableRow(method) %>
26
28
 
27
- <%- getMarkdownMethodExamples(method) %>
29
+ <%- helpers.getMarkdownMethodExamples(method) %>
28
30
  <%_ } _%>
29
31
  <%_ } _%>
30
32
 
@@ -49,9 +51,9 @@ ___
49
51
 
50
52
  #### Type
51
53
  `<%- style.type %>`
52
- <%_ if (exists(style.default)) { _%>
54
+ <%_ if (helpers.exists(style.default)) { _%>
53
55
  #### Default Value
54
- `<%= getStyleDefaultValue(style) %>`
56
+ `<%= helpers.getStyleDefaultValue(style) %>`
55
57
  <%_ } _%>
56
58
 
57
59
  <%_ if (style.type === 'enum') { _%>
@@ -61,18 +63,18 @@ ___
61
63
  <%_ } _%>
62
64
 
63
65
  <%_ } _%>
64
- <%_ if (exists(style.units)) { _%>
66
+ <%_ if (helpers.exists(style.units)) { _%>
65
67
  #### Units
66
68
  `<%- style.units %>`
67
69
 
68
70
  <%_ } _%>
69
- <%_ if (exists(style.minimum)) { _%>
71
+ <%_ if (helpers.exists(style.minimum)) { _%>
70
72
  #### Minimum
71
73
  `<%- style.minimum %>`
72
74
 
73
75
  <%_ } _%>
74
76
 
75
- <%_ if (exists(style.maximum)) { _%>
77
+ <%_ if (helpers.exists(style.maximum)) { _%>
76
78
  #### Maximum
77
79
  `<%- style.maximum %>`
78
80
 
@@ -1,5 +1,6 @@
1
1
  <%
2
2
  const layers = locals.layers;
3
+ const helpers = locals.helpers;
3
4
  -%>
4
5
  // DO NOT MODIFY
5
6
  // THIS FILE IS AUTOGENERATED
@@ -20,7 +21,7 @@ const styleMap = {
20
21
  <%_ for (let layer of layers) { _%>
21
22
  <%_ for (let prop of layer.properties) { _%>
22
23
  <%_ if (!['color', 'colorTransition', 'visibility'].includes(prop.name)) { _%>
23
- <%= prop.name %>: <%- jsStyleType(prop) %>,
24
+ <%= prop.name %>: <%- helpers.jsStyleType(prop) %>,
24
25
  <%_ if (prop.transition) { _%>
25
26
  <%= prop.name %>Transition: StyleTypes.Transition,
26
27
  <%_ } _%>
@@ -1,5 +1,6 @@
1
1
  <%
2
2
  const layers = locals.layers;
3
+ const helpers = locals.helpers;
3
4
  -%>
4
5
  /* eslint-disable */
5
6
  // DO NOT MODIFY
@@ -33,7 +34,7 @@ const styleMap = {
33
34
  <%_ for (let layer of layers) { _%>
34
35
  <%_ for (let prop of layer.properties) { _%>
35
36
  <%_ if (prop.name !== 'visibility') { _%>
36
- <%= prop.name %>: <%- jsStyleType(prop) %>,
37
+ <%= prop.name %>: <%- helpers.jsStyleType(prop) %>,
37
38
  <%_ if (prop.transition) { _%>
38
39
  <%= prop.name %>Transition: StyleTypes.Transition,
39
40
  <%_ } _%>
@@ -1,36 +1,30 @@
1
- const { exec } = require("child_process");
2
- const fs = require("fs");
3
- const dir = require("node-dir");
4
- const path = require("path");
5
- const docgen = require("react-docgen");
6
- const parseJsDoc = require("react-docgen/dist/utils/parseJsDoc").default;
7
-
8
- const JSDocNodeTree = require("./JSDocNodeTree");
9
- const { pascalCase } = require("./template-globals");
10
-
11
- const COMPONENT_PATH = path.join(
12
- __dirname,
13
- "..",
14
- "..",
1
+ import { exec } from "child_process";
2
+ import { promises as fs } from "node:fs";
3
+ import path from "node:path";
4
+ import * as docgen from "react-docgen";
5
+ import { parseJsDoc } from "react-docgen/dist/utils";
6
+
7
+ import { JSDocNodeTree } from "./JSDocNodeTree";
8
+ import { pascalCase } from "./TemplateHelpers";
9
+
10
+ const WORKSPACE_ROOT = path.join(__dirname, "..", "..");
11
+
12
+ const COMPONENT_DIRECTORY = path.join(
13
+ WORKSPACE_ROOT,
15
14
  "javascript",
16
15
  "components",
17
16
  );
18
- const MODULES_PATH = path.join(__dirname, "..", "..", "javascript", "modules");
19
-
20
- const OUTPUT_PATH = path.join(__dirname, "..", "..", "docs", "docs.json");
21
- const IGNORE_FILES = [
22
- "AbstractLayer",
23
- "AbstractSource",
24
- "NativeBridgeComponent",
25
- ];
26
- const IGNORE_PATTERN = /\.web\./;
17
+ const MODULES_DIRECTORY = path.join(WORKSPACE_ROOT, "javascript", "modules");
18
+ const OUTPUT_PATH = path.join(WORKSPACE_ROOT, "docs", "docs.json");
27
19
 
28
20
  const IGNORE_METHODS = ["setNativeProps"];
29
21
 
30
22
  const fileExtensionsRegex = /.(js|tsx|(?<!d.)ts)$/;
31
23
 
32
- class DocJSONBuilder {
33
- constructor(styledLayers) {
24
+ export class DocJSONBuilder {
25
+ _styledLayers: any;
26
+
27
+ constructor(styledLayers: any) {
34
28
  this._styledLayers = {};
35
29
 
36
30
  for (const styleLayer of styledLayers) {
@@ -56,7 +50,7 @@ class DocJSONBuilder {
56
50
  return !methodName || methodName.charAt(0) === "_";
57
51
  }
58
52
 
59
- postprocess(component, name) {
53
+ postprocess(component: any, name: string) {
60
54
  // Remove all private methods and parse examples from docblock
61
55
 
62
56
  if (!Array.isArray(component.methods)) {
@@ -66,7 +60,7 @@ class DocJSONBuilder {
66
60
  component.name = name;
67
61
 
68
62
  // Main description
69
- component.description = component.description.replace(
63
+ component.description = component.description?.replace(
70
64
  /(\n*)(@\w+) (\{.*})/g,
71
65
  "",
72
66
  );
@@ -79,7 +73,7 @@ class DocJSONBuilder {
79
73
  const docStyle = {
80
74
  name: prop.name,
81
75
  type: prop.type,
82
- values: [],
76
+ values: [] as any[],
83
77
  minimum: prop.doc.minimum,
84
78
  maximum: prop.doc.maximum,
85
79
  units: prop.doc.units,
@@ -103,7 +97,7 @@ class DocJSONBuilder {
103
97
  }
104
98
  }
105
99
 
106
- function mapNestedProp(propMeta) {
100
+ function mapNestedProp(propMeta: any) {
107
101
  const result = {
108
102
  type: {
109
103
  name: propMeta.name,
@@ -112,13 +106,15 @@ class DocJSONBuilder {
112
106
  description: propMeta.description,
113
107
  required: propMeta.required,
114
108
  };
109
+
115
110
  if (propMeta.value) {
116
111
  result.type.value = propMeta.value;
117
112
  }
113
+
118
114
  return result;
119
115
  }
120
116
 
121
- function tsTypeDesc(tsType) {
117
+ function tsTypeDesc(tsType: TSType) {
122
118
  if (!tsType?.name) {
123
119
  return null;
124
120
  }
@@ -137,44 +133,63 @@ class DocJSONBuilder {
137
133
  return tsType.raw.replace(/\|/g, "\\|");
138
134
  } else if (tsType.elements) {
139
135
  // Methods
140
- return tsType.elements.map((e) => e.name).join(" \\| ");
136
+ return tsType.elements.map((element) => element.name).join(" \\| ");
141
137
  }
142
- } else {
143
- return tsType.name;
144
138
  }
139
+
140
+ return tsType.name;
141
+ }
142
+
143
+ type TSTypeType = {
144
+ name: string;
145
+ raw: string;
146
+ };
147
+
148
+ type TSFuncSignature = {
149
+ arguments: { type: TSType; name: string }[];
150
+ return: TSType;
151
+ };
152
+
153
+ type TSKVProperties = { key: string; value: TSType; description: string }[];
154
+
155
+ type TSObjectSignature = {
156
+ properties: TSKVProperties;
157
+ };
158
+
159
+ interface TSVoidType extends TSTypeType {
160
+ name: "void";
161
+ type: never;
162
+ }
163
+
164
+ interface TSUnionType extends TSTypeType {
165
+ name: "union";
166
+ type: never;
167
+ elements: any[];
168
+ }
169
+
170
+ interface TSFunctionType extends TSTypeType {
171
+ name: "signature";
172
+ type: "function";
173
+ signature: TSFuncSignature;
145
174
  }
146
175
 
147
- /**
148
- * @typedef {{arguments: {type:TSType,name:string}[], return: TSType]}} TSFuncSignature
149
- * @typedef {{key:string, value:TSType}[]} TSKVProperties
150
- * @typedef {{properties: TSKVProperties}} TSObjectSignature
151
- * @typedef {{name: 'void'}} TSVoidType
152
- * @typedef {{name: string}} TSTypeType
153
- * @typedef {{name: 'signature', type:'function', raw:string, signature: TSFuncSignature}} TSFunctionType
154
- * @typedef {{name: 'signature', type:'object', raw:string, signature: TSObjectSignature}} TSObjectType
155
- * @typedef {TSVoidType | TSFunctionType | TSTypeType | TSObjectType} TSType
156
- */
157
-
158
- /**
159
- * @params {TSType} tsType
160
- * @returns {tsType is TSFunctionType}
161
- */
162
- function tsTypeIsFunction(tsType) {
163
- return tsType.type === "function";
176
+ interface TSObjectType extends TSTypeType {
177
+ name: "signature";
178
+ type: "object";
179
+ signature: TSObjectSignature;
164
180
  }
165
181
 
166
- /**
167
- * @params {TSType} tsType
168
- * @returns {tsType is TSObjectType}
169
- */
170
- function tsTypeIsObject(tsType) {
171
- return tsType.type === "object";
182
+ type TSType = TSVoidType | TSUnionType | TSFunctionType | TSObjectType;
183
+
184
+ function tsTypeIsFunction(tsType: TSType): tsType is TSFunctionType {
185
+ return "type" in tsType && tsType.type === "function";
186
+ }
187
+
188
+ function tsTypeIsObject(tsType: TSType): tsType is TSObjectType {
189
+ return "type" in tsType && tsType.type === "object";
172
190
  }
173
191
 
174
- /**
175
- * @param {TSType} tsType
176
- */
177
- function tsTypeDump(tsType) {
192
+ function tsTypeDump(tsType: TSType): string {
178
193
  if (tsTypeIsFunction(tsType)) {
179
194
  const { signature } = tsType;
180
195
  return `(${signature.arguments
@@ -190,8 +205,8 @@ class DocJSONBuilder {
190
205
  }
191
206
  }
192
207
 
193
- function tsTypeDescType(tsType) {
194
- if (!tsType?.name) {
208
+ function tsTypeDescType(tsType?: TSType) {
209
+ if (!tsType) {
195
210
  return null;
196
211
  }
197
212
 
@@ -223,13 +238,17 @@ class DocJSONBuilder {
223
238
  // Methods
224
239
  return tsType.elements.map((e) => e.name).join(" \\| ");
225
240
  }
226
- } else {
227
- return tsType.name;
228
241
  }
242
+
243
+ return tsType.name;
229
244
  }
230
245
 
231
- function mapProp(propMeta, propName, array) {
232
- let result = {};
246
+ function mapProp(
247
+ propMeta: any,
248
+ propName: string | undefined,
249
+ array: boolean,
250
+ ) {
251
+ let result: Record<string, any> = {};
233
252
  if (!array) {
234
253
  result = {
235
254
  name: propName || "FIX ME NO NAME",
@@ -314,7 +333,7 @@ class DocJSONBuilder {
314
333
  });
315
334
 
316
335
  // methods
317
- const privateMethods = [];
336
+ const privateMethods: string[] = [];
318
337
  for (const method of component.methods) {
319
338
  if (this.isPrivateMethod(method.name)) {
320
339
  privateMethods.push(method.name);
@@ -324,8 +343,8 @@ class DocJSONBuilder {
324
343
  if (method.docblock) {
325
344
  const examples = method.docblock
326
345
  .split("@")
327
- .filter((block) => block.startsWith("example"));
328
- method.examples = examples.map((example) =>
346
+ .filter((block: string) => block.startsWith("example"));
347
+ method.examples = examples.map((example: any) =>
329
348
  example.substring("example".length),
330
349
  );
331
350
  }
@@ -333,11 +352,11 @@ class DocJSONBuilder {
333
352
  privateMethods.push(...IGNORE_METHODS);
334
353
 
335
354
  component.methods = component.methods.filter(
336
- (method) => !privateMethods.includes(method.name),
355
+ (method: any) => !privateMethods.includes(method.name),
337
356
  );
338
357
 
339
- component.methods.forEach((method) => {
340
- method.params.forEach((param) => {
358
+ component.methods.forEach((method: any) => {
359
+ method.params.forEach((param: any) => {
341
360
  param.type = { name: tsTypeDesc(param.type) };
342
361
  });
343
362
  });
@@ -349,48 +368,46 @@ class DocJSONBuilder {
349
368
  );
350
369
  }
351
370
 
352
- generateReactComponentsTask(results, filePath) {
353
- return new Promise((resolve, reject) => {
354
- dir.readFiles(
355
- filePath,
356
- this.options,
357
- (err, content, fileNameWithExt, next) => {
358
- if (err) {
359
- return reject(err);
360
- }
371
+ async generateReactComponentsTask(results: Record<string, any>) {
372
+ const filesNames = await fs.readdir(COMPONENT_DIRECTORY);
373
+
374
+ const files = await Promise.all(
375
+ filesNames.map(async (base) => {
376
+ return {
377
+ base,
378
+ content: await fs.readFile(
379
+ path.join(COMPONENT_DIRECTORY, base),
380
+ "utf-8",
381
+ ),
382
+ };
383
+ }),
384
+ );
361
385
 
362
- let fileName = fileNameWithExt.replace(/\.(js|tsx|ts$)/, "");
363
- if (
364
- IGNORE_FILES.includes(fileName) ||
365
- fileName.match(IGNORE_PATTERN)
366
- ) {
367
- next();
368
- return;
369
- }
386
+ files.forEach(({ base, content }) => {
387
+ const parsedComponents = docgen.parse(content, {
388
+ babelOptions: {
389
+ filename: base,
390
+ },
391
+ });
370
392
 
371
- const parsedComponents = docgen.parse(content, {
372
- babelOptions: {
373
- filename: fileNameWithExt,
374
- },
375
- });
376
- const [parsed] = parsedComponents;
377
- fileName = fileName.replace(fileExtensionsRegex, "");
378
- parsed.fileNameWithExt = fileNameWithExt;
379
- results[fileName] = parsed;
393
+ const [parsed] = parsedComponents;
380
394
 
381
- this.postprocess(results[fileName], fileName);
395
+ results[path.parse(base).name] = {
396
+ ...parsed,
397
+ filePath: path.relative(
398
+ WORKSPACE_ROOT,
399
+ path.join(COMPONENT_DIRECTORY, base),
400
+ ),
401
+ };
382
402
 
383
- return next();
384
- },
385
- () => resolve(),
386
- );
403
+ this.postprocess(results[path.parse(base).name], path.parse(base).name);
387
404
  });
388
405
  }
389
406
 
390
- generateModulesTask(results, filePath) {
391
- return new Promise((resolve, reject) => {
407
+ async generateModulesTask(results: Record<string, any>) {
408
+ return new Promise<void>((resolve, reject) => {
392
409
  exec(
393
- `yarn run documentation build ${MODULES_PATH} -f json`,
410
+ `yarn run documentation build ${MODULES_DIRECTORY} -f json`,
394
411
  (err, stdout, stderr) => {
395
412
  if (err || stderr) {
396
413
  reject(err || stderr);
@@ -404,12 +421,9 @@ class DocJSONBuilder {
404
421
  .charAt(0)
405
422
  .toLowerCase()}${module.name.substring(1)}`;
406
423
 
407
- const pathParts = module.context.file.split("/");
408
- const fileNameWithExt = pathParts[pathParts.length - 1];
409
-
410
424
  results[name] = {
411
425
  name,
412
- fileNameWithExt,
426
+ filePath: path.relative(WORKSPACE_ROOT, module.context.file),
413
427
  description: node.getText(),
414
428
  props: [],
415
429
  styles: [],
@@ -423,36 +437,27 @@ class DocJSONBuilder {
423
437
  });
424
438
  }
425
439
 
426
- sortObject(not_sorted) {
427
- return Object.keys(not_sorted)
440
+ sortObject(unsorted: Record<string, any>) {
441
+ return Object.keys(unsorted)
428
442
  .sort()
429
443
  .reduce(
430
444
  (acc, key) => ({
431
445
  ...acc,
432
- [key]: not_sorted[key],
446
+ [key]: unsorted[key],
433
447
  }),
434
448
  {},
435
449
  );
436
450
  }
437
451
 
438
452
  async generate() {
439
- this.generateModulesTask({}, MODULES_PATH);
440
-
441
453
  const results = {};
442
454
 
443
- const tasks = [
444
- this.generateReactComponentsTask(results, COMPONENT_PATH),
445
- this.generateModulesTask(results, MODULES_PATH),
446
- ];
455
+ await this.generateReactComponentsTask(results);
456
+ await this.generateModulesTask(results);
447
457
 
448
- return Promise.all(tasks).then(() => {
449
- fs.writeFileSync(
450
- OUTPUT_PATH,
451
- JSON.stringify(this.sortObject(results), null, 2),
452
- );
453
- return true;
454
- });
458
+ await fs.writeFile(
459
+ OUTPUT_PATH,
460
+ JSON.stringify(this.sortObject(results), null, 2),
461
+ );
455
462
  }
456
463
  }
457
-
458
- module.exports = DocJSONBuilder;
@@ -1,13 +1,16 @@
1
- class JSDocNodeTree {
2
- constructor(root) {
1
+ export class JSDocNodeTree {
2
+ _root: any;
3
+
4
+ constructor(root: any) {
3
5
  this._root = root;
4
6
  }
5
7
 
6
- getChildrenByTag(node, tag) {
8
+ getChildrenByTag(node: any, tag: any) {
7
9
  if (!node || !Array.isArray(node.children)) {
8
10
  return [];
9
11
  }
10
- return node.children.filter((child) => child.type === tag);
12
+
13
+ return node.children.filter((child: any) => child.type === tag);
11
14
  }
12
15
 
13
16
  getName() {
@@ -59,7 +62,7 @@ class JSDocNodeTree {
59
62
  return methods;
60
63
  }
61
64
 
62
- getMethodParams(field) {
65
+ getMethodParams(field: any) {
63
66
  if (!this._hasArray(field, "params")) {
64
67
  return [];
65
68
  }
@@ -82,14 +85,14 @@ class JSDocNodeTree {
82
85
  return methodParams;
83
86
  }
84
87
 
85
- getExamples(field) {
88
+ getExamples(field: any) {
86
89
  if (!this._hasArray(field, "examples")) {
87
90
  return [];
88
91
  }
89
- return field.examples.map((example) => example.description);
92
+ return field.examples.map((example: any) => example.description);
90
93
  }
91
94
 
92
- getReturnValue(field) {
95
+ getReturnValue(field: any) {
93
96
  if (!this._hasArray(field, "returns")) {
94
97
  return null;
95
98
  }
@@ -103,7 +106,7 @@ class JSDocNodeTree {
103
106
  };
104
107
  }
105
108
 
106
- getType(typeNode) {
109
+ getType(typeNode: any) {
107
110
  if (!typeNode) {
108
111
  return "";
109
112
  }
@@ -119,16 +122,14 @@ class JSDocNodeTree {
119
122
  return this._hasArray(this._root.description, "children");
120
123
  }
121
124
 
122
- _hasArray(node, propName) {
125
+ _hasArray(node: any, propName: string) {
123
126
  if (!this._root) {
124
127
  return false;
125
128
  }
126
129
  return Array.isArray(node[propName]) && node[propName].length;
127
130
  }
128
131
 
129
- _isPrivateMethod(field) {
132
+ _isPrivateMethod(field: any) {
130
133
  return field.name.charAt(0) === "_";
131
134
  }
132
135
  }
133
-
134
- module.exports = JSDocNodeTree;
@@ -0,0 +1,44 @@
1
+ import ejs from "ejs";
2
+ import { promises as fs } from "node:fs";
3
+ import path from "node:path";
4
+
5
+ import * as TemplateHelpers from "./TemplateHelpers";
6
+
7
+ const TMPL_PATH = path.join(__dirname, "..", "templates");
8
+
9
+ export class MarkdownBuilder {
10
+ async generateComponentFile(docJSON: any, componentName: string) {
11
+ const tmpl = ejs.compile(
12
+ await fs.readFile(path.join(TMPL_PATH, "component.md.ejs"), "utf8"),
13
+ {
14
+ async: true,
15
+ strict: true,
16
+ },
17
+ );
18
+ const fileContents = await tmpl({
19
+ component: docJSON[componentName],
20
+ helpers: TemplateHelpers,
21
+ });
22
+ await fs.writeFile(
23
+ path.join(__dirname, "..", "..", "docs", `${componentName}.md`),
24
+ fileContents,
25
+ );
26
+ }
27
+
28
+ async generate() {
29
+ const docJSONFile = await fs.readFile(
30
+ path.join(__dirname, "..", "..", "docs", "docs.json"),
31
+ "utf8",
32
+ );
33
+ const docJSON = JSON.parse(docJSONFile);
34
+ const componentPaths = Object.keys(docJSON);
35
+
36
+ await Promise.all(
37
+ componentPaths.map((componentPath) =>
38
+ this.generateComponentFile(docJSON, componentPath),
39
+ ),
40
+ );
41
+
42
+ console.log("Markdown is finished generating");
43
+ }
44
+ }