@asyncapi/generator 2.1.3 → 2.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @asyncapi/generator
2
2
 
3
+ ## 2.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 44fcc33: ts-node is registered only when it's actually needed
8
+
9
+ ## 2.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 81dfd0c: Enable `noOverwriteGlobs` option for templates based on react rendering engine.
14
+
3
15
  ## 2.1.3
4
16
 
5
17
  ### Patch Changes
@@ -1,7 +1,7 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs');
3
3
  const xfs = require('fs.extra');
4
- const { isAsyncFunction } = require('./utils');
4
+ const { isAsyncFunction, registerTypeScript } = require('./utils');
5
5
  const nunjucksFilters = require('@asyncapi/nunjucks-filters');
6
6
 
7
7
  /**
@@ -38,7 +38,12 @@ function registerLocalFilters(nunjucks, templateDir, filtersDir) {
38
38
 
39
39
  walker.on('file', async (root, stats, next) => {
40
40
  try {
41
- const filePath = path.resolve(templateDir, path.resolve(root, stats.name));
41
+ const filePath = path.resolve(
42
+ templateDir,
43
+ path.resolve(root, stats.name)
44
+ );
45
+
46
+ registerTypeScript(filePath);
42
47
  // If it's a module constructor, inject dependencies to ensure consistent usage in remote templates in other projects or plain directories.
43
48
  delete require.cache[require.resolve(filePath)];
44
49
  const mod = require(filePath);
package/lib/generator.js CHANGED
@@ -28,7 +28,6 @@ const {
28
28
  isReactTemplate,
29
29
  isJsFile,
30
30
  registerSourceMap,
31
- registerTypeScript,
32
31
  getTemplateDetails,
33
32
  convertCollectionToObject,
34
33
  } = require('./utils');
@@ -59,7 +58,6 @@ const shouldIgnoreDir = dirPath =>
59
58
  || dirPath.startsWith(`.git${path.sep}`);
60
59
 
61
60
  registerSourceMap();
62
- registerTypeScript();
63
61
 
64
62
  class Generator {
65
63
  /**
@@ -852,7 +850,7 @@ class Generator {
852
850
  if (renderContent === undefined) {
853
851
  return;
854
852
  } else if (isReactTemplate(this.templateConfig)) {
855
- await saveRenderedReactContent(renderContent, outputpath);
853
+ await saveRenderedReactContent(renderContent, outputpath, this.noOverwriteGlobs);
856
854
  } else {
857
855
  await writeFile(outputpath, renderContent);
858
856
  }
@@ -1,6 +1,6 @@
1
1
  const path = require('path');
2
2
  const xfs = require('fs.extra');
3
- const { exists } = require('./utils');
3
+ const { exists, registerTypeScript } = require('./utils');
4
4
 
5
5
  /**
6
6
  * Registers all template hooks.
@@ -37,6 +37,9 @@ async function registerLocalHooks(hooks, templateDir, hooksDir) {
37
37
  walker.on('file', async (root, stats, next) => {
38
38
  try {
39
39
  const filePath = path.resolve(templateDir, path.resolve(root, stats.name));
40
+
41
+ registerTypeScript(filePath);
42
+
40
43
  delete require.cache[require.resolve(filePath)];
41
44
  const mod = require(filePath);
42
45
 
@@ -6,22 +6,22 @@ const NODE_MODULES_INSTALL ='Remember that your local template must have its own
6
6
 
7
7
  const NPM_INSTALL_TRIGGER = 'Installation of template located on disk technically means symlink creation betweed node_modules of the generator and template sources. Your local template must have its own node_modules, "npm install" is not triggered.';
8
8
 
9
- function templateVersion(ver) {
9
+ function templateVersion(ver) {
10
10
  return `Version of used template is ${ver}.`;
11
- }
11
+ }
12
12
 
13
13
  function templateSource(localHtmlTemplate) {
14
14
  return `Template sources taken from ${localHtmlTemplate}.`;
15
- }
15
+ }
16
16
 
17
17
  function templateNotFound(templateName) {
18
18
  return `${templateName} not found in local dependencies but found it installed as a global package.`;
19
- }
19
+ }
20
20
 
21
21
  function packageNotAvailable(packageDetails) {
22
22
  if (packageDetails && packageDetails.pkgPath) {
23
23
  return `Unable to resolve template location at ${packageDetails.pkgPath}. Package is not available locally.`;
24
- }
24
+ }
25
25
 
26
26
  return `Template is not available locally and expected location is undefined. Known details are: ${JSON.stringify(packageDetails, null, 2)}`;
27
27
  }
@@ -38,6 +38,10 @@ function relativeSourceFileNotGenerated(relativeSourceFile , subject) {
38
38
  return `${relativeSourceFile} was not generated because ${subject} specified in template configuration in conditionalFiles was not found in provided AsyncAPI specification file.`;
39
39
  }
40
40
 
41
+ function skipOverwrite(testFilePath) {
42
+ return `Skipping overwrite for: ${testFilePath}`;
43
+ }
44
+
41
45
  function conditionalFilesMatched(relativeSourceFile) {
42
46
  return `${relativeSourceFile} was not generated because condition specified for this file in template configuration in conditionalFiles matched.`;
43
47
  }
@@ -54,6 +58,6 @@ module.exports = {
54
58
  installationDebugMessage,
55
59
  templateSuccessfullyInstalled,
56
60
  relativeSourceFileNotGenerated,
57
- conditionalFilesMatched
58
-
59
- };
61
+ conditionalFilesMatched,
62
+ skipOverwrite
63
+ };
@@ -1,5 +1,8 @@
1
1
  const path = require('path');
2
2
  const AsyncReactSDK = require('@asyncapi/generator-react-sdk');
3
+ const minimatch = require('minimatch');
4
+ const logMessage = require('../logMessages.js');
5
+ const log = require('loglevel');
3
6
  const {
4
7
  writeFile
5
8
  } = require('../utils');
@@ -8,7 +11,7 @@ const reactExport = module.exports;
8
11
 
9
12
  /**
10
13
  * Configures React templating system, this handles all the transpilation work.
11
- *
14
+ *
12
15
  * @private
13
16
  * @param {string} templateLocation located for thetemplate
14
17
  * @param {string} templateContentDir where the template content are located
@@ -23,9 +26,9 @@ reactExport.configureReact = async (templateLocation, templateContentDir, transp
23
26
 
24
27
  /**
25
28
  * Renders the template with react and returns the content and meta data for the file.
26
- *
29
+ *
27
30
  * @private
28
- * @param {AsyncAPIDocument} asyncapiDocument
31
+ * @param {AsyncAPIDocument} asyncapiDocument
29
32
  * @param {string} filePath path to the template file
30
33
  * @param {Object} extraTemplateData Extra data to pass to the template.
31
34
  * @param {string} templateLocation located for thetemplate
@@ -33,34 +36,34 @@ reactExport.configureReact = async (templateLocation, templateContentDir, transp
33
36
  * @param {string} transpiledTemplateLocation folder for the transpiled code
34
37
  * @param {Object} templateParams provided template parameters
35
38
  * @param {boolean} debug flag
36
- * @param {string} originalAsyncAPI
39
+ * @param {string} originalAsyncAPI
37
40
  * @return {Promise<TemplateRenderResult>}
38
41
  */
39
42
  reactExport.renderReact = async (asyncapiDocument, filePath, extraTemplateData, templateLocation, templateContentDir, transpiledTemplateLocation, templateParams, debug, originalAsyncAPI) => {
40
43
  extraTemplateData = extraTemplateData || {};
41
44
  filePath = filePath.replace(templateContentDir, path.resolve(templateLocation, transpiledTemplateLocation));
42
45
  return await AsyncReactSDK.renderTemplate(
43
- filePath,
46
+ filePath,
44
47
  {
45
48
  asyncapi: asyncapiDocument,
46
49
  params: templateParams,
47
50
  originalAsyncAPI,
48
51
  ...extraTemplateData
49
- },
52
+ },
50
53
  debug
51
54
  );
52
55
  };
53
56
 
54
57
  /**
55
58
  * Save the single rendered react content based on the meta data available.
56
- *
59
+ *
57
60
  * @private
58
61
  * @param {TemplateRenderResult} renderedContent the react content rendered
59
62
  * @param {String} outputPath Path to the file being rendered.
60
63
  */
61
- const saveContentToFile = async (renderedContent, outputPath) => {
64
+ const saveContentToFile = async (renderedContent, outputPath, noOverwriteGlobs = []) => {
62
65
  let filePath = outputPath;
63
- // Might be the same as in the `fs` package, but is an active choice for our default file permission for any rendered files.
66
+ // Might be the same as in the `fs` package, but is an active choice for our default file permission for any rendered files.
64
67
  let permissions = 0o666;
65
68
  const content = renderedContent.content;
66
69
 
@@ -78,21 +81,32 @@ const saveContentToFile = async (renderedContent, outputPath) => {
78
81
  }
79
82
  }
80
83
 
81
- await writeFile(filePath, content, {
82
- mode: permissions
83
- });
84
+ // get the final file name of the file
85
+ const finalFileName = path.basename(filePath);
86
+ // check whether the filename should be ignored based on user's inputs
87
+ const shouldOverwrite = !noOverwriteGlobs.some(globExp => minimatch(finalFileName, globExp));
88
+
89
+ // Write the file only if it should not be skipped
90
+ if (shouldOverwrite) {
91
+ await writeFile(filePath, content, {
92
+ mode: permissions
93
+ });
94
+ } else {
95
+ await log.debug(logMessage.skipOverwrite(filePath));
96
+ }
84
97
  };
85
98
 
86
99
  /**
87
100
  * Save the rendered react content based on the meta data available.
88
- *
101
+ *
89
102
  * @private
90
103
  * @param {TemplateRenderResult[] | TemplateRenderResult} renderedContent the react content rendered
91
104
  * @param {String} outputPath Path to the file being rendered.
105
+ * @param noOverwriteGlobs Array of globs to skip overwriting files.
92
106
  */
93
- reactExport.saveRenderedReactContent = async (renderedContent, outputPath) => {
107
+ reactExport.saveRenderedReactContent = async (renderedContent, outputPath, noOverwriteGlobs = []) => {
94
108
  if (Array.isArray(renderedContent)) {
95
- return Promise.all(renderedContent.map(content => saveContentToFile(content, outputPath)));
109
+ return Promise.all(renderedContent.map(content => saveContentToFile(content, outputPath, noOverwriteGlobs)));
96
110
  }
97
- return saveContentToFile(renderedContent, outputPath);
111
+ return await saveContentToFile(renderedContent, outputPath, noOverwriteGlobs);
98
112
  };
package/lib/utils.js CHANGED
@@ -149,7 +149,13 @@ utils.registerSourceMap = () => {
149
149
  *
150
150
  * @private
151
151
  */
152
- utils.registerTypeScript = () => {
152
+ utils.registerTypeScript = (filePath) => {
153
+ const isTypescriptFile = filePath.endsWith('.ts');
154
+
155
+ if (!isTypescriptFile) {
156
+ return;
157
+ }
158
+
153
159
  const { REGISTER_INSTANCE, register } = require('ts-node');
154
160
  // if the ts-node has already been registered before, do not register it again.
155
161
  // Check the env. TS_NODE_ENV if ts-node started via ts-node-dev package
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asyncapi/generator",
3
- "version": "2.1.3",
3
+ "version": "2.3.0",
4
4
  "description": "The AsyncAPI generator. It can generate documentation, code, anything!",
5
5
  "main": "./lib/generator.js",
6
6
  "bin": {
@@ -15,8 +15,8 @@
15
15
  "test": "npm run test:unit && npm run test:integration && npm run test:cli",
16
16
  "test:unit": "jest --coverage --testPathIgnorePatterns=integration --testPathIgnorePatterns=test-project",
17
17
  "test:dev": "npm run test:unit -- --watchAll",
18
- "test:integration": "npm run test:cleanup && jest --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__'",
19
- "test:integration:update": "jest --updateSnapshot --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__'",
18
+ "test:integration": "npm run test:cleanup && jest --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__(?!\\/loglevel\\.js$)'",
19
+ "test:integration:update": "jest --updateSnapshot --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__(?!\\/loglevel\\.js$)'",
20
20
  "test:cli": "node cli.js ./test/docs/dummy.yml ./test/test-templates/react-template -o test/output --force-write --debug && test -e test/output/test-file.md",
21
21
  "test:cleanup": "rimraf \"test/temp\"",
22
22
  "docs": "jsdoc2md --partial docs/jsdoc2md-handlebars/custom-sig-name.hbs docs/jsdoc2md-handlebars/main.hbs docs/jsdoc2md-handlebars/docs.hbs docs/jsdoc2md-handlebars/header.hbs docs/jsdoc2md-handlebars/defaultvalue.hbs docs/jsdoc2md-handlebars/link.hbs docs/jsdoc2md-handlebars/params-table.hbs --files lib/generator.js > docs/api.md",
@@ -2,7 +2,7 @@
2
2
  * @jest-environment node
3
3
  */
4
4
 
5
- const { readFile } = require('fs').promises;
5
+ const { mkdir, writeFile, readFile } = require('fs').promises;
6
6
  const path = require('path');
7
7
  const Generator = require('../lib/generator');
8
8
  const dummySpecPath = path.resolve(__dirname, './docs/dummy.yml');
@@ -24,7 +24,7 @@ describe('Integration testing generateFromFile() to make sure the result of the
24
24
 
25
25
  it('generated using Nunjucks template', async () => {
26
26
  const outputDir = generateFolderName();
27
- const generator = new Generator(nunjucksTemplate, outputDir, {
27
+ const generator = new Generator(nunjucksTemplate, outputDir, {
28
28
  forceWrite: true,
29
29
  templateParams: { version: 'v1', mode: 'production' }
30
30
  });
@@ -35,7 +35,7 @@ describe('Integration testing generateFromFile() to make sure the result of the
35
35
 
36
36
  it('generate using React template', async () => {
37
37
  const outputDir = generateFolderName();
38
- const generator = new Generator(reactTemplate, outputDir, {
38
+ const generator = new Generator(reactTemplate, outputDir, {
39
39
  forceWrite: true ,
40
40
  templateParams: { version: 'v1', mode: 'production' }
41
41
  });
@@ -55,4 +55,33 @@ describe('Integration testing generateFromFile() to make sure the result of the
55
55
  const file = await readFile(path.join(outputDir, testOutputFile), 'utf8');
56
56
  expect(file).toMatchSnapshot();
57
57
  });
58
+
59
+ it('should ignore specified files with noOverwriteGlobs', async () => {
60
+ const outputDir = generateFolderName();
61
+ // Manually create a file to test if it's not overwritten
62
+ await mkdir(outputDir, { recursive: true });
63
+ // Create a variable to store the file content
64
+ const testContent = '<script>const initialContent = "This should not change";</script>';
65
+ // eslint-disable-next-line sonarjs/no-duplicate-string
66
+ const testFilePath = path.normalize(path.resolve(outputDir, testOutputFile));
67
+ await writeFile(testFilePath, testContent);
68
+
69
+ // Manually create an output first, before generation, with additional custom file to validate if later it is still there, not overwritten
70
+ const generator = new Generator(reactTemplate, outputDir, {
71
+ forceWrite: true,
72
+ noOverwriteGlobs: [`**/${testOutputFile}`],
73
+ debug: true,
74
+ });
75
+
76
+ await generator.generateFromFile(dummySpecPath);
77
+
78
+ // Read the file to confirm it was not overwritten
79
+ const fileContent = await readFile(testFilePath, 'utf8');
80
+ // Check if the files have been overwritten
81
+ expect(fileContent).toBe(testContent);
82
+ // Check if the log debug message was printed
83
+ /*TODO:
84
+ Include log message test in the future to ensure that the log.debug for skipping overwrite is called
85
+ */
86
+ });
58
87
  });