@abaplint/transpiler 2.13.32 → 2.13.34

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,10 +1,13 @@
1
1
  import * as abaplint from "@abaplint/core";
2
2
  import { config } from "./validation";
3
- import { IFile, IOutput, IProgress, ITranspilerOptions, IOutputFile, UnknownTypesEnum } from "./types";
4
- export { config, ITranspilerOptions, IFile, IProgress, IOutputFile, IOutput, UnknownTypesEnum };
3
+ import { IFile, IOutput, IProgress, ITranspilerOptions, ITranspilerPlugin, IOutputFile, UnknownTypesEnum } from "./types";
4
+ import { Chunk } from "./chunk";
5
+ import { DatabaseSetupResult } from "./db/database_setup_result";
6
+ export { config, ITranspilerOptions, ITranspilerPlugin, IFile, IProgress, IOutputFile, IOutput, UnknownTypesEnum, Chunk, DatabaseSetupResult };
5
7
  export declare class Transpiler {
6
8
  private readonly options;
7
- constructor(options?: ITranspilerOptions);
9
+ private readonly plugin;
10
+ constructor(options?: ITranspilerOptions, plugin?: ITranspilerPlugin);
8
11
  runRaw(files: IFile[]): Promise<IOutput>;
9
12
  run(reg: abaplint.IRegistry, progress?: IProgress): Promise<IOutput>;
10
13
  protected validate(reg: abaplint.IRegistry): void;
@@ -33,13 +33,15 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.Transpiler = exports.UnknownTypesEnum = exports.config = void 0;
36
+ exports.Transpiler = exports.Chunk = exports.UnknownTypesEnum = exports.config = void 0;
37
37
  const abaplint = __importStar(require("@abaplint/core"));
38
38
  const validation_1 = require("./validation");
39
39
  Object.defineProperty(exports, "config", { enumerable: true, get: function () { return validation_1.config; } });
40
40
  const unit_test_1 = require("./unit_test");
41
41
  const types_1 = require("./types");
42
42
  Object.defineProperty(exports, "UnknownTypesEnum", { enumerable: true, get: function () { return types_1.UnknownTypesEnum; } });
43
+ const chunk_1 = require("./chunk");
44
+ Object.defineProperty(exports, "Chunk", { enumerable: true, get: function () { return chunk_1.Chunk; } });
43
45
  const db_1 = require("./db");
44
46
  const handle_table_1 = require("./handlers/handle_table");
45
47
  const handle_abap_1 = require("./handlers/handle_abap");
@@ -56,8 +58,10 @@ const handle_fugr_1 = require("./handlers/handle_fugr");
56
58
  const initialization_1 = require("./initialization");
57
59
  class Transpiler {
58
60
  options;
59
- constructor(options) {
61
+ plugin;
62
+ constructor(options, plugin) {
60
63
  this.options = options;
64
+ this.plugin = plugin;
61
65
  if (this.options === undefined) {
62
66
  this.options = {};
63
67
  }
@@ -75,15 +79,17 @@ class Transpiler {
75
79
  reg.parse();
76
80
  this.validate(reg);
77
81
  const dbSetup = new db_1.DatabaseSetup(reg).run(this.options);
82
+ this.plugin?.amendDatabaseSetup?.(dbSetup, reg, this.options || {});
78
83
  const output = {
79
84
  objects: [],
80
85
  unitTestScript: new unit_test_1.UnitTest().unitTestScript(reg, this.options?.skip),
81
86
  unitTestScriptOpen: new unit_test_1.UnitTest().unitTestScriptOpen(reg, this.options?.skip),
82
- initializationScript: new initialization_1.Initialization().script(reg, dbSetup, this.options),
83
- initializationScript2: new initialization_1.Initialization().script(reg, dbSetup, this.options, true),
87
+ initializationScript: "",
88
+ initializationScript2: "",
84
89
  databaseSetup: dbSetup,
85
90
  reg: reg,
86
91
  };
92
+ const pluginOutputs = [];
87
93
  progress?.set(reg.getObjectCount().total, "Building");
88
94
  for (const obj of reg.getObjects()) {
89
95
  await progress?.tick("Building, " + obj.getName());
@@ -123,12 +129,22 @@ class Transpiler {
123
129
  else if (obj instanceof abaplint.Objects.MessageClass) {
124
130
  output.objects.push(...new handle_msag_1.HandleMSAG().runObject(obj, reg));
125
131
  }
132
+ else if (this.plugin !== undefined) {
133
+ const handled = this.plugin.handleObject(obj, reg, this.options || {});
134
+ if (handled !== undefined) {
135
+ output.objects.push(...handled);
136
+ pluginOutputs.push(...handled);
137
+ }
138
+ }
126
139
  }
140
+ // after the object loop, plugin output files are imported by the initialization scripts
141
+ output.initializationScript = new initialization_1.Initialization().script(reg, dbSetup, this.options, false, pluginOutputs);
142
+ output.initializationScript2 = new initialization_1.Initialization().script(reg, dbSetup, this.options, true, pluginOutputs);
127
143
  return output;
128
144
  }
129
145
  // ///////////////////////////////
130
146
  validate(reg) {
131
- const issues = new validation_1.Validation(this.options).run(reg);
147
+ const issues = new validation_1.Validation(this.options, this.plugin).run(reg);
132
148
  if (issues.length > 0) {
133
149
  const messages = issues.map(i => i.getKey() + ", " +
134
150
  i.getMessage() + ", " +
@@ -1,9 +1,9 @@
1
1
  import { DatabaseSetupResult } from "./db/database_setup_result";
2
2
  import * as abaplint from "@abaplint/core";
3
- import { ITranspilerOptions } from "./types";
3
+ import { ITranspilerOptions, IOutputFile } from "./types";
4
4
  export declare function escapeNamespaceFilename(filename: string): string;
5
5
  export declare class Initialization {
6
- script(reg: abaplint.IRegistry, dbSetup: DatabaseSetupResult, options: ITranspilerOptions | undefined, useImport?: boolean): string;
6
+ script(reg: abaplint.IRegistry, dbSetup: DatabaseSetupResult, options: ITranspilerOptions | undefined, useImport?: boolean, pluginOutputs?: readonly IOutputFile[]): string;
7
7
  private buildImports;
8
8
  private hasClassConstructor;
9
9
  }
@@ -43,7 +43,7 @@ function escapeNamespaceFilename(filename) {
43
43
  return filename.replace(/\//g, "%23");
44
44
  }
45
45
  class Initialization {
46
- script(reg, dbSetup, options, useImport) {
46
+ script(reg, dbSetup, options, useImport, pluginOutputs) {
47
47
  let ret = "";
48
48
  if (useImport === true) {
49
49
  ret = `/* eslint-disable import/newline-after-import */
@@ -86,13 +86,13 @@ globalThis.abap = new runtime.ABAP();\n`;
86
86
  }
87
87
  ret += `}\n\n`;
88
88
  ret += `await initializeABAP();\n\n`;
89
- ret += `${this.buildImports(reg, useImport, options)}`;
89
+ ret += `${this.buildImports(reg, useImport, options, pluginOutputs)}`;
90
90
  if (options?.setup?.postFunction !== undefined) {
91
91
  ret += `\n\nawait setup.${options?.setup?.postFunction}();\n`;
92
92
  }
93
93
  return ret;
94
94
  }
95
- buildImports(reg, useImport, options) {
95
+ buildImports(reg, useImport, options, pluginOutputs) {
96
96
  // note: ES modules are hoised, so use the dynamic import(), due to setting of globalThis.abap
97
97
  // some sorting required: eg. a class constructor using constant from interface
98
98
  const list = [];
@@ -105,6 +105,9 @@ globalThis.abap = new runtime.ABAP();\n`;
105
105
  return `await import("./${filename}.mjs");`;
106
106
  }
107
107
  };
108
+ for (const pluginOutput of pluginOutputs || []) {
109
+ list.push(imp(pluginOutput.filename.replace(/\.mjs$/i, "")));
110
+ }
108
111
  for (const obj of reg.getObjects()) {
109
112
  if (obj instanceof abaplint.Objects.Table
110
113
  || obj instanceof abaplint.Objects.DataElement
@@ -40,6 +40,18 @@ export declare enum UnknownTypesEnum {
40
40
  compileError = "compileError",
41
41
  runtimeError = "runtimeError"
42
42
  }
43
+ /** handles additional object types, may be supplied by a separate npm package */
44
+ export interface ITranspilerPlugin {
45
+ /** object types handled by the plugin, merged into allowed_object_types during validation */
46
+ objectTypes(): string[];
47
+ /** returns undefined if the object is not handled by the plugin,
48
+ * returned output files are imported in the initialization script,
49
+ * return an empty array to accept the object without producing output */
50
+ handleObject(obj: abaplint.IObject, reg: abaplint.IRegistry, options: ITranspilerOptions): IOutputFile[] | undefined;
51
+ /** optional, called after the default schemas and inserts are built,
52
+ * amend the database setup by mutating the supplied result directly */
53
+ amendDatabaseSetup?(dbSetup: DatabaseSetupResult, reg: abaplint.IRegistry, options: ITranspilerOptions): void;
54
+ }
43
55
  export interface ITranspilerOptions {
44
56
  /** ignore syntax check, used for internal testing */
45
57
  ignoreSyntaxCheck?: boolean;
@@ -1,8 +1,9 @@
1
1
  import { Issue, IRegistry, IConfig } from "@abaplint/core";
2
- import { ITranspilerOptions } from "./types";
2
+ import { ITranspilerOptions, ITranspilerPlugin } from "./types";
3
3
  export declare const config: IConfig;
4
4
  export declare class Validation {
5
5
  private readonly options;
6
- constructor(options?: ITranspilerOptions);
6
+ private readonly plugin;
7
+ constructor(options?: ITranspilerOptions, plugin?: ITranspilerPlugin);
7
8
  run(reg: IRegistry): readonly Issue[];
8
9
  }
@@ -3,6 +3,74 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Validation = exports.config = void 0;
4
4
  const core_1 = require("@abaplint/core");
5
5
  const types_1 = require("./types");
6
+ const defaultAllowedObjectTypes = [
7
+ "APIS",
8
+ "AUTH",
9
+ "CLAS",
10
+ "DEVC",
11
+ "DOMA",
12
+ "DTEL",
13
+ "ENHO",
14
+ "ENHS",
15
+ "ENQU",
16
+ "FUGR",
17
+ "HTTP",
18
+ "INTF",
19
+ "IWMO",
20
+ "IWOM",
21
+ "IWPR",
22
+ "IWSG",
23
+ "IWSV",
24
+ "MSAG",
25
+ "NROB",
26
+ "NSPC",
27
+ "OA2P",
28
+ "PARA",
29
+ "PINF",
30
+ "PROG",
31
+ "WAPA",
32
+ "SHLP",
33
+ "SHMA",
34
+ "SICF",
35
+ "SMIM",
36
+ "SPLO",
37
+ "SRFC",
38
+ "SUSC",
39
+ "SUSH",
40
+ "SUSO",
41
+ "SXCI",
42
+ "TABL",
43
+ "TOBJ",
44
+ "TRAN",
45
+ "TTYP",
46
+ "TYPE",
47
+ "VCLS",
48
+ "VIEW",
49
+ "W3MI",
50
+ "XSLT",
51
+ "ZN01",
52
+ "ZN02",
53
+ "ZN03",
54
+ "ZN04",
55
+ "ZN05",
56
+ "ZN06",
57
+ "ZN07",
58
+ "ZN08",
59
+ "ZN09",
60
+ "ZN10",
61
+ "ZN11",
62
+ "ZN12",
63
+ "ZN13",
64
+ "ZN14",
65
+ "ZN15",
66
+ "ZN16",
67
+ "ZN17",
68
+ "ZN18",
69
+ "ZN19",
70
+ "ZN20",
71
+ "ZN21",
72
+ "ZN22",
73
+ ];
6
74
  exports.config = {
7
75
  "global": {
8
76
  "files": "/**/*.*",
@@ -25,75 +93,7 @@ exports.config = {
25
93
  },
26
94
  "parser_error": true,
27
95
  "allowed_object_types": {
28
- "allowed": [
29
- "APIS",
30
- "AUTH",
31
- "CLAS",
32
- "DEVC",
33
- "DOMA",
34
- "DTEL",
35
- "ENHO",
36
- "ENHS",
37
- "ENQU",
38
- "FUGR",
39
- "HTTP",
40
- "INTF",
41
- "IWMO",
42
- "IWOM",
43
- "IWPR",
44
- "IWSG",
45
- "IWSV",
46
- "MSAG",
47
- "NROB",
48
- "NSPC",
49
- "OA2P",
50
- "PARA",
51
- "PINF",
52
- "PROG",
53
- "WAPA",
54
- "SHLP",
55
- "SHMA",
56
- "SICF",
57
- "SMIM",
58
- "SMIM",
59
- "SPLO",
60
- "SRFC",
61
- "SUSC",
62
- "SUSH",
63
- "SUSO",
64
- "SXCI",
65
- "TABL",
66
- "TOBJ",
67
- "TRAN",
68
- "TTYP",
69
- "TYPE",
70
- "VCLS",
71
- "VIEW",
72
- "W3MI",
73
- "XSLT",
74
- "ZN01",
75
- "ZN02",
76
- "ZN03",
77
- "ZN04",
78
- "ZN05",
79
- "ZN06",
80
- "ZN07",
81
- "ZN08",
82
- "ZN09",
83
- "ZN10",
84
- "ZN11",
85
- "ZN12",
86
- "ZN13",
87
- "ZN14",
88
- "ZN15",
89
- "ZN16",
90
- "ZN17",
91
- "ZN18",
92
- "ZN19",
93
- "ZN20",
94
- "ZN21",
95
- "ZN22",
96
- ],
96
+ "allowed": defaultAllowedObjectTypes,
97
97
  },
98
98
  "unknown_types": true,
99
99
  "ambiguous_statement": true,
@@ -110,8 +110,10 @@ exports.config = {
110
110
  // hmm this ^ is okay? since lines will be prefixed with "abap.builtin"?
111
111
  class Validation {
112
112
  options;
113
- constructor(options) {
113
+ plugin;
114
+ constructor(options, plugin) {
114
115
  this.options = options;
116
+ this.plugin = plugin;
115
117
  }
116
118
  run(reg) {
117
119
  if (this.options?.ignoreSyntaxCheck === true) {
@@ -121,6 +123,13 @@ class Validation {
121
123
  exports.config.rules["check_syntax"] = true;
122
124
  }
123
125
  exports.config.rules["forbidden_identifier"]["check"] = ["^unique\\d+$"];
126
+ const allowed = [...defaultAllowedObjectTypes];
127
+ for (const type of this.plugin?.objectTypes() || []) {
128
+ if (allowed.includes(type.toUpperCase()) === false) {
129
+ allowed.push(type.toUpperCase());
130
+ }
131
+ }
132
+ exports.config.rules["allowed_object_types"]["allowed"] = allowed;
124
133
  if (this.options?.unknownTypes === types_1.UnknownTypesEnum.runtimeError) {
125
134
  // this is not a constant, just a regex that happens to not match anything
126
135
  exports.config.syntax.errorNamespace = "VOID_EVERYTHING";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler",
3
- "version": "2.13.32",
3
+ "version": "2.13.34",
4
4
  "description": "Transpiler",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/src/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "author": "abaplint",
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
- "@abaplint/core": "^2.119.54",
32
+ "@abaplint/core": "^2.119.55",
33
33
  "source-map": "^0.7.6"
34
34
  },
35
35
  "devDependencies": {