@sap/cds-dk 9.8.3 → 9.9.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 +22 -0
- package/bin/add.js +3 -3
- package/bin/cds.js +16 -2
- package/bin/import.js +6 -2
- package/bin/logout.js +9 -12
- package/lib/bind/shared.js +2 -2
- package/lib/build/constants.js +0 -1
- package/lib/build/index.js +420 -463
- package/lib/build/plugins/hana/index.js +121 -2
- package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/content-deployment/templates/job.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/content-deployment/values.schema.json +4 -0
- package/lib/build/plugins/helm/files/subcharts/content-deployment/values.yaml +5 -2
- package/lib/build/plugins/internal.js +1 -1
- package/lib/build/plugins/mtx-extension/index.js +0 -2
- package/lib/deploy/index.js +23 -3
- package/lib/deploy/to-hana/hana.js +24 -15
- package/lib/import/common.js +6 -3
- package/lib/init/constants.js +3 -1
- package/lib/init/indent.js +0 -1
- package/lib/init/merge.js +0 -1
- package/lib/init/mvn.js +4 -2
- package/lib/init/projectReader.js +0 -1
- package/lib/init/registries/mta.js +4 -2
- package/lib/init/template/app-frontend/index.js +39 -4
- package/lib/init/template/data/as-csv.js +2 -0
- package/lib/init/template/esm/index.js +5 -0
- package/lib/init/template/extensibility/index.js +1 -1
- package/lib/init/template/hana/index.js +1 -1
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +9 -20
- package/lib/init/template/http/index.js +34 -6
- package/lib/init/template/kyma/index.js +1 -0
- package/lib/init/template/postgres/files/values.yaml.hbs +1 -1
- package/lib/init/template/postgres/index.js +1 -1
- package/lib/init/template/react/files/index.html +13 -0
- package/lib/init/template/react/files/package.json.hbs +22 -0
- package/lib/init/template/react/files/public/favicon.svg +1 -0
- package/lib/init/template/react/files/src/App.jsx.hbs +29 -0
- package/lib/init/template/react/files/src/index.css +28 -0
- package/lib/init/template/react/files/src/main.jsx +10 -0
- package/lib/init/template/react/files/vite.config.js +19 -0
- package/lib/init/template/react/index.js +29 -0
- package/lib/init/template/sample/index.js +1 -4
- package/lib/init/template/typer/index.js +1 -1
- package/lib/init/template/typescript/files/package.json +1 -1
- package/lib/init/template/typescript/index.js +1 -1
- package/lib/init/template/ui5/index.js +2 -1
- package/lib/init/template/vue/files/index.html +13 -0
- package/lib/init/template/vue/files/package.json.hbs +19 -0
- package/lib/init/template/vue/files/public/favicon.svg +1 -0
- package/lib/init/template/vue/files/src/App.vue.hbs +34 -0
- package/lib/init/template/vue/files/src/main.js +5 -0
- package/lib/init/template/vue/files/src/style.css +20 -0
- package/lib/init/template/vue/files/vite.config.js +19 -0
- package/lib/init/template/vue/index.js +29 -0
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +2 -13
- package/lib/init/xml.js +0 -2
- package/lib/mtx/auth_manager.js +21 -11
- package/lib/mtx/download_legacy.js +9 -8
- package/lib/mtx/pull.js +9 -8
- package/lib/mtx/push.js +42 -28
- package/lib/mtx/settings_manager.js +17 -10
- package/lib/mtx/tenant_action.js +9 -9
- package/lib/mtx/util/request.js +158 -0
- package/lib/util/cf.js +30 -29
- package/lib/watch/node-watch.js +1 -1
- package/lib/watch/vite-watch.js +76 -0
- package/lib/watch/watched.js +5 -4
- package/npm-shrinkwrap.json +25 -165
- package/package.json +1 -2
- package/lib/init/template/sample/files/db/hana/index.cds +0 -10
- package/lib/init/template/sample/files/db/sqlite/index.cds +0 -10
- package/lib/init/template/sample/files/package.json.hbs +0 -14
- package/lib/util/axios.js +0 -118
|
@@ -21,7 +21,7 @@ module.exports = class PostgresTemplate extends require('../../plugin') {
|
|
|
21
21
|
const project = readProject()
|
|
22
22
|
const { configFile, isJava } = project
|
|
23
23
|
project.shortcut = !exists(configFile) || typeof (await read(configFile)).cds?.requires?.db !== 'object'
|
|
24
|
-
await merge(__dirname, 'files/package.json.hbs').into(configFile, { with: project, forceOverwrite: true })
|
|
24
|
+
await merge(__dirname, 'files/package.json.hbs').into(configFile, { with: project, forceOverwrite: true })
|
|
25
25
|
if (isJava) await mvn.add('postgresql')
|
|
26
26
|
|
|
27
27
|
await sort('package.json', 'dependencies')
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>catalog</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{app}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"react": "^19",
|
|
13
|
+
"react-dom": "^19"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/react": "^19",
|
|
17
|
+
"@types/react-dom": "^19",
|
|
18
|
+
"@vitejs/plugin-react": "^6",
|
|
19
|
+
"adm-zip": "^0",
|
|
20
|
+
"vite": "^8"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 56 56" aria-hidden="true"><path fill="#5A7A94" d="M45.84 21.462a8.489 8.489 0 0 0-12.783-5.713A10.747 10.747 0 0 0 22.41 8.5C10 8.5 11.09 21.488 11.09 21.488A10.3 10.3 0 0 0 13 41.5v-3a7.477 7.477 0 0 1-5.639-5 7.247 7.247 0 0 1 4.666-9.164l2.279-.768-.286-1.5A7.521 7.521 0 0 1 13.9 20a10.535 10.535 0 0 1 2.188-5.828 7.375 7.375 0 0 1 6.4-2.824c3.264 0 7.286 2.9 8.221 5.636l.934 2.732 2.424-1.318a7.6 7.6 0 0 1 3.39-.894 5.546 5.546 0 0 1 5.443 4.518l.288 1.528 1.125.514A7.809 7.809 0 0 1 48.891 29.7 7.809 7.809 0 0 1 43 38.5v3.02A10.793 10.793 0 0 0 52 31a10.483 10.483 0 0 0-6.16-9.538"/><g fill="#0092D1" transform="scale(1.05 1.2)"><g transform="translate(-2 -7)"><path d="M24.561 38.939l-6-6a1.5 1.5 0 0 0-2.122 2.122L21.379 40l-4.94 4.939a1.5 1.5 0 0 0 2.122 2.122l6-6a1.5 1.5 0 0 0 0-2.122"/><path d="M26.5 35.5h12a1.5 1.5 0 0 0 0-3h-12a1.5 1.5 0 0 0 0 3"/><path d="M38.5 38.5h-9a1.5 1.5 0 0 0 0 3h9a1.5 1.5 0 0 0 0-3"/><path d="M38.5 44.5h-12a1.5 1.5 0 0 0 0 3h12a1.5 1.5 0 0 0 0-3"/></g></g></svg>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
export default function App() {
|
|
4
|
+
const [books, setBooks] = useState([])
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
fetch('/odata/v4/{{#isJava}}CatalogService{{/isJava}}{{^isJava}}catalog{{/isJava}}/Books')
|
|
8
|
+
.then(r => r.json())
|
|
9
|
+
.then(r => setBooks(r.value))
|
|
10
|
+
}, [])
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<h1>Books</h1>
|
|
15
|
+
<table>
|
|
16
|
+
<tbody>
|
|
17
|
+
{books.map(b => (
|
|
18
|
+
<tr key={b.ID}>
|
|
19
|
+
<td>
|
|
20
|
+
<span className="title">{b.title}</span>{{^isJava}}
|
|
21
|
+
<span className="author"><i> by {b.author}</i></span>{{/isJava}}
|
|
22
|
+
</td>
|
|
23
|
+
</tr>
|
|
24
|
+
))}
|
|
25
|
+
</tbody>
|
|
26
|
+
</table>
|
|
27
|
+
</>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--text: #111;
|
|
3
|
+
--text-muted: #777;
|
|
4
|
+
--bg: #fff;
|
|
5
|
+
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
|
|
6
|
+
font-family: var(--sans);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@media (prefers-color-scheme: dark) {
|
|
10
|
+
:root {
|
|
11
|
+
--text: #fff;
|
|
12
|
+
--text-muted: #a3a3a3;
|
|
13
|
+
--bg: #16171d;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
body {
|
|
18
|
+
color: var(--text);
|
|
19
|
+
background: var(--bg);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.title {
|
|
23
|
+
color: var(--text);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.author {
|
|
27
|
+
color: var(--text-muted);
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import AdmZip from 'adm-zip'
|
|
3
|
+
import react from '@vitejs/plugin-react'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [react(), {
|
|
7
|
+
name: 'zip-dist', // zipping ./dist is required for BTP HTML5 repo or Application Frontend deployment
|
|
8
|
+
closeBundle() {
|
|
9
|
+
const zip = new AdmZip()
|
|
10
|
+
zip.addLocalFolder('dist')
|
|
11
|
+
zip.writeZip('dist/catalog.zip')
|
|
12
|
+
}
|
|
13
|
+
}],
|
|
14
|
+
server: {
|
|
15
|
+
proxy: {
|
|
16
|
+
'/odata': 'http://localhost:4004'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const cds = require('../../../cds')
|
|
2
|
+
const { path, sh: $ } = cds.utils
|
|
3
|
+
const { ask4 } = require('../../../util/question')
|
|
4
|
+
const { renderAndCopy } = require('../../template')
|
|
5
|
+
|
|
6
|
+
module.exports = class ReactTemplate extends require('../../plugin') {
|
|
7
|
+
|
|
8
|
+
options() {
|
|
9
|
+
return {
|
|
10
|
+
'into': {
|
|
11
|
+
type: 'string',
|
|
12
|
+
short: 'i',
|
|
13
|
+
help: `Name of the app folder in 'app/'. Example: 'catalog' → 'app/catalog'.`
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static help() {
|
|
19
|
+
return 'user interface for React'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async run() {
|
|
23
|
+
const app = cds.cli.options.into ?? await ask4([`app name: `])
|
|
24
|
+
let into = path.join(cds.env.folders.app, app)
|
|
25
|
+
await renderAndCopy(path.join(__dirname, 'files'), into, { app, isJava: cds.env['project-nature'] === 'java' })
|
|
26
|
+
if (cds.cli.command === 'init') into = path.join(cds.cli.argv[0], into)
|
|
27
|
+
await $`npm i --prefix ${into}`
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -2,7 +2,6 @@ const { join } = require('path')
|
|
|
2
2
|
const cds = require('../../../cds')
|
|
3
3
|
const { read, write, copy } = cds.utils
|
|
4
4
|
const { readProject } = require('../../projectReader')
|
|
5
|
-
const { merge } = require('../../merge')
|
|
6
5
|
const { renderAndCopy } = require('../../template')
|
|
7
6
|
const mvn = require('../../mvn')
|
|
8
7
|
|
|
@@ -46,8 +45,6 @@ module.exports = class SampleTemplate extends require('../../plugin') {
|
|
|
46
45
|
])
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: { appPath }})
|
|
50
|
-
|
|
51
48
|
// manifest.json IDs must be unique -> otherwise deployment failures on conflicts
|
|
52
49
|
await Promise.all(project.appUIPaths.map(async p => {
|
|
53
50
|
const manifest = await read(join(appPath, p, 'webapp/manifest.json'))
|
|
@@ -55,7 +52,7 @@ module.exports = class SampleTemplate extends require('../../plugin') {
|
|
|
55
52
|
await write(join(appPath, p, 'webapp/manifest.json'), manifest, { spaces: 2 })
|
|
56
53
|
}))
|
|
57
54
|
|
|
58
|
-
if (project.isNodejs) {
|
|
55
|
+
if (project.isNodejs) {
|
|
59
56
|
const fioriSandboxConfigPath = join(appPath, 'appconfig/fioriSandboxConfig.json')
|
|
60
57
|
const fioriSandboxConfig = await read(fioriSandboxConfigPath)
|
|
61
58
|
const sampleInbounds = { BrowseBooks: 'browse', ManageAuthors: 'admin-authors', BrowseGenres: 'genres', ManageBooks: 'admin-books' }
|
|
@@ -28,7 +28,7 @@ module.exports = class TyperTemplate extends require('../../plugin') {
|
|
|
28
28
|
}
|
|
29
29
|
await merge(template('package.json')).into('package.json')
|
|
30
30
|
await mergeGitignore('.gitignore', template('gitignore'))
|
|
31
|
-
console.log(dim(` adding '@cds-models' to .gitignore to ignore generated types`))
|
|
31
|
+
console.log(dim(` adding '@cds-models' to .gitignore to ignore generated types`))
|
|
32
32
|
console.log(dim(' added new dependencies to the project. Run ') + bold('npm i') + dim(' to install.'))
|
|
33
33
|
try {
|
|
34
34
|
await merge(source).into(target)
|
|
@@ -34,6 +34,6 @@ module.exports = class TypescriptTemplate extends require('../../plugin') {
|
|
|
34
34
|
: e
|
|
35
35
|
}
|
|
36
36
|
await merge(join(__dirname, 'files', 'package.json')).into('package.json')
|
|
37
|
-
await new TyperTemplate().run()
|
|
37
|
+
await new TyperTemplate().run()
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -8,7 +8,8 @@ module.exports = class extends require('../../plugin') {
|
|
|
8
8
|
const startPage = path.join(cds.root, cds.env.folders.app, 'index.html')
|
|
9
9
|
const packageJson = path.join(cds.root, 'package.json')
|
|
10
10
|
return exists(startPage) && fs.readFileSync(startPage).includes('https://sapui5') ||
|
|
11
|
-
exists(packageJson) && fs.readFileSync(packageJson).includes('"sapux":')
|
|
11
|
+
exists(packageJson) && fs.readFileSync(packageJson).includes('"sapux":') ||
|
|
12
|
+
exists(path.join(cds.root, cds.env.folders.app, 'fiori-apps.html'))
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
static help() {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>catalog</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.js"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{app}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"vue": "^3"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@vitejs/plugin-vue": "^6",
|
|
16
|
+
"adm-zip": "^0",
|
|
17
|
+
"vite": "^8"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 56 56" aria-hidden="true"><path fill="#5A7A94" d="M45.84 21.462a8.489 8.489 0 0 0-12.783-5.713A10.747 10.747 0 0 0 22.41 8.5C10 8.5 11.09 21.488 11.09 21.488A10.3 10.3 0 0 0 13 41.5v-3a7.477 7.477 0 0 1-5.639-5 7.247 7.247 0 0 1 4.666-9.164l2.279-.768-.286-1.5A7.521 7.521 0 0 1 13.9 20a10.535 10.535 0 0 1 2.188-5.828 7.375 7.375 0 0 1 6.4-2.824c3.264 0 7.286 2.9 8.221 5.636l.934 2.732 2.424-1.318a7.6 7.6 0 0 1 3.39-.894 5.546 5.546 0 0 1 5.443 4.518l.288 1.528 1.125.514A7.809 7.809 0 0 1 48.891 29.7 7.809 7.809 0 0 1 43 38.5v3.02A10.793 10.793 0 0 0 52 31a10.483 10.483 0 0 0-6.16-9.538"/><g fill="#0092D1" transform="scale(1.05 1.2)"><g transform="translate(-2 -7)"><path d="M24.561 38.939l-6-6a1.5 1.5 0 0 0-2.122 2.122L21.379 40l-4.94 4.939a1.5 1.5 0 0 0 2.122 2.122l6-6a1.5 1.5 0 0 0 0-2.122"/><path d="M26.5 35.5h12a1.5 1.5 0 0 0 0-3h-12a1.5 1.5 0 0 0 0 3"/><path d="M38.5 38.5h-9a1.5 1.5 0 0 0 0 3h9a1.5 1.5 0 0 0 0-3"/><path d="M38.5 44.5h-12a1.5 1.5 0 0 0 0 3h12a1.5 1.5 0 0 0 0-3"/></g></g></svg>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, onMounted } from 'vue'
|
|
3
|
+
|
|
4
|
+
const books = ref([])
|
|
5
|
+
|
|
6
|
+
onMounted(async () => {
|
|
7
|
+
const r = await fetch('/odata/v4/{{#isJava}}CatalogService{{/isJava}}{{^isJava}}catalog{{/isJava}}/Books')
|
|
8
|
+
books.value = (await r.json()).value
|
|
9
|
+
})
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<main>
|
|
14
|
+
<h1>Books</h1>
|
|
15
|
+
<table>
|
|
16
|
+
<tr v-for="b in books" :key="b.ID">
|
|
17
|
+
<td>
|
|
18
|
+
<span class="title">{{ b.title }}</span>{{^isJava}}
|
|
19
|
+
<span class="author"><i> by {{ b.author }}</i></span>{{/isJava}}
|
|
20
|
+
</td>
|
|
21
|
+
</tr>
|
|
22
|
+
</table>
|
|
23
|
+
</main>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<style scoped>
|
|
27
|
+
.title {
|
|
28
|
+
color: var(--text);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.author {
|
|
32
|
+
color: var(--text-muted);
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--text: #111;
|
|
3
|
+
--text-muted: #777;
|
|
4
|
+
--bg: #fff;
|
|
5
|
+
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
|
|
6
|
+
font-family: var(--sans);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@media (prefers-color-scheme: dark) {
|
|
10
|
+
:root {
|
|
11
|
+
--text: #fff;
|
|
12
|
+
--text-muted: #a3a3a3;
|
|
13
|
+
--bg: #16171d;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
body {
|
|
18
|
+
color: var(--text);
|
|
19
|
+
background: var(--bg);
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import AdmZip from 'adm-zip'
|
|
3
|
+
import vue from '@vitejs/plugin-vue'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [vue(), {
|
|
7
|
+
name: 'zip-dist', // zipping ./dist is required for BTP HTML5 repo or Application Frontend deployment
|
|
8
|
+
closeBundle() {
|
|
9
|
+
const zip = new AdmZip()
|
|
10
|
+
zip.addLocalFolder('dist')
|
|
11
|
+
zip.writeZip('dist/catalog.zip')
|
|
12
|
+
}
|
|
13
|
+
}],
|
|
14
|
+
server: {
|
|
15
|
+
proxy: {
|
|
16
|
+
'/odata': 'http://localhost:4004'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const cds = require('../../../cds')
|
|
2
|
+
const { path, sh: $ } = cds.utils
|
|
3
|
+
const { ask4 } = require('../../../util/question')
|
|
4
|
+
const { renderAndCopy } = require('../../template')
|
|
5
|
+
|
|
6
|
+
module.exports = class VueTemplate extends require('../../plugin') {
|
|
7
|
+
|
|
8
|
+
options() {
|
|
9
|
+
return {
|
|
10
|
+
'into': {
|
|
11
|
+
type: 'string',
|
|
12
|
+
short: 'i',
|
|
13
|
+
help: `Name of the app folder in 'app/'. Example: 'catalog' → 'app/catalog'.`
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static help() {
|
|
19
|
+
return 'user interface for Vue.js'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async run() {
|
|
23
|
+
const app = cds.cli.options.into ?? await ask4([`app name: `])
|
|
24
|
+
let into = path.join(cds.env.folders.app, app)
|
|
25
|
+
await renderAndCopy(path.join(__dirname, 'files'), into, { app, isJava: cds.env['project-nature'] === 'java' })
|
|
26
|
+
if (cds.cli.command === 'init') into = path.join(cds.cli.argv[0], into)
|
|
27
|
+
await $`npm i --prefix ${into}`
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -56,10 +56,10 @@ resources:
|
|
|
56
56
|
parameters:
|
|
57
57
|
service: destination
|
|
58
58
|
service-plan: lite
|
|
59
|
+
{{#hasMultitenancy}}
|
|
59
60
|
config:
|
|
60
61
|
HTML5Runtime_enabled: true
|
|
61
62
|
init_data:
|
|
62
|
-
{{#hasMultitenancy}}
|
|
63
63
|
subaccount:
|
|
64
64
|
existing_destinations_policy: update
|
|
65
65
|
destinations:
|
|
@@ -69,18 +69,7 @@ resources:
|
|
|
69
69
|
ProxyType: Internet
|
|
70
70
|
URL: https://${org}.launchpad.${default-domain}
|
|
71
71
|
CEP.HTML5contentprovider: true
|
|
72
|
-
|
|
73
|
-
instance:
|
|
74
|
-
existing_destinations_policy: update
|
|
75
|
-
destinations:
|
|
76
|
-
- Name: srv-api
|
|
77
|
-
URL: ~{srv-api/srv-url}
|
|
78
|
-
Authentication: NoAuthentication
|
|
79
|
-
Type: HTTP
|
|
80
|
-
ProxyType: Internet
|
|
81
|
-
HTML5.ForwardAuthToken: true
|
|
82
|
-
HTML5.DynamicDestination: true
|
|
83
|
-
{{#hasIas}}HTML5.IASDependencyName: {{appName}}-ias-api{{/hasIas}}
|
|
72
|
+
{{/hasMultitenancy}}
|
|
84
73
|
requires:
|
|
85
74
|
- name: srv-api
|
|
86
75
|
|
package/lib/init/xml.js
CHANGED
package/lib/mtx/auth_manager.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
const axios = require('axios');
|
|
2
|
-
|
|
3
1
|
const cds = require('../cds');
|
|
4
2
|
const { SettingsManager } = require('./settings_manager');
|
|
5
3
|
const { ParamCollection } = require('./params');
|
|
6
4
|
const { getMessage } = require('./util/logging');
|
|
7
|
-
|
|
8
|
-
require('../util/axios').pruneErrors();
|
|
5
|
+
const { buildResponseError, buildNetworkError, parseResponseBody } = require('./util/request');
|
|
9
6
|
|
|
10
7
|
const DEBUG = cds.debug('cli');
|
|
11
8
|
const REASONS = { invalid_scope: /\binvalid_scope\b/ };
|
|
@@ -71,7 +68,7 @@ async function fetchToken(params) {
|
|
|
71
68
|
return;
|
|
72
69
|
}
|
|
73
70
|
|
|
74
|
-
let
|
|
71
|
+
let responseData, error;
|
|
75
72
|
const method = 'post';
|
|
76
73
|
do {
|
|
77
74
|
const { url, data, ignored } = reqParams(method, params);
|
|
@@ -81,11 +78,23 @@ async function fetchToken(params) {
|
|
|
81
78
|
DEBUG?.(`Getting authentication token from ${method.toUpperCase()} ${params.obfuscateQueryParams(url)}`);
|
|
82
79
|
error = undefined;
|
|
83
80
|
try {
|
|
84
|
-
response = await
|
|
81
|
+
const response = await fetch(url, {
|
|
82
|
+
method: method.toUpperCase(),
|
|
83
|
+
body: data,
|
|
84
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded' }
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
throw await buildResponseError(method, url, response);
|
|
88
|
+
}
|
|
89
|
+
responseData = await parseResponseBody(response);
|
|
85
90
|
break;
|
|
86
91
|
} catch (e) {
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
if (e.status) {
|
|
93
|
+
error = e;
|
|
94
|
+
} else {
|
|
95
|
+
error = buildNetworkError(method, url, e);
|
|
96
|
+
}
|
|
97
|
+
DEBUG?.(`HTTP status ${error.status}`);
|
|
89
98
|
if (params.has('refreshToken')) {
|
|
90
99
|
DEBUG?.('Discarding invalid refresh token');
|
|
91
100
|
params.delete('refreshToken');
|
|
@@ -93,8 +102,8 @@ async function fetchToken(params) {
|
|
|
93
102
|
break;
|
|
94
103
|
}
|
|
95
104
|
}
|
|
96
|
-
} while (!
|
|
97
|
-
const data =
|
|
105
|
+
} while (!responseData);
|
|
106
|
+
const data = responseData ?? error?.auth;
|
|
98
107
|
assign(params, data);
|
|
99
108
|
if (error) {
|
|
100
109
|
let message;
|
|
@@ -126,7 +135,8 @@ module.exports = class AuthManager {
|
|
|
126
135
|
const params = new ParamCollection(paramValues);
|
|
127
136
|
await SettingsManager.loadAndMergeSettings(params);
|
|
128
137
|
if (params.has('username')) {
|
|
129
|
-
|
|
138
|
+
const encoded = Buffer.from(`${params.get('username')}:${params.get('password')}`).toString('base64');
|
|
139
|
+
params.set('reqAuth', { headers: { Authorization: `Basic ${encoded}` } });
|
|
130
140
|
} else if (!params.get('skipToken')) {
|
|
131
141
|
try {
|
|
132
142
|
await fetchToken(params);
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const { join } = require('path');
|
|
3
|
-
const axios = require('axios');
|
|
4
3
|
|
|
5
4
|
const { login } = require('./auth_manager');
|
|
6
5
|
|
|
7
|
-
require('
|
|
8
|
-
const { handleHttpError } = require('./util/errors');
|
|
6
|
+
const { mtxFetch } = require('./util/request');
|
|
9
7
|
|
|
10
8
|
const DOWNLOAD_FILE_NAME = 'migrated_projects.tgz'; // TODO try to add tenant later, if possible
|
|
11
9
|
|
|
@@ -33,10 +31,13 @@ module.exports = class Download {
|
|
|
33
31
|
const tagRule = params.get('tagRule');
|
|
34
32
|
const defaultTag = params.get('defaultTag');
|
|
35
33
|
const downloadUrl = `${(params.get('appUrl'))}/-/cds/extensibility/getMigratedProjects`;
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
const reqAuth = params.get('reqAuth') || {};
|
|
35
|
+
const headers = { 'content-type': 'application/json', ...reqAuth.headers };
|
|
36
|
+
|
|
37
|
+
const response = await mtxFetch('POST', downloadUrl, {
|
|
38
|
+
headers,
|
|
39
|
+
body: JSON.stringify({ tagRule, defaultTag })
|
|
40
|
+
}, params);
|
|
41
|
+
return Buffer.from(await response.arrayBuffer());
|
|
41
42
|
}
|
|
42
43
|
}
|
package/lib/mtx/pull.js
CHANGED
|
@@ -3,13 +3,11 @@ const { local, tar } = cds.utils;
|
|
|
3
3
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const { join, dirname } = require('path');
|
|
6
|
-
const axios = require('axios');
|
|
7
6
|
|
|
8
7
|
const { login } = require('./auth_manager');
|
|
8
|
+
const { mtxFetch } = require('./util/request');
|
|
9
9
|
|
|
10
|
-
require('../util/axios').pruneErrors();
|
|
11
10
|
const { getMessage } = require('./util/logging');
|
|
12
|
-
const { handleHttpError } = require('./util/errors');
|
|
13
11
|
const { grepQR } = require('./util/fs');
|
|
14
12
|
const { escapeRegex } = require('./util/strings');
|
|
15
13
|
|
|
@@ -148,11 +146,14 @@ module.exports = class Pull {
|
|
|
148
146
|
|
|
149
147
|
async pullTgz() {
|
|
150
148
|
const pullUrl = `${(this.params.get('appUrl'))}/-/cds/extensibility/pull`;
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
const reqAuth = this.params.get('reqAuth') || {};
|
|
150
|
+
const headers = { 'content-type': 'application/json', ...reqAuth.headers };
|
|
151
|
+
|
|
152
|
+
const response = await mtxFetch('POST', pullUrl, {
|
|
153
|
+
headers,
|
|
154
|
+
body: JSON.stringify({ tag: this.getExtensionName() })
|
|
155
|
+
}, this.params);
|
|
156
|
+
return Buffer.from(await response.arrayBuffer());
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
static transformBasePackage(baseModelFolder, baseModelName) {
|