@sap-ux/adp-tooling 0.12.12 → 0.12.13

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.
@@ -1,4 +1,4 @@
1
- import type { Manifest } from '@sap-ux/project-access';
1
+ import type { Manifest, ManifestNamespace } from '@sap-ux/project-access';
2
2
  import type { ToolsLogger } from '@sap-ux/logger';
3
3
  import type { AdpPreviewConfig } from '../types';
4
4
  /**
@@ -10,4 +10,15 @@ import type { AdpPreviewConfig } from '../types';
10
10
  * @returns {Promise<Manifest>} The manifest.
11
11
  */
12
12
  export declare function getManifest(appId: string, adpConfig: AdpPreviewConfig, logger: ToolsLogger): Promise<Manifest>;
13
+ type DataSources = Record<string, ManifestNamespace.DataSource>;
14
+ /**
15
+ * Returns the adaptation project configuration, throws an error if not found.
16
+ *
17
+ * @param {string} reference - The base application id.
18
+ * @param {AdpPreviewConfig} adpConfig - The adaptation project configuration.
19
+ * @param {ToolsLogger} logger - The logger.
20
+ * @returns {Promise<DataSources>} data sources from base application manifest
21
+ */
22
+ export declare function getManifestDataSources(reference: string, adpConfig: AdpPreviewConfig, logger: ToolsLogger): Promise<DataSources>;
23
+ export {};
13
24
  //# sourceMappingURL=abap.d.ts.map
package/dist/base/abap.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getManifest = void 0;
3
+ exports.getManifestDataSources = exports.getManifest = void 0;
4
4
  const system_access_1 = require("@sap-ux/system-access");
5
5
  const axios_extension_1 = require("@sap-ux/axios-extension");
6
6
  /**
@@ -36,4 +36,21 @@ async function getManifest(appId, adpConfig, logger) {
36
36
  }
37
37
  }
38
38
  exports.getManifest = getManifest;
39
+ /**
40
+ * Returns the adaptation project configuration, throws an error if not found.
41
+ *
42
+ * @param {string} reference - The base application id.
43
+ * @param {AdpPreviewConfig} adpConfig - The adaptation project configuration.
44
+ * @param {ToolsLogger} logger - The logger.
45
+ * @returns {Promise<DataSources>} data sources from base application manifest
46
+ */
47
+ async function getManifestDataSources(reference, adpConfig, logger) {
48
+ const manifest = await exports.getManifest(reference, adpConfig, logger);
49
+ const dataSources = manifest['sap.app'].dataSources;
50
+ if (!dataSources) {
51
+ throw new Error('No data sources found in the manifest');
52
+ }
53
+ return dataSources;
54
+ }
55
+ exports.getManifestDataSources = getManifestDataSources;
39
56
  //# sourceMappingURL=abap.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Check if the project is a CF project.
3
+ *
4
+ * @param {string} basePath - The path to the adaptation project.
5
+ * @returns {boolean} true if the project is a CF project, false otherwise
6
+ */
7
+ export declare function isCFEnvironment(basePath: string): boolean;
8
+ //# sourceMappingURL=cf.d.ts.map
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isCFEnvironment = void 0;
4
+ const path_1 = require("path");
5
+ const fs_1 = require("fs");
6
+ /**
7
+ * Check if the project is a CF project.
8
+ *
9
+ * @param {string} basePath - The path to the adaptation project.
10
+ * @returns {boolean} true if the project is a CF project, false otherwise
11
+ */
12
+ function isCFEnvironment(basePath) {
13
+ const configJsonPath = (0, path_1.join)(basePath, '.adp', 'config.json');
14
+ if ((0, fs_1.existsSync)(configJsonPath)) {
15
+ const config = JSON.parse((0, fs_1.readFileSync)(configJsonPath, 'utf-8'));
16
+ if (config.environment === 'CF') {
17
+ return true;
18
+ }
19
+ }
20
+ return false;
21
+ }
22
+ exports.isCFEnvironment = isCFEnvironment;
23
+ //# sourceMappingURL=cf.js.map
@@ -1,5 +1,5 @@
1
1
  import type { Editor } from 'mem-fs-editor';
2
- import type { AnnotationsData, ChangeType, DescriptorVariant, InboundContent, ManifestChangeProperties, PropertyValueType } from '../types';
2
+ import { type AnnotationsData, type ChangeType, type DescriptorVariant, type InboundContent, type ManifestChangeProperties, type PropertyValueType } from '../types';
3
3
  export type ChangeMetadata = Pick<DescriptorVariant, 'id' | 'layer' | 'namespace'>;
4
4
  type InboundChangeData = {
5
5
  filePath: string;
@@ -12,12 +12,13 @@ interface InboundChange extends ManifestChangeProperties {
12
12
  * Writes annotation changes to the specified project path using the provided `mem-fs-editor` instance.
13
13
  *
14
14
  * @param {string} projectPath - The root path of the project.
15
+ * @param {number} timestamp - The timestamp of the change.
15
16
  * @param {AnnotationsData} data - The data object containing information about the annotation change.
16
17
  * @param {ManifestChangeProperties} change - The annotation data change that will be written.
17
18
  * @param {Editor} fs - The `mem-fs-editor` instance used for file operations.
18
19
  * @returns {void}
19
20
  */
20
- export declare function writeAnnotationChange(projectPath: string, data: AnnotationsData, change: ManifestChangeProperties, fs: Editor): void;
21
+ export declare function writeAnnotationChange(projectPath: string, timestamp: number, data: AnnotationsData, change: ManifestChangeProperties, fs: Editor): void;
21
22
  /**
22
23
  * Writes a given change object to a file within a specified folder in the project's 'changes' directory.
23
24
  * If an additional subdirectory is specified, the change file is written there.
@@ -11,27 +11,28 @@ const project_access_1 = require("@sap-ux/project-access");
11
11
  * Writes annotation changes to the specified project path using the provided `mem-fs-editor` instance.
12
12
  *
13
13
  * @param {string} projectPath - The root path of the project.
14
+ * @param {number} timestamp - The timestamp of the change.
14
15
  * @param {AnnotationsData} data - The data object containing information about the annotation change.
15
16
  * @param {ManifestChangeProperties} change - The annotation data change that will be written.
16
17
  * @param {Editor} fs - The `mem-fs-editor` instance used for file operations.
17
18
  * @returns {void}
18
19
  */
19
- function writeAnnotationChange(projectPath, data, change, fs) {
20
+ function writeAnnotationChange(projectPath, timestamp, data, change, fs) {
20
21
  try {
21
- const { timestamp, annotation } = data;
22
+ const { fileName, answers } = data;
22
23
  const changeFileName = `id_${timestamp}_addAnnotationsToOData.change`;
23
24
  const changesFolderPath = path_1.default.join(projectPath, project_access_1.DirName.Webapp, project_access_1.DirName.Changes);
24
25
  const changeFilePath = path_1.default.join(changesFolderPath, project_access_1.DirName.Manifest, changeFileName);
25
26
  const annotationsFolderPath = path_1.default.join(changesFolderPath, project_access_1.DirName.Annotations);
26
27
  writeChangeToFile(changeFilePath, change, fs);
27
- if (!annotation.filePath) {
28
- fs.write(path_1.default.join(annotationsFolderPath, annotation.fileName ?? ''), '');
28
+ if (!answers.filePath) {
29
+ const annotationsTemplate = path_1.default.join(__dirname, '..', '..', 'templates', 'changes', "annotation.xml" /* TemplateFileName.Annotation */);
30
+ fs.copy(annotationsTemplate, path_1.default.join(annotationsFolderPath, fileName ?? ''));
29
31
  }
30
32
  else {
31
- const { filePath, fileName } = annotation;
32
- const selectedDir = path_1.default.dirname(filePath);
33
+ const selectedDir = path_1.default.dirname(answers.filePath);
33
34
  if (selectedDir !== annotationsFolderPath) {
34
- fs.copy(filePath, path_1.default.join(annotationsFolderPath, fileName ?? ''));
35
+ fs.copy(answers.filePath, path_1.default.join(annotationsFolderPath, fileName ?? ''));
35
36
  }
36
37
  }
37
38
  }
@@ -1,15 +1,17 @@
1
+ import type { DescriptorVariant, AdpPreviewConfig } from '../types';
1
2
  /**
2
- * Checks if the input is a non-empty string.
3
+ * Get the app descriptor variant.
3
4
  *
4
- * @param input - input to check
5
- * @returns true if the input is a non-empty string
5
+ * @param {string} basePath - The path to the adaptation project.
6
+ * @returns {DescriptorVariant} The app descriptor variant.
6
7
  */
7
- export declare function isNotEmptyString(input: string | undefined): boolean;
8
+ export declare function getVariant(basePath: string): DescriptorVariant;
8
9
  /**
9
- * Checks if the input is a valid SAP client.
10
+ * Returns the adaptation project configuration, throws an error if not found.
10
11
  *
11
- * @param input - input to check
12
- * @returns true if the input is a valid SAP client
12
+ * @param {string} basePath - The path to the adaptation project.
13
+ * @param {string} yamlPath - The path to yaml configuration file.
14
+ * @returns {Promise<AdpPreviewConfig>} the adp configuration
13
15
  */
14
- export declare function isValidSapClient(input: string | undefined): boolean;
16
+ export declare function getAdpConfig(basePath: string, yamlPath: string): Promise<AdpPreviewConfig>;
15
17
  //# sourceMappingURL=helper.d.ts.map
@@ -1,24 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isValidSapClient = exports.isNotEmptyString = void 0;
3
+ exports.getAdpConfig = exports.getVariant = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const ui5_config_1 = require("@sap-ux/ui5-config");
4
7
  /**
5
- * Checks if the input is a non-empty string.
8
+ * Get the app descriptor variant.
6
9
  *
7
- * @param input - input to check
8
- * @returns true if the input is a non-empty string
10
+ * @param {string} basePath - The path to the adaptation project.
11
+ * @returns {DescriptorVariant} The app descriptor variant.
9
12
  */
10
- function isNotEmptyString(input) {
11
- return typeof input === 'string' && input.trim().length > 0;
13
+ function getVariant(basePath) {
14
+ return JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(basePath, 'webapp', 'manifest.appdescr_variant'), 'utf-8'));
12
15
  }
13
- exports.isNotEmptyString = isNotEmptyString;
16
+ exports.getVariant = getVariant;
14
17
  /**
15
- * Checks if the input is a valid SAP client.
18
+ * Returns the adaptation project configuration, throws an error if not found.
16
19
  *
17
- * @param input - input to check
18
- * @returns true if the input is a valid SAP client
20
+ * @param {string} basePath - The path to the adaptation project.
21
+ * @param {string} yamlPath - The path to yaml configuration file.
22
+ * @returns {Promise<AdpPreviewConfig>} the adp configuration
19
23
  */
20
- function isValidSapClient(input) {
21
- return !input || (input.length < 4 && !!new RegExp(/^\d*$/).exec(input));
24
+ async function getAdpConfig(basePath, yamlPath) {
25
+ const ui5ConfigPath = (0, path_1.isAbsolute)(yamlPath) ? yamlPath : (0, path_1.join)(basePath, yamlPath);
26
+ const ui5Conf = await ui5_config_1.UI5Config.newInstance((0, fs_1.readFileSync)(ui5ConfigPath, 'utf-8'));
27
+ const customMiddlerware = ui5Conf.findCustomMiddleware('fiori-tools-preview') ??
28
+ ui5Conf.findCustomMiddleware('preview-middleware');
29
+ const adp = customMiddlerware?.configuration?.adp;
30
+ if (!adp) {
31
+ throw new Error('No system configuration found in ui5.yaml');
32
+ }
33
+ return adp;
22
34
  }
23
- exports.isValidSapClient = isValidSapClient;
35
+ exports.getAdpConfig = getAdpConfig;
24
36
  //# sourceMappingURL=helper.js.map
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.promptTarget = exports.promptGeneratorInput = void 0;
7
7
  const prompts_1 = __importDefault(require("prompts"));
8
8
  const system_access_1 = require("@sap-ux/system-access");
9
+ const validators_1 = require("./validators");
9
10
  const uuid_1 = require("uuid");
10
- const helper_1 = require("./helper");
11
11
  const project_utils_1 = require("../writer/project-utils");
12
12
  /**
13
13
  * Prompt the user for the required properties for an adaptation project.
@@ -114,7 +114,7 @@ async function promptTarget(defaults, logger) {
114
114
  name: 'url',
115
115
  message: 'Target system url:',
116
116
  initial: target.url,
117
- validate: helper_1.isNotEmptyString,
117
+ validate: validators_1.isNotEmptyString,
118
118
  format: (input) => input.trim()
119
119
  },
120
120
  {
@@ -122,7 +122,7 @@ async function promptTarget(defaults, logger) {
122
122
  name: 'client',
123
123
  message: 'Client (optional):',
124
124
  initial: target.client,
125
- validate: helper_1.isValidSapClient
125
+ validate: validators_1.isValidSapClient
126
126
  }
127
127
  ]);
128
128
  const systemInfo = await fetchSystemInformation(target, defaults.ignoreCertErrors, logger);
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Checks if the input is a non-empty string.
3
+ *
4
+ * @param input - input to check
5
+ * @returns true if the input is a non-empty string
6
+ */
7
+ export declare function isNotEmptyString(input: string | undefined): boolean;
8
+ /**
9
+ * Checks if the input is a valid SAP client.
10
+ *
11
+ * @param input - input to check
12
+ * @returns true if the input is a valid SAP client
13
+ */
14
+ export declare function isValidSapClient(input: string | undefined): boolean;
15
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidSapClient = exports.isNotEmptyString = void 0;
4
+ /**
5
+ * Checks if the input is a non-empty string.
6
+ *
7
+ * @param input - input to check
8
+ * @returns true if the input is a non-empty string
9
+ */
10
+ function isNotEmptyString(input) {
11
+ return typeof input === 'string' && input.trim().length > 0;
12
+ }
13
+ exports.isNotEmptyString = isNotEmptyString;
14
+ /**
15
+ * Checks if the input is a valid SAP client.
16
+ *
17
+ * @param input - input to check
18
+ * @returns true if the input is a valid SAP client
19
+ */
20
+ function isValidSapClient(input) {
21
+ return !input || (input.length < 4 && !!new RegExp(/^\d*$/).exec(input));
22
+ }
23
+ exports.isValidSapClient = isValidSapClient;
24
+ //# sourceMappingURL=validators.js.map
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  export * from './types';
2
2
  export * from './prompts';
3
3
  export * from './preview/adp-preview';
4
+ export * from './base/helper';
5
+ export * from './base/validators';
6
+ export * from './base/abap';
4
7
  export { generate, migrate } from './writer';
5
8
  export { generateChange } from './writer/editors';
6
9
  export { promptGeneratorInput, PromptDefaults } from './base/prompt';
7
- export { getManifest } from './base/abap';
10
+ export { isCFEnvironment } from './base/cf';
8
11
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -14,10 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getManifest = exports.promptGeneratorInput = exports.generateChange = exports.migrate = exports.generate = void 0;
17
+ exports.isCFEnvironment = exports.promptGeneratorInput = exports.generateChange = exports.migrate = exports.generate = void 0;
18
18
  __exportStar(require("./types"), exports);
19
19
  __exportStar(require("./prompts"), exports);
20
20
  __exportStar(require("./preview/adp-preview"), exports);
21
+ __exportStar(require("./base/helper"), exports);
22
+ __exportStar(require("./base/validators"), exports);
23
+ __exportStar(require("./base/abap"), exports);
21
24
  var writer_1 = require("./writer");
22
25
  Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return writer_1.generate; } });
23
26
  Object.defineProperty(exports, "migrate", { enumerable: true, get: function () { return writer_1.migrate; } });
@@ -25,6 +28,6 @@ var editors_1 = require("./writer/editors");
25
28
  Object.defineProperty(exports, "generateChange", { enumerable: true, get: function () { return editors_1.generateChange; } });
26
29
  var prompt_1 = require("./base/prompt");
27
30
  Object.defineProperty(exports, "promptGeneratorInput", { enumerable: true, get: function () { return prompt_1.promptGeneratorInput; } });
28
- var abap_1 = require("./base/abap");
29
- Object.defineProperty(exports, "getManifest", { enumerable: true, get: function () { return abap_1.getManifest; } });
31
+ var cf_1 = require("./base/cf");
32
+ Object.defineProperty(exports, "isCFEnvironment", { enumerable: true, get: function () { return cf_1.isCFEnvironment; } });
30
33
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,12 @@
1
+ import type { YUIQuestion } from '@sap-ux/inquirer-common';
2
+ import type { ManifestNamespace } from '@sap-ux/project-access';
3
+ import { type AddAnnotationsAnswers } from '../../types';
4
+ /**
5
+ * Gets the prompts for adding annotations to OData service.
6
+ *
7
+ * @param {string} basePath - The base path of the project.
8
+ * @param {Record<string, ManifestNamespace.DataSource>} dataSources - Data sources from the manifest.
9
+ * @returns {YUIQuestion<AddAnnotationsAnswers>[]} The questions/prompts.
10
+ */
11
+ export declare function getPrompts(basePath: string, dataSources: Record<string, ManifestNamespace.DataSource>): YUIQuestion<AddAnnotationsAnswers>[];
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPrompts = void 0;
4
+ const i18n_1 = require("../../i18n");
5
+ const project_access_1 = require("@sap-ux/project-access");
6
+ const fs_1 = require("fs");
7
+ const validators_1 = require("../../base/validators");
8
+ const path_1 = require("path");
9
+ /**
10
+ * Gets the prompts for adding annotations to OData service.
11
+ *
12
+ * @param {string} basePath - The base path of the project.
13
+ * @param {Record<string, ManifestNamespace.DataSource>} dataSources - Data sources from the manifest.
14
+ * @returns {YUIQuestion<AddAnnotationsAnswers>[]} The questions/prompts.
15
+ */
16
+ function getPrompts(basePath, dataSources) {
17
+ const dataSourceIds = Object.keys((0, project_access_1.filterDataSourcesByType)(dataSources, 'OData'));
18
+ const annotationFileSelectOptions = [
19
+ { name: (0, i18n_1.t)('choices.annotationFile.selectFromWorkspace'), value: 1 /* AnnotationFileSelectType.ExistingFile */ },
20
+ { name: (0, i18n_1.t)('choices.annotationFile.createEmptyFile'), value: 2 /* AnnotationFileSelectType.NewEmptyFile */ }
21
+ ];
22
+ return [
23
+ {
24
+ type: 'list',
25
+ name: 'id',
26
+ message: (0, i18n_1.t)('prompts.oDataSourceLabel'),
27
+ choices: dataSourceIds,
28
+ default: dataSourceIds[0],
29
+ store: false,
30
+ guiOptions: {
31
+ mandatory: true,
32
+ hint: (0, i18n_1.t)('prompts.addAnnotationOdataSourceTooltip')
33
+ }
34
+ },
35
+ {
36
+ type: 'list',
37
+ name: 'fileSelectOption',
38
+ message: (0, i18n_1.t)('prompts.fileSelectOptionLabel'),
39
+ choices: annotationFileSelectOptions,
40
+ default: 0,
41
+ guiOptions: {
42
+ mandatory: true,
43
+ hint: (0, i18n_1.t)('prompts.fileSelectOptionTooltip')
44
+ },
45
+ when: (answers) => answers.id !== ''
46
+ },
47
+ {
48
+ type: 'input',
49
+ name: 'filePath',
50
+ message: (0, i18n_1.t)('prompts.filePathLabel'),
51
+ guiType: 'file-browser',
52
+ guiOptions: {
53
+ mandatory: true,
54
+ hint: (0, i18n_1.t)('prompts.filePathTooltip')
55
+ },
56
+ default: '',
57
+ when: (answers) => answers.id !== '' && answers.fileSelectOption === 1 /* AnnotationFileSelectType.ExistingFile */,
58
+ validate: (value) => {
59
+ if (!(0, validators_1.isNotEmptyString)(value)) {
60
+ return (0, i18n_1.t)('validators.inputCannotBeEmpty');
61
+ }
62
+ const filePath = (0, path_1.isAbsolute)(value) ? value : (0, path_1.join)(basePath, value);
63
+ if (!(0, fs_1.existsSync)(filePath)) {
64
+ return (0, i18n_1.t)('validators.fileDoesNotExist');
65
+ }
66
+ const fileName = filePath.split(path_1.sep).pop();
67
+ if ((0, fs_1.existsSync)((0, path_1.join)(basePath, 'webapp', 'changes', 'annotations', fileName))) {
68
+ return (0, i18n_1.t)('validators.annotationFileAlreadyExists');
69
+ }
70
+ return true;
71
+ }
72
+ }
73
+ ];
74
+ }
75
+ exports.getPrompts = getPrompts;
76
+ //# sourceMappingURL=index.js.map
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPrompts = void 0;
4
4
  const i18n_1 = require("../../i18n");
5
5
  const project_access_1 = require("@sap-ux/project-access");
6
- const helper_1 = require("../../base/helper");
6
+ const validators_1 = require("../../base/validators");
7
7
  /**
8
8
  * Gets the prompts for changing the data source.
9
9
  *
@@ -33,7 +33,7 @@ function getPrompts(dataSources) {
33
33
  mandatory: true,
34
34
  hint: (0, i18n_1.t)('prompts.oDataSourceURITooltip')
35
35
  },
36
- validate: helper_1.isNotEmptyString,
36
+ validate: validators_1.isNotEmptyString,
37
37
  when: !!dataSourceIds.length,
38
38
  store: false
39
39
  },
@@ -1,2 +1,3 @@
1
1
  export { getPrompts as getPromptsForChangeDataSource } from './change-data-source';
2
+ export { getPrompts as getPromptsForAddAnnotationsToOData } from './add-annotations-to-odata';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPromptsForChangeDataSource = void 0;
3
+ exports.getPromptsForAddAnnotationsToOData = exports.getPromptsForChangeDataSource = void 0;
4
4
  var change_data_source_1 = require("./change-data-source");
5
5
  Object.defineProperty(exports, "getPromptsForChangeDataSource", { enumerable: true, get: function () { return change_data_source_1.getPrompts; } });
6
+ var add_annotations_to_odata_1 = require("./add-annotations-to-odata");
7
+ Object.defineProperty(exports, "getPromptsForAddAnnotationsToOData", { enumerable: true, get: function () { return add_annotations_to_odata_1.getPrompts; } });
6
8
  //# sourceMappingURL=index.js.map
@@ -8,13 +8,21 @@
8
8
  "maxAgeTooltip": "(Optional) Enter the time in seconds it takes for a cached response of the service to expire.",
9
9
  "oDataAnnotationSourceURILabel": "OData Annotation Data Source URI",
10
10
  "oDataAnnotationSourceURITooltip": "Server side annotations have been detected for the selected OData service. If needed, enter new annotation data source URI for the changed service",
11
- "oDataURIInfoLabel": "Have in mind that common OData Service path prefixes are '{{- v2Prefix}}' or '{{- v4Prefix}}'",
12
- "isInSafeModeLabel": "Making manifest changes is not upgrade safe and the project will be set in advanced mode. Please continue if you are sure you want to have your project in advanced mode.",
13
- "oDataURIV2InfoLabel": "Have in mind that you are trying to replace OData {{versionOne}} Service with OData {{versionTwo}} Service"
11
+ "addAnnotationOdataSourceTooltip": "Select the annotation file from your workspace",
12
+ "fileSelectOptionLabel": "Annotation XML",
13
+ "fileSelectOptionTooltip": "Select the annotation file source",
14
+ "filePathLabel": "Annotation File path",
15
+ "filePathTooltip": "Select the annotation file from your workspace"
16
+ },
17
+ "choices": {
18
+ "annotationFile": {
19
+ "selectFromWorkspace": "Select annotation file from workspace",
20
+ "createEmptyFile": "Create an empty annotation file"
21
+ }
14
22
  },
15
23
  "validators": {
16
- "manifestContainsNoODataServices": "Manifest contains no OData Services.",
17
- "inputCannotBeEmpty": "{{input}} cannot be empty.",
18
- "inpuCannotHaveSpaces": "{{input}} cannot contain spaces."
24
+ "inputCannotBeEmpty": "Input cannot be empty.",
25
+ "fileDoesNotExist": "The file doesn't exist",
26
+ "annotationFileAlreadyExists": "There is already an annotation file with the same name, please choose another file or rename the file and select it again"
19
27
  }
20
28
  }
package/dist/types.d.ts CHANGED
@@ -172,9 +172,11 @@ export interface CodeExtChange extends CommonChangeProperties {
172
172
  controllerName: string;
173
173
  };
174
174
  }
175
+ export declare const CUSTOMER_BASE = "CUSTOMER_BASE";
175
176
  export declare const enum TemplateFileName {
176
177
  Fragment = "fragment.xml",
177
- Controller = "controller.ejs"
178
+ Controller = "controller.ejs",
179
+ Annotation = "annotation.xml"
178
180
  }
179
181
  export declare const enum HttpStatusCodes {
180
182
  OK = 200,
@@ -238,18 +240,13 @@ export declare const enum ChangeType {
238
240
  */
239
241
  export type GeneratorData<T extends ChangeType> = T extends ChangeType.ADD_ANNOTATIONS_TO_ODATA ? AnnotationsData : T extends ChangeType.ADD_COMPONENT_USAGES ? ComponentUsagesData : T extends ChangeType.ADD_LIBRARY_REFERENCE ? ComponentUsagesData : T extends ChangeType.ADD_NEW_MODEL ? NewModelData : T extends ChangeType.CHANGE_DATA_SOURCE ? DataSourceData : T extends ChangeType.CHANGE_INBOUND ? InboundData : never;
240
242
  export interface AnnotationsData {
241
- projectData: AdpProjectData;
242
- timestamp: number;
243
- /** Indicates whether the annotation is for internal use only. */
244
- isInternalUsage: boolean;
245
- annotation: {
246
- /** Optional name of the annotation file. */
247
- fileName?: string;
248
- /** Data source associated with the annotation. */
249
- dataSource: string;
250
- /** Path to the annotation file. */
251
- filePath: string;
252
- };
243
+ fileName?: string;
244
+ variant: DescriptorVariant;
245
+ answers: AddAnnotationsAnswers;
246
+ }
247
+ export declare const enum AnnotationFileSelectType {
248
+ ExistingFile = 1,
249
+ NewEmptyFile = 2
253
250
  }
254
251
  export interface ComponentUsagesData {
255
252
  projectData: AdpProjectData;
@@ -359,6 +356,14 @@ export interface ChangeDataSourceAnswers {
359
356
  /** Data Source Annotation URI */
360
357
  annotationUri?: string;
361
358
  }
359
+ export interface AddAnnotationsAnswers {
360
+ /** Data Source identifier */
361
+ id: string;
362
+ /** Selected option for Annotation File */
363
+ fileSelectOption: number;
364
+ /** Annotation File path */
365
+ filePath?: string;
366
+ }
362
367
  export type DataSource = ManifestNamespace.DataSource & {
363
368
  dataSourceName: string;
364
369
  annotations: string[];
package/dist/types.js CHANGED
@@ -1,3 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CUSTOMER_BASE = void 0;
4
+ exports.CUSTOMER_BASE = 'CUSTOMER_BASE';
3
5
  //# sourceMappingURL=types.js.map
@@ -1,5 +1,5 @@
1
1
  import type { Editor } from 'mem-fs-editor';
2
- import type { IWriter, AnnotationsData } from '../../../types';
2
+ import { type IWriter, type AnnotationsData } from '../../../types';
3
3
  /**
4
4
  * Handles the creation and writing of annotations data changes for a project.
5
5
  */
@@ -1,10 +1,31 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
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;
4
24
  };
5
25
  Object.defineProperty(exports, "__esModule", { value: true });
6
26
  exports.AnnotationsWriter = void 0;
7
- const path_1 = __importDefault(require("path"));
27
+ const path_1 = __importStar(require("path"));
28
+ const types_1 = require("../../../types");
8
29
  const change_utils_1 = require("../../../base/change-utils");
9
30
  /**
10
31
  * Handles the creation and writing of annotations data changes for a project.
@@ -27,13 +48,13 @@ class AnnotationsWriter {
27
48
  * @returns {object} The constructed content object for the annotation change.
28
49
  */
29
50
  constructContent(data) {
30
- const { isInternalUsage, annotation: { dataSource, fileName } } = data;
51
+ const { variant: { layer }, fileName, answers: { id } } = data;
31
52
  const annotationFileNameWithoutExtension = fileName?.toLocaleLowerCase().replace('.xml', '');
32
- const annotationNameSpace = isInternalUsage
33
- ? `annotation.${annotationFileNameWithoutExtension}`
34
- : `customer.annotation.${annotationFileNameWithoutExtension}`;
53
+ const annotationNameSpace = layer === types_1.CUSTOMER_BASE
54
+ ? `customer.annotation.${annotationFileNameWithoutExtension}`
55
+ : `annotation.${annotationFileNameWithoutExtension}`;
35
56
  return {
36
- dataSourceId: `${dataSource}`,
57
+ dataSourceId: `${id}`,
37
58
  annotations: [annotationNameSpace],
38
59
  annotationsInsertPosition: 'END',
39
60
  dataSource: {
@@ -50,8 +71,8 @@ class AnnotationsWriter {
50
71
  * @param {AnnotationsData} data - The answers object containing user choices.
51
72
  * @returns {string | undefined} The determined filename for the annotation file.
52
73
  */
53
- getAnnotationFileName({ annotation }) {
54
- return annotation.filePath ? path_1.default.basename(annotation.filePath) : `annotation_${Date.now()}.xml`;
74
+ getAnnotationFileName({ answers }) {
75
+ return answers.filePath ? path_1.default.basename(answers.filePath) : `annotation_${Date.now()}.xml`;
55
76
  }
56
77
  /**
57
78
  * Writes the annotation change to the project based on the provided data.
@@ -60,10 +81,17 @@ class AnnotationsWriter {
60
81
  * @returns {Promise<void>} A promise that resolves when the change writing process is completed.
61
82
  */
62
83
  async write(data) {
63
- data.annotation.fileName = this.getAnnotationFileName(data);
84
+ const { variant } = data;
85
+ data.fileName = this.getAnnotationFileName(data);
86
+ if (data.answers.filePath) {
87
+ data.answers.filePath = (0, path_1.isAbsolute)(data.answers.filePath)
88
+ ? data.answers.filePath
89
+ : path_1.default.join(this.projectPath, data.answers.filePath);
90
+ }
64
91
  const content = this.constructContent(data);
65
- const change = (0, change_utils_1.getChange)(data.projectData, data.timestamp, content, "appdescr_app_addAnnotationsToOData" /* ChangeType.ADD_ANNOTATIONS_TO_ODATA */);
66
- (0, change_utils_1.writeAnnotationChange)(this.projectPath, data, change, this.fs);
92
+ const timestamp = Date.now();
93
+ const change = (0, change_utils_1.getChange)(variant, timestamp, content, "appdescr_app_addAnnotationsToOData" /* ChangeType.ADD_ANNOTATIONS_TO_ODATA */);
94
+ (0, change_utils_1.writeAnnotationChange)(this.projectPath, timestamp, data, change, this.fs);
67
95
  }
68
96
  }
69
97
  exports.AnnotationsWriter = AnnotationsWriter;
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%3Aadp-tooling"
11
11
  },
12
- "version": "0.12.12",
12
+ "version": "0.12.13",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -0,0 +1,15 @@
1
+ <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
2
+ <edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Common.xml">
3
+ <edmx:Include Namespace="com.sap.vocabularies.Common.v1" Alias="Common"/>
4
+ </edmx:Reference>
5
+ <edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/UI.xml">
6
+ <edmx:Include Namespace="com.sap.vocabularies.UI.v1" Alias="UI"/>
7
+ </edmx:Reference>
8
+ <edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Communication.xml">
9
+ <edmx:Include Namespace="com.sap.vocabularies.Communication.v1" Alias="Communication"/>
10
+ </edmx:Reference>
11
+ <edmx:DataServices>
12
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="local">
13
+ </Schema>
14
+ </edmx:DataServices>
15
+ </edmx:Edmx>