@sap-ux/odata-service-inquirer 0.1.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/LICENSE +201 -0
- package/README.md +87 -0
- package/dist/error-handler/error-handler.d.ts +176 -0
- package/dist/error-handler/error-handler.js +450 -0
- package/dist/error-handler/help/help-topics.d.ts +37 -0
- package/dist/error-handler/help/help-topics.js +40 -0
- package/dist/error-handler/help/images/guidedAnswersIcon_svg_base64.d.ts +2 -0
- package/dist/error-handler/help/images/guidedAnswersIcon_svg_base64.js +5 -0
- package/dist/error-handler/help/images/index.d.ts +2 -0
- package/dist/error-handler/help/images/index.js +18 -0
- package/dist/i18n.d.ts +15 -0
- package/dist/i18n.js +50 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +73 -0
- package/dist/prompts/datasources/cap-project/cap-helpers.d.ts +26 -0
- package/dist/prompts/datasources/cap-project/cap-helpers.js +215 -0
- package/dist/prompts/datasources/cap-project/questions.d.ts +14 -0
- package/dist/prompts/datasources/cap-project/questions.js +172 -0
- package/dist/prompts/datasources/cap-project/types.d.ts +27 -0
- package/dist/prompts/datasources/cap-project/types.js +12 -0
- package/dist/prompts/datasources/cap-project/validators.d.ts +8 -0
- package/dist/prompts/datasources/cap-project/validators.js +35 -0
- package/dist/prompts/datasources/metadata-file/index.d.ts +10 -0
- package/dist/prompts/datasources/metadata-file/index.js +47 -0
- package/dist/prompts/datasources/metadata-file/validators.d.ts +13 -0
- package/dist/prompts/datasources/metadata-file/validators.js +45 -0
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.js +18 -0
- package/dist/prompts/logger-helper.d.ts +20 -0
- package/dist/prompts/logger-helper.js +27 -0
- package/dist/prompts/prompt-helpers.d.ts +14 -0
- package/dist/prompts/prompt-helpers.js +44 -0
- package/dist/prompts/prompts.d.ts +9 -0
- package/dist/prompts/prompts.js +98 -0
- package/dist/prompts/validators.d.ts +13 -0
- package/dist/prompts/validators.js +45 -0
- package/dist/translations/odata-service-inquirer.i18n.json +88 -0
- package/dist/types.d.ts +176 -0
- package/dist/types.js +76 -0
- package/dist/utils/index.d.ts +26 -0
- package/dist/utils/index.js +70 -0
- package/dist/utils/prompt-state.d.ts +13 -0
- package/dist/utils/prompt-state.js +18 -0
- package/package.json +55 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type InquirerAdapter } from '@sap-ux/inquirer-common';
|
|
2
|
+
import { type Logger } from '@sap-ux/logger';
|
|
3
|
+
import { OdataVersion } from '@sap-ux/odata-service-writer';
|
|
4
|
+
import { type ToolsSuiteTelemetryClient } from '@sap-ux/telemetry';
|
|
5
|
+
import { DatasourceType, promptNames, type CapRuntime, type CapService, type OdataServiceAnswers, type OdataServicePromptOptions, type OdataServiceQuestion } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Get the inquirer prompts for odata service.
|
|
8
|
+
*
|
|
9
|
+
* @param promptOptions - options that can control some of the prompt behavior. See {@link OdataServicePromptOptions} for details
|
|
10
|
+
* @param logger - a logger compatible with the {@link Logger} interface
|
|
11
|
+
* @param enableGuidedAnswers - if true, the prompts will use guided answers to help users with validation errors
|
|
12
|
+
* @param telemetryClient - the telemetry client to use for sending telemetry data
|
|
13
|
+
* @param isYUI - if true, the prompt is being called from the Yeoman UI extension host
|
|
14
|
+
* @returns the prompts used to provide input for odata service generation and a reference to the answers object which will be populated with the user's responses once `inquirer.prompt` returns
|
|
15
|
+
*/
|
|
16
|
+
declare function getPrompts(promptOptions?: OdataServicePromptOptions, logger?: Logger, enableGuidedAnswers?: boolean, telemetryClient?: ToolsSuiteTelemetryClient, isYUI?: boolean): Promise<{
|
|
17
|
+
prompts: OdataServiceQuestion[];
|
|
18
|
+
answers: {
|
|
19
|
+
odataService: Partial<OdataServiceAnswers>;
|
|
20
|
+
};
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Prompt for odata service writer inputs.
|
|
24
|
+
*
|
|
25
|
+
* @param adapter - optionally provide references to a calling inquirer instance, this supports integration to Yeoman generators, for example
|
|
26
|
+
* @param promptOptions - options that can control some of the prompt behavior. See {@link OdataServicePromptOptions} for details
|
|
27
|
+
* @param logger - a logger compatible with the {@link Logger} interface
|
|
28
|
+
* @param enableGuidedAnswers - if true, the prompts will use guided answers to help users with validation errors
|
|
29
|
+
* @param telemetryClient - the telemetry client to use for sending telemetry data
|
|
30
|
+
* @param isYUI - if true, the prompt is being called from the Yeoman UI extension host
|
|
31
|
+
* @returns the prompt answers
|
|
32
|
+
*/
|
|
33
|
+
declare function prompt(adapter: InquirerAdapter, promptOptions?: OdataServicePromptOptions, logger?: Logger, enableGuidedAnswers?: boolean, telemetryClient?: ToolsSuiteTelemetryClient, isYUI?: boolean): Promise<OdataServiceAnswers>;
|
|
34
|
+
export { DatasourceType, OdataVersion, getPrompts, prompt, promptNames, type CapRuntime, type CapService, type InquirerAdapter, type OdataServiceAnswers, type OdataServicePromptOptions };
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.promptNames = exports.prompt = exports.getPrompts = exports.OdataVersion = exports.DatasourceType = void 0;
|
|
16
|
+
const logger_1 = require("@sap-ux/logger");
|
|
17
|
+
const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
|
|
18
|
+
Object.defineProperty(exports, "OdataVersion", { enumerable: true, get: function () { return odata_service_writer_1.OdataVersion; } });
|
|
19
|
+
const error_handler_1 = require("./error-handler/error-handler");
|
|
20
|
+
const prompts_1 = require("./prompts");
|
|
21
|
+
const logger_helper_1 = __importDefault(require("./prompts/logger-helper"));
|
|
22
|
+
const types_1 = require("./types");
|
|
23
|
+
Object.defineProperty(exports, "DatasourceType", { enumerable: true, get: function () { return types_1.DatasourceType; } });
|
|
24
|
+
Object.defineProperty(exports, "promptNames", { enumerable: true, get: function () { return types_1.promptNames; } });
|
|
25
|
+
const utils_1 = require("./utils");
|
|
26
|
+
/**
|
|
27
|
+
* Get the inquirer prompts for odata service.
|
|
28
|
+
*
|
|
29
|
+
* @param promptOptions - options that can control some of the prompt behavior. See {@link OdataServicePromptOptions} for details
|
|
30
|
+
* @param logger - a logger compatible with the {@link Logger} interface
|
|
31
|
+
* @param enableGuidedAnswers - if true, the prompts will use guided answers to help users with validation errors
|
|
32
|
+
* @param telemetryClient - the telemetry client to use for sending telemetry data
|
|
33
|
+
* @param isYUI - if true, the prompt is being called from the Yeoman UI extension host
|
|
34
|
+
* @returns the prompts used to provide input for odata service generation and a reference to the answers object which will be populated with the user's responses once `inquirer.prompt` returns
|
|
35
|
+
*/
|
|
36
|
+
function getPrompts(promptOptions, logger, enableGuidedAnswers = false, telemetryClient, isYUI = false) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
logger_helper_1.default.logger = logger !== null && logger !== void 0 ? logger : new logger_1.ToolsLogger({ logPrefix: '@sap-ux/odata-service-inquirer' });
|
|
39
|
+
error_handler_1.ErrorHandler.logger = logger_helper_1.default.logger;
|
|
40
|
+
error_handler_1.ErrorHandler.guidedAnswersEnabled = enableGuidedAnswers;
|
|
41
|
+
utils_1.PromptState.isYUI = isYUI;
|
|
42
|
+
(0, utils_1.setTelemetryClient)(telemetryClient);
|
|
43
|
+
return {
|
|
44
|
+
prompts: yield (0, prompts_1.getQuestions)(promptOptions),
|
|
45
|
+
// Return reference to derived answers object that will be populated with user responses (after prompting is complete)
|
|
46
|
+
answers: utils_1.PromptState
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
exports.getPrompts = getPrompts;
|
|
51
|
+
/**
|
|
52
|
+
* Prompt for odata service writer inputs.
|
|
53
|
+
*
|
|
54
|
+
* @param adapter - optionally provide references to a calling inquirer instance, this supports integration to Yeoman generators, for example
|
|
55
|
+
* @param promptOptions - options that can control some of the prompt behavior. See {@link OdataServicePromptOptions} for details
|
|
56
|
+
* @param logger - a logger compatible with the {@link Logger} interface
|
|
57
|
+
* @param enableGuidedAnswers - if true, the prompts will use guided answers to help users with validation errors
|
|
58
|
+
* @param telemetryClient - the telemetry client to use for sending telemetry data
|
|
59
|
+
* @param isYUI - if true, the prompt is being called from the Yeoman UI extension host
|
|
60
|
+
* @returns the prompt answers
|
|
61
|
+
*/
|
|
62
|
+
function prompt(adapter, promptOptions, logger, enableGuidedAnswers, telemetryClient, isYUI = false) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
const odataServicePrompts = (yield getPrompts(promptOptions, logger, enableGuidedAnswers, telemetryClient, isYUI))
|
|
65
|
+
.prompts;
|
|
66
|
+
const answers = yield adapter.prompt(odataServicePrompts);
|
|
67
|
+
// Add dervied service answers to the answers object
|
|
68
|
+
Object.assign(answers, utils_1.PromptState.odataService);
|
|
69
|
+
return answers;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
exports.prompt = prompt;
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CapService, CapServiceChoice } from '../../../types';
|
|
2
|
+
import type { CapProjectChoice, CapProjectPaths } from './types';
|
|
3
|
+
export declare const enterCapPathChoiceValue = "enterCapPath";
|
|
4
|
+
/**
|
|
5
|
+
* Search for CAP projects in the specified paths and create prompt choices from the results.
|
|
6
|
+
* The resulting choices will include an additional entry to enter a custom path.
|
|
7
|
+
*
|
|
8
|
+
* @param paths - The paths used to search for CAP projects
|
|
9
|
+
* @returns The CAP project prompt choices
|
|
10
|
+
*/
|
|
11
|
+
export declare function getCapProjectChoices(paths: string[]): Promise<CapProjectChoice[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Gets the CAP service choices for the specified CAP project paths.
|
|
14
|
+
*
|
|
15
|
+
* @param capProjectPaths - The CAP project paths
|
|
16
|
+
* @returns The CAP project service choices
|
|
17
|
+
*/
|
|
18
|
+
export declare function getCapServiceChoices(capProjectPaths: CapProjectPaths): Promise<CapServiceChoice[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the edmx metadata for the CAP service.
|
|
21
|
+
*
|
|
22
|
+
* @param capService - The CAP service
|
|
23
|
+
* @returns The edmx metadata for the CAP service
|
|
24
|
+
*/
|
|
25
|
+
export declare function getCapEdmx(capService: CapService): Promise<string | undefined>;
|
|
26
|
+
//# sourceMappingURL=cap-helpers.d.ts.map
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
12
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
13
|
+
var m = o[Symbol.asyncIterator], i;
|
|
14
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
15
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
|
+
};
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.getCapEdmx = exports.getCapServiceChoices = exports.getCapProjectChoices = exports.enterCapPathChoiceValue = void 0;
|
|
23
|
+
const project_access_1 = require("@sap-ux/project-access");
|
|
24
|
+
const path_1 = require("path");
|
|
25
|
+
const i18n_1 = require("../../../i18n");
|
|
26
|
+
const logger_helper_1 = __importDefault(require("../../logger-helper"));
|
|
27
|
+
const prompt_helpers_1 = require("../../prompt-helpers");
|
|
28
|
+
exports.enterCapPathChoiceValue = 'enterCapPath';
|
|
29
|
+
/**
|
|
30
|
+
* Search for CAP projects in the specified paths.
|
|
31
|
+
*
|
|
32
|
+
* @param paths - The paths used to search for CAP projects
|
|
33
|
+
* @returns The CAP project paths and the number of folders with the same name
|
|
34
|
+
*/
|
|
35
|
+
function getCapProjectPaths(paths) {
|
|
36
|
+
var _a;
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
const capProjectRoots = yield (0, project_access_1.findCapProjects)({ wsFolders: paths });
|
|
39
|
+
const capRootPaths = [];
|
|
40
|
+
// Keep track of duplicate folder names to append the path to the name when displaying the choices
|
|
41
|
+
const folderNameCount = new Map();
|
|
42
|
+
for (const root of capProjectRoots) {
|
|
43
|
+
const folderName = (0, path_1.basename)(root);
|
|
44
|
+
capRootPaths.push({ folderName, path: root });
|
|
45
|
+
folderNameCount.set(folderName, ((_a = folderNameCount.get(folderName)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
46
|
+
}
|
|
47
|
+
capRootPaths.sort((a, b) => a.folderName.localeCompare(b.folderName));
|
|
48
|
+
return {
|
|
49
|
+
capProjectPaths: capRootPaths,
|
|
50
|
+
folderCounts: folderNameCount
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Search for CAP projects in the specified paths and create prompt choices from the results.
|
|
56
|
+
* The resulting choices will include an additional entry to enter a custom path.
|
|
57
|
+
*
|
|
58
|
+
* @param paths - The paths used to search for CAP projects
|
|
59
|
+
* @returns The CAP project prompt choices
|
|
60
|
+
*/
|
|
61
|
+
function getCapProjectChoices(paths) {
|
|
62
|
+
var _a, e_1, _b, _c;
|
|
63
|
+
var _d;
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
const { capProjectPaths, folderCounts } = yield getCapProjectPaths(paths);
|
|
66
|
+
const capChoices = [];
|
|
67
|
+
try {
|
|
68
|
+
for (var _e = true, capProjectPaths_1 = __asyncValues(capProjectPaths), capProjectPaths_1_1; capProjectPaths_1_1 = yield capProjectPaths_1.next(), _a = capProjectPaths_1_1.done, !_a; _e = true) {
|
|
69
|
+
_c = capProjectPaths_1_1.value;
|
|
70
|
+
_e = false;
|
|
71
|
+
const capProjectPath = _c;
|
|
72
|
+
const customCapPaths = yield (0, project_access_1.getCapCustomPaths)(capProjectPath.path);
|
|
73
|
+
const folderCount = (_d = folderCounts.get(capProjectPath.folderName)) !== null && _d !== void 0 ? _d : 1;
|
|
74
|
+
capChoices.push({
|
|
75
|
+
name: `${capProjectPath.folderName}${folderCount > 1 ? ' (' + capProjectPath.path + ')' : ''}`,
|
|
76
|
+
value: Object.assign(capProjectPath, customCapPaths)
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
81
|
+
finally {
|
|
82
|
+
try {
|
|
83
|
+
if (!_e && !_a && (_b = capProjectPaths_1.return)) yield _b.call(capProjectPaths_1);
|
|
84
|
+
}
|
|
85
|
+
finally { if (e_1) throw e_1.error; }
|
|
86
|
+
}
|
|
87
|
+
return [
|
|
88
|
+
...capChoices,
|
|
89
|
+
{
|
|
90
|
+
name: (0, i18n_1.t)('prompts.capProject.enterCapPathChoiceName'),
|
|
91
|
+
value: exports.enterCapPathChoiceValue
|
|
92
|
+
}
|
|
93
|
+
];
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
exports.getCapProjectChoices = getCapProjectChoices;
|
|
97
|
+
/**
|
|
98
|
+
* Create a cap service choice from the service info.
|
|
99
|
+
*
|
|
100
|
+
* @param capModel - The cap model
|
|
101
|
+
* @param serviceInfo - The service info
|
|
102
|
+
* @param projectPath - The project path
|
|
103
|
+
* @param appPath - The app path
|
|
104
|
+
* @returns a cap service choice
|
|
105
|
+
*/
|
|
106
|
+
function createCapServiceChoice(capModel, serviceInfo, projectPath, appPath) {
|
|
107
|
+
var _a, _b, _c;
|
|
108
|
+
const srvDef = (_a = capModel.definitions) === null || _a === void 0 ? void 0 : _a[serviceInfo.name];
|
|
109
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
110
|
+
const serviceFilePath = (_b = srvDef === null || srvDef === void 0 ? void 0 : srvDef.$location) === null || _b === void 0 ? void 0 : _b.file;
|
|
111
|
+
logger_helper_1.default.logger.debug(`Cap service def: ${JSON.stringify(srvDef)}`);
|
|
112
|
+
logger_helper_1.default.logger.debug(`Cap service def $location.file: ${JSON.stringify(serviceFilePath)}`);
|
|
113
|
+
// Find the source path for the service definition file, we cannot resolve '../' path segments as
|
|
114
|
+
// we have no idea where the cwd was when the cds compiler was run. Remove the '../' or '..\\' path segments so the relative path can
|
|
115
|
+
// be resolved against the project root. This is a workaround until cds provides the correct path in the service info.
|
|
116
|
+
const absServicePath = (_c = capModel.$sources) === null || _c === void 0 ? void 0 : _c.find((source) => source.indexOf(serviceFilePath.replace(/\.\.\\\\|\.\.\\|\.\.\//g, '')) > -1);
|
|
117
|
+
logger_helper_1.default.logger.debug(`Source file path for service: ${serviceInfo.name}: ${absServicePath}`);
|
|
118
|
+
if (absServicePath && (0, path_1.isAbsolute)(absServicePath)) {
|
|
119
|
+
let serviceCdsFilePath = (0, path_1.relative)(projectPath, absServicePath);
|
|
120
|
+
// remove the file extension
|
|
121
|
+
serviceCdsFilePath = serviceCdsFilePath.substring(0, serviceCdsFilePath.lastIndexOf('.cds'));
|
|
122
|
+
logger_helper_1.default.logger.debug(`serviceCdsFilePath: ${serviceCdsFilePath}`);
|
|
123
|
+
const capService = {
|
|
124
|
+
serviceName: serviceInfo.name,
|
|
125
|
+
urlPath: !serviceInfo.urlPath.startsWith('/') ? `/${serviceInfo.urlPath}` : serviceInfo.urlPath,
|
|
126
|
+
serviceCdsPath: serviceCdsFilePath,
|
|
127
|
+
projectPath,
|
|
128
|
+
appPath,
|
|
129
|
+
// Assume Node.js if not defined
|
|
130
|
+
capType: serviceInfo.runtime ? serviceInfo.runtime : 'Node.js'
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
name: capService.capType
|
|
134
|
+
? capService.serviceName + ' (' + capService.capType + ')'
|
|
135
|
+
: capService.serviceName,
|
|
136
|
+
value: capService
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
logger_helper_1.default.logger.error(`Path for cds service file : ${serviceInfo.name} not found in cds model, $sources, or is not an absolute path`);
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Gets the CAP service choices for the specified CAP project paths.
|
|
144
|
+
*
|
|
145
|
+
* @param capProjectPaths - The CAP project paths
|
|
146
|
+
* @returns The CAP project service choices
|
|
147
|
+
*/
|
|
148
|
+
function getCapServiceChoices(capProjectPaths) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
logger_helper_1.default.logger.debug(`getCapServiceChoices: ${JSON.stringify(capProjectPaths)}`);
|
|
151
|
+
if (!capProjectPaths) {
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
let capServices = [];
|
|
156
|
+
let capModel;
|
|
157
|
+
try {
|
|
158
|
+
// Workaround for missing clear cache functionality in `getCapModelAnsdServices`, this resets the cds.resolve.cache.
|
|
159
|
+
// If this is not done then errors can be thrown where out-of-processs changes to the files system have occurred
|
|
160
|
+
yield (0, project_access_1.getCdsRoots)(capProjectPaths.path, true);
|
|
161
|
+
// Load the CAP model and services
|
|
162
|
+
const { model, services } = yield (0, project_access_1.getCapModelAndServices)({
|
|
163
|
+
projectRoot: capProjectPaths.path,
|
|
164
|
+
logger: logger_helper_1.default.logger
|
|
165
|
+
});
|
|
166
|
+
capServices = services;
|
|
167
|
+
capModel = model;
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
prompt_helpers_1.errorHandler.logErrorMsgs(error);
|
|
171
|
+
logger_helper_1.default.logger.error((0, i18n_1.t)('errors.capModelAndServicesLoadError', { error: error === null || error === void 0 ? void 0 : error.message }));
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
// We need the relative service definitions file paths (.cds) for the generated annotation file
|
|
175
|
+
const projectPath = capProjectPaths.path;
|
|
176
|
+
const appPath = capProjectPaths.app;
|
|
177
|
+
logger_helper_1.default.logger.debug(`CDS model source paths: ${JSON.stringify(capModel.$sources)}`);
|
|
178
|
+
const serviceChoices = capServices
|
|
179
|
+
.map((service) => {
|
|
180
|
+
return createCapServiceChoice(capModel, service, projectPath, appPath);
|
|
181
|
+
})
|
|
182
|
+
.filter((service) => !!service); // filter undefined entries
|
|
183
|
+
return serviceChoices !== null && serviceChoices !== void 0 ? serviceChoices : [];
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
prompt_helpers_1.errorHandler.logErrorMsgs(err);
|
|
187
|
+
}
|
|
188
|
+
return [];
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
exports.getCapServiceChoices = getCapServiceChoices;
|
|
192
|
+
/**
|
|
193
|
+
* Get the edmx metadata for the CAP service.
|
|
194
|
+
*
|
|
195
|
+
* @param capService - The CAP service
|
|
196
|
+
* @returns The edmx metadata for the CAP service
|
|
197
|
+
*/
|
|
198
|
+
function getCapEdmx(capService) {
|
|
199
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
+
if (!capService.urlPath) {
|
|
201
|
+
const errorMsg = (0, i18n_1.t)('errors.capServiceUrlPathNotDefined', { serviceName: capService.serviceName });
|
|
202
|
+
prompt_helpers_1.errorHandler.logErrorMsgs(errorMsg);
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
return yield (0, project_access_1.readCapServiceMetadataEdmx)(capService.projectPath, capService.urlPath, 'v4');
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
prompt_helpers_1.errorHandler.logErrorMsgs((0, i18n_1.t)('errors.cannotReadCapServiceMetadata', { serviceName: capService.serviceName }));
|
|
210
|
+
logger_helper_1.default.logger.error(error);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
exports.getCapEdmx = getCapEdmx;
|
|
215
|
+
//# sourceMappingURL=cap-helpers.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { YUIQuestion } from '@sap-ux/inquirer-common';
|
|
2
|
+
import type { Question } from 'inquirer';
|
|
3
|
+
import type { OdataServicePromptOptions } from '../../../types';
|
|
4
|
+
import { type CapServiceAnswers } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Get the prompts for selecting a CAP project from local path discovery.
|
|
7
|
+
* Two prompts are returned, one for selecting a CAP project from a list of discovered projects and
|
|
8
|
+
* one for entering a custom path to a CAP project.
|
|
9
|
+
*
|
|
10
|
+
* @param promptOptions - The prompt options which control CAP project search paths and default value
|
|
11
|
+
* @returns the prompt used to provide input for selecting a CAP project
|
|
12
|
+
*/
|
|
13
|
+
export declare function getLocalCapProjectPrompts(promptOptions?: OdataServicePromptOptions): (YUIQuestion<CapServiceAnswers> | Question)[];
|
|
14
|
+
//# sourceMappingURL=questions.d.ts.map
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getLocalCapProjectPrompts = void 0;
|
|
13
|
+
const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
|
|
14
|
+
const project_access_1 = require("@sap-ux/project-access");
|
|
15
|
+
const i18n_1 = require("../../../i18n");
|
|
16
|
+
const types_1 = require("../../../types");
|
|
17
|
+
const utils_1 = require("../../../utils");
|
|
18
|
+
const prompt_helpers_1 = require("../../prompt-helpers");
|
|
19
|
+
const cap_helpers_1 = require("./cap-helpers");
|
|
20
|
+
const types_2 = require("./types");
|
|
21
|
+
const validators_1 = require("./validators");
|
|
22
|
+
/**
|
|
23
|
+
* Find the specified choice in the list of CAP project choices and return its index.
|
|
24
|
+
*
|
|
25
|
+
* @param capChoices The list of CAP project choices
|
|
26
|
+
* @param defaultChoicePath The path of the default choice
|
|
27
|
+
* @returns The index of the default choice in the list of CAP project choices
|
|
28
|
+
*/
|
|
29
|
+
function getDefaultCapChoice(capChoices, defaultChoicePath) {
|
|
30
|
+
if (defaultChoicePath) {
|
|
31
|
+
return capChoices.findIndex((choice) => {
|
|
32
|
+
if (typeof choice.value === 'string') {
|
|
33
|
+
return choice.value === defaultChoicePath;
|
|
34
|
+
}
|
|
35
|
+
return choice.value.path === defaultChoicePath;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
else if (capChoices.length === 2) {
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
return -1;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get the prompts for selecting a CAP project from local path discovery.
|
|
45
|
+
* Two prompts are returned, one for selecting a CAP project from a list of discovered projects and
|
|
46
|
+
* one for entering a custom path to a CAP project.
|
|
47
|
+
*
|
|
48
|
+
* @param promptOptions - The prompt options which control CAP project search paths and default value
|
|
49
|
+
* @returns the prompt used to provide input for selecting a CAP project
|
|
50
|
+
*/
|
|
51
|
+
function getLocalCapProjectPrompts(promptOptions) {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
let capChoices = [];
|
|
54
|
+
const defaultCapPath = (_a = promptOptions === null || promptOptions === void 0 ? void 0 : promptOptions[types_1.promptNames.capProject]) === null || _a === void 0 ? void 0 : _a.defaultChoice;
|
|
55
|
+
const defaultCapService = (_b = promptOptions === null || promptOptions === void 0 ? void 0 : promptOptions[types_1.promptNames.capService]) === null || _b === void 0 ? void 0 : _b.defaultChoice;
|
|
56
|
+
let selectedCapProject;
|
|
57
|
+
let capServiceChoices;
|
|
58
|
+
let defaultServiceIndex = 0;
|
|
59
|
+
utils_1.PromptState.reset();
|
|
60
|
+
const prompts = [
|
|
61
|
+
{
|
|
62
|
+
when: () => __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
var _c, _d;
|
|
64
|
+
capChoices = yield (0, cap_helpers_1.getCapProjectChoices)((_d = (_c = promptOptions === null || promptOptions === void 0 ? void 0 : promptOptions[types_1.promptNames.capProject]) === null || _c === void 0 ? void 0 : _c.capSearchPaths) !== null && _d !== void 0 ? _d : []);
|
|
65
|
+
return (capChoices === null || capChoices === void 0 ? void 0 : capChoices.length) > 1;
|
|
66
|
+
}),
|
|
67
|
+
type: 'list',
|
|
68
|
+
name: types_1.promptNames.capProject,
|
|
69
|
+
message: (0, i18n_1.t)('prompts.capProject.message'),
|
|
70
|
+
default: () => {
|
|
71
|
+
const defChoice = getDefaultCapChoice(capChoices, defaultCapPath);
|
|
72
|
+
return defChoice;
|
|
73
|
+
},
|
|
74
|
+
choices: () => capChoices,
|
|
75
|
+
guiOptions: {
|
|
76
|
+
applyDefaultWhenDirty: true,
|
|
77
|
+
mandatory: true,
|
|
78
|
+
breadcrumb: (0, i18n_1.t)('prompts.capProject.breadcrumb')
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
when: (answers) => capChoices.length === 1 || (answers === null || answers === void 0 ? void 0 : answers.capProject) === cap_helpers_1.enterCapPathChoiceValue,
|
|
83
|
+
type: 'input',
|
|
84
|
+
guiType: 'folder-browser',
|
|
85
|
+
name: types_2.capInternalPromptNames.capProjectPath,
|
|
86
|
+
message: (0, i18n_1.t)('prompts.capProjectPath.message'),
|
|
87
|
+
default: () => {
|
|
88
|
+
if (defaultCapPath) {
|
|
89
|
+
return defaultCapPath;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
guiOptions: { mandatory: true, breadcrumb: (0, i18n_1.t)('prompts.capProject.breadcrumb') },
|
|
93
|
+
validate: (projectPath) => __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
const validCapPath = yield (0, validators_1.validateCapPath)(projectPath);
|
|
95
|
+
// Load the cap paths if the path is valid
|
|
96
|
+
if (validCapPath === true) {
|
|
97
|
+
selectedCapProject = Object.assign({ path: projectPath }, yield (0, project_access_1.getCapCustomPaths)(projectPath));
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
selectedCapProject = undefined;
|
|
101
|
+
return validCapPath;
|
|
102
|
+
})
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
when: (answers) => __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
if (typeof (answers === null || answers === void 0 ? void 0 : answers.capProject) === 'object') {
|
|
107
|
+
selectedCapProject = answers.capProject;
|
|
108
|
+
}
|
|
109
|
+
if (selectedCapProject) {
|
|
110
|
+
capServiceChoices = yield (0, cap_helpers_1.getCapServiceChoices)(selectedCapProject);
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}),
|
|
115
|
+
type: 'list',
|
|
116
|
+
name: types_1.promptNames.capService,
|
|
117
|
+
message: (0, i18n_1.t)('prompts.capService.message'),
|
|
118
|
+
choices: () => {
|
|
119
|
+
if (defaultCapService) {
|
|
120
|
+
// Find the cap service, qualified by the provided project path
|
|
121
|
+
defaultServiceIndex = capServiceChoices === null || capServiceChoices === void 0 ? void 0 : capServiceChoices.findIndex((choice) => {
|
|
122
|
+
var _a, _b;
|
|
123
|
+
// project path is an extra validation that the prompt options for each
|
|
124
|
+
// of `defaultCapProject` and `defaultCapService` are compatible
|
|
125
|
+
return ((_a = choice.value) === null || _a === void 0 ? void 0 : _a.projectPath) === (defaultCapService === null || defaultCapService === void 0 ? void 0 : defaultCapService.projectPath) &&
|
|
126
|
+
((_b = choice.value) === null || _b === void 0 ? void 0 : _b.serviceName) === (defaultCapService === null || defaultCapService === void 0 ? void 0 : defaultCapService.serviceName);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return capServiceChoices;
|
|
130
|
+
},
|
|
131
|
+
guiOptions: {
|
|
132
|
+
applyDefaultWhenDirty: true,
|
|
133
|
+
mandatory: true,
|
|
134
|
+
breadcrumb: true
|
|
135
|
+
},
|
|
136
|
+
default: () => {
|
|
137
|
+
return (capServiceChoices === null || capServiceChoices === void 0 ? void 0 : capServiceChoices.length) > 1 ? defaultServiceIndex : 0;
|
|
138
|
+
},
|
|
139
|
+
validate: (capService) => __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
const errMsg = prompt_helpers_1.errorHandler.getErrorMsg(undefined, true);
|
|
141
|
+
if (errMsg) {
|
|
142
|
+
return errMsg;
|
|
143
|
+
}
|
|
144
|
+
if (capService) {
|
|
145
|
+
utils_1.PromptState.odataService.metadata = yield (0, cap_helpers_1.getCapEdmx)(capService);
|
|
146
|
+
utils_1.PromptState.odataService.servicePath = capService.urlPath;
|
|
147
|
+
utils_1.PromptState.odataService.odataVersion = odata_service_writer_1.OdataVersion.v4;
|
|
148
|
+
return utils_1.PromptState.odataService.metadata !== undefined
|
|
149
|
+
? true
|
|
150
|
+
: (0, i18n_1.t)('prompts.validationMessages.metadataInvalid');
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
];
|
|
156
|
+
if ((0, utils_1.getPlatform)() === types_1.hostEnvironment.cli) {
|
|
157
|
+
prompts.push({
|
|
158
|
+
when: (answers) => __awaiter(this, void 0, void 0, function* () {
|
|
159
|
+
if (answers === null || answers === void 0 ? void 0 : answers.capService) {
|
|
160
|
+
utils_1.PromptState.odataService.metadata = yield (0, cap_helpers_1.getCapEdmx)(answers === null || answers === void 0 ? void 0 : answers.capService);
|
|
161
|
+
utils_1.PromptState.odataService.servicePath = answers === null || answers === void 0 ? void 0 : answers.capService.urlPath;
|
|
162
|
+
utils_1.PromptState.odataService.odataVersion = odata_service_writer_1.OdataVersion.v4;
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}),
|
|
166
|
+
name: types_2.capInternalPromptNames.capCliStateSetter
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return prompts;
|
|
170
|
+
}
|
|
171
|
+
exports.getLocalCapProjectPrompts = getLocalCapProjectPrompts;
|
|
172
|
+
//# sourceMappingURL=questions.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CapCustomPaths } from '@sap-ux/project-access';
|
|
2
|
+
import type { CapService, CapServiceChoice, promptNames } from '../../../types';
|
|
3
|
+
import type { ListChoiceOptions } from 'inquirer';
|
|
4
|
+
/**
|
|
5
|
+
* Enumeration of internal prompt names used internally and not supported for modification using OdataServiceInquirerPromptOptions
|
|
6
|
+
*/
|
|
7
|
+
export declare enum capInternalPromptNames {
|
|
8
|
+
capProjectPath = "capProjectPath",
|
|
9
|
+
capCliStateSetter = "capCliStateSetter"
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Answers to CAP service prompt
|
|
13
|
+
*/
|
|
14
|
+
export interface CapServiceAnswers extends CapService {
|
|
15
|
+
[promptNames.capProject]: CapProjectChoice['value'];
|
|
16
|
+
[capInternalPromptNames.capProjectPath]: string;
|
|
17
|
+
[promptNames.capService]: CapServiceChoice['value'];
|
|
18
|
+
}
|
|
19
|
+
export type CapProjectRootPath = {
|
|
20
|
+
folderName: string;
|
|
21
|
+
path: string;
|
|
22
|
+
};
|
|
23
|
+
export type CapProjectPaths = CapProjectRootPath & CapCustomPaths;
|
|
24
|
+
export interface CapProjectChoice extends ListChoiceOptions {
|
|
25
|
+
value: CapProjectPaths | string;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.capInternalPromptNames = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Enumeration of internal prompt names used internally and not supported for modification using OdataServiceInquirerPromptOptions
|
|
6
|
+
*/
|
|
7
|
+
var capInternalPromptNames;
|
|
8
|
+
(function (capInternalPromptNames) {
|
|
9
|
+
capInternalPromptNames["capProjectPath"] = "capProjectPath";
|
|
10
|
+
capInternalPromptNames["capCliStateSetter"] = "capCliStateSetter";
|
|
11
|
+
})(capInternalPromptNames || (exports.capInternalPromptNames = capInternalPromptNames = {}));
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensure the path specified is a valid CAP project.
|
|
3
|
+
*
|
|
4
|
+
* @param capProjectPath - The path to the CAP project
|
|
5
|
+
* @returns A boolean indicating if the path is a valid CAP project or an error message
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateCapPath(capProjectPath: string): Promise<boolean | string>;
|
|
8
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.validateCapPath = void 0;
|
|
13
|
+
const project_access_1 = require("@sap-ux/project-access");
|
|
14
|
+
const i18n_1 = require("../../../i18n");
|
|
15
|
+
/**
|
|
16
|
+
* Ensure the path specified is a valid CAP project.
|
|
17
|
+
*
|
|
18
|
+
* @param capProjectPath - The path to the CAP project
|
|
19
|
+
* @returns A boolean indicating if the path is a valid CAP project or an error message
|
|
20
|
+
*/
|
|
21
|
+
function validateCapPath(capProjectPath) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
if (capProjectPath) {
|
|
24
|
+
try {
|
|
25
|
+
return !!(yield (0, project_access_1.getCapProjectType)(capProjectPath)) || (0, i18n_1.t)('prompts.validationMessages.capProjectNotFound');
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
return (0, i18n_1.t)('prompts.validationMessages.capProjectNotFound');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
exports.validateCapPath = validateCapPath;
|
|
35
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { YUIQuestion } from '@sap-ux/inquirer-common';
|
|
2
|
+
import type { MetadataPromptOptions, OdataServiceAnswers } from '../../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the metadata file question based on the provided @type{MetadataPromptOptions}.
|
|
5
|
+
*
|
|
6
|
+
* @param promptOptions - The metadata prompt options
|
|
7
|
+
* @returns the metadata file question
|
|
8
|
+
*/
|
|
9
|
+
export declare function getMetadataFileQuestion(promptOptions?: MetadataPromptOptions): YUIQuestion<OdataServiceAnswers>;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|