@sap-ux/cf-deploy-config-writer 0.3.91 → 0.3.93

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.
@@ -8,10 +8,10 @@ const mem_fs_1 = require("mem-fs");
8
8
  const mem_fs_editor_1 = require("mem-fs-editor");
9
9
  const utils_1 = require("../utils");
10
10
  const mta_config_1 = require("../mta-config");
11
+ const wait_for_mta_1 = require("../mta-config/wait-for-mta");
11
12
  const logger_helper_1 = __importDefault(require("../logger-helper"));
12
13
  const i18n_1 = require("../i18n");
13
14
  const project_access_1 = require("@sap-ux/project-access");
14
- const constants_1 = require("../constants");
15
15
  /**
16
16
  * Add a standalone | managed approuter to a CAP project.
17
17
  *
@@ -30,8 +30,8 @@ async function generateCAPConfig(config, fs, logger) {
30
30
  logger?.debug(`Generate CAP configuration using: \n ${JSON.stringify(config)}`);
31
31
  await validateConfig(config);
32
32
  await (0, mta_config_1.generateCAPMTA)(config, fs);
33
- // Delay to ensure MTA file write completes before subsequent read operations
34
- await new Promise((resolve) => setTimeout(resolve, constants_1.MTA_FILE_OPERATION_DELAY_MS));
33
+ // Wait until mta.yaml is readable by mta-lib before proceeding
34
+ await (0, wait_for_mta_1.waitForMtaFile)(config.mtaPath);
35
35
  await (0, mta_config_1.addRoutingConfig)(config, fs);
36
36
  await (0, utils_1.updateRootPackage)({ mtaId: config.mtaId, rootPath: config.mtaPath }, fs);
37
37
  logger_helper_1.default.logger?.debug((0, i18n_1.t)('debug.capGenerationCompleted'));
@@ -10,7 +10,8 @@ import { type Editor } from 'mem-fs-editor';
10
10
  export declare function getMtaId(rootPath: string): Promise<string | undefined>;
11
11
  /**
12
12
  * Get the MTA configuration from the target folder.
13
- * Retries up to 5 times with delays to handle file system timing issues.
13
+ * Waits for mta.yaml to be fully written and parseable before reading,
14
+ * replacing the previous retry-with-delay approach.
14
15
  *
15
16
  * @param rootPath Path to the root folder
16
17
  * @returns MtaConfig instance if found
@@ -32,6 +32,7 @@ const ejs_1 = require("ejs");
32
32
  const mta_1 = require("./mta");
33
33
  const utils_1 = require("../utils");
34
34
  const constants_1 = require("../constants");
35
+ const wait_for_mta_1 = require("./wait-for-mta");
35
36
  const types_1 = require("../types");
36
37
  const logger_helper_1 = __importDefault(require("../logger-helper"));
37
38
  const hasbin_1 = require("hasbin");
@@ -49,27 +50,22 @@ async function getMtaId(rootPath) {
49
50
  }
50
51
  /**
51
52
  * Get the MTA configuration from the target folder.
52
- * Retries up to 5 times with delays to handle file system timing issues.
53
+ * Waits for mta.yaml to be fully written and parseable before reading,
54
+ * replacing the previous retry-with-delay approach.
53
55
  *
54
56
  * @param rootPath Path to the root folder
55
57
  * @returns MtaConfig instance if found
56
58
  */
57
59
  async function getMtaConfig(rootPath) {
58
- let mtaConfig;
59
- const MAX_RETRIES = 5;
60
- for (let retries = MAX_RETRIES; retries >= 0; retries--) {
61
- try {
62
- mtaConfig = await mta_1.MtaConfig.newInstance(rootPath, logger_helper_1.default.logger);
63
- if (mtaConfig?.prefix) {
64
- break;
65
- }
66
- }
67
- catch (error) {
68
- logger_helper_1.default.logger?.debug((0, i18n_1.t)('debug.errorReadingMta', { error: error.message }));
69
- // Delay before retry to allow file system operations to complete
70
- await new Promise((resolve) => setTimeout(resolve, constants_1.MTA_FILE_OPERATION_DELAY_MS));
71
- }
60
+ try {
61
+ await (0, wait_for_mta_1.waitForMtaFile)(rootPath);
62
+ }
63
+ catch {
64
+ // File did not become ready — return undefined (same behaviour as before)
65
+ logger_helper_1.default.logger?.debug((0, i18n_1.t)('debug.mtaReadWithPrefix', { prefix: undefined }));
66
+ return undefined;
72
67
  }
68
+ const mtaConfig = await mta_1.MtaConfig.newInstance(rootPath, logger_helper_1.default.logger);
73
69
  logger_helper_1.default.logger?.debug((0, i18n_1.t)('debug.mtaReadWithPrefix', { prefix: mtaConfig?.prefix }));
74
70
  return mtaConfig;
75
71
  }
@@ -161,8 +161,10 @@ class MtaConfig {
161
161
  name: `${this.prefix?.slice(0, constants_1.MAX_MTA_PREFIX_LENGTH)}-uaa`,
162
162
  type: 'org.cloudfoundry.managed-service',
163
163
  parameters: {
164
- 'service-plan': 'application',
165
164
  service: 'xsuaa',
165
+ 'service-plan': 'application',
166
+ path: './xs-security.json',
167
+ 'service-name': `${this.prefix?.slice(0, constants_1.MAX_MTA_PREFIX_LENGTH)}-xsuaa-service`,
166
168
  config: {
167
169
  xsappname: `${this.prefix?.slice(0, constants_1.MAX_MTA_PREFIX_LENGTH)}` + '-${space-guid}',
168
170
  'tenant-mode': 'dedicated'
@@ -0,0 +1,17 @@
1
+ export interface WaitForMtaOptions {
2
+ /** Maximum time to wait in milliseconds. Default: 5000 */
3
+ maxWaitMs?: number;
4
+ /** Polling interval in milliseconds. Default: 100 */
5
+ pollIntervalMs?: number;
6
+ }
7
+ /**
8
+ * Waits until mta.yaml exists on disk and is readable by mta-lib.
9
+ * Replaces hardcoded setTimeout delays used to work around mta-lib requiring
10
+ * files to be fully written before they can be read.
11
+ *
12
+ * @param mtaPath Directory containing (or that will contain) mta.yaml
13
+ * @param options Polling configuration
14
+ * @throws {Error} If the file is not ready within maxWaitMs
15
+ */
16
+ export declare function waitForMtaFile(mtaPath: string, options?: WaitForMtaOptions): Promise<void>;
17
+ //# sourceMappingURL=wait-for-mta.d.ts.map
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.waitForMtaFile = waitForMtaFile;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const mta_lib_1 = require("@sap/mta-lib");
7
+ const project_access_1 = require("@sap-ux/project-access");
8
+ const i18n_1 = require("../i18n");
9
+ /**
10
+ * Waits until mta.yaml exists on disk and is readable by mta-lib.
11
+ * Replaces hardcoded setTimeout delays used to work around mta-lib requiring
12
+ * files to be fully written before they can be read.
13
+ *
14
+ * @param mtaPath Directory containing (or that will contain) mta.yaml
15
+ * @param options Polling configuration
16
+ * @throws {Error} If the file is not ready within maxWaitMs
17
+ */
18
+ async function waitForMtaFile(mtaPath, options = {}) {
19
+ const { maxWaitMs = 5000, pollIntervalMs = 100 } = options;
20
+ const mtaFilePath = (0, node_path_1.join)(mtaPath, project_access_1.FileName.MtaYaml);
21
+ const deadline = Date.now() + maxWaitMs;
22
+ while (Date.now() < deadline) {
23
+ if ((0, node_fs_1.existsSync)(mtaFilePath)) {
24
+ try {
25
+ const mta = new mta_lib_1.Mta(mtaPath, false);
26
+ const id = await mta.getMtaID();
27
+ if (id) {
28
+ return;
29
+ }
30
+ }
31
+ catch {
32
+ // File exists but not yet parseable — keep polling
33
+ }
34
+ }
35
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
36
+ }
37
+ throw new Error((0, i18n_1.t)('error.mtaFileNotReady', { mtaPath }));
38
+ }
39
+ //# sourceMappingURL=wait-for-mta.js.map
@@ -38,7 +38,8 @@
38
38
  "doesNotContainACapApp": "The target folder does not contain a Node.js CAP project. Please ensure the folder contains a Node.js CAP project.",
39
39
  "errorInstallingNodeModules": "An error occurred when installing node modules. Please check the logs.",
40
40
  "errorGeneratingMtaYaml": "An error occurred when creating the mta.yaml file. For more information, check the logs.",
41
- "noUI5AppFound": "No SAPUI5 application found. Please ensure the manifest.json file contains a valid 'sap.app.id'."
41
+ "noUI5AppFound": "No SAPUI5 application found. Please ensure the manifest.json file contains a valid 'sap.app.id'.",
42
+ "mtaFileNotReady": "The `mta.yaml` file in '{{- mtaPath}}' was not ready within the allowed time. Please check the file system and retry."
42
43
  },
43
44
  "info": {
44
45
  "existingMTAExtensionNotFound": "Cannot find a valid existing MTA extension file. A new one will be created. Error: {{- error}}.",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sap-ux/cf-deploy-config-writer",
3
3
  "description": "Add or amend Cloud Foundry and ABAP deployment configuration for SAP projects",
4
- "version": "0.3.91",
4
+ "version": "0.3.93",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -29,12 +29,12 @@
29
29
  "mem-fs": "2.1.0",
30
30
  "mem-fs-editor": "9.4.0",
31
31
  "hasbin": "1.2.3",
32
- "@sap-ux/project-access": "1.35.18",
33
32
  "@sap-ux/yaml": "0.17.6",
34
33
  "@sap-ux/btp-utils": "1.1.12",
35
34
  "@sap-ux/logger": "0.8.4",
36
35
  "@sap-ux/ui5-config": "0.30.1",
37
- "@sap-ux/nodejs-utils": "0.2.19"
36
+ "@sap-ux/nodejs-utils": "0.2.19",
37
+ "@sap-ux/project-access": "1.35.18"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/ejs": "3.1.5",