@sap-ux/odata-service-writer 0.23.3 → 0.24.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.
- package/dist/data/annotations.js +30 -13
- package/dist/data/defaults.d.ts +5 -2
- package/dist/data/defaults.js +75 -19
- package/dist/delete.d.ts +30 -0
- package/dist/delete.js +183 -0
- package/dist/index.d.ts +31 -6
- package/dist/index.js +219 -70
- package/dist/types.d.ts +10 -1
- package/dist/updates.d.ts +7 -6
- package/dist/updates.js +95 -38
- package/package.json +4 -4
- package/templates/extend/manifest.json +43 -13
package/dist/data/annotations.js
CHANGED
|
@@ -4,25 +4,19 @@ exports.getAnnotationNamespaces = getAnnotationNamespaces;
|
|
|
4
4
|
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
5
5
|
const i18n_1 = require("../i18n");
|
|
6
6
|
/**
|
|
7
|
-
* Returns the namespaces parsed from the specified metadata and
|
|
7
|
+
* Returns the namespaces parsed from the specified metadata and single annotation.
|
|
8
8
|
*
|
|
9
|
-
* @param {
|
|
10
|
-
* @param {
|
|
11
|
-
* @param {string} service.annotations - OData service annotations xml
|
|
9
|
+
* @param {EdmxAnnotationsInfo} edmxAnnotation - OData service annotations xml
|
|
10
|
+
* @param {NamespaceAlias[]} schemaNamespaces - namespaces array from metadata
|
|
12
11
|
* @returns A reference to the namspaces array
|
|
13
12
|
*/
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
const schemaNamespaces = metadata ? getNamespaces(metadata) : [];
|
|
17
|
-
const edmxAnnotations = annotations;
|
|
18
|
-
if (edmxAnnotations?.xml) {
|
|
13
|
+
function getAnnotationNamespacesForSingleAnnotation(edmxAnnotation, schemaNamespaces) {
|
|
14
|
+
if (edmxAnnotation?.xml) {
|
|
19
15
|
// Parse once
|
|
20
|
-
const annotationsJson = xmlToJson(
|
|
16
|
+
const annotationsJson = xmlToJson(edmxAnnotation.xml);
|
|
21
17
|
return schemaNamespaces.map((schema) => {
|
|
22
18
|
// Check if alias exists in backend annotation file, if so use it
|
|
23
|
-
const annotationAlias =
|
|
24
|
-
? getAliasFromAnnotation(annotationsJson, schema.namespace)
|
|
25
|
-
: '';
|
|
19
|
+
const annotationAlias = edmxAnnotation.xml && schema.namespace ? getAliasFromAnnotation(annotationsJson, schema.namespace) : '';
|
|
26
20
|
if (annotationAlias) {
|
|
27
21
|
schema.alias = annotationAlias;
|
|
28
22
|
}
|
|
@@ -31,6 +25,29 @@ function getAnnotationNamespaces({ metadata, annotations }) {
|
|
|
31
25
|
}
|
|
32
26
|
return schemaNamespaces;
|
|
33
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the namespaces parsed from the specified metadata and annotations.
|
|
30
|
+
*
|
|
31
|
+
* @param {Partial<OdataService>} service - an odata service where at least metadata and annotations properties are defined
|
|
32
|
+
* @param {string} service.metadata - OData service metadata xml
|
|
33
|
+
* @param {string} service.annotations - OData service annotations xml
|
|
34
|
+
* @returns A reference to the namspaces array
|
|
35
|
+
*/
|
|
36
|
+
function getAnnotationNamespaces({ metadata, annotations }) {
|
|
37
|
+
// Enhance service with annotations namespaces
|
|
38
|
+
let schemaNamespaces = metadata ? getNamespaces(metadata) : [];
|
|
39
|
+
if (Array.isArray(annotations)) {
|
|
40
|
+
for (const annotationName in annotations) {
|
|
41
|
+
const edmxAnnotation = annotations[annotationName];
|
|
42
|
+
schemaNamespaces = getAnnotationNamespacesForSingleAnnotation(edmxAnnotation, schemaNamespaces);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const edmxAnnotation = annotations;
|
|
47
|
+
schemaNamespaces = getAnnotationNamespacesForSingleAnnotation(edmxAnnotation, schemaNamespaces);
|
|
48
|
+
}
|
|
49
|
+
return schemaNamespaces;
|
|
50
|
+
}
|
|
34
51
|
/**
|
|
35
52
|
* Convert specified xml string to JSON.
|
|
36
53
|
*
|
package/dist/data/defaults.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { OdataService } from '../types';
|
|
2
|
+
import type { Editor } from 'mem-fs-editor';
|
|
2
3
|
/**
|
|
3
4
|
* Enhances the provided OData service object with path, name and model information.
|
|
4
5
|
* Directly modifies the passed object reference.
|
|
5
6
|
*
|
|
6
|
-
* @param {
|
|
7
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
8
|
+
* @param {OdataService} service - the OData service instance
|
|
9
|
+
* @param {Editor} fs - the memfs editor instance
|
|
7
10
|
*/
|
|
8
|
-
export declare function enhanceData(service: OdataService): void
|
|
11
|
+
export declare function enhanceData(basePath: string, service: OdataService, fs: Editor): Promise<void>;
|
|
9
12
|
//# sourceMappingURL=defaults.d.ts.map
|
package/dist/data/defaults.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.enhanceData = enhanceData;
|
|
4
|
+
const path_1 = require("path");
|
|
4
5
|
const types_1 = require("../types");
|
|
5
6
|
const constants_1 = require("./constants");
|
|
7
|
+
const project_access_1 = require("@sap-ux/project-access");
|
|
6
8
|
/**
|
|
7
9
|
* Sets the default path for a given service.
|
|
8
10
|
* If the service path is not defined, it sets the path to '/'.
|
|
@@ -15,45 +17,99 @@ function setDefaultServicePath(service) {
|
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* Sets the default name for a given service.
|
|
18
|
-
*
|
|
20
|
+
* Default serivce name is used only for first service.
|
|
19
21
|
*
|
|
22
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
20
23
|
* @param {OdataService} service - The service object whose name needs to be set or modified.
|
|
24
|
+
* @param fs - the memfs editor instance
|
|
21
25
|
*/
|
|
22
|
-
function setDefaultServiceName(service) {
|
|
23
|
-
|
|
26
|
+
async function setDefaultServiceName(basePath, service, fs) {
|
|
27
|
+
const manifestPath = (0, path_1.join)(await (0, project_access_1.getWebappPath)(basePath, fs), project_access_1.FileName.Manifest);
|
|
28
|
+
const manifest = fs.readJSON(manifestPath);
|
|
29
|
+
// Check if manifest has already any dataSources defined, DEFAULT_DATASOURCE_NAME should be used for the first service
|
|
30
|
+
const dataSources = manifest?.['sap.app']?.dataSources;
|
|
31
|
+
if (dataSources) {
|
|
32
|
+
// Filter out ODataAnnotation dataSources and keep only OData ones
|
|
33
|
+
const oDataSources = Object.values(dataSources).filter((dataSource) => dataSource.type === 'OData');
|
|
34
|
+
if (oDataSources.length === 0) {
|
|
35
|
+
service.name = constants_1.DEFAULT_DATASOURCE_NAME;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// No existing dataSources - no existing services, use default name
|
|
40
|
+
service.name = constants_1.DEFAULT_DATASOURCE_NAME;
|
|
41
|
+
}
|
|
24
42
|
}
|
|
25
43
|
/**
|
|
26
44
|
* Sets the default model for a given service.
|
|
27
|
-
*
|
|
45
|
+
* Default UI5 model is used for first service model.
|
|
46
|
+
* For next services service model or service name is used as model (if model is not defined).
|
|
28
47
|
*
|
|
29
|
-
* @param {
|
|
48
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
49
|
+
* @param {OdataService} service - The service object whose model needs to be set or modified
|
|
50
|
+
* @param fs - the memfs editor instance
|
|
30
51
|
*/
|
|
31
|
-
function setDefaultServiceModel(service) {
|
|
32
|
-
|
|
52
|
+
async function setDefaultServiceModel(basePath, service, fs) {
|
|
53
|
+
const manifestPath = (0, path_1.join)(await (0, project_access_1.getWebappPath)(basePath, fs), 'manifest.json');
|
|
54
|
+
const manifest = fs.readJSON(manifestPath);
|
|
55
|
+
// Check if manifest has already any dataSource models defined, empty string '' should be used for the first service
|
|
56
|
+
const models = manifest?.['sap.ui5']?.models;
|
|
57
|
+
if (models) {
|
|
58
|
+
// Filter dataSource models by dataSource property
|
|
59
|
+
const servicesModels = Object.values(models).filter((model) => model.dataSource);
|
|
60
|
+
service.model = servicesModels.length === 0 ? '' : service.model ?? service.name;
|
|
61
|
+
}
|
|
62
|
+
// No models defined, that means first one is being added, set model to ''
|
|
63
|
+
service.model ??= '';
|
|
33
64
|
}
|
|
34
65
|
/**
|
|
35
|
-
* Sets
|
|
36
|
-
* If the service
|
|
66
|
+
* Sets default annotation name for a single annotation of a given service.
|
|
67
|
+
* If the service annotation name is not defined or empty, it creates a default annotations name
|
|
37
68
|
* from the technicalName by replacing all '/' characters with '_' and removing the leading '_'.
|
|
69
|
+
* If the service and annotation names are the same, then '_Annotation' string is added at the end of annotation name.
|
|
70
|
+
*
|
|
71
|
+
* @param {EdmxAnnotationsInfo} annotation - annotation of a given service
|
|
72
|
+
* @param {string} serviceName - name of the service whose annotations are getting modified.
|
|
73
|
+
*/
|
|
74
|
+
function setDefaultAnnotationName(annotation, serviceName) {
|
|
75
|
+
if (annotation?.technicalName && !annotation.name) {
|
|
76
|
+
annotation.name = annotation?.technicalName?.replace(/\//g, '_')?.replace(/^_/, '');
|
|
77
|
+
}
|
|
78
|
+
if (annotation.name === serviceName) {
|
|
79
|
+
annotation.name += '_Annotation';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Sets default names for annotations of a given service.
|
|
84
|
+
* Handles single annotation in object or annotations array.
|
|
38
85
|
*
|
|
39
86
|
* @param {OdataService} service - The service object whose annotations name needs to be set or modified.
|
|
40
87
|
*/
|
|
41
88
|
function setDefaultAnnotationsName(service) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
89
|
+
if (Array.isArray(service.annotations)) {
|
|
90
|
+
const annotations = service.annotations;
|
|
91
|
+
for (const annotationName in annotations) {
|
|
92
|
+
const annotation = annotations[annotationName];
|
|
93
|
+
setDefaultAnnotationName(annotation, service.name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (service.annotations) {
|
|
97
|
+
const annotation = service.annotations;
|
|
98
|
+
setDefaultAnnotationName(annotation, service.name);
|
|
45
99
|
}
|
|
46
100
|
}
|
|
47
101
|
/**
|
|
48
102
|
* Enhances the provided OData service object with path, name and model information.
|
|
49
103
|
* Directly modifies the passed object reference.
|
|
50
104
|
*
|
|
51
|
-
* @param {
|
|
105
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
106
|
+
* @param {OdataService} service - the OData service instance
|
|
107
|
+
* @param {Editor} fs - the memfs editor instance
|
|
52
108
|
*/
|
|
53
|
-
function enhanceData(service) {
|
|
109
|
+
async function enhanceData(basePath, service, fs) {
|
|
54
110
|
setDefaultServicePath(service);
|
|
55
|
-
setDefaultServiceName(service);
|
|
56
|
-
setDefaultServiceModel(service);
|
|
111
|
+
await setDefaultServiceName(basePath, service, fs);
|
|
112
|
+
await setDefaultServiceModel(basePath, service, fs);
|
|
57
113
|
// set service type to EDMX if not defined
|
|
58
114
|
service.type = service.type ?? types_1.ServiceType.EDMX;
|
|
59
115
|
/**
|
|
@@ -65,10 +121,10 @@ function enhanceData(service) {
|
|
|
65
121
|
setDefaultAnnotationsName(service);
|
|
66
122
|
}
|
|
67
123
|
// enhance preview settings with service configuration
|
|
68
|
-
service.previewSettings = service.previewSettings
|
|
124
|
+
service.previewSettings = service.previewSettings ?? {};
|
|
69
125
|
service.previewSettings.path =
|
|
70
|
-
service.previewSettings.path
|
|
71
|
-
service.previewSettings.url = service.previewSettings.url
|
|
126
|
+
service.previewSettings.path ?? `/${service.path?.split('/').filter((s) => s !== '')[0] ?? ''}`;
|
|
127
|
+
service.previewSettings.url = service.previewSettings.url ?? service.url ?? 'http://localhost';
|
|
72
128
|
if (service.client && !service.previewSettings.client) {
|
|
73
129
|
service.previewSettings.client = service.client;
|
|
74
130
|
}
|
package/dist/delete.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Editor } from 'mem-fs-editor';
|
|
2
|
+
import type { CdsAnnotationsInfo, EdmxAnnotationsInfo } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Removes annotations from CDS files.
|
|
5
|
+
* This function takes cds annotations and an Editor instance,
|
|
6
|
+
* then updates the relevant cds files with the given annotations.
|
|
7
|
+
*
|
|
8
|
+
* @param {CdsAnnotationsInfo} annotations - The cds annotations info.
|
|
9
|
+
* @param {Editor} fs - The memfs editor instance
|
|
10
|
+
* @returns {Promise<void>} A promise that resolves when the cds files have been updated.
|
|
11
|
+
*/
|
|
12
|
+
export declare function removeAnnotationsFromCDSFiles(annotations: CdsAnnotationsInfo | CdsAnnotationsInfo[], fs: Editor): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Removes annotation XML files for EDMX annotations.
|
|
15
|
+
*
|
|
16
|
+
* @param {Editor} fs - The memfs editor instance.
|
|
17
|
+
* @param {string} basePath - The base path of the project.
|
|
18
|
+
* @param {string} serviceName - Name of The OData service.
|
|
19
|
+
* @param {OdataService} edmxAnnotations - The OData service annotations.
|
|
20
|
+
*/
|
|
21
|
+
export declare function removeAnnotationXmlFiles(fs: Editor, basePath: string, serviceName: string, edmxAnnotations: EdmxAnnotationsInfo | EdmxAnnotationsInfo[]): void;
|
|
22
|
+
/**
|
|
23
|
+
* Internal function that deletes service from the manifest.json based on the given service name.
|
|
24
|
+
*
|
|
25
|
+
* @param basePath - the root path of an existing UI5 application
|
|
26
|
+
* @param serviceName - name of the OData service instance
|
|
27
|
+
* @param fs - the memfs editor instance
|
|
28
|
+
*/
|
|
29
|
+
export declare function deleteServiceFromManifest(basePath: string, serviceName: string, fs: Editor): void;
|
|
30
|
+
//# sourceMappingURL=delete.d.ts.map
|
package/dist/delete.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeAnnotationsFromCDSFiles = removeAnnotationsFromCDSFiles;
|
|
4
|
+
exports.removeAnnotationXmlFiles = removeAnnotationXmlFiles;
|
|
5
|
+
exports.deleteServiceFromManifest = deleteServiceFromManifest;
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const i18n_1 = require("./i18n");
|
|
8
|
+
/**
|
|
9
|
+
* Removes the cds index or service file with the provided annotations.
|
|
10
|
+
* This function takes an Editor instance and cds annotations
|
|
11
|
+
* and deletes either from the index file or the service file with the given annotations.
|
|
12
|
+
*
|
|
13
|
+
* @param {Editor} fs - The memfs editor instance
|
|
14
|
+
* @param {CdsAnnotationsInfo} annotations - The cds annotations info.
|
|
15
|
+
* @returns {Promise<void>} A promise that resolves when the cds files have been updated.
|
|
16
|
+
*/
|
|
17
|
+
async function removeCdsIndexOrServiceFile(fs, annotations) {
|
|
18
|
+
const dirPath = (0, path_1.join)(annotations.projectName, 'annotations');
|
|
19
|
+
const annotationPath = (0, path_1.normalize)(dirPath).split(/[\\/]/g).join(path_1.posix.sep);
|
|
20
|
+
const annotationConfig = `\nusing from './${annotationPath}';`;
|
|
21
|
+
// Get index and service file paths
|
|
22
|
+
const indexFilePath = (0, path_1.join)(annotations.projectPath, annotations.appPath ?? '', 'index.cds');
|
|
23
|
+
const serviceFilePath = (0, path_1.join)(annotations.projectPath, annotations.appPath ?? '', 'services.cds');
|
|
24
|
+
// Remove annotation config from index or service file
|
|
25
|
+
if (indexFilePath && fs.exists(indexFilePath)) {
|
|
26
|
+
// Read old annotations content and replace it with empty string
|
|
27
|
+
const initialIndexContent = fs.read(indexFilePath);
|
|
28
|
+
const updatedContent = initialIndexContent.replace(annotationConfig, '');
|
|
29
|
+
fs.write(indexFilePath, updatedContent);
|
|
30
|
+
}
|
|
31
|
+
else if (fs.exists(serviceFilePath)) {
|
|
32
|
+
// Read old annotations content and replace it with empty string
|
|
33
|
+
const initialServiceFileContent = fs.read(serviceFilePath);
|
|
34
|
+
const updatedContent = initialServiceFileContent.replace(annotationConfig, '');
|
|
35
|
+
fs.write(serviceFilePath, updatedContent);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Removes annotations from CDS files.
|
|
40
|
+
* This function takes cds annotations and an Editor instance,
|
|
41
|
+
* then updates the relevant cds files with the given annotations.
|
|
42
|
+
*
|
|
43
|
+
* @param {CdsAnnotationsInfo} annotations - The cds annotations info.
|
|
44
|
+
* @param {Editor} fs - The memfs editor instance
|
|
45
|
+
* @returns {Promise<void>} A promise that resolves when the cds files have been updated.
|
|
46
|
+
*/
|
|
47
|
+
async function removeAnnotationsFromCDSFiles(annotations, fs) {
|
|
48
|
+
if (Array.isArray(annotations)) {
|
|
49
|
+
for (const annotationName in annotations) {
|
|
50
|
+
const annotation = annotations[annotationName];
|
|
51
|
+
const annotationCdsPath = (0, path_1.join)(annotation.projectPath, annotation.appPath ?? '', annotation.projectName, 'annotations.cds');
|
|
52
|
+
// Remove from annotations.cds file
|
|
53
|
+
if (fs.exists(annotationCdsPath)) {
|
|
54
|
+
// Read old annotations content and replace it with empty string
|
|
55
|
+
const initialCDSContent = fs.read(annotationCdsPath);
|
|
56
|
+
const updatedContent = initialCDSContent.replace(annotation.cdsFileContents, '');
|
|
57
|
+
fs.write(annotationCdsPath, updatedContent);
|
|
58
|
+
}
|
|
59
|
+
await removeCdsIndexOrServiceFile(fs, annotation);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const annotationCdsPath = (0, path_1.join)(annotations.projectPath, annotations.appPath ?? '', annotations.projectName, 'annotations.cds');
|
|
64
|
+
// Write into annotations.cds file
|
|
65
|
+
if (fs.exists(annotationCdsPath)) {
|
|
66
|
+
// Read old annotations content and replace it with empty string
|
|
67
|
+
const initialCDSContent = fs.read(annotationCdsPath);
|
|
68
|
+
const updatedContent = initialCDSContent.replace(annotations.cdsFileContents, '');
|
|
69
|
+
fs.write(annotationCdsPath, updatedContent);
|
|
70
|
+
}
|
|
71
|
+
await removeCdsIndexOrServiceFile(fs, annotations);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Removes annotation XML files for EDMX annotations.
|
|
76
|
+
*
|
|
77
|
+
* @param {Editor} fs - The memfs editor instance.
|
|
78
|
+
* @param {string} basePath - The base path of the project.
|
|
79
|
+
* @param {string} serviceName - Name of The OData service.
|
|
80
|
+
* @param {OdataService} edmxAnnotations - The OData service annotations.
|
|
81
|
+
*/
|
|
82
|
+
function removeAnnotationXmlFiles(fs, basePath, serviceName, edmxAnnotations) {
|
|
83
|
+
// Write annotation xml if annotations are provided and service type is EDMX
|
|
84
|
+
if (Array.isArray(edmxAnnotations)) {
|
|
85
|
+
for (const annotationName in edmxAnnotations) {
|
|
86
|
+
const annotation = edmxAnnotations[annotationName];
|
|
87
|
+
const pathToAnnotationFile = (0, path_1.join)(basePath, 'webapp', 'localService', serviceName, `${annotation.technicalName}.xml`);
|
|
88
|
+
if (fs.exists(pathToAnnotationFile)) {
|
|
89
|
+
fs.delete(pathToAnnotationFile);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (edmxAnnotations?.xml) {
|
|
94
|
+
const pathToAnnotationFile = (0, path_1.join)(basePath, 'webapp', 'localService', serviceName, `${edmxAnnotations.technicalName}.xml`);
|
|
95
|
+
if (fs.exists(pathToAnnotationFile)) {
|
|
96
|
+
fs.delete(pathToAnnotationFile);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Internal function that removes files related to dataSource.
|
|
102
|
+
*
|
|
103
|
+
* @param fs - the memfs editor instance
|
|
104
|
+
* @param manifestPath - the root path of an existing UI5 application
|
|
105
|
+
* @param dataSource - name of the OData service instance
|
|
106
|
+
*/
|
|
107
|
+
function removeFileForDataSource(fs, manifestPath, dataSource) {
|
|
108
|
+
const serviceSettings = dataSource.settings || {};
|
|
109
|
+
if (serviceSettings?.localUri) {
|
|
110
|
+
const localUriPath = (0, path_1.join)((0, path_1.dirname)(manifestPath), serviceSettings?.localUri);
|
|
111
|
+
if (fs.exists(localUriPath)) {
|
|
112
|
+
// delete the local data source file
|
|
113
|
+
fs.delete(localUriPath);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Internal function that removes annotation files related to service.
|
|
119
|
+
*
|
|
120
|
+
* @param fs - the memfs editor instance
|
|
121
|
+
* @param manifestPath - the root path of an existing UI5 application
|
|
122
|
+
* @param annotations - annotations list
|
|
123
|
+
* @param dataSources - list of dataSources from manifest.json
|
|
124
|
+
*/
|
|
125
|
+
function removeAnnotations(fs, manifestPath, annotations, dataSources) {
|
|
126
|
+
for (const datasourceKey of annotations) {
|
|
127
|
+
const annotationDatasource = dataSources?.[datasourceKey];
|
|
128
|
+
if (annotationDatasource?.type === 'ODataAnnotation') {
|
|
129
|
+
if (annotationDatasource.uri === annotationDatasource?.settings?.localUri) {
|
|
130
|
+
// This is localAnnotaton file. Do not delete it.
|
|
131
|
+
}
|
|
132
|
+
else if (annotationDatasource) {
|
|
133
|
+
removeFileForDataSource(fs, manifestPath, annotationDatasource);
|
|
134
|
+
// delete dataSource from manifest
|
|
135
|
+
delete dataSources?.[datasourceKey];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Internal function that deletes service from the manifest.json based on the given service name.
|
|
142
|
+
*
|
|
143
|
+
* @param basePath - the root path of an existing UI5 application
|
|
144
|
+
* @param serviceName - name of the OData service instance
|
|
145
|
+
* @param fs - the memfs editor instance
|
|
146
|
+
*/
|
|
147
|
+
function deleteServiceFromManifest(basePath, serviceName, fs) {
|
|
148
|
+
const manifestPath = (0, path_1.join)(basePath, 'webapp', 'manifest.json');
|
|
149
|
+
// Get component app id
|
|
150
|
+
const manifest = fs.readJSON(manifestPath);
|
|
151
|
+
const appProp = 'sap.app';
|
|
152
|
+
const appid = manifest?.[appProp]?.id;
|
|
153
|
+
// Throw if required property is not found manifest.json
|
|
154
|
+
if (!appid) {
|
|
155
|
+
throw new Error((0, i18n_1.t)('error.requiredProjectPropertyNotFound', { property: `'${appProp}'.id`, path: manifestPath }));
|
|
156
|
+
}
|
|
157
|
+
const dataSources = manifest?.[appProp]?.dataSources;
|
|
158
|
+
if (dataSources?.[serviceName]) {
|
|
159
|
+
removeFileForDataSource(fs, manifestPath, dataSources?.[serviceName]);
|
|
160
|
+
}
|
|
161
|
+
const serviceSettings = dataSources?.[serviceName]?.settings;
|
|
162
|
+
// Check for linked backend annotations and delete if found.
|
|
163
|
+
if (serviceSettings?.annotations && serviceSettings.annotations.length > 0) {
|
|
164
|
+
removeAnnotations(fs, manifestPath, serviceSettings.annotations, dataSources);
|
|
165
|
+
}
|
|
166
|
+
// delete dataSource from manifest
|
|
167
|
+
if (dataSources?.[serviceName]) {
|
|
168
|
+
delete dataSources[serviceName];
|
|
169
|
+
}
|
|
170
|
+
const modelsProp = 'sap.ui5';
|
|
171
|
+
// delete models for this service
|
|
172
|
+
const models = manifest?.[modelsProp]?.models;
|
|
173
|
+
if (models) {
|
|
174
|
+
for (const modelKey of Object.keys(models)) {
|
|
175
|
+
const modelObj = models[modelKey];
|
|
176
|
+
if (modelObj?.dataSource === serviceName) {
|
|
177
|
+
delete models[modelKey];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
fs.writeJSON(manifestPath, manifest);
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=delete.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import type { Editor } from 'mem-fs-editor';
|
|
2
2
|
import { getAnnotationNamespaces } from './data';
|
|
3
|
+
import type { ProjectPaths } from './types';
|
|
3
4
|
import { OdataService, OdataVersion, ServiceType, CdsAnnotationsInfo, EdmxAnnotationsInfo, NamespaceAlias } from './types';
|
|
4
5
|
/**
|
|
5
6
|
* Try finding a package.json and a ui5.yaml for the given project by looking upwards in the folder hierachy.
|
|
6
7
|
*
|
|
7
8
|
* @param {string} basePath - the root path of an existing UI5 application
|
|
8
9
|
* @param {Editor} [fs] - the memfs editor instance
|
|
9
|
-
* @returns an object with the optional locations of the package.json and ui5.yaml
|
|
10
|
+
* @returns an object with the optional locations of the package.json and ui5.yaml, ui5-local.yaml, ui5-mock.yaml
|
|
10
11
|
*/
|
|
11
|
-
export declare function findProjectFiles(basePath: string, fs: Editor): Promise<
|
|
12
|
-
packageJson?: string;
|
|
13
|
-
ui5Yaml?: string;
|
|
14
|
-
}>;
|
|
12
|
+
export declare function findProjectFiles(basePath: string, fs: Editor): Promise<ProjectPaths>;
|
|
15
13
|
/**
|
|
16
14
|
* Writes the odata service related file updates to an existing UI5 project specified by the base path.
|
|
17
15
|
*
|
|
@@ -22,6 +20,33 @@ export declare function findProjectFiles(basePath: string, fs: Editor): Promise<
|
|
|
22
20
|
* @returns {Promise<Editor>} the updated memfs editor instance
|
|
23
21
|
*/
|
|
24
22
|
declare function generate(basePath: string, service: OdataService, fs?: Editor): Promise<Editor>;
|
|
25
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Removes service related data from project files for an existing UI5 project specified by the base path.
|
|
25
|
+
* Works as follow:
|
|
26
|
+
* 1. Service is removed from manifest.
|
|
27
|
+
* If service type is EDMX:
|
|
28
|
+
* 2. ui5.yaml
|
|
29
|
+
* - backend data of the service is removed from fiori-tools-proxy middleware
|
|
30
|
+
* 3. ui5-local.yaml
|
|
31
|
+
* - backend data of the service is removed from fiori-tools-proxy middleware
|
|
32
|
+
* - service is removed from mockserver middleware
|
|
33
|
+
* 4. ui5-mock.yaml
|
|
34
|
+
* - service is removed from mockserver middleware
|
|
35
|
+
* If service type is CDS:
|
|
36
|
+
* 2. annotations of the service are removed from CDS files.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
39
|
+
* @param {OdataService} service - the OData service instance
|
|
40
|
+
* @param {string} service.name - name of the OData service instance
|
|
41
|
+
* @param {string} service.path - path of the OData service instance
|
|
42
|
+
* @param {string} service.url - url of the OData service instance
|
|
43
|
+
* @param {ServiceType} service.type - type of the OData service instance
|
|
44
|
+
* @param {OdataService['annotations']} service.annotations - services annotations (EDMX or CDS)
|
|
45
|
+
* @param {Editor} [fs] - the memfs editor instance
|
|
46
|
+
* @throws {Error} - if required UI5 project files are not found
|
|
47
|
+
* @returns {Promise<Editor>} the updated memfs editor instance
|
|
48
|
+
*/
|
|
49
|
+
declare function remove(basePath: string, service: Required<Pick<OdataService, 'name' | 'path' | 'url' | 'type' | 'annotations'>>, fs?: Editor): Promise<Editor>;
|
|
50
|
+
export { generate, remove, OdataVersion, OdataService, ServiceType, EdmxAnnotationsInfo, CdsAnnotationsInfo };
|
|
26
51
|
export { getAnnotationNamespaces, NamespaceAlias };
|
|
27
52
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getAnnotationNamespaces = exports.ServiceType = exports.OdataVersion = void 0;
|
|
7
7
|
exports.findProjectFiles = findProjectFiles;
|
|
8
8
|
exports.generate = generate;
|
|
9
|
+
exports.remove = remove;
|
|
9
10
|
const path_1 = require("path");
|
|
10
11
|
const mem_fs_1 = require("mem-fs");
|
|
11
12
|
const mem_fs_editor_1 = require("mem-fs-editor");
|
|
@@ -20,6 +21,7 @@ Object.defineProperty(exports, "OdataVersion", { enumerable: true, get: function
|
|
|
20
21
|
Object.defineProperty(exports, "ServiceType", { enumerable: true, get: function () { return types_1.ServiceType; } });
|
|
21
22
|
const project_access_1 = require("@sap-ux/project-access");
|
|
22
23
|
const mockserver_config_writer_1 = require("@sap-ux/mockserver-config-writer");
|
|
24
|
+
const delete_1 = require("./delete");
|
|
23
25
|
/**
|
|
24
26
|
* Ensures the existence of the given files in the provided base path. If a file in the provided list does not exit, an error would be thrown.
|
|
25
27
|
*
|
|
@@ -39,12 +41,12 @@ function ensureExists(basePath, files, fs) {
|
|
|
39
41
|
*
|
|
40
42
|
* @param {string} basePath - the root path of an existing UI5 application
|
|
41
43
|
* @param {Editor} [fs] - the memfs editor instance
|
|
42
|
-
* @returns an object with the optional locations of the package.json and ui5.yaml
|
|
44
|
+
* @returns an object with the optional locations of the package.json and ui5.yaml, ui5-local.yaml, ui5-mock.yaml
|
|
43
45
|
*/
|
|
44
46
|
async function findProjectFiles(basePath, fs) {
|
|
45
47
|
const files = {};
|
|
46
48
|
const parts = basePath.split(path_1.sep);
|
|
47
|
-
while (parts.length > 0 && (!files.packageJson || !files.ui5Yaml)) {
|
|
49
|
+
while (parts.length > 0 && (!files.packageJson || !files.ui5Yaml || !files.ui5LocalYaml || !files.ui5MockYaml)) {
|
|
48
50
|
const path = parts.join(path_1.sep);
|
|
49
51
|
if (!files.packageJson && fs.exists((0, path_1.join)(path, 'package.json'))) {
|
|
50
52
|
files.packageJson = (0, path_1.join)(path, 'package.json');
|
|
@@ -52,10 +54,150 @@ async function findProjectFiles(basePath, fs) {
|
|
|
52
54
|
if (!files.ui5Yaml && fs.exists((0, path_1.join)(path, 'ui5.yaml'))) {
|
|
53
55
|
files.ui5Yaml = (0, path_1.join)(path, 'ui5.yaml');
|
|
54
56
|
}
|
|
57
|
+
if (!files.ui5LocalYaml && fs.exists((0, path_1.join)(path, 'ui5-local.yaml'))) {
|
|
58
|
+
files.ui5LocalYaml = (0, path_1.join)(path, 'ui5-local.yaml');
|
|
59
|
+
}
|
|
60
|
+
if (!files.ui5MockYaml && fs.exists((0, path_1.join)(path, 'ui5-mock.yaml'))) {
|
|
61
|
+
files.ui5MockYaml = (0, path_1.join)(path, 'ui5-mock.yaml');
|
|
62
|
+
}
|
|
55
63
|
parts.pop();
|
|
56
64
|
}
|
|
57
65
|
return files;
|
|
58
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Generates mockserver middleware config for ui5-local.yaml file based on ui5-mock.yaml.
|
|
69
|
+
*
|
|
70
|
+
* @param {Editor} fs - the memfs editor instance
|
|
71
|
+
* @param {OdataService} ui5YamlPath - path pointing to the ui5.yaml file
|
|
72
|
+
* @param {UI5Config} ui5LocalConfigPath - ui5-local.yaml configuration
|
|
73
|
+
* @param {string} ui5LocalConfig - path pointing to the ui5-local.yaml file
|
|
74
|
+
* @returns {Promise<Editor>} the updated memfs editor instance
|
|
75
|
+
*/
|
|
76
|
+
async function generateMockserverMiddlewareBasedOnUi5MockYaml(fs, ui5YamlPath, ui5LocalConfigPath, ui5LocalConfig) {
|
|
77
|
+
// Update ui5-local.yaml with mockserver middleware from ui5-mock.yaml
|
|
78
|
+
const ui5MockYamlPath = (0, path_1.join)((0, path_1.dirname)(ui5YamlPath), 'ui5-mock.yaml');
|
|
79
|
+
const ui5MockYamlConfig = await ui5_config_1.UI5Config.newInstance(fs.read(ui5MockYamlPath));
|
|
80
|
+
const mockserverMiddlewareFromUi5Mock = ui5MockYamlConfig.findCustomMiddleware('sap-fe-mockserver');
|
|
81
|
+
if (ui5LocalConfigPath && fs.exists(ui5LocalConfigPath) && ui5LocalConfig && mockserverMiddlewareFromUi5Mock) {
|
|
82
|
+
ui5LocalConfig.updateCustomMiddleware(mockserverMiddlewareFromUi5Mock);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Extends backend middleware for UI5Config with service data.
|
|
87
|
+
*
|
|
88
|
+
* @param {Editor} fs - the memfs editor instance
|
|
89
|
+
* @param {OdataService} service - the OData service instance data
|
|
90
|
+
* @param {UI5Config} ui5Config - UI5 configuration
|
|
91
|
+
* @param {string} ui5ConfigPath - path to the YAML config file
|
|
92
|
+
* @throws {Error} - if required UI5 project files are not found
|
|
93
|
+
*/
|
|
94
|
+
function extendBackendMiddleware(fs, service, ui5Config, ui5ConfigPath) {
|
|
95
|
+
try {
|
|
96
|
+
ui5Config.addBackendToFioriToolsProxydMiddleware(service.previewSettings);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if ((error instanceof ui5_config_1.YAMLError && error.code === ui5_config_1.yamlErrorCode.nodeNotFound) ||
|
|
100
|
+
error.message === 'Could not find fiori-tools-proxy') {
|
|
101
|
+
ui5Config.addFioriToolsProxydMiddleware({
|
|
102
|
+
backend: [service.previewSettings],
|
|
103
|
+
ignoreCertError: service.ignoreCertError
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
fs.write(ui5ConfigPath, ui5Config.toString());
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Returns all paths of the EDMX service annotations.
|
|
114
|
+
*
|
|
115
|
+
* @param {OdataService} edmxAnnotations - EDMX OData service annotations.
|
|
116
|
+
* @returns {string} annotation paths.
|
|
117
|
+
*/
|
|
118
|
+
function getEDMXAnnotationPaths(edmxAnnotations) {
|
|
119
|
+
const emdxAnnotationsPaths = [];
|
|
120
|
+
if (Array.isArray(edmxAnnotations)) {
|
|
121
|
+
edmxAnnotations.forEach((annotation) => {
|
|
122
|
+
const technicalName = encodeURIComponent(annotation.technicalName);
|
|
123
|
+
emdxAnnotationsPaths.push(`/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='${technicalName}',Version='0001')/$value/` // This is how annotation paths are stored in manifest for ODataAnnotations
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const technicalName = encodeURIComponent(edmxAnnotations.technicalName);
|
|
129
|
+
emdxAnnotationsPaths.push(`/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='${technicalName}',Version='0001')/$value/`);
|
|
130
|
+
}
|
|
131
|
+
return emdxAnnotationsPaths;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Writes local copies of metadata and annotations.
|
|
135
|
+
*
|
|
136
|
+
* @param {Editor} fs - the memfs editor instance
|
|
137
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
138
|
+
* @param {string} webappPath - the webapp path of an existing UI5 application
|
|
139
|
+
* @param {string} templateRoot - path to the file templates
|
|
140
|
+
* @param {OdataService} service - the OData service instance with EDMX type
|
|
141
|
+
*/
|
|
142
|
+
async function writeLocalServiceFiles(fs, basePath, webappPath, templateRoot, service) {
|
|
143
|
+
// mainService should be used in case there is no name defined for service
|
|
144
|
+
fs.write((0, path_1.join)(webappPath, 'localService', service.name ?? 'mainService', 'metadata.xml'), (0, prettify_xml_1.default)(service.metadata, { indent: 4 }));
|
|
145
|
+
// Adds local annotations to datasources section of manifest.json and writes the annotations file
|
|
146
|
+
if (service.localAnnotationsName) {
|
|
147
|
+
const namespaces = (0, data_1.getAnnotationNamespaces)(service);
|
|
148
|
+
fs.copyTpl((0, path_1.join)(templateRoot, 'add', 'annotation.xml'), (0, path_1.join)(basePath, 'webapp', 'annotations', `${service.localAnnotationsName}.xml`), { ...service, namespaces });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Writes EDMX service data to ui5.yaml, ui5-mock.yaml, ui5-local.yaml, package.json and annotations xml files.
|
|
153
|
+
*
|
|
154
|
+
* @param {Editor} fs - the memfs editor instance
|
|
155
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
156
|
+
* @param {ProjectPaths} paths - locations of the package.json and ui5.yaml, ui5-local.yaml, ui5-mock.yaml
|
|
157
|
+
* @param {string} templateRoot - path to the file templates
|
|
158
|
+
* @param {OdataService} service - the OData service instance with EDMX type
|
|
159
|
+
*/
|
|
160
|
+
async function writeEDMXServiceFiles(fs, basePath, paths, templateRoot, service) {
|
|
161
|
+
let ui5Config;
|
|
162
|
+
let ui5LocalConfig;
|
|
163
|
+
let ui5MockConfig;
|
|
164
|
+
if (paths.ui5Yaml) {
|
|
165
|
+
ui5Config = await ui5_config_1.UI5Config.newInstance(fs.read(paths.ui5Yaml));
|
|
166
|
+
// Update ui5.yaml with backend middleware
|
|
167
|
+
extendBackendMiddleware(fs, service, ui5Config, paths.ui5Yaml);
|
|
168
|
+
// Update ui5-local.yaml with backend middleware
|
|
169
|
+
if (paths.ui5LocalYaml) {
|
|
170
|
+
ui5LocalConfig = await ui5_config_1.UI5Config.newInstance(fs.read(paths.ui5LocalYaml));
|
|
171
|
+
extendBackendMiddleware(fs, service, ui5LocalConfig, paths.ui5LocalYaml);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (service.metadata) {
|
|
175
|
+
const webappPath = await (0, project_access_1.getWebappPath)(basePath, fs);
|
|
176
|
+
if (paths.ui5Yaml && ui5Config) {
|
|
177
|
+
const config = {
|
|
178
|
+
webappPath: webappPath
|
|
179
|
+
};
|
|
180
|
+
// Generate mockserver middleware for ui5-mock.yaml
|
|
181
|
+
await (0, mockserver_config_writer_1.generateMockserverConfig)(basePath, config, fs);
|
|
182
|
+
// Update ui5-local.yaml with mockserver middleware from newly created/updated ui5-mock.yaml
|
|
183
|
+
await generateMockserverMiddlewareBasedOnUi5MockYaml(fs, paths.ui5Yaml, paths.ui5LocalYaml, ui5LocalConfig);
|
|
184
|
+
// Update ui5-mock.yaml with backend middleware
|
|
185
|
+
if (paths.ui5MockYaml) {
|
|
186
|
+
ui5MockConfig = await ui5_config_1.UI5Config.newInstance(fs.read(paths.ui5MockYaml));
|
|
187
|
+
extendBackendMiddleware(fs, service, ui5MockConfig, paths.ui5MockYaml);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
await writeLocalServiceFiles(fs, basePath, webappPath, templateRoot, service);
|
|
191
|
+
}
|
|
192
|
+
if (paths.packageJson && paths.ui5Yaml) {
|
|
193
|
+
(0, updates_1.updatePackageJson)(paths.packageJson, fs, !!service.metadata);
|
|
194
|
+
}
|
|
195
|
+
if (paths.ui5LocalYaml && ui5LocalConfig) {
|
|
196
|
+
// write ui5 local yaml if service type is not CDS
|
|
197
|
+
fs.write(paths.ui5LocalYaml, ui5LocalConfig.toString());
|
|
198
|
+
}
|
|
199
|
+
(0, updates_1.writeAnnotationXmlFiles)(fs, basePath, service.name ?? 'mainService', service.annotations);
|
|
200
|
+
}
|
|
59
201
|
/**
|
|
60
202
|
* Writes the odata service related file updates to an existing UI5 project specified by the base path.
|
|
61
203
|
*
|
|
@@ -71,84 +213,91 @@ async function generate(basePath, service, fs) {
|
|
|
71
213
|
}
|
|
72
214
|
const paths = await findProjectFiles(basePath, fs);
|
|
73
215
|
ensureExists(basePath, ['webapp/manifest.json'], fs);
|
|
74
|
-
(0, data_1.enhanceData)(service);
|
|
75
|
-
//
|
|
216
|
+
await (0, data_1.enhanceData)(basePath, service, fs);
|
|
217
|
+
// Set isServiceTypeEdmx true if service is EDMX
|
|
76
218
|
const isServiceTypeEdmx = service.type === types_1.ServiceType.EDMX;
|
|
77
|
-
//
|
|
219
|
+
// Prepare template folder for manifest and xml updates
|
|
78
220
|
const templateRoot = (0, path_1.join)(__dirname, '../templates');
|
|
79
|
-
//
|
|
80
|
-
|
|
221
|
+
// Update manifest.json
|
|
222
|
+
await (0, updates_1.updateManifest)(basePath, service, fs, templateRoot);
|
|
223
|
+
// Dont extend backend and mockserver middlewares if service type is CDS
|
|
224
|
+
if (isServiceTypeEdmx) {
|
|
225
|
+
await writeEDMXServiceFiles(fs, basePath, paths, templateRoot, service);
|
|
226
|
+
}
|
|
227
|
+
else if (!isServiceTypeEdmx && service.annotations) {
|
|
228
|
+
// Update cds files with annotations only if service type is CDS and annotations are provided
|
|
81
229
|
await (0, updates_1.updateCdsFilesWithAnnotations)(service.annotations, fs);
|
|
82
230
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
231
|
+
return fs;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Removes service related data from project files for an existing UI5 project specified by the base path.
|
|
235
|
+
* Works as follow:
|
|
236
|
+
* 1. Service is removed from manifest.
|
|
237
|
+
* If service type is EDMX:
|
|
238
|
+
* 2. ui5.yaml
|
|
239
|
+
* - backend data of the service is removed from fiori-tools-proxy middleware
|
|
240
|
+
* 3. ui5-local.yaml
|
|
241
|
+
* - backend data of the service is removed from fiori-tools-proxy middleware
|
|
242
|
+
* - service is removed from mockserver middleware
|
|
243
|
+
* 4. ui5-mock.yaml
|
|
244
|
+
* - service is removed from mockserver middleware
|
|
245
|
+
* If service type is CDS:
|
|
246
|
+
* 2. annotations of the service are removed from CDS files.
|
|
247
|
+
*
|
|
248
|
+
* @param {string} basePath - the root path of an existing UI5 application
|
|
249
|
+
* @param {OdataService} service - the OData service instance
|
|
250
|
+
* @param {string} service.name - name of the OData service instance
|
|
251
|
+
* @param {string} service.path - path of the OData service instance
|
|
252
|
+
* @param {string} service.url - url of the OData service instance
|
|
253
|
+
* @param {ServiceType} service.type - type of the OData service instance
|
|
254
|
+
* @param {OdataService['annotations']} service.annotations - services annotations (EDMX or CDS)
|
|
255
|
+
* @param {Editor} [fs] - the memfs editor instance
|
|
256
|
+
* @throws {Error} - if required UI5 project files are not found
|
|
257
|
+
* @returns {Promise<Editor>} the updated memfs editor instance
|
|
258
|
+
*/
|
|
259
|
+
async function remove(basePath, service, fs) {
|
|
260
|
+
if (!fs) {
|
|
261
|
+
fs = (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
262
|
+
}
|
|
86
263
|
let ui5Config;
|
|
87
264
|
let ui5LocalConfig;
|
|
88
|
-
let
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
fs.write(paths.ui5Yaml, ui5Config.toString());
|
|
107
|
-
// ui5-local.yaml
|
|
108
|
-
ui5LocalConfigPath = (0, path_1.join)((0, path_1.dirname)(paths.ui5Yaml), 'ui5-local.yaml');
|
|
109
|
-
if (fs.exists(ui5LocalConfigPath)) {
|
|
110
|
-
ui5LocalConfig = await ui5_config_1.UI5Config.newInstance(fs.read(ui5LocalConfigPath));
|
|
111
|
-
ui5LocalConfig.addFioriToolsProxydMiddleware({
|
|
112
|
-
backend: [service.previewSettings],
|
|
113
|
-
ignoreCertError: service.ignoreCertError
|
|
114
|
-
});
|
|
265
|
+
let ui5MockConfig;
|
|
266
|
+
const paths = await findProjectFiles(basePath, fs);
|
|
267
|
+
// Delete service and it's annotations from manifest
|
|
268
|
+
(0, delete_1.deleteServiceFromManifest)(basePath, service.name, fs);
|
|
269
|
+
const isServiceTypeEdmx = service.type === types_1.ServiceType.EDMX;
|
|
270
|
+
// Remove service related data from middlewares for EDMX services
|
|
271
|
+
if (isServiceTypeEdmx) {
|
|
272
|
+
// Delete service data from manifest.json
|
|
273
|
+
if (paths.ui5Yaml) {
|
|
274
|
+
ui5Config = await ui5_config_1.UI5Config.newInstance(fs.read(paths.ui5Yaml));
|
|
275
|
+
// Delete service backend from fiori-tools-proxy middleware config
|
|
276
|
+
ui5Config.removeBackendFromFioriToolsProxydMiddleware(service.url);
|
|
277
|
+
fs.write(paths.ui5Yaml, ui5Config.toString());
|
|
115
278
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
webappPath: webappPath,
|
|
125
|
-
ui5MockYamlConfig: { path: service.path }
|
|
126
|
-
};
|
|
127
|
-
await (0, mockserver_config_writer_1.generateMockserverConfig)(basePath, config, fs);
|
|
128
|
-
// add mockserver middleware to ui5-local.yaml
|
|
129
|
-
if (ui5LocalConfig) {
|
|
130
|
-
ui5LocalConfig.addMockServerMiddleware(service.path);
|
|
131
|
-
}
|
|
279
|
+
const serviceAnnotationPaths = getEDMXAnnotationPaths(service.annotations);
|
|
280
|
+
if (paths.ui5LocalYaml) {
|
|
281
|
+
ui5LocalConfig = await ui5_config_1.UI5Config.newInstance(fs.read(paths.ui5LocalYaml));
|
|
282
|
+
// Delete service backend from fiori-tools-proxy middleware config
|
|
283
|
+
ui5LocalConfig.removeBackendFromFioriToolsProxydMiddleware(service.url);
|
|
284
|
+
// Delete service from mockserver middleware config
|
|
285
|
+
ui5LocalConfig.removeServiceFromMockServerMiddleware(service.path, serviceAnnotationPaths);
|
|
286
|
+
fs.write(paths.ui5LocalYaml, ui5LocalConfig.toString());
|
|
132
287
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
288
|
+
if (paths.ui5MockYaml) {
|
|
289
|
+
ui5MockConfig = await ui5_config_1.UI5Config.newInstance(fs.read(paths.ui5MockYaml));
|
|
290
|
+
// Delete service backend from fiori-tools-proxy middleware config
|
|
291
|
+
ui5MockConfig.removeBackendFromFioriToolsProxydMiddleware(service.url);
|
|
292
|
+
// Delete service from mockserver config
|
|
293
|
+
ui5MockConfig.removeServiceFromMockServerMiddleware(service.path, serviceAnnotationPaths);
|
|
294
|
+
fs.write(paths.ui5MockYaml, ui5MockConfig.toString());
|
|
139
295
|
}
|
|
296
|
+
(0, delete_1.removeAnnotationXmlFiles)(fs, basePath, service.name ?? 'mainService', service.annotations);
|
|
140
297
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
(0,
|
|
144
|
-
}
|
|
145
|
-
if (isServiceTypeEdmx && ui5LocalConfigPath && ui5LocalConfig) {
|
|
146
|
-
// write ui5 local yaml if service type is not CDS
|
|
147
|
-
fs.write(ui5LocalConfigPath, ui5LocalConfig.toString());
|
|
148
|
-
}
|
|
149
|
-
// Write annotation xml if annotations are provided and service type is EDMX
|
|
150
|
-
if (isServiceTypeEdmx) {
|
|
151
|
-
(0, updates_1.writeAnnotationXmlFiles)(fs, basePath, service);
|
|
298
|
+
else {
|
|
299
|
+
// Remove annotations from CDS files based on annotations info
|
|
300
|
+
await (0, delete_1.removeAnnotationsFromCDSFiles)(service.annotations, fs);
|
|
152
301
|
}
|
|
153
302
|
return fs;
|
|
154
303
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export interface OdataService {
|
|
|
65
65
|
/**
|
|
66
66
|
* Annotations can either be EDMX annotations or CDS annotations.
|
|
67
67
|
*/
|
|
68
|
-
annotations?: EdmxAnnotationsInfo | CdsAnnotationsInfo;
|
|
68
|
+
annotations?: EdmxAnnotationsInfo | EdmxAnnotationsInfo[] | CdsAnnotationsInfo | CdsAnnotationsInfo[];
|
|
69
69
|
localAnnotationsName?: string;
|
|
70
70
|
previewSettings?: Partial<ProxyBackend>;
|
|
71
71
|
/**
|
|
@@ -73,4 +73,13 @@ export interface OdataService {
|
|
|
73
73
|
*/
|
|
74
74
|
ignoreCertError?: boolean;
|
|
75
75
|
}
|
|
76
|
+
export type EdmxOdataService = Omit<OdataService, 'annotations'> & {
|
|
77
|
+
annotations: EdmxAnnotationsInfo | EdmxAnnotationsInfo[];
|
|
78
|
+
};
|
|
79
|
+
export interface ProjectPaths {
|
|
80
|
+
packageJson?: string;
|
|
81
|
+
ui5Yaml?: string;
|
|
82
|
+
ui5LocalYaml?: string;
|
|
83
|
+
ui5MockYaml?: string;
|
|
84
|
+
}
|
|
76
85
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/updates.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Editor } from 'mem-fs-editor';
|
|
2
|
-
import type { OdataService, CdsAnnotationsInfo } from './types';
|
|
2
|
+
import type { OdataService, CdsAnnotationsInfo, EdmxAnnotationsInfo } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Internal function that updates the manifest.json based on the given service configuration.
|
|
5
5
|
*
|
|
@@ -8,15 +8,16 @@ import type { OdataService, CdsAnnotationsInfo } from './types';
|
|
|
8
8
|
* @param fs - the memfs editor instance
|
|
9
9
|
* @param templateRoot - root folder contain the ejs templates
|
|
10
10
|
*/
|
|
11
|
-
export declare function updateManifest(basePath: string, service: OdataService, fs: Editor, templateRoot: string): void
|
|
11
|
+
export declare function updateManifest(basePath: string, service: OdataService, fs: Editor, templateRoot: string): Promise<void>;
|
|
12
12
|
/**
|
|
13
|
-
* Writes annotation XML files.
|
|
13
|
+
* Writes annotation XML files for EDMX service annotations.
|
|
14
14
|
*
|
|
15
15
|
* @param {Editor} fs - The memfs editor instance.
|
|
16
16
|
* @param {string} basePath - The base path of the project.
|
|
17
|
-
* @param {
|
|
17
|
+
* @param {string} serviceName - Name of The OData service.
|
|
18
|
+
* @param {OdataService} edmxAnnotations - The OData service annotations.
|
|
18
19
|
*/
|
|
19
|
-
export declare function writeAnnotationXmlFiles(fs: Editor, basePath: string,
|
|
20
|
+
export declare function writeAnnotationXmlFiles(fs: Editor, basePath: string, serviceName: string, edmxAnnotations: EdmxAnnotationsInfo | EdmxAnnotationsInfo[]): void;
|
|
20
21
|
/**
|
|
21
22
|
* Updates cds files with the provided annotations.
|
|
22
23
|
* This function takes cds annotations and an Editor instance,
|
|
@@ -26,7 +27,7 @@ export declare function writeAnnotationXmlFiles(fs: Editor, basePath: string, se
|
|
|
26
27
|
* @param {Editor} fs - The memfs editor instance
|
|
27
28
|
* @returns {Promise<void>} A promise that resolves when the cds files have been updated.
|
|
28
29
|
*/
|
|
29
|
-
export declare function updateCdsFilesWithAnnotations(annotations: CdsAnnotationsInfo, fs: Editor): Promise<void>;
|
|
30
|
+
export declare function updateCdsFilesWithAnnotations(annotations: CdsAnnotationsInfo | CdsAnnotationsInfo[], fs: Editor): Promise<void>;
|
|
30
31
|
/**
|
|
31
32
|
* Update the package.json with the required middlewares.
|
|
32
33
|
*
|
package/dist/updates.js
CHANGED
|
@@ -1,27 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
@@ -31,11 +8,63 @@ exports.writeAnnotationXmlFiles = writeAnnotationXmlFiles;
|
|
|
31
8
|
exports.updateCdsFilesWithAnnotations = updateCdsFilesWithAnnotations;
|
|
32
9
|
exports.updatePackageJson = updatePackageJson;
|
|
33
10
|
const ejs_1 = require("ejs");
|
|
34
|
-
const path_1 =
|
|
11
|
+
const path_1 = require("path");
|
|
35
12
|
const i18n_1 = require("./i18n");
|
|
36
13
|
const semver_1 = __importDefault(require("semver"));
|
|
37
14
|
const prettify_xml_1 = __importDefault(require("prettify-xml"));
|
|
38
15
|
const project_access_1 = require("@sap-ux/project-access");
|
|
16
|
+
/**
|
|
17
|
+
* Modifies service in manifest.json and service files in a way that is supported by multiple services.
|
|
18
|
+
* If service files are defined in 'localService' folder then those files are moved to respective service folder and service configuration URI are modified in manifest.json.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} webappPath - the webapp path of an existing UI5 application
|
|
21
|
+
* @param {string} dataSourceKey - dataSource key in manifest.json
|
|
22
|
+
* @param {Manifest} dataSource - dataSource configuration from manifest.json
|
|
23
|
+
* @param {Editor} fs - the memfs editor instance
|
|
24
|
+
*/
|
|
25
|
+
function updateExistingService(webappPath, dataSourceKey, dataSource, fs) {
|
|
26
|
+
const settings = dataSource.settings;
|
|
27
|
+
if (settings) {
|
|
28
|
+
// "localService/metadata.xml"
|
|
29
|
+
const localUri = settings.localUri;
|
|
30
|
+
// -> ["localService", "metadata.xml"]
|
|
31
|
+
const localUriParts = localUri ? localUri.split('/') : undefined;
|
|
32
|
+
if (localUriParts && localUriParts[0] === project_access_1.DirName.LocalService && localUriParts.length === 2) {
|
|
33
|
+
const localFileName = localUriParts[localUriParts.length - 1];
|
|
34
|
+
settings.localUri = `${project_access_1.DirName.LocalService}/${dataSourceKey}/${localFileName}`;
|
|
35
|
+
// move related files to service folder
|
|
36
|
+
const fromFilePath = (0, path_1.join)(webappPath, localUriParts.join(path_1.sep));
|
|
37
|
+
const toFilePath = (0, path_1.join)(webappPath, project_access_1.DirName.LocalService, dataSourceKey, localFileName);
|
|
38
|
+
if (fs.exists(fromFilePath)) {
|
|
39
|
+
fs.move(fromFilePath, toFilePath);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Modifies services in manifest.json and services files in a way that is supported by multiple services.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} webappPath - the webapp path of an existing UI5 application
|
|
48
|
+
* @param {Manifest} manifest - the manifest.json of the application
|
|
49
|
+
* @param {Editor} fs - the memfs editor instance
|
|
50
|
+
*/
|
|
51
|
+
async function updateExistingServices(webappPath, manifest, fs) {
|
|
52
|
+
const dataSources = manifest?.['sap.app']?.dataSources;
|
|
53
|
+
for (const dataSourceKey in dataSources) {
|
|
54
|
+
const dataSource = dataSources[dataSourceKey];
|
|
55
|
+
if (dataSource.type === 'OData') {
|
|
56
|
+
updateExistingService(webappPath, dataSourceKey, dataSource, fs);
|
|
57
|
+
const annotations = dataSource.settings?.annotations;
|
|
58
|
+
if (annotations) {
|
|
59
|
+
annotations.forEach((annotationName) => {
|
|
60
|
+
const annotationDataSource = dataSources[annotationName];
|
|
61
|
+
updateExistingService(webappPath, dataSourceKey, annotationDataSource, fs);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
fs.writeJSON((0, path_1.join)(webappPath, 'manifest.json'), manifest);
|
|
67
|
+
}
|
|
39
68
|
/**
|
|
40
69
|
* Internal function that updates the manifest.json based on the given service configuration.
|
|
41
70
|
*
|
|
@@ -44,18 +73,22 @@ const project_access_1 = require("@sap-ux/project-access");
|
|
|
44
73
|
* @param fs - the memfs editor instance
|
|
45
74
|
* @param templateRoot - root folder contain the ejs templates
|
|
46
75
|
*/
|
|
47
|
-
function updateManifest(basePath, service, fs, templateRoot) {
|
|
48
|
-
const
|
|
76
|
+
async function updateManifest(basePath, service, fs, templateRoot) {
|
|
77
|
+
const webappPath = await (0, project_access_1.getWebappPath)(basePath, fs);
|
|
78
|
+
const manifestPath = (0, path_1.join)(webappPath, 'manifest.json');
|
|
49
79
|
// Get component app id
|
|
50
80
|
const manifest = fs.readJSON(manifestPath);
|
|
51
81
|
const appProp = 'sap.app';
|
|
52
82
|
const appid = manifest?.[appProp]?.id;
|
|
83
|
+
// Check and update existing services
|
|
84
|
+
await updateExistingServices(webappPath, manifest, fs);
|
|
85
|
+
const modifiedManifest = fs.readJSON(manifestPath);
|
|
53
86
|
// Throw if required property is not found manifest.json
|
|
54
87
|
if (!appid) {
|
|
55
88
|
throw new Error((0, i18n_1.t)('error.requiredProjectPropertyNotFound', { property: `'${appProp}'.id`, path: manifestPath }));
|
|
56
89
|
}
|
|
57
90
|
const manifestJsonExt = fs.read((0, path_1.join)(templateRoot, 'extend', `manifest.json`));
|
|
58
|
-
const manifestSettings = Object.assign(service, getModelSettings((0, project_access_1.getMinimumUI5Version)(
|
|
91
|
+
const manifestSettings = Object.assign(service, getModelSettings((0, project_access_1.getMinimumUI5Version)(modifiedManifest)));
|
|
59
92
|
// If the service object includes ejs options, for example 'client' (see: https://ejs.co/#docs),
|
|
60
93
|
// resulting in unexpected behaviour and problems when webpacking. Passing an empty options object prevents this.
|
|
61
94
|
fs.extendJSON(manifestPath, JSON.parse((0, ejs_1.render)(manifestJsonExt, manifestSettings, {})));
|
|
@@ -71,7 +104,7 @@ function updateManifest(basePath, service, fs, templateRoot) {
|
|
|
71
104
|
*/
|
|
72
105
|
async function updateCdsIndexOrServiceFile(fs, annotations) {
|
|
73
106
|
const dirPath = (0, path_1.join)(annotations.projectName, 'annotations');
|
|
74
|
-
const annotationPath = path_1.
|
|
107
|
+
const annotationPath = (0, path_1.normalize)(dirPath).split(/[\\/]/g).join(path_1.posix.sep);
|
|
75
108
|
const annotationConfig = `\nusing from './${annotationPath}';`;
|
|
76
109
|
// get index and service file paths
|
|
77
110
|
const indexFilePath = (0, path_1.join)(annotations.projectPath, annotations.appPath ?? '', 'index.cds');
|
|
@@ -88,17 +121,25 @@ async function updateCdsIndexOrServiceFile(fs, annotations) {
|
|
|
88
121
|
}
|
|
89
122
|
}
|
|
90
123
|
/**
|
|
91
|
-
* Writes annotation XML files.
|
|
124
|
+
* Writes annotation XML files for EDMX service annotations.
|
|
92
125
|
*
|
|
93
126
|
* @param {Editor} fs - The memfs editor instance.
|
|
94
127
|
* @param {string} basePath - The base path of the project.
|
|
95
|
-
* @param {
|
|
128
|
+
* @param {string} serviceName - Name of The OData service.
|
|
129
|
+
* @param {OdataService} edmxAnnotations - The OData service annotations.
|
|
96
130
|
*/
|
|
97
|
-
function writeAnnotationXmlFiles(fs, basePath,
|
|
131
|
+
function writeAnnotationXmlFiles(fs, basePath, serviceName, edmxAnnotations) {
|
|
98
132
|
// Write annotation xml if annotations are provided and service type is EDMX
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
133
|
+
if (Array.isArray(edmxAnnotations)) {
|
|
134
|
+
for (const annotationName in edmxAnnotations) {
|
|
135
|
+
const annotation = edmxAnnotations[annotationName];
|
|
136
|
+
if (annotation?.xml) {
|
|
137
|
+
fs.write((0, path_1.join)(basePath, 'webapp', 'localService', serviceName, `${annotation.technicalName}.xml`), (0, prettify_xml_1.default)(annotation.xml, { indent: 4 }));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else if (edmxAnnotations?.xml) {
|
|
142
|
+
fs.write((0, path_1.join)(basePath, 'webapp', 'localService', serviceName, `${edmxAnnotations.technicalName}.xml`), (0, prettify_xml_1.default)(edmxAnnotations.xml, { indent: 4 }));
|
|
102
143
|
}
|
|
103
144
|
}
|
|
104
145
|
/**
|
|
@@ -111,10 +152,26 @@ function writeAnnotationXmlFiles(fs, basePath, service) {
|
|
|
111
152
|
* @returns {Promise<void>} A promise that resolves when the cds files have been updated.
|
|
112
153
|
*/
|
|
113
154
|
async function updateCdsFilesWithAnnotations(annotations, fs) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
155
|
+
if (Array.isArray(annotations)) {
|
|
156
|
+
for (const annotationName in annotations) {
|
|
157
|
+
const annotation = annotations[annotationName];
|
|
158
|
+
const annotationCdsPath = (0, path_1.join)(annotation.projectPath, annotation.appPath ?? '', annotation.projectName, 'annotations.cds');
|
|
159
|
+
// write into annotations.cds file
|
|
160
|
+
if (fs.exists(annotationCdsPath)) {
|
|
161
|
+
fs.append(annotationCdsPath, annotation.cdsFileContents);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
fs.write(annotationCdsPath, annotation.cdsFileContents);
|
|
165
|
+
}
|
|
166
|
+
await updateCdsIndexOrServiceFile(fs, annotation);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
const annotationCdsPath = (0, path_1.join)(annotations.projectPath, annotations.appPath ?? '', annotations.projectName, 'annotations.cds');
|
|
171
|
+
// write into annotations.cds file
|
|
172
|
+
fs.write(annotationCdsPath, annotations.cdsFileContents);
|
|
173
|
+
await updateCdsIndexOrServiceFile(fs, annotations);
|
|
174
|
+
}
|
|
118
175
|
}
|
|
119
176
|
/**
|
|
120
177
|
* Determines model settings based on the UI5 version.
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"bugs": {
|
|
10
10
|
"url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Aodata-service-writer"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.24.1",
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"main": "dist/index.js",
|
|
15
15
|
"files": [
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"mem-fs-editor": "9.4.0",
|
|
28
28
|
"prettify-xml": "1.2.0",
|
|
29
29
|
"semver": "7.5.4",
|
|
30
|
-
"@sap-ux/mockserver-config-writer": "0.
|
|
31
|
-
"@sap-ux/ui5-config": "0.
|
|
30
|
+
"@sap-ux/mockserver-config-writer": "0.7.0",
|
|
31
|
+
"@sap-ux/ui5-config": "0.26.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/ejs": "3.1.2",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@types/semver": "7.5.2",
|
|
39
39
|
"fs-extra": "10.0.0",
|
|
40
40
|
"lodash": "4.17.21",
|
|
41
|
-
"@sap-ux/project-access": "1.28.
|
|
41
|
+
"@sap-ux/project-access": "1.28.8"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=18.x"
|
|
@@ -5,22 +5,52 @@
|
|
|
5
5
|
"uri": "<%=path%>",
|
|
6
6
|
"type": "OData",
|
|
7
7
|
"settings": {
|
|
8
|
-
"annotations": [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
"annotations": [
|
|
9
|
+
<% if (locals.annotations && typeof annotations !== 'undefined') { %>
|
|
10
|
+
<% if (annotations.length) { %>
|
|
11
|
+
<% annotations.forEach(function(annotation, index) { %>
|
|
12
|
+
<% if (annotation.technicalName) { %>
|
|
13
|
+
"<%= annotation.name %>"<% if (index < annotations.length - 1) { %>,<% } %>
|
|
14
|
+
<% } %>
|
|
15
|
+
<% }); %>
|
|
16
|
+
<% } else if (annotations.technicalName) { %>
|
|
17
|
+
"<%= annotations.name %>"
|
|
18
|
+
<% } %>
|
|
19
|
+
<% if (locals.localAnnotationsName) {%>,<%}%><% } %>
|
|
20
|
+
<% if (locals.localAnnotationsName) { %>
|
|
21
|
+
"<%- localAnnotationsName %>"
|
|
22
|
+
<% } %>
|
|
23
|
+
]
|
|
24
|
+
<% if (locals.metadata) { %>,
|
|
25
|
+
"localUri": "localService/<%- name %>/metadata.xml" <% } %><%if (version === '4') {%>,
|
|
13
26
|
"odataVersion": "4.0"<% } %><%if (version === '2') {%>,
|
|
14
27
|
"odataVersion": "2.0"<% } %>
|
|
15
28
|
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
}
|
|
30
|
+
<% if (locals.annotations && typeof annotations !== 'undefined') { %>
|
|
31
|
+
<% if (annotations.length && annotations.length > 0) { %>
|
|
32
|
+
<% annotations.forEach(function(annotation, index) { %>
|
|
33
|
+
<% if (annotation.technicalName) { %>,
|
|
34
|
+
"<%= annotation.name %>": {
|
|
35
|
+
"uri": "/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='<%- encodeURIComponent(annotation.technicalName) %>',Version='0001')/$value/",
|
|
36
|
+
"type": "ODataAnnotation",
|
|
37
|
+
"settings": {
|
|
38
|
+
"localUri": "localService/<%- name %>/<%- annotation.technicalName %>.xml"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
<% } %>
|
|
42
|
+
<% }); %>
|
|
43
|
+
<% } else if (annotations.technicalName) { %>,
|
|
44
|
+
"<%= annotations.name %>": {
|
|
45
|
+
"uri": "/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='<%- encodeURIComponent(annotations.technicalName) %>',Version='0001')/$value/",
|
|
46
|
+
"type": "ODataAnnotation",
|
|
47
|
+
"settings": {
|
|
48
|
+
"localUri": "localService/<%- name %>/<%- annotations.technicalName %>.xml"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
<% } %>
|
|
52
|
+
<% } %>
|
|
53
|
+
<% if (locals.localAnnotationsName) { %>,
|
|
24
54
|
"<%- localAnnotationsName %>": {
|
|
25
55
|
"type": "ODataAnnotation",
|
|
26
56
|
"uri": "annotations/<%- localAnnotationsName %>.xml",
|