diff --git a/abap-api-tools/README.md b/abap-api-tools/README.md
index c1d42044..d4000bab 100644
--- a/abap-api-tools/README.md
+++ b/abap-api-tools/README.md
@@ -97,8 +97,11 @@ ABAP API for Value Help annotations, if exposed in backend system (see [ABAP hel
```yaml
MME:
search_help_api:
- determine: YWS_SHLP_DETERMINE
- dom_values: YWS_SHLP_DOMVALUES_GET
+ determine: /COE/RBP_FE_SHLP_DETERM_SEARCH
+ FV_descriptor_get: /COE/RBP_FE_SHLP_DOMVALUES_GET
+ CT_descriptor_get: FDT_GET_DDIC_METADATA
+ SH_descriptor_get: /COE/RBP_FE_SHLP_METADATA_GET
+ search: /COE/RBP_FE_SHLP_GET
```
Run `abap` command, to show help:
diff --git a/abap-api-tools/package-lock.json b/abap-api-tools/package-lock.json
index f311108f..747a3b46 100644
--- a/abap-api-tools/package-lock.json
+++ b/abap-api-tools/package-lock.json
@@ -11,7 +11,7 @@
],
"license": "Apache-2.0",
"dependencies": {
- "abap-value-help": "file:../abap-value-help",
+ "abap-value-help": "^1.0.0",
"chalk": "^4.1.0",
"js-yaml": "^4.0.0",
"loglevel": "^1.7.1",
@@ -37,28 +37,6 @@
"node": "~10 >=10.23 || ~12 >=12.17 || >= 14.0"
}
},
- "../abap-value-help": {
- "version": "0.9.6",
- "cpu": [
- "!arm"
- ],
- "license": "Apache-2.0",
- "dependencies": {
- "loglevel": "^1.7.1",
- "node-rfc": "^2.4.0"
- },
- "devDependencies": {
- "@types/node": "^14.14.31",
- "@typescript-eslint/eslint-plugin": "^4.15.2",
- "@typescript-eslint/parser": "^4.15.2",
- "eslint": "^7.20.0",
- "jest": "^26.6.3",
- "typescript": "^4.2.2"
- },
- "engines": {
- "node": "~10 >=10.23 || ~12 >=12.17 || >= 14.0"
- }
- },
"node_modules/@babel/code-frame": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
@@ -1284,8 +1262,19 @@
"dev": true
},
"node_modules/abap-value-help": {
- "resolved": "../abap-value-help",
- "link": true
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/abap-value-help/-/abap-value-help-1.0.0.tgz",
+ "integrity": "sha512-bWztYAC5MFC5ioNYKLM2x++C+7g1o/Xu20CDF97nADrJgvElcRSxLo4jTxBR2P1DxEmXLpuxOCro90jPg5ugdA==",
+ "cpu": [
+ "!arm"
+ ],
+ "dependencies": {
+ "loglevel": "^1.7.1",
+ "node-rfc": "^2.4.0"
+ },
+ "engines": {
+ "node": "~10 >=10.23 || ~12 >=12.17 || >= 14.0"
+ }
},
"node_modules/acorn": {
"version": "7.4.1",
@@ -8339,16 +8328,12 @@
"dev": true
},
"abap-value-help": {
- "version": "file:../abap-value-help",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/abap-value-help/-/abap-value-help-1.0.0.tgz",
+ "integrity": "sha512-bWztYAC5MFC5ioNYKLM2x++C+7g1o/Xu20CDF97nADrJgvElcRSxLo4jTxBR2P1DxEmXLpuxOCro90jPg5ugdA==",
"requires": {
- "@types/node": "^14.14.31",
- "@typescript-eslint/eslint-plugin": "^4.15.2",
- "@typescript-eslint/parser": "^4.15.2",
- "eslint": "^7.20.0",
- "jest": "^26.6.3",
"loglevel": "^1.7.1",
- "node-rfc": "^2.4.0",
- "typescript": "^4.2.2"
+ "node-rfc": "^2.4.0"
}
},
"acorn": {
diff --git a/abap-api-tools/package.json b/abap-api-tools/package.json
index 4e786915..e85744a1 100644
--- a/abap-api-tools/package.json
+++ b/abap-api-tools/package.json
@@ -1,7 +1,7 @@
{
"name": "abap-api-tools",
"description": "ABAP api tools",
- "version": "2.0.0",
+ "version": "2.1.0",
"homepage": "https://github.com/sap/fundamental-tools",
"author": "SAP",
"license": "Apache-2.0",
@@ -45,7 +45,7 @@
"nodejs"
],
"dependencies": {
- "abap-value-help": "file:../abap-value-help",
+ "abap-value-help": "^1.0.0",
"chalk": "^4.1.0",
"js-yaml": "^4.0.0",
"loglevel": "^1.7.1",
diff --git a/abap-api-tools/src/ts/backend.ts b/abap-api-tools/src/ts/backend.ts
index 3b6e6d8e..bca3fce6 100644
--- a/abap-api-tools/src/ts/backend.ts
+++ b/abap-api-tools/src/ts/backend.ts
@@ -28,19 +28,13 @@ import {
import { Alpha, AlphaCatalogType } from "./alpha";
-import {
- deleteFile,
- isEmpty,
- log,
- fileLoad,
- fileSave,
- fileExists,
-} from "./utils";
+import { isEmpty, log, fileLoad, fileSave, fileExists, rmDir } from "./utils";
import {
ShlpApiType,
ValueInputHelp,
DescriptorType,
+ FVDescriptorType,
ValueHelpType,
} from "abap-value-help";
@@ -355,18 +349,17 @@ export class Backend {
result.format.valueInputType = ValueInput.list;
// Binary / List type
- const descriptor = this.Descriptors[helpFound.id];
+ const descriptor = this.Descriptors[helpFound.id] as FVDescriptorType;
if (descriptor) {
- if (descriptor["valueInputType"]) {
- result.format.valueInputType = descriptor["valueInputType"];
- }
+ if (descriptor.valueInputType === ValueInput.binary) {
+ result.format.valueInputType = ValueInput.binary;
- // Checkbox uses SHLP only when values differ from "X" and "";
- if (
- result.format.valueInputType === ValueInput.binary &&
- !descriptor["customCheckbox"]
- ) {
- delete result.input.shlpId;
+ // Checkbox SHLP used only when values differ from "X" and ""
+ if (descriptor.customCheckbox) {
+ //result.input.customCheckbox = "X";
+ } else {
+ delete result.input.shlpId;
+ }
}
}
}
@@ -384,6 +377,24 @@ export class Backend {
// write search help id into selection field descriptor
if (selectionHelpFound.id) {
field.shlpId = selectionHelpFound.id;
+ field.valueInputType = ValueInput.list;
+
+ // Binary / List type
+ const descriptor = this.Descriptors[
+ selectionHelpFound.id
+ ] as FVDescriptorType;
+ if (descriptor) {
+ if (descriptor.valueInputType === ValueInput.binary) {
+ field.valueInputType = ValueInput.binary;
+
+ // Checkbox SHLP used only when values differ from "X" and ""
+ if (descriptor.customCheckbox) {
+ field.customCheckbox = "X";
+ // } else {
+ // delete field.shlpId;
+ }
+ }
+ }
}
}
}
@@ -865,26 +876,9 @@ export class Backend {
}
annotations_clean(): void {
- const folder_yaml = path.join(
- this.argv.output as string,
- this.api_name,
- "yaml"
- );
-
- log.debug(`AnnotationsType clean ${folder_yaml}`);
-
- for (const fileName of [
- "parameters",
- "fields",
- "helps",
- "stat",
- "alpha",
- "usage",
- "texts",
- "descriptors",
- ]) {
- deleteFile(path.join(folder_yaml, `${fileName}.yaml`));
- }
+ const rootdir = path.join(this.argv.output as string, this.api_name);
+ log.debug("Clean annotations", rootdir);
+ rmDir(rootdir);
}
}
diff --git a/abap-api-tools/src/ts/frontend.ts b/abap-api-tools/src/ts/frontend.ts
index 20ff1a5b..65aa06ef 100644
--- a/abap-api-tools/src/ts/frontend.ts
+++ b/abap-api-tools/src/ts/frontend.ts
@@ -6,7 +6,15 @@ import chalk from "chalk";
import path from "path";
import { sprintf } from "sprintf-js";
-import { EmptyObject, Writer, isEmpty, log, fileLoad } from "./utils";
+import {
+ EmptyObject,
+ Writer,
+ isEmpty,
+ log,
+ fileLoad,
+ makeDir,
+ rmDir,
+} from "./utils";
import {
ParamClass,
@@ -30,14 +38,14 @@ import {
import { ElementaryHelpType, EHDescriptorType } from "abap-value-help";
-import { RfcStructure } from "node-rfc";
+import { RfcStructure, RfcTable } from "node-rfc";
import { Command, Arguments, Signature } from "./abap";
interface IElementaryHelp {
id: string;
title: string;
- selectionFields: FieldType[];
+ selectionFields: RfcStructure[]; // FieldType[];
selectionParameters: string[];
blacklisted: boolean;
}
@@ -562,45 +570,171 @@ export class Frontend {
}
valueHelps(): { js: string; html?: string } {
- const fileName = path.join(
+ const outDir = path.join(
this.argv.output || "",
this.api_name,
"valueHelps"
);
- const htmlWriter = new Writer(
- `${fileName}.html`,
- this.argv.save as boolean
- );
+ if (this.argv.save) {
+ rmDir(outDir);
+ makeDir(outDir);
+ }
+
+ function newWriter(suffix: "js" | "html", shlpId, title, save: boolean) {
+ const writer = new Writer(
+ path.join(
+ outDir,
+ `${shlpId
+ .toLowerCase()
+ .replace(/\//g, "_")
+ .replace(" ", "_")}.${suffix}`
+ ),
+ save
+ );
+ writer.write(
+ suffix === "js"
+ ? `// ${shlpId} ${title} : ${Signature}\n`
+ : `}\n`
+ );
+
+ if (suffix === "html") return writer;
+ writer.write(
+ `const helpSign = [{ id: 'I', name: 'Include' }, { id: 'E', name: 'Exclude' }];
+const helpOption = [
+ { id: 'EQ', name: 'is' },
+ { id: 'NE', name: 'is not' },
+ { id: 'GT', name: 'greater than' },
+ { id: 'LT', name: 'less than' },
+ { id: 'GE', name: 'not less' },
+ { id: 'LE', name: 'not greater' },
+ { id: 'BT', name: 'between' },
+ { id: 'NB', name: 'not between' },
+ { id: 'CP', name: 'with pattern' },
+ { id: 'NP', name: 'w/o pattern' }
+];\n`
+ );
+ return writer;
+ }
+
+ function selectionParams(jsWriter, FIELDDESCR: RfcTable): void {
+ jsWriter.write(`const selectParams = [`);
+ jsWriter.addindent();
+ for (const field of FIELDDESCR) {
+ jsWriter.write(`{`);
+ jsWriter.addindent();
+ for (const k of ["FIELDNAME", "DATATYPE", "LENG", "DECIMALS"]) {
+ jsWriter.write(
+ `${k}: ${
+ typeof field[k] === "string" ? '"' + field[k] + '"' : field[k]
+ },`
+ );
+ }
+ for (const k of ["MEMORYID", "PARVA"]) {
+ if (k in field && field[k])
+ jsWriter.write(
+ `${k}: ${
+ typeof field[k] === "string" ? '"' + field[k] + '"' : field[k]
+ }`
+ );
+ }
+
+ jsWriter.deindent();
+ jsWriter.write(`},`);
+ }
+ jsWriter.deindent();
+ jsWriter.write(`];`);
+ }
+
+ let JS = "",
+ HTML = "";
//
// html header
//
- htmlWriter.write(``);
-
- for (const [shlp_key, shelp] of Object.entries(
+ for (const [shlp_key, shlp] of Object.entries(
this.abap.helps as HelpsCatalogType
)) {
- const stype = shlp_key.split(" ")[0];
- if (stype !== "SH") {
+ if (shlp_key.substr(0, 2) !== "SH") {
continue;
}
- log.info(shlp_key, shelp.title);
- if (shelp.elementaryHelps) {
- for (const eh of shelp.elementaryHelps) {
- const skey = Object.keys(eh)[0];
- const title = eh[skey];
- log.info(" ", skey, title);
- this.elementaryHelp(skey);
+ if (shlp.elementaryHelps) {
+ // html
+ const htmlWriter = newWriter(
+ "html",
+ shlp_key,
+ `${shlp.title} (${shlp.elementaryHelps.length})`,
+ this.argv.save as boolean
+ );
+ htmlWriter.write(
+ ``
+ );
+ HTML += htmlWriter.save();
+
+ // js
+ const jsWriter = newWriter(
+ "js",
+ shlp_key,
+ `${shlp.title} (${shlp.elementaryHelps.length})`,
+ this.argv.save as boolean
+ );
+ jsWriter.write("const helpSelector = [");
+ jsWriter.addindent();
+ shlp.elementaryHelps.map((eh) =>
+ jsWriter.write(JSON.stringify(eh) + ",")
+ );
+ jsWriter.deindent();
+ jsWriter.write("];");
+ JS += jsWriter.save();
+
+ for (const elem of shlp.elementaryHelps) {
+ const shlpId = Object.keys(elem)[0];
+ const EH = this.elementaryHelp(shlpId);
+
+ // html
+ const htmlWriter = newWriter(
+ "html",
+ shlpId,
+ elem[shlpId].title,
+ this.argv.save as boolean
+ );
+ EH.selectionParameters.map((sp) => htmlWriter.write(sp));
+ HTML += htmlWriter.save();
+ // js
+ const jsWriter = newWriter(
+ "js",
+ shlpId,
+ elem[shlpId].title,
+ this.argv.save as boolean
+ );
+ selectionParams(jsWriter, EH.selectionFields);
+
+ JS += jsWriter.save();
}
} else {
- this.elementaryHelp(shlp_key);
+ const htmlWriter = newWriter(
+ "html",
+ shlp_key,
+ shlp.title,
+ this.argv.save as boolean
+ );
+ const jsWriter = newWriter(
+ "js",
+ shlp_key,
+ shlp.title,
+ this.argv.save as boolean
+ );
+ const EH = this.elementaryHelp(shlp_key);
+ EH.selectionParameters.map((sp) => htmlWriter.write(sp));
+ HTML += htmlWriter.save();
+ selectionParams(jsWriter, EH.selectionFields);
+ JS += jsWriter.save();
}
}
- return { js: "", html: "" }; // htmlWriter.save() };
+ return { js: JS, html: HTML };
}
elementaryHelp(shlp_key: string): IElementaryHelp {
@@ -615,28 +749,26 @@ export class Frontend {
const result: IElementaryHelp = {
id: shlp_key,
title: selection.INTDESCR.DDTEXT as string,
- selectionFields: [] as FieldType[],
+ selectionFields: [] as RfcStructure[], // FieldType[],
selectionParameters: [] as string[],
blacklisted: false,
};
if (VH.blacklist) {
result.blacklisted = true;
- log.error(`Value Help black-listed: ${shlp_key}`);
+ log.debug(`Value Help black-listed: ${shlp_key}`);
return result;
}
for (const field of selection.FIELDDESCR) {
- const selField = Frontend.dfiesFieldToABAP(field);
-
const Parameter: ParameterType = {
paramType: ParamType.struct,
PARAMCLASS: "paramClass",
TABNAME: field.TABNAME as string,
FIELDNAME: field.FIELDNAME as string,
- PARAMTEXT: selField.text.FIELDTEXT as string,
+ PARAMTEXT: field.FIELDTEXT as string,
functionName: `valueHelp`,
- paramName: `selection`,
+ paramName: `searchParamLow`,
required: "",
//default?: string;
// nativeKey?: string;
@@ -644,11 +776,11 @@ export class Frontend {
const html_field = this.html_field(
Parameter,
- selField,
+ Frontend.dfiesFieldToABAP(field),
field.FIELDNAME as string
);
- result.selectionFields.push(selField);
+ result.selectionFields.push(field);
result.selectionParameters.push(html_field.html);
}
@@ -690,6 +822,14 @@ export class Frontend {
if (field.CONVEXIT) result.input.CONVEXIT = field.CONVEXIT as string;
if (field.MEMORYID) result.input.MEMORYID = field.MEMORYID as string;
if (field.shlpId) result.input.shlpId = field.shlpId as string;
+ if (field.valueInputType) {
+ result.format.valueInputType = field.valueInputType as string;
+ if (field.valueInputType === ValueInput.binary) {
+ if (!field.customCheckbox) {
+ delete result.input.shlpId;
+ }
+ }
+ }
if (isEmpty(result.input)) delete result.input;
if (field.valueInputType) {
@@ -913,12 +1053,17 @@ export class Frontend {
result.abap.unit = Field.format.REFFIELD;
} else {
result.abap.unit = "!notfound";
- log.error(
- `${Field["format"]["DATATYPE"]} unit not found for rfm: ${Param.functionName} parameter: ${Param.paramName}` +
- field_name
- ? ` field: ${field_name}`
- : ""
- );
+ if (Param.functionName === "valueHelp") {
+ log.error(
+ `${Field.format.DATATYPE} unit not found for ${
+ field_name ? field_name : Param.FIELDNAME
+ }`
+ );
+ } else {
+ log.error(
+ `${Field.format.DATATYPE} unit not found for rfm: ${Param.functionName} parameter: ${Param.paramName}`
+ );
+ }
}
}
diff --git a/abap-api-tools/src/ts/utils.ts b/abap-api-tools/src/ts/utils.ts
index 1b45fc47..8ebbe33a 100644
--- a/abap-api-tools/src/ts/utils.ts
+++ b/abap-api-tools/src/ts/utils.ts
@@ -68,6 +68,11 @@ export function makeDir(dir: string): void {
log.debug(`mkdir ${dir}`);
}
+export function rmDir(dir: string): void {
+ fs.rmSync(dir, { recursive: true, force: true });
+ log.debug(`rmdir ${dir}`);
+}
+
export function isEmpty(obj?: unknown[] | Record): boolean {
if (obj === undefined) return true;
if (Array.isArray(obj)) return obj.length === 0;
@@ -127,7 +132,8 @@ export class Writer {
this.indent = this.SPACE.repeat(this.indent_count);
}
- write(line = ""): void {
+ write(line: string | string[] = ""): void {
+ if (Array.isArray(line)) line = line.join("");
this.output.push(line.length > 0 ? this.indent + line : line);
}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..d8339bf0
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "fundamental-tools",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {}
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/package.json
@@ -0,0 +1 @@
+{}