@sap/cds-dk 6.1.5 → 6.2.1

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 (152) hide show
  1. package/CHANGELOG.md +36 -2
  2. package/bin/cds.js +7 -5
  3. package/bin/deploy/index.js +3 -2
  4. package/bin/deploy/to-sqlite.js +4 -3
  5. package/bin/help.js +4 -0
  6. package/bin/init.js +2 -1
  7. package/bin/login.js +23 -9
  8. package/bin/mock.js +1 -0
  9. package/bin/pull.js +24 -19
  10. package/bin/push.js +20 -9
  11. package/bin/subscribe.js +40 -10
  12. package/bin/watch.js +15 -10
  13. package/lib/bind/kubernetesCredentialsProvider.js +1 -0
  14. package/lib/client/activate.js +42 -51
  15. package/lib/client/auth_manager.js +7 -8
  16. package/lib/client/base_command.js +5 -2
  17. package/lib/client/extend.js +33 -38
  18. package/lib/client/helper/cf_helper.js +11 -11
  19. package/lib/client/helper/dependency_helper.js +2 -2
  20. package/lib/client/helper/errors.js +4 -3
  21. package/lib/client/helper/logging.js +17 -23
  22. package/lib/client/params.js +5 -5
  23. package/lib/client/pull.js +19 -21
  24. package/lib/client/push.js +16 -15
  25. package/lib/client/settings_manager.js +54 -55
  26. package/lib/compile/openapi/csdl2openapi.js +18 -12
  27. package/lib/import/message.js +1 -1
  28. package/lib/import/odata/metadataconverter/MetadataConverter.js +23 -17
  29. package/lib/import/odata/v2parser.js +43 -17
  30. package/lib/import/odata/v4parser.js +77 -22
  31. package/lib/init/constants.js +5 -2
  32. package/lib/init/index.js +16 -4
  33. package/lib/init/template/_merging/registry-mta.js +13 -0
  34. package/lib/init/template/approuter/index.js +9 -0
  35. package/lib/{k8s/connectivity/templates/connectivity.yaml → init/template/auditlog/files/auditlog.yaml} +0 -0
  36. package/lib/init/template/auditlog/index.js +46 -27
  37. package/lib/{k8s/connectivity/templates → init/template/connectivity/files}/connectivity-binding.yaml +0 -0
  38. package/lib/{k8s/connectivity/templates → init/template/connectivity/files}/connectivity-proxy-info.yaml +1 -1
  39. package/lib/init/template/connectivity/files/connectivity.yaml +1 -0
  40. package/lib/init/template/connectivity/files/values.yaml.hbs +26 -0
  41. package/lib/init/template/connectivity/index.js +41 -0
  42. package/lib/init/template/data/index.js +8 -8
  43. package/lib/init/template/destinations/files/destination.yaml +1 -0
  44. package/lib/init/template/destinations/index.js +44 -0
  45. package/lib/init/template/enterprise-messaging/files/cds.package.json +10 -0
  46. package/lib/init/template/enterprise-messaging/files/cds.profile.package.json.hbs +12 -0
  47. package/lib/init/template/enterprise-messaging/files/cdsrc.json +8 -0
  48. package/lib/init/template/enterprise-messaging/files/cdsrc.json.hbs +10 -0
  49. package/lib/init/template/enterprise-messaging/files/event-mesh.yaml +1 -0
  50. package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +13 -0
  51. package/lib/init/template/enterprise-messaging/files/values.yaml +8 -0
  52. package/lib/init/template/enterprise-messaging/index.js +56 -0
  53. package/lib/init/template/extensibility/files/cdsrc.json +5 -0
  54. package/lib/init/template/extensibility/files/cdsrc.json.hbs +7 -0
  55. package/lib/init/template/extensibility/index.js +18 -13
  56. package/lib/{k8s/hana-deployer/templates → init/template/hana/files}/hana-deployer-job.yaml +0 -0
  57. package/lib/init/template/hana/files/java/{cdsrc.json.hbs → cds.json.hbs} +0 -0
  58. package/lib/init/template/hana/files/java/{profile.cdsrc.json.hbs → cds.profile.json.hbs} +0 -0
  59. package/lib/init/template/hana/files/java/cds.shortcut.json.hbs +5 -0
  60. package/lib/init/template/hana/files/java/cds.shortcut.profile.json.hbs +8 -0
  61. package/lib/init/template/hana/files/java/db/package.json +2 -1
  62. package/lib/init/template/hana/files/mta.yaml.hbs +6 -0
  63. package/lib/init/template/hana/files/nodejs/{cds.package.json.hbs → cds.json.hbs} +0 -0
  64. package/lib/init/template/hana/files/nodejs/{cds.profile.package.json.hbs → cds.profile.json.hbs} +0 -0
  65. package/lib/init/template/hana/files/nodejs/cds.shortcut.json.hbs +7 -0
  66. package/lib/init/template/hana/files/nodejs/cds.shortcut.profile.json.hbs +10 -0
  67. package/lib/init/template/hana/files/values.yaml.hbs +19 -0
  68. package/lib/init/template/hana/index.js +29 -29
  69. package/lib/{k8s → init/template/helm}/Model.d.ts +0 -0
  70. package/lib/{k8s/resources → init/template}/helm/chart/templates/NOTES.txt +0 -0
  71. package/lib/{k8s/resources → init/template}/helm/chart/templates/_deployment_helpers.tpl +0 -0
  72. package/lib/{k8s/resources → init/template}/helm/chart/templates/_helpers.tpl +4 -5
  73. package/lib/{k8s/resources → init/template}/helm/chart/templates/_sapcp_helpers.tpl +0 -0
  74. package/lib/{k8s/resources/helm/chart/schemas → init/template/helm/chart}/values.root.schema.json +0 -0
  75. package/lib/{k8s/resources/helm/chart/schemas → init/template/helm/chart}/values.schema.json +0 -0
  76. package/lib/init/template/helm/files/Chart.yaml.hbs +13 -0
  77. package/lib/init/template/helm/files/values.yaml.hbs +26 -0
  78. package/lib/init/template/helm/index.js +74 -14
  79. package/lib/{k8s/deployment → init/template/helm}/subchart/Chart.yaml +0 -0
  80. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/_helpers.tpl +0 -0
  81. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/api-rule.yaml +0 -0
  82. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/deployment.yaml +0 -0
  83. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/network-policy.yaml +0 -0
  84. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/pod-disruption-budget.yaml +0 -0
  85. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/secret.yaml +0 -0
  86. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/service-binding.yaml +0 -0
  87. package/lib/{k8s/deployment → init/template/helm}/subchart/templates/service.yaml +0 -0
  88. package/lib/{k8s/deployment → init/template/helm}/subchart/values-lint.yaml +0 -0
  89. package/lib/{k8s/deployment → init/template/helm}/subchart/values.md +0 -0
  90. package/lib/{k8s/deployment → init/template/helm}/subchart/values.schema.json +0 -0
  91. package/lib/{k8s/deployment → init/template/helm}/subchart/values.yaml +0 -0
  92. package/lib/{k8s/html5-apps-deployer/templates → init/template/html5-repo/files}/_html5_deployment_helpers.tpl +0 -0
  93. package/lib/{k8s/html5-apps-deployer/templates → init/template/html5-repo/files}/html5-apps-deployer-job.yaml +1 -1
  94. package/lib/{k8s/html5-apps-repo-host/templates → init/template/html5-repo/files}/html5-apps-repo-host.yaml +0 -0
  95. package/lib/init/template/html5-repo/index.js +59 -0
  96. package/lib/init/template/kibana-logging/index.js +8 -0
  97. package/lib/init/template/lint/index.js +1 -4
  98. package/lib/init/template/mta/files/mta.yaml.hbs +3 -2
  99. package/lib/init/template/mta/index.js +6 -1
  100. package/lib/init/template/multitenancy/files/java/.cdsrc.json +3 -0
  101. package/lib/init/template/multitenancy/files/java/package.json +2 -6
  102. package/lib/{k8s/multitenancy/templates → init/template/multitenancy/files}/saas-registry.yaml +3 -3
  103. package/lib/init/template/multitenancy/files/xsuaa.yaml +1 -0
  104. package/lib/init/template/multitenancy/index.js +53 -26
  105. package/lib/init/template/nodejs/files/.gitignore.hbs +1 -0
  106. package/lib/init/template/templateBase.js +1 -1
  107. package/lib/init/template/xsuaa/files/values.yaml.hbs +10 -0
  108. package/lib/init/template/xsuaa/files/xsuaa.yaml +1 -0
  109. package/lib/init/template/xsuaa/index.js +34 -22
  110. package/lib/init/util/fsUtil.js +11 -5
  111. package/lib/init/util/projectReader.js +24 -32
  112. package/lib/init/util/templateUtil.js +17 -5
  113. package/lib/lint/Linter.js +9 -17
  114. package/lib/lint/checks.js +0 -1
  115. package/lib/lint/generators.js +2 -192
  116. package/lib/lint/io.js +1 -3
  117. package/lib/watch/node-watch.js +2 -2
  118. package/npm-shrinkwrap.json +1666 -873
  119. package/package.json +5 -4
  120. package/lib/init/template/helm/update/index.js +0 -28
  121. package/lib/k8s/ChartAdder.js +0 -75
  122. package/lib/k8s/ChartBuilder.js +0 -192
  123. package/lib/k8s/Context.js +0 -71
  124. package/lib/k8s/ImageUtil.js +0 -21
  125. package/lib/k8s/auditlog/index.js +0 -29
  126. package/lib/k8s/auditlog/templates/auditlog.yaml +0 -1
  127. package/lib/k8s/buildModel.js +0 -68
  128. package/lib/k8s/connectivity/index.js +0 -80
  129. package/lib/k8s/deployment/index.js +0 -79
  130. package/lib/k8s/deployment/subchart-override/templates/_web_application_helpers.tpl +0 -81
  131. package/lib/k8s/destinations/index.js +0 -40
  132. package/lib/k8s/destinations/lib.js +0 -16
  133. package/lib/k8s/destinations/templates/destinations.yaml +0 -1
  134. package/lib/k8s/docker/push.js +0 -8
  135. package/lib/k8s/event-mesh/index.js +0 -53
  136. package/lib/k8s/event-mesh/lib.js +0 -9
  137. package/lib/k8s/event-mesh/templates/event-mesh.yaml +0 -1
  138. package/lib/k8s/hana-deployer/index.js +0 -48
  139. package/lib/k8s/helm/Release.js +0 -80
  140. package/lib/k8s/html5-apps-deployer/index.js +0 -53
  141. package/lib/k8s/html5-apps-repo-host/index.js +0 -26
  142. package/lib/k8s/html5-apps-repo-host/lib.js +0 -16
  143. package/lib/k8s/index.js +0 -153
  144. package/lib/k8s/modules.js +0 -36
  145. package/lib/k8s/multitenancy/index.js +0 -24
  146. package/lib/k8s/multitenancy/lib.js +0 -25
  147. package/lib/k8s/readProject.js +0 -14
  148. package/lib/k8s/util.js +0 -186
  149. package/lib/k8s/wrapFeature.js +0 -55
  150. package/lib/k8s/xsuaa/index.js +0 -64
  151. package/lib/k8s/xsuaa/lib.js +0 -17
  152. package/lib/k8s/xsuaa/templates/xsuaa.yaml +0 -1
@@ -1,7 +1,8 @@
1
1
  const path = require('path')
2
2
  const { nullLogger } = require('../util/logger')
3
- const { BuildTaskFactory } = require('@sap/cds/bin/build')
4
- const { fs } = require('@sap/cds').utils
3
+ const cds = require('../../cds')
4
+ const { BuildTaskFactory } = cds.build
5
+ const { fs } = cds.utils
5
6
  const P_LANGUAGE_JAVA = 'java'
6
7
  const P_LANGUAGE_NODEJS = 'nodejs'
7
8
  const DEFAULT_P_LANGUAGE = P_LANGUAGE_NODEJS
@@ -72,15 +73,13 @@ module.exports = class ProjectReader {
72
73
  requires: [],
73
74
  get isMultitenant() {
74
75
  return options?.add?.has('mtx') || options?.add?.has('multitenancy') ||
75
- env.requires.multitenancy ||
76
- env.requires.db?.multiTenant ||
76
+ env.requires.multitenancy || env.requires.db?.multiTenant ||
77
77
  this.isJava && fs.existsSync(path.join('mtx', 'sidecar')) ||
78
78
  false
79
79
  },
80
80
  get isExtensible() {
81
- const sidecarPackage = path.join('mtx', 'sidecar', 'package.json')
82
81
  return options?.add?.has('mtx') || options?.add?.has('extensibility') || env.requires.extensibility ||
83
- fs.existsSync(sidecarPackage) && JSON.parse(fs.readFileSync(sidecarPackage, 'utf8')).cds.requires.extensibility === true
82
+ this.isJava && fs.existsSync('.cdsrc.json') && JSON.parse(fs.readFileSync('.cdsrc.json', 'utf8'))?.requires?.extensibility === true
84
83
  },
85
84
  get isNodejs() {
86
85
  return this.pLanguage === P_LANGUAGE_NODEJS
@@ -100,14 +99,32 @@ module.exports = class ProjectReader {
100
99
  get hasXsuaa() {
101
100
  return this.requires.some(({ resource }) => resource.isXsuaa)
102
101
  },
102
+ get hasAuditlog() {
103
+ return false // TODO: Need a `cds.requires.auditlog` or some other way to detect if enabled.
104
+ },
103
105
  get needsSidecar() {
104
- return (options && options.add.has('hana') || this.db.length > 0) && (this.isJava || !this.isMultitenant)
106
+ return (options?.add.has('hana') || this.db.length > 0) && (this.isJava || !this.isMultitenant)
105
107
  },
106
108
  get hasApprouter() {
107
109
  return !!env.requires.approuter
108
110
  },
111
+ get hasMessaging() {
112
+ return !!env.requires.messaging
113
+ },
114
+ get hasDestination() {
115
+ const kinds = { odata: 1, 'odata-v2': 1, 'odata-v4': 1, rest: 1 }
116
+ return Object.entries(env.requires).some(([service, require]) => !kinds[service] && kinds[require.kind])
117
+ },
118
+ get hasHtml5Repo() {
119
+ return fs.existsSync(path.join(projectPath, 'chart', 'templates', 'html5-apps-repo-host.yaml'))
120
+ },
109
121
  get hasMtaDeployment() {
122
+ if (!options?.add.has('mta') && options?.add.has('helm')) return false
110
123
  return fs.existsSync(path.join(projectPath, 'mta.yaml'))
124
+ },
125
+ get hasHelmDeployment() {
126
+ if (options?.add.has('mta') && !options?.add.has('helm')) return false
127
+ return fs.existsSync(path.join(projectPath, 'chart', 'values.yaml'))
111
128
  }
112
129
  }
113
130
 
@@ -213,31 +230,6 @@ module.exports = class ProjectReader {
213
230
  throw Error(`${capDescriptor.pLanguage} not supported`)
214
231
  }
215
232
 
216
- // TODO - shall we use project related data from existing mta like version, name, id or description
217
- // and overwrite everything else?
218
- //
219
- // const mtaFile = path.join(this.projectPath, 'mta.yaml')
220
- // let mta
221
- // if (await this.fsUtil.pathExists(mtaFile)) {
222
- // try {
223
- // const {yaml} = require('@sap/cds-foss')
224
- // const content = await this.fsUtil.readFile(mtaFile, 'utf-8')
225
- // mta = yaml.parse(content)
226
- // } catch (e) {
227
- // this.logger.error(`Failed to load ${mtaFile} - skip mta data`)
228
- // this.logger.error(e)
229
- // }
230
- // }
231
-
232
- // if (mta) {
233
- // details.id = mta.ID
234
- // details.description = mta.description
235
- // details.version = mta.version
236
- // if (mta.ID) {
237
- // details.name = mta.ID.replace('.', '-')
238
- // }
239
- // }
240
-
241
233
  // 1.1. java - use parent pom.xml
242
234
  if (capDescriptor.pLanguage === P_LANGUAGE_JAVA) {
243
235
  const pomXmlPath = path.join(this.projectPath, 'pom.xml')
@@ -1,6 +1,7 @@
1
1
  const path = require('path');
2
- const YAML = require('@sap/cds-foss')('yaml');
2
+ const YAML = require('@sap/cds-foss').yaml;
3
3
  const Mustache = require('mustache');
4
+ const { fs } = require('../../cds').utils;
4
5
 
5
6
  const TEMPLATE_EXTENSION = '.hbs';
6
7
  const TEMPLATE_EXTENSION_REGEX = new RegExp(`${TEMPLATE_EXTENSION}$`);
@@ -111,10 +112,21 @@ module.exports = class TemplateUtil {
111
112
  }
112
113
 
113
114
  async mergeYAML(into, from, projectDescriptor, semantics) {
114
- const target = typeof into === 'string' ? await this.fsUtil.readYAML(into) : into
115
- const source = typeof from === 'string' ? await this.fsUtil.readYAML(from, projectDescriptor) : from
116
-
117
- if (!target || !target.contents) return // Has no YAML file
115
+ const target =
116
+ typeof into === 'string' ? await this.fsUtil.readYAML(into) :
117
+ into instanceof YAML.Document ? into :
118
+ new YAML.Document(into)
119
+ const source =
120
+ typeof from === 'string' ? await this.fsUtil.readYAML(from, projectDescriptor)
121
+ : from instanceof YAML.Document ? from :
122
+ new YAML.Document(from)
123
+
124
+ if (!target || !target.contents) {
125
+ if (typeof into === 'string' && typeof from === 'string') {
126
+ return projectDescriptor ? this.fsUtil.writeYAML(into, source) : fs.copy(from, into)
127
+ }
128
+ return /* has no YAML */
129
+ }
118
130
 
119
131
  const existenceMap = new Map()
120
132
  const templateExistenceMap = new Map()
@@ -70,9 +70,6 @@ class Linter {
70
70
  // Determine if case "local" or "global" and resolve plugin accordingly
71
71
  await this._getConfigFileAndSetProjectPath(args);
72
72
 
73
- // Add custom rules
74
- await this._addRulePaths();
75
-
76
73
  const overwriteRules = checks.hasEslintConfigContent(this.configContents, "rules");
77
74
  if (overwriteRules) {
78
75
  await this._overwriteRuleSeverities();
@@ -105,16 +102,6 @@ class Linter {
105
102
  return options;
106
103
  }
107
104
 
108
- async _addRulePaths() {
109
- const rulesPath = path.relative(".", ".eslint/rules");
110
- if (await exists(rulesPath) && await isdir(rulesPath)) {
111
- const opts = io.mergeWithUserOpts(this.eslintCmdOpts, "rulesdir", path.relative(".", rulesPath));
112
- this.customRulesOpts = opts.rulesdir;
113
- await generators.genDocs(this.projectPath.replace(rulesPath, ""));
114
- }
115
- return;
116
- }
117
-
118
105
  /**
119
106
  * Searches for ESLint config file types (in order or precedence)
120
107
  * and returns corresponding directory (usually project's root dir)
@@ -136,8 +123,13 @@ class Linter {
136
123
  while (configDir !== path.resolve(configDir, "..")) {
137
124
  for (let i = 0; i < configFiles.length; i++) {
138
125
  const configPath = path.join(configDir, configFiles[i]);
139
- if (await exists(configPath) && await isfile(configPath)) {
140
- return configPath;
126
+ if (configFiles[i] !== "package.json" || (
127
+ configFiles[i] !== "package.json" && require(configPath).eslintConfig
128
+ )) {
129
+ if (await exists(configPath) && await isfile(configPath)) {
130
+
131
+ return configPath;
132
+ }
141
133
  }
142
134
  }
143
135
  configDir = path.join(configDir, "..");
@@ -191,13 +183,13 @@ class Linter {
191
183
  LOG_CONFIG && LOG_CONFIG(eslintOpts);
192
184
 
193
185
  let lintString = `eslint`;
194
- if (this.fileExtensions) { lintString += ` --ext "${this.fileExtensions.join(",")}"`};
186
+ if (this.fileExtensions) { lintString += ` --ext "${this.fileExtensions.join(",")}"`}
195
187
  for (const ruleOpt of Object.entries(this.ruleOpts)) {
196
188
  lintString += ` --rule ${ruleOpt[0]}:${ruleOpt[1]}`;
197
189
  }
198
190
  if (this.customRulesOpts && this.customRulesOpts.length > 0) {
199
191
  lintString += ` --rulesdir "${this.customRulesOpts}"`
200
- };
192
+ }
201
193
 
202
194
  LOG && LOG(lintString);
203
195
 
@@ -3,7 +3,6 @@ const os = require("os");
3
3
  const path = require("path");
4
4
  const term = require("../util/term");
5
5
  const commandUtil = require("../init/util/commandUtil");
6
- const io = require("./io");
7
6
 
8
7
  const IS_WIN = os.platform() === "win32";
9
8
  const { URLS } = require("../init/constants");
@@ -1,8 +1,5 @@
1
- const fs = require("fs");
2
1
  const os = require("os");
3
2
  const cp = require("child_process");
4
- const path = require("path");
5
- const { mkdirp } = require("@sap/cds").utils;
6
3
  const term = require("../util/term");
7
4
 
8
5
  const IS_WIN = os.platform() === "win32";
@@ -78,7 +75,7 @@ module.exports = {
78
75
  }
79
76
  });
80
77
  const optionsWithoutShortcuts = allOptions.filter((o) => !optionsWithShortcuts.includes(o));
81
- optionsWithoutShortcuts.forEach((opt) => {
78
+ optionsWithoutShortcuts.forEach(() => {
82
79
  shortcuts.push(undefined)
83
80
  });
84
81
  let options = optionsWithShortcuts.concat(optionsWithoutShortcuts);
@@ -95,193 +92,6 @@ module.exports = {
95
92
  */
96
93
  genEslintFlags: function (help) {
97
94
  return help.match(REGEX_FLAGS).map((str) => str.trim().replace(",", ""));
98
- },
99
-
100
- /**
101
- * Generates custom rules documentation for user
102
- * according to contents of rules files
103
- * @param {*} projectPath
104
- */
105
- async genDocs(projectPath) {
106
- let mdRule, mdRuleSources, mdRuleContents;
107
- const testPath = path.join(projectPath, ".eslint/tests");
108
- const rulePath = path.join(projectPath, ".eslint/rules");
109
- const docsPath = path.join(projectPath, ".eslint/docs");
110
-
111
- if (!fs.existsSync(testPath)) {
112
- await mkdirp(testPath);
113
- }
114
- if (!fs.existsSync(rulePath)) {
115
- await mkdirp(rulePath);
116
- }
117
- if (!fs.existsSync(docsPath)) {
118
- await mkdirp(docsPath);
119
- }
120
-
121
- const ruleDocsPath = path.join(docsPath, "Rules.md");
122
- const ruleListDocsPath = path.join(docsPath, "RuleList.md");
123
- const ruleDict = {};
124
-
125
- if (!fs.existsSync(ruleDocsPath)) {
126
- fs.writeFileSync(ruleDocsPath, "", "utf8");
127
- }
128
- if (!fs.existsSync(ruleListDocsPath)) {
129
- fs.writeFileSync(ruleListDocsPath, "", "utf8");
130
- }
131
-
132
- function getKeyFromMeta(text, key) {
133
- const regexQuote = new RegExp(`${key}:[\\s]+[\\', \\\`, \\"]`, "gm");
134
- const matchQuote = regexQuote.exec(text);
135
- if (matchQuote) {
136
- const quote = matchQuote[0].slice(-1);
137
- const exprStart = `${key}:[\\s]+\\${quote}`;
138
- const exprEnd = `(\\${quote},?)`;
139
- const regexKey = new RegExp(`${exprStart}[\\s\\S]*?${exprEnd}`, "gm");
140
- const matchKey = regexKey.exec(text);
141
- if (matchKey) {
142
- const regexStart = new RegExp(`${exprStart}`, "gm");
143
- const regexEnd = new RegExp(`${exprEnd}`, "gm");
144
- return matchKey[0]
145
- .replace(regexStart, "")
146
- .replace(regexEnd, "")
147
- .replace("fixable:", "")
148
- .trim();
149
- } else {
150
- return "";
151
- }
152
- } else {
153
- return "";
154
- }
155
- }
156
-
157
- function getKeyFromTest(text, key) {
158
- let dissallowPrefix = "";
159
- if (key === "valid") {
160
- dissallowPrefix = "[^n]";
161
- }
162
- const exprStart = `${dissallowPrefix}${key}:[\\s]+\\[[\\s\\n]+{[\\s\\n]+code:[\\s\\n]+`;
163
- const regexTestKey = new RegExp(`${exprStart}[\\', \\\`, \\"]`, "gm");
164
- const matchTestKey = regexTestKey.exec(text);
165
- if (matchTestKey) {
166
- const quote = matchTestKey[0].slice(-1);
167
- const exprStart = `${dissallowPrefix}${key}:[\\s]+\\[[\\s\\n]+{[\\s\\n]+code:[\\s\\n]+`;
168
- const regexStart = new RegExp(exprStart, "gm");
169
- const regexCode = new RegExp(
170
- `${exprStart}${quote}[\\s\\S]*?(\\${quote},?)`,
171
- "gm"
172
- );
173
- const matchCode = regexCode.exec(text);
174
- const code = matchCode[0].replace(regexStart, "");
175
- const regex = new RegExp(`${quote},`, "gm");
176
- const regex2 = new RegExp(`${quote}`, "gm");
177
- return code.replace(regex, "").replace(regex2, "");
178
- } else {
179
- return "";
180
- }
181
- }
182
-
183
- function genMdRules(release, table = true) {
184
- let version = "latest";
185
- if (release) {
186
- version = release;
187
- }
188
- let mdRules = `# @sap/eslint-plugin-cds [${version}]\n\n`;
189
- if (table) {
190
- Object.entries(ruleDict).forEach(([category, rules]) => {
191
- mdRules += `## Category: ${category}\n\n`;
192
- mdRules += "<table>";
193
- mdRules += "<tr><th>Rule</th><th>Fixable</th><th>Version</th></tr>";
194
- rules.forEach(function (rule) {
195
- mdRules += `<tr><td><a href="./Rules.md#rule-${rule.name}">${rule.name}</a></td><td>${rule.fix}</td><td>${rule.version}</td></tr>`;
196
- });
197
- mdRules += "</table>\n\n<br>\n\n";
198
- });
199
- }
200
- return mdRules;
201
- }
202
-
203
- const mdRulesCur = fs.readFileSync(ruleDocsPath, "utf8");
204
- const mdRuleListCur = fs.readFileSync(ruleListDocsPath, "utf8");
205
- fs.readdirSync(rulePath).filter(function (file) {
206
- if (path.extname(file).toLowerCase() === ".js") {
207
- const rule = path.basename(file).replace(path.extname(file), "");
208
- const ruleTestPath = path.join(testPath, `${rule}.test.js`);
209
-
210
- // Get rule meta information
211
- const ruleMeta = fs.readFileSync(path.join(rulePath, file), "utf8");
212
- const details = getKeyFromMeta(ruleMeta, "description");
213
- const category = getKeyFromMeta(ruleMeta, "category");
214
- const fixable = getKeyFromMeta(ruleMeta, "fixable");
215
- let isFixable = "";
216
- if (["code", "whitespace"].includes(fixable)) {
217
- isFixable = ":wrench:";
218
- }
219
- const version = getKeyFromMeta(ruleMeta, "version");
220
-
221
- // Get rule valid/invalid tests
222
- mdRule = "";
223
- if (fs.existsSync(ruleTestPath)) {
224
- const ruleTest = fs.readFileSync(ruleTestPath, "utf8");
225
- const valid = getKeyFromTest(ruleTest, "valid");
226
- const invalid = getKeyFromTest(ruleTest, "invalid");
227
-
228
- mdRule +=
229
- `<span>:heavy_check_mark:&nbsp;&nbsp; Example of ` +
230
- `<font style="color:green">correct</font> ` +
231
- `code for this rule:</span>\n\n\`\`\`\n${valid}\n\`\`\`\n\n`;
232
- mdRule +=
233
- `<span>:x:&nbsp;&nbsp; Example of ` +
234
- `<font style="color:red">incorrect</font> ` +
235
- `code for this rule:</span>\n\n\`\`\`\n${invalid}\n\`\`\``;
236
- }
95
+ }
237
96
 
238
- mdRuleContents = `## Rule: ${rule}\n`;
239
- mdRuleContents += `<span class='label shifted'>${category}</span>\n\n`;
240
- mdRuleContents += `### Rule Details\n${details}\n\n`;
241
- if (mdRule) {
242
- mdRuleContents += `### Examples\n${mdRule}\n\n`;
243
- }
244
- mdRuleContents += `### Version\nThis rule was introduced in \`@sap/eslint-plugin-cds ${version}\`.\n\n`;
245
- mdRuleSources = `### Resources\n[Rule & Documentation source](${path.relative(
246
- docsPath,
247
- path.join(rulePath, `${rule}.js`)
248
- )})\n\n`;
249
-
250
- if (Object.keys(ruleDict).includes(category)) {
251
- ruleDict[category].push({
252
- name: rule,
253
- fix: isFixable,
254
- version: version,
255
- contents: mdRuleContents,
256
- sources: mdRuleSources,
257
- });
258
- } else {
259
- ruleDict[category] = [
260
- {
261
- name: rule,
262
- fix: isFixable,
263
- version: version,
264
- contents: mdRuleContents,
265
- sources: mdRuleSources,
266
- },
267
- ];
268
- }
269
- }
270
- });
271
-
272
- let mdRules = genMdRules(undefined, false);
273
- let mdRuleList = genMdRules();
274
-
275
- /* eslint-disable-next-line no-unused-vars */
276
- Object.entries(ruleDict).forEach(([category, rules]) => {
277
- rules.forEach(function (rule) {
278
- mdRules += `${rule.contents}\n\n${rule.sources}\n\n---\n\n`;
279
- });
280
- });
281
-
282
- if (mdRuleListCur !== mdRuleList || mdRulesCur !== mdRules) {
283
- fs.writeFileSync(ruleDocsPath, mdRules, "utf8");
284
- fs.writeFileSync(ruleListDocsPath, mdRuleList, "utf8");
285
- }
286
- },
287
97
  };
package/lib/lint/io.js CHANGED
@@ -1,12 +1,10 @@
1
- const os = require("os");
2
1
  const fsp = require("fs").promises;
3
2
  const path = require("path");
4
3
  const yaml = require("@sap/cds-foss")("yaml");
5
4
  const term = require("../util/term");
6
5
  const FsUtil = require("../init/util/fsUtil");
7
6
  const fsUtil = new FsUtil();
8
-
9
- const IS_WIN = os.platform() === "win32";
7
+ const JSONC = require("../util/jsonc")
10
8
 
11
9
  module.exports = {
12
10
  /**
@@ -1,6 +1,6 @@
1
1
  const DEBUG = /\bwatch\b/.test(process.env.DEBUG) && console.debug
2
2
 
3
- module.exports = ({ cwd, script, ext, ignore=RegExp(), env={}, delay=200, options={} })=>{
3
+ module.exports = ({ cwd, script, ext, includes=RegExp(), ignore=RegExp(), env={}, delay=200, options={} })=>{
4
4
 
5
5
  let child
6
6
 
@@ -46,7 +46,7 @@ module.exports = ({ cwd, script, ext, ignore=RegExp(), env={}, delay=200, option
46
46
 
47
47
  // Watching for touched files...
48
48
  const watch = require('node-watch')
49
- const include = RegExp(`\\.(${ext.replace(/,/g,'|')})$`)
49
+ const include = RegExp(`\\.(${ext.replace(/,/g,'|')})$|${includes.source}`)
50
50
  const filter = f => !ignore.test(f) && include.test(f)
51
51
  watch (cwd||process.cwd(),{ recursive:true, filter, delay:0 }, restart)
52
52