@sap/cds-dk 7.2.0 → 7.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.
Files changed (56) hide show
  1. package/bin/activate.js +2 -2
  2. package/bin/build.js +6 -3
  3. package/bin/compile/index.js +9 -5
  4. package/bin/env.js +0 -3
  5. package/bin/extend.js +25 -3
  6. package/bin/import.js +7 -3
  7. package/bin/push.js +10 -6
  8. package/bin/watch.js +1 -1
  9. package/lib/build/{buildTaskHandler.js → buildPlugin.js} +23 -25
  10. package/lib/build/buildTaskEngine.js +73 -73
  11. package/lib/build/buildTaskFactory.js +6 -23
  12. package/lib/build/buildTaskProvider.js +24 -19
  13. package/lib/build/buildTaskProviderFactory.js +170 -57
  14. package/lib/build/constants.js +4 -4
  15. package/lib/build/index.js +3 -2
  16. package/lib/build/provider/{buildTaskHandlerEdmx.js → edmxBuildPlugin.js} +6 -6
  17. package/lib/build/provider/{buildTaskHandlerFeatureToggles.js → featureToggleBuildPlugin.js} +3 -3
  18. package/lib/build/provider/fiori/index.js +5 -6
  19. package/lib/build/provider/hana/index.js +54 -30
  20. package/lib/build/provider/{buildTaskHandlerInternal.js → internalBuildPlugin.js} +10 -10
  21. package/lib/build/provider/{buildTaskProviderInternal.js → internalBuildTaskProvider.js} +27 -28
  22. package/lib/build/provider/java/index.js +24 -24
  23. package/lib/build/provider/mtx/index.js +4 -4
  24. package/lib/build/provider/mtx/resourcesTarBuilder.js +8 -8
  25. package/lib/build/provider/mtx-extension/index.js +17 -9
  26. package/lib/build/provider/mtx-sidecar/index.js +17 -11
  27. package/lib/build/provider/nodejs/index.js +14 -13
  28. package/lib/client/auth_manager.js +6 -12
  29. package/lib/client/base_command.js +1 -1
  30. package/lib/client/download_legacy.js +48 -0
  31. package/lib/client/params.js +5 -0
  32. package/lib/client/push.js +41 -1
  33. package/lib/client/settings_manager.js +12 -3
  34. package/lib/env/schema.js +36 -0
  35. package/lib/env/schemas/cds-rc.json +101 -0
  36. package/lib/import/common.js +23 -10
  37. package/lib/import/importapi.js +2 -2
  38. package/lib/import/message.js +3 -1
  39. package/lib/import/odata/v4parser.js +23 -7
  40. package/lib/index.js +5 -0
  41. package/lib/init/constants.js +4 -2
  42. package/lib/init/index.js +2 -3
  43. package/lib/init/template/_merging/registry-mta.js +21 -0
  44. package/lib/init/template/approuter/files/mta.yaml.hbs +1 -1
  45. package/lib/init/template/approuter/index.js +9 -9
  46. package/lib/init/template/connectivity/index.js +5 -4
  47. package/lib/init/template/destination/index.js +2 -5
  48. package/lib/init/template/html5-repo/index.js +27 -3
  49. package/lib/init/template/mta/index.js +9 -3
  50. package/lib/init/template/postgres/files/mta.yaml.hbs +27 -0
  51. package/lib/init/template/postgres/files/package.json.hbs +5 -0
  52. package/lib/init/template/postgres/index.js +52 -0
  53. package/lib/init/util/projectReader.js +0 -1
  54. package/lib/util/pruneAxiosErrors.js +22 -8
  55. package/npm-shrinkwrap.json +1829 -23
  56. package/package.json +1 -1
@@ -9,7 +9,7 @@ let common = require("../common");
9
9
  let versionInfo = require("../../../package.json").version;
10
10
  let Multimap = require("./util/MultiMap");
11
11
  const ignoreObjects = ["$Reference"]; // add all the objects that needs to be ignored for parsing.
12
- const { warn } = require("../../util/term");
12
+ const { warn, info } = require("../../util/term");
13
13
  const MetadataConverterFactory = require("./metadataconverter/MetadataConverterFactory");
14
14
 
15
15
  const edmPrimitiveTypes = [
@@ -1216,6 +1216,12 @@ function _parseAnnotations(schemaAnnotations, csnDefs, parserContext) {
1216
1216
  });
1217
1217
  }
1218
1218
 
1219
+ function _addSuffixForCollisionTypes(fqName, suffix) {
1220
+ console.log(info(`INFO: Due to collision in ${fqName} suffix "${suffix}" is added.`));
1221
+ const suffixedFqElementName = (fqName + suffix);
1222
+ return suffixedFqElementName;
1223
+ }
1224
+
1219
1225
  function _parseEntityContainer(csnDefs, entityContainerElements, parserContext) {
1220
1226
  const entityContainerElementNames = Object.keys(entityContainerElements);
1221
1227
  const redundantElementNames = [];
@@ -1241,16 +1247,26 @@ function _parseEntityContainer(csnDefs, entityContainerElements, parserContext)
1241
1247
  let fqDefRefName = _resolveAliasedElementName(definitionRefName, parserContext);
1242
1248
  let fqElementName = parserContext.primarySchema + "." + ecElement;
1243
1249
 
1244
- /**
1245
- * For now we don't support the collision between entitycontainer element name
1246
- * and any of the schema elemetents like entitytype, complextype, etc.
1247
- * TODO: In future we might have to support it.
1248
- */
1249
1250
  if (csnDefs[fqElementName] && csnDefs[fqElementName].kind !== kind) {
1250
- throw new Error(messages.ELEMENT_NAME_COLLISION + ecElement);
1251
+ console.log(info(messages.COLLISION_DETECTED));
1252
+ let suffixedFqElementName;
1253
+ // Check the type category that experienced the collision
1254
+ if (parserContext.complexTypes.includes(fqElementName)) {
1255
+ suffixedFqElementName = _addSuffixForCollisionTypes(fqElementName, "_ComplexType");
1256
+ } else if (parserContext.enumTypes.includes(fqElementName)) {
1257
+ suffixedFqElementName = _addSuffixForCollisionTypes(fqElementName, "_EnumType");
1258
+ } else if (parserContext.typeDefinitions.includes(fqElementName)) {
1259
+ suffixedFqElementName = _addSuffixForCollisionTypes(fqElementName, "_TypeDefinition");
1260
+ }
1261
+ // copy the definition with new suffixed name and delete the old definition from csnDefs
1262
+ csnDefs[suffixedFqElementName] = csnDefs[fqElementName];
1263
+ delete csnDefs[fqElementName];
1251
1264
  }
1252
1265
 
1253
1266
  if (fqElementName !== fqDefRefName) {
1267
+ if (csnDefs[fqElementName] && !parserContext.entityToEntitySetMap.get(fqElementName)) {
1268
+ fqElementName = _addSuffixForCollisionTypes(fqElementName, "_EntityType");
1269
+ }
1254
1270
  csnDefs[fqElementName] = Object.assign({}, csnDefs[fqDefRefName]);
1255
1271
  /**
1256
1272
  * Capture all the defintion reference element name which are no
package/lib/index.js CHANGED
@@ -18,3 +18,8 @@ cds.extend (cds.compile.to.constructor) .with (class {
18
18
  if (cds.compile.to.constructor.name === 'Object') { // not a class as in cds 7
19
19
  cds.compile.to.xsuaa = require('./compile/to-xsuaa')
20
20
  }
21
+
22
+ cds.schema = cds.schema || {} // backward compatibility
23
+ cds.extend (cds.schema) .with ( {
24
+ overlay4: require('./env/schema')
25
+ })
@@ -4,7 +4,7 @@ module.exports = {
4
4
  COMMAND_INIT: 'init',
5
5
  COMMAND_ADD: 'add',
6
6
 
7
- MAVEN_ARCHETYPE_VERSION: '2.2.0',
7
+ MAVEN_ARCHETYPE_VERSION: '2.3.0',
8
8
 
9
9
  OPTIONS: Object.freeze({
10
10
  JAVA: 'java',
@@ -24,6 +24,7 @@ module.exports = {
24
24
  EXTENSIBILITY: 'extensibility',
25
25
  XSUAA: 'xsuaa',
26
26
  HANA: 'hana',
27
+ POSTGRES: 'postgres',
27
28
  SQLITE: 'sqlite',
28
29
  H2: 'h2',
29
30
  ENTERPRISE_MESSAGING: 'enterprise-messaging',
@@ -38,7 +39,8 @@ module.exports = {
38
39
  LINT_GLOBAL: 'lint:global',
39
40
  LINT_DEV: 'lint:dev',
40
41
  HELM: 'helm',
41
- TYPER: 'typer'
42
+ TYPER: 'typer',
43
+ HTML5_REPO: 'html5-repo'
42
44
  }),
43
45
 
44
46
  PROJECT_TYPE: Object.freeze({ nodejs: 1, java: 2, unknown: 3 }),
package/lib/init/index.js CHANGED
@@ -126,9 +126,8 @@ module.exports = class CDSGenerator {
126
126
  }
127
127
 
128
128
  async stepInit(projectName, options) {
129
-
130
- if (!cds.cli?.command) {
131
- // called from CAP generator
129
+ if (options) {
130
+ // called from CAP generator with options
132
131
  cds.cli = {
133
132
  command: COMMAND_INIT,
134
133
  // keep caller independent from internal names
@@ -126,6 +126,25 @@ const serviceManager = {
126
126
  }]
127
127
  }
128
128
 
129
+ const postgres = {
130
+ in: 'resources',
131
+ where: [{
132
+ property: 'parameters.service',
133
+ isEqualTo: 'postgresql-db',
134
+ }]
135
+ }
136
+
137
+ const postgresDeployer = {
138
+ in: 'modules',
139
+ where: [{
140
+ property: 'type',
141
+ isEqualTo: 'nodejs',
142
+ }, {
143
+ property: 'path',
144
+ isEqualTo: 'gen/pg',
145
+ }]
146
+ }
147
+
129
148
  const saasRegistry = {
130
149
  in: 'resources',
131
150
  where: [{
@@ -255,6 +274,8 @@ module.exports = {
255
274
  hdbDeployer,
256
275
  hdiContainer,
257
276
  serviceManager,
277
+ postgres,
278
+ postgresDeployer,
258
279
  saasRegistry,
259
280
  redis,
260
281
  srvApi4,
@@ -19,7 +19,7 @@ modules:
19
19
 
20
20
  - name: {{appName}}
21
21
  type: approuter.nodejs
22
- path: {{& approuterPath }}
22
+ path: {{& appPath}}
23
23
  parameters:
24
24
  keep-existing-routes: true
25
25
  disk-quota: 256M
@@ -3,7 +3,7 @@ const { exists } = cds.utils
3
3
  const { join } = require('path')
4
4
  const { readProject } = require('../../util/projectReader')
5
5
  const { mergeJSON, mergeYAML, sort } = require('../../util/merge')
6
- const { XSUAA, KIBANA } = require('../../constants').OPTIONS
6
+ const { XSUAA, KIBANA, HTML5_REPO } = require('../../constants').OPTIONS
7
7
  const {
8
8
  srvNode4, srvJava4, mtxSidecar4, approuter, // Modules
9
9
  xsuaa, // BTP Services
@@ -16,8 +16,7 @@ const { copyAndTrack, parseMd5File, writeMd5File } = require('../../util/md5')
16
16
  module.exports = class ApprouterTemplate extends require('../templateBase') {
17
17
 
18
18
  static hasFacet(env) {
19
- return exists(join(env.folders.app, 'router', 'xs-app.json')) ||
20
- exists(join(env.folders.app, 'xs-app.json'))
19
+ return exists(join(env.folders.app, 'xs-app.json'))
21
20
  }
22
21
 
23
22
  getDependencies() {
@@ -25,20 +24,20 @@ module.exports = class ApprouterTemplate extends require('../templateBase') {
25
24
  }
26
25
 
27
26
  getRelatedFacets() {
28
- return [KIBANA]
27
+ return [KIBANA, HTML5_REPO]
29
28
  }
30
29
 
31
30
  async run() {
32
- const { approuterPath } = await readProject()
33
- const appPackageJSONPath = join(approuterPath, 'package.json')
31
+ const { appPath = 'app' } = await readProject()
32
+ const appPackageJSONPath = join(appPath, 'package.json')
34
33
  await mergeJSON(appPackageJSONPath, join(__dirname, 'files', 'package.json'))
35
34
  await sort(appPackageJSONPath, 'dependencies')
36
- await mergeJSON(join(approuterPath, 'default-env.json'), join(__dirname, 'files', 'default-env.json'))
35
+ await mergeJSON(join(appPath, 'default-env.json'), join(__dirname, 'files', 'default-env.json'))
37
36
  }
38
37
 
39
38
  async runDependentMerging(context = {}) {
40
39
  const project = await readProject()
41
- const { isNodejs, isJava, isExtensible, isMultitenant, hasMta, hasHelm, srvPath, approuterPath } = project
40
+ const { isNodejs, isJava, isExtensible, isMultitenant, hasMta, hasHelm, srvPath, appPath } = project
42
41
 
43
42
  if (hasMta) {
44
43
  const srv = (isNodejs ? srvNode4 : srvJava4)(srvPath)
@@ -115,9 +114,10 @@ module.exports = class ApprouterTemplate extends require('../templateBase') {
115
114
  }
116
115
 
117
116
  if (isIndependentCommand) await writeMd5File(join('chart', '.cds-add-helm-files.md5'), context.newTrackingData);
117
+
118
118
  }
119
119
 
120
- const xsAppPath = join(approuterPath, 'xs-app.json')
120
+ const xsAppPath = join(appPath, 'xs-app.json')
121
121
  const additions = isExtensible ? [{ ...approuterExtensibility, at: 0 }] : []
122
122
  await mergeJSON(xsAppPath, join(__dirname, 'files', 'xs-app.json.hbs'), project, { additions })
123
123
  }
@@ -1,6 +1,6 @@
1
1
  const { join } = require('path')
2
2
  const { readProject } = require('../../util/projectReader')
3
- const { mergeJSON, mergeYAML } = require('../../util/merge')
3
+ const { mergeYAML } = require('../../util/merge')
4
4
  const { copyAndTrack, parseMd5File, writeMd5File } = require('../../util/md5')
5
5
  const { srvJava4, srvNode4, connectivity } = require('../_merging/registry-mta')
6
6
 
@@ -11,9 +11,10 @@ module.exports = class ConnectivityTemplate extends require('../templateBase') {
11
11
  }
12
12
 
13
13
  async run() {
14
- const project = await readProject()
15
- const { configFile } = project
16
- await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), project)
14
+ // Disable setting cds.requires.connectivity for now.
15
+ // const project = await readProject()
16
+ // const { configFile } = project
17
+ // await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), project)
17
18
  }
18
19
 
19
20
  async runDependentMerging(context = {}) {
@@ -22,7 +22,7 @@ module.exports = class DestinationTemplate extends require('../templateBase') {
22
22
 
23
23
  async runDependentMerging(context = {}) {
24
24
  const project = await readProject()
25
- const { isJava, hasHelm, hasDestination, hasMta, srvPath, hasHtml5Repo } = project
25
+ const { isJava, hasHelm, hasDestination, hasMta, srvPath } = project
26
26
 
27
27
  if (hasMta) {
28
28
  const srv = (isJava ? srvJava4 : srvNode4)(srvPath)
@@ -36,7 +36,6 @@ module.exports = class DestinationTemplate extends require('../templateBase') {
36
36
 
37
37
  if (hasHelm) {
38
38
  const binding = hasDestination && { srv: { bindings: { destination: { serviceInstanceName: 'destination' }}}}
39
- const html5Binding = hasHtml5Repo && { 'html5-apps-deployer': { bindings: { destination: { serviceInstanceName: 'destination' }}}}
40
39
 
41
40
  //in case facet is being added to the already exisiting charts folder
42
41
  let isIndependentCommand = false
@@ -48,13 +47,11 @@ module.exports = class DestinationTemplate extends require('../templateBase') {
48
47
  join('chart', 'values.yaml'),
49
48
  {
50
49
  ...binding,
51
- ...html5Binding,
52
50
  destination: {
53
51
  serviceOfferingName: 'destination',
54
52
  servicePlanName: 'lite',
55
53
  parameters: {
56
- version: '1.0.0',
57
- ...(hasHtml5Repo) && { HTML5Runtime_enabled: true }
54
+ version: '1.0.0'
58
55
  }
59
56
  }
60
57
  }
@@ -27,7 +27,7 @@ module.exports = class Html5RepoTemplate extends require('../templateBase') {
27
27
  }
28
28
 
29
29
  async runDependentMerging(context = {}) {
30
- const { appName, hasHelm } = await readProject()
30
+ const { appName, hasHelm, hasApprouter} = await readProject()
31
31
 
32
32
  if (hasHelm) {
33
33
  //in case facet is being added to the already exisiting charts folder
@@ -69,14 +69,38 @@ module.exports = class Html5RepoTemplate extends require('../templateBase') {
69
69
  }
70
70
  },
71
71
  backendDestinations: {},
72
+ destination: {
73
+ parameters: {
74
+ HTML5Runtime_enabled: true
75
+ }
76
+ }
72
77
  }
73
78
  )
74
-
79
+
75
80
  // copy content deployment chart if it is not present
76
81
  const HelmTemplate = require(`../helm`);
77
82
  const helmTemplate = new HelmTemplate(context.oldTrackingData, context.newTrackingData);
78
- isIndependentCommand = isIndependentCommand | await helmTemplate.addSubChart('content-deployment');
79
83
 
84
+ if (hasApprouter) {
85
+ await mergeYAML(
86
+ join('chart', 'values.yaml'),
87
+ {
88
+ 'html5-apps-repo-runtime': {
89
+ serviceOfferingName: 'html5-apps-repo',
90
+ servicePlanName: 'app-runtime'
91
+ },
92
+ approuter: {
93
+ bindings: {
94
+ 'html5-apps-repo-runtime': { serviceInstanceName: 'html5-apps-repo-runtime' }
95
+ }
96
+ },
97
+ }
98
+ )
99
+ await helmTemplate.addDependency('service-instance', 'html5-apps-repo-runtime');
100
+ }
101
+
102
+ isIndependentCommand = isIndependentCommand | await helmTemplate.addSubChart('content-deployment');
103
+
80
104
  // add dependency entry in chart.yaml
81
105
  await helmTemplate.addDependency('content-deployment', 'html5-apps-deployer');
82
106
 
@@ -4,17 +4,23 @@ const { exists } = cds.utils
4
4
  const { copyRenderedYAML } = require('../../../util/fs')
5
5
  const { readProject } = require('../../util/projectReader')
6
6
  const { mergeJSON, sort } = require('../../util/merge')
7
-
7
+ const {
8
+ APPROUTER, XSUAA, MULTITENANCY, EXTENSIBILITY,
9
+ MTA, HELM,
10
+ HANA, POSTGRES,
11
+ ENTERPRISE_MESSAGING, ENTERPRISE_MESSAGING_SHARED, REDIS_MESSAGING,
12
+ CONNECTIVITY, DESTINATION
13
+ } = require('../../constants').OPTIONS
8
14
  module.exports = class MtaTemplate extends require('../templateBase') {
9
15
 
10
16
  static hasFacet() {
11
17
  const { options } = cds.cli
12
- if (!options?.add.has('mta') && options?.add.has('helm')) return false
18
+ if (!options?.add.has(MTA) && options?.add.has(HELM)) return false
13
19
  return exists('mta.yaml')
14
20
  }
15
21
 
16
22
  getRelatedFacets() {
17
- return ['approuter', 'xsuaa', 'multitenancy', 'hana', 'extensibility', 'enterprise-messaging', 'enterprise-messaging-shared', 'redis-messaging', 'connectivity', 'destination']
23
+ return [APPROUTER, XSUAA, MULTITENANCY, HANA, POSTGRES, EXTENSIBILITY, ENTERPRISE_MESSAGING, ENTERPRISE_MESSAGING_SHARED, REDIS_MESSAGING, CONNECTIVITY, DESTINATION]
18
24
  }
19
25
 
20
26
  async run() {
@@ -0,0 +1,27 @@
1
+ ---
2
+ modules:
3
+ - name: {{appName}}-srv
4
+ type: {{language}}
5
+ path: {{& srvPath}}
6
+ requires:
7
+ - name: {{appName}}-postgres
8
+
9
+ - name: {{appName}}-postgres-deployer
10
+ type: nodejs
11
+ path: gen/pg
12
+ parameters:
13
+ buildpack: nodejs_buildpack
14
+ no-route: true
15
+ no-start: true
16
+ tasks:
17
+ - name: deploy-to-postgresql
18
+ command: npm start
19
+ requires:
20
+ - name: {{appName}}-postgres
21
+
22
+ resources:
23
+ - name: {{appName}}-postgres
24
+ type: org.cloudfoundry.managed-service
25
+ parameters:
26
+ service: postgresql-db
27
+ service-plan: development
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@cap-js/postgres": "^1"
4
+ }
5
+ }
@@ -0,0 +1,52 @@
1
+ const { join } = require('path')
2
+ const cds = require('../../../cds')
3
+ const { read } = cds.utils
4
+ const { readProject } = require('../../util/projectReader')
5
+ const { mergeJSON, mergeYAML } = require('../../util/merge')
6
+ const { srvNode4, srvJava4, postgres, postgresDeployer } = require('../_merging/registry-mta')
7
+
8
+ module.exports = class PostgresTemplate extends require('../templateBase') {
9
+
10
+ async canRun() {
11
+ const { hasMta, hasHelm, isJava } = await readProject(this.options)
12
+ if (isJava) throw `'cds add postgres' is not available for Java yet`
13
+ if (hasHelm && !hasMta) throw `'cds add postgres' is not available for Kyma yet`
14
+ return true
15
+ }
16
+
17
+ static hasFacet(env) {
18
+ return env.requires?.db?.kind === 'postgres'
19
+ }
20
+
21
+ async run() {
22
+ const project = await readProject(this.options)
23
+ const { configFile } = project
24
+ project.shortcut = !(await read(configFile)).cds?.requires?.db?.kind
25
+ await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), project)
26
+ await this.runDependentMerging()
27
+ }
28
+
29
+ async runDependentMerging() {
30
+ const project = await readProject(this.options)
31
+ const { hasMta, isNodejs, srvPath } = project
32
+
33
+ if (hasMta) {
34
+ const srv = (isNodejs ? srvNode4 : srvJava4)(srvPath)
35
+ await mergeYAML(
36
+ 'mta.yaml',
37
+ join(__dirname, 'files', 'mta.yaml.hbs'),
38
+ project,
39
+ {
40
+ additions: [srv, postgres, postgresDeployer],
41
+ relationships: [{
42
+ insert: [postgres, 'name'],
43
+ into: [srv, 'requires', 'name']
44
+ }, {
45
+ insert: [postgres, 'name'],
46
+ into: [postgresDeployer, 'requires', 'name']
47
+ }]
48
+ }
49
+ )
50
+ }
51
+ }
52
+ }
@@ -81,7 +81,6 @@ module.exports = new class ProjectReader {
81
81
  get hasMta() { return _hasFacet('mta') },
82
82
  get hasHelm() { return _hasFacet('helm') },
83
83
  get appPath() { return env.folders.app ?? 'app' },
84
- get approuterPath() { return join(env.folders.app ?? 'app', 'router') },
85
84
  get appVersion() { return appVersion },
86
85
  get appName() { return appName },
87
86
  get appId() { return appId },
@@ -1,19 +1,33 @@
1
+ function stacklessError(message) {
2
+ const { stackTraceLimit } = Error;
3
+ Error.stackTraceLimit = 0;
4
+ const error = new Error(message);
5
+ Error.stackTraceLimit = stackTraceLimit;
6
+ return error;
7
+ }
8
+
1
9
  require('axios').interceptors.response.use(
2
10
  response => response,
3
11
  axError => {
12
+ const { inspect } = require('util');
4
13
  const { url, method } = axError.config ?? {};
5
- const { code, response } = axError;
6
- const { status, data } = response ?? {};
7
- const reason = data?.error /* RFC 6749 */ ?? axError.message;
14
+ const { response = {} } = axError;
15
+ const { status, statusText } = response;
16
+ let { data } = response;
17
+ if (Buffer.isBuffer(data)) {
18
+ data = JSON.parse(data.toString());
19
+ }
20
+ const reason = data?.error /* RFC 6749 */ && (typeof data.error === 'string' ? data.error : inspect(data.error));
8
21
  const message = (url && method ? `${method.toUpperCase()} ${url} ` : '') +
9
22
  'failed' +
10
- (status || code ? ':' : '') +
23
+ (status || statusText ? ':' : '') +
11
24
  (status ? ` ${status}` : '') +
12
- (code ? ` ${code}` : '') +
13
- `. ${reason}.` +
14
- (data ? ` Details: '${data.error_description /* RFC 6749 */ || require('util').inspect(data)}'.` : '');
25
+ (statusText ? ` ${statusText}` : '') +
26
+ (reason ? `. ${reason}` : '') +
27
+ (data ? `. Details: '${data.error_description /* RFC 6749 */ || inspect(data)}'` : '');
15
28
 
16
- const error = new Error(message);
29
+ const error = stacklessError(message);
30
+ error.status = status;
17
31
  if (require('../').debug('req')) {
18
32
  error.cause = axError;
19
33
  }