@open-rap/runtime 0.0.0-stage → 0.1.0

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.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +14 -2
  3. package/dist/abap/background.d.ts +14 -0
  4. package/dist/abap/background.js +130 -0
  5. package/dist/abap/background.js.map +1 -0
  6. package/dist/abap/bridge.d.ts +62 -0
  7. package/dist/abap/bridge.js +402 -0
  8. package/dist/abap/bridge.js.map +1 -0
  9. package/dist/abap/convert.d.ts +26 -0
  10. package/dist/abap/convert.js +197 -0
  11. package/dist/abap/convert.js.map +1 -0
  12. package/dist/abap/http.d.ts +34 -0
  13. package/dist/abap/http.js +133 -0
  14. package/dist/abap/http.js.map +1 -0
  15. package/dist/abap/mail.d.ts +10 -0
  16. package/dist/abap/mail.js +83 -0
  17. package/dist/abap/mail.js.map +1 -0
  18. package/dist/abap/odata-client.d.ts +33 -0
  19. package/dist/abap/odata-client.js +576 -0
  20. package/dist/abap/odata-client.js.map +1 -0
  21. package/dist/abap/sql.d.ts +92 -0
  22. package/dist/abap/sql.js +261 -0
  23. package/dist/abap/sql.js.map +1 -0
  24. package/dist/abap/utils.d.ts +41 -0
  25. package/dist/abap/utils.js +976 -0
  26. package/dist/abap/utils.js.map +1 -0
  27. package/dist/app.d.ts +53 -0
  28. package/dist/app.js +169 -0
  29. package/dist/app.js.map +1 -0
  30. package/dist/auth/auth.d.ts +68 -0
  31. package/dist/auth/auth.js +140 -0
  32. package/dist/auth/auth.js.map +1 -0
  33. package/dist/auth/authorizations.d.ts +39 -0
  34. package/dist/auth/authorizations.js +103 -0
  35. package/dist/auth/authorizations.js.map +1 -0
  36. package/dist/auth/business-users.d.ts +15 -0
  37. package/dist/auth/business-users.js +36 -0
  38. package/dist/auth/business-users.js.map +1 -0
  39. package/dist/auth/dev-oauth.d.ts +38 -0
  40. package/dist/auth/dev-oauth.js +156 -0
  41. package/dist/auth/dev-oauth.js.map +1 -0
  42. package/dist/auth/environment.d.ts +7 -0
  43. package/dist/auth/environment.js +57 -0
  44. package/dist/auth/environment.js.map +1 -0
  45. package/dist/auth/session.d.ts +45 -0
  46. package/dist/auth/session.js +257 -0
  47. package/dist/auth/session.js.map +1 -0
  48. package/dist/auth/user.d.ts +21 -0
  49. package/dist/auth/user.js +12 -0
  50. package/dist/auth/user.js.map +1 -0
  51. package/dist/db/database.d.ts +30 -0
  52. package/dist/db/database.js +131 -0
  53. package/dist/db/database.js.map +1 -0
  54. package/dist/db/seed.d.ts +9 -0
  55. package/dist/db/seed.js +63 -0
  56. package/dist/db/seed.js.map +1 -0
  57. package/dist/index.d.ts +20 -0
  58. package/dist/index.js +21 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/launchpad/dev.d.ts +14 -0
  61. package/dist/launchpad/dev.js +48 -0
  62. package/dist/launchpad/dev.js.map +1 -0
  63. package/dist/launchpad/proxy.d.ts +30 -0
  64. package/dist/launchpad/proxy.js +98 -0
  65. package/dist/launchpad/proxy.js.map +1 -0
  66. package/dist/launchpad/server.d.ts +77 -0
  67. package/dist/launchpad/server.js +177 -0
  68. package/dist/launchpad/server.js.map +1 -0
  69. package/dist/mcp/server.d.ts +22 -0
  70. package/dist/mcp/server.js +222 -0
  71. package/dist/mcp/server.js.map +1 -0
  72. package/dist/odata/access.d.ts +31 -0
  73. package/dist/odata/access.js +142 -0
  74. package/dist/odata/access.js.map +1 -0
  75. package/dist/odata/batch.d.ts +36 -0
  76. package/dist/odata/batch.js +147 -0
  77. package/dist/odata/batch.js.map +1 -0
  78. package/dist/odata/csrf.d.ts +13 -0
  79. package/dist/odata/csrf.js +27 -0
  80. package/dist/odata/csrf.js.map +1 -0
  81. package/dist/odata/custom.d.ts +90 -0
  82. package/dist/odata/custom.js +373 -0
  83. package/dist/odata/custom.js.map +1 -0
  84. package/dist/odata/draft.d.ts +78 -0
  85. package/dist/odata/draft.js +590 -0
  86. package/dist/odata/draft.js.map +1 -0
  87. package/dist/odata/errors.d.ts +27 -0
  88. package/dist/odata/errors.js +41 -0
  89. package/dist/odata/errors.js.map +1 -0
  90. package/dist/odata/handler.d.ts +90 -0
  91. package/dist/odata/handler.js +312 -0
  92. package/dist/odata/handler.js.map +1 -0
  93. package/dist/odata/json.d.ts +23 -0
  94. package/dist/odata/json.js +85 -0
  95. package/dist/odata/json.js.map +1 -0
  96. package/dist/odata/read.d.ts +90 -0
  97. package/dist/odata/read.js +686 -0
  98. package/dist/odata/read.js.map +1 -0
  99. package/dist/odata/service.d.ts +45 -0
  100. package/dist/odata/service.js +145 -0
  101. package/dist/odata/service.js.map +1 -0
  102. package/dist/odata/uri/ast.d.ts +103 -0
  103. package/dist/odata/uri/ast.js +3 -0
  104. package/dist/odata/uri/ast.js.map +1 -0
  105. package/dist/odata/uri/parser.d.ts +26 -0
  106. package/dist/odata/uri/parser.js +697 -0
  107. package/dist/odata/uri/parser.js.map +1 -0
  108. package/dist/odata/write.d.ts +127 -0
  109. package/dist/odata/write.js +799 -0
  110. package/dist/odata/write.js.map +1 -0
  111. package/dist/platform.d.ts +14 -0
  112. package/dist/platform.js +66 -0
  113. package/dist/platform.js.map +1 -0
  114. package/dist/rap/bo.d.ts +76 -0
  115. package/dist/rap/bo.js +184 -0
  116. package/dist/rap/bo.js.map +1 -0
  117. package/dist/rap/kernel.d.ts +7 -0
  118. package/dist/rap/kernel.js +287 -0
  119. package/dist/rap/kernel.js.map +1 -0
  120. package/dist/rap/runtime.d.ts +84 -0
  121. package/dist/rap/runtime.js +128 -0
  122. package/dist/rap/runtime.js.map +1 -0
  123. package/dist/rap/transaction.d.ts +227 -0
  124. package/dist/rap/transaction.js +1385 -0
  125. package/dist/rap/transaction.js.map +1 -0
  126. package/dist/rap/types.d.ts +74 -0
  127. package/dist/rap/types.js +25 -0
  128. package/dist/rap/types.js.map +1 -0
  129. package/dist/server.d.ts +34 -0
  130. package/dist/server.js +114 -0
  131. package/dist/server.js.map +1 -0
  132. package/dist/ui/plugin.d.ts +14 -0
  133. package/dist/ui/plugin.js +47 -0
  134. package/dist/ui/plugin.js.map +1 -0
  135. package/dist/ui/resources.d.ts +22 -0
  136. package/dist/ui/resources.js +88 -0
  137. package/dist/ui/resources.js.map +1 -0
  138. package/dist/ui/variants.d.ts +25 -0
  139. package/dist/ui/variants.js +68 -0
  140. package/dist/ui/variants.js.map +1 -0
  141. package/dist/values.d.ts +43 -0
  142. package/dist/values.js +367 -0
  143. package/dist/values.js.map +1 -0
  144. package/package.json +60 -3
@@ -0,0 +1,27 @@
1
+ /**
2
+ * CSRF tokens in the SAP Gateway style: a client fetches a token with `X-CSRF-Token: Fetch` on a
3
+ * GET or HEAD request, and sends it back on modifying requests. Only requests authenticated by a
4
+ * session cookie need it: bearer tokens and the development mode carry no ambient credentials.
5
+ */
6
+ import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
7
+ export class CsrfTokens {
8
+ secret;
9
+ constructor(secret) {
10
+ this.secret = secret === undefined ? randomBytes(32) : Buffer.from(secret);
11
+ }
12
+ token(user, session = "") {
13
+ return createHmac("sha256", this.secret).update(`${user.id}\u0000${session}`).digest("base64url");
14
+ }
15
+ valid(user, token, session = "") {
16
+ if (token === undefined) {
17
+ return false;
18
+ }
19
+ const expected = Buffer.from(this.token(user, session));
20
+ const given = Buffer.from(token);
21
+ return expected.length === given.length && timingSafeEqual(expected, given);
22
+ }
23
+ required(user, method) {
24
+ return user.authenticatedBy === "session" && !["GET", "HEAD", "OPTIONS"].includes(method.toUpperCase());
25
+ }
26
+ }
27
+ //# sourceMappingURL=csrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../src/odata/csrf.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGvE,MAAM,OAAO,UAAU;IACJ,MAAM,CAAS;IAEhC,YAAmB,MAAe;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7E,CAAC;IAEM,KAAK,CAAC,IAAU,EAAE,OAAO,GAAG,EAAE;QACnC,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACpG,CAAC;IAEM,KAAK,CAAC,IAAU,EAAE,KAAyB,EAAE,OAAO,GAAG,EAAE;QAC9D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC9E,CAAC;IAEM,QAAQ,CAAC,IAAU,EAAE,MAAc;QACxC,OAAO,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1G,CAAC;CACF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Reads of custom entities (decision D43): the query class of the entity
3
+ * (`@ObjectModel.query.implementedBy`) is called with the request of the OData read — filter as
4
+ * ABAP SQL condition and as ranges, sort elements, paging, requested elements, count — and
5
+ * returns the rows through `io_response->set_data`, as in ABAP Cloud.
6
+ */
7
+ import { type AbapType, type EntityModel } from "@open-rap/model";
8
+ import type { Database } from "../db/database.js";
9
+ import type { RapRuntime } from "../rap/runtime.js";
10
+ import { type CanonicalValue } from "../values.js";
11
+ import type { Row } from "./read.js";
12
+ import type { ServiceRuntime, TypeInfo } from "./service.js";
13
+ import type { Expr, OrderItem } from "./uri/ast.js";
14
+ /** A condition on the elements of a custom entity, values in canonical form. */
15
+ export type Cond = {
16
+ kind: "cmp";
17
+ name: string;
18
+ op: "eq" | "ne" | "gt" | "ge" | "lt" | "le";
19
+ value: CanonicalValue;
20
+ } | {
21
+ kind: "like";
22
+ name: string;
23
+ pattern: string;
24
+ negated?: boolean;
25
+ } | {
26
+ kind: "and" | "or";
27
+ items: Cond[];
28
+ } | {
29
+ kind: "not";
30
+ item: Cond;
31
+ };
32
+ export interface QueryCall {
33
+ filter?: Cond;
34
+ /** Conditions the rows must meet even if the query class ignores them (keys, navigations). */
35
+ scope?: Cond[];
36
+ orderby?: OrderItem[];
37
+ top?: number;
38
+ skip?: number;
39
+ count: boolean;
40
+ data: boolean;
41
+ /** OData properties to read. */
42
+ properties: string[];
43
+ search?: string;
44
+ }
45
+ export interface QueryResult {
46
+ rows: Row[];
47
+ total?: number;
48
+ }
49
+ /** A canonical value in the internal format of ABAP (dates YYYYMMDD, booleans X…). */
50
+ export declare function abapText(t: AbapType, value: CanonicalValue): string;
51
+ export declare class CustomQueries {
52
+ private readonly service;
53
+ private readonly db;
54
+ private readonly rap;
55
+ /** The rows handed over by io_response of the running queries (innermost last). */
56
+ private readonly running;
57
+ constructor(service: ServiceRuntime, db: () => Database, rap: RapRuntime);
58
+ private type;
59
+ /** The element behind an OData property. */
60
+ fieldName(info: TypeInfo, property: string): string;
61
+ /** The condition of an OData $filter. */
62
+ condition(info: TypeInfo, expr: Expr): Cond;
63
+ /** The element of a property path of $filter. */
64
+ private element;
65
+ private literal;
66
+ /** The condition as get_as_sql_string gives it: `( PRODUCTID = 'P1' AND … )`. */
67
+ sql(entity: EntityModel, cond: Cond): string;
68
+ /**
69
+ * The condition as get_as_ranges gives it: one range table per element, the elements combined
70
+ * with AND, the lines of a range with OR. Undefined when it cannot be expressed so.
71
+ */
72
+ ranges(entity: EntityModel, cond: Cond): Map<string, Array<{
73
+ sign: string;
74
+ option: string;
75
+ low: string;
76
+ high: string;
77
+ }>> | undefined;
78
+ private rangeLines;
79
+ /** Reads a custom entity of the service: rows keyed by OData property. */
80
+ select(info: TypeInfo, call: QueryCall): Promise<QueryResult>;
81
+ /**
82
+ * Calls the query class of a custom entity: rows keyed by element. Inside a LUW (the RAP
83
+ * runtime reading the instances of a BO), in that LUW; otherwise in a LUW of its own,
84
+ * serialized with the other ABAP work.
85
+ */
86
+ run(entity: EntityModel, call: QueryCall): Promise<QueryResult>;
87
+ private call;
88
+ }
89
+ /** Whether a row meets a condition of a scope (equalities, and, or). */
90
+ export declare function holds(row: Row, cond: Cond): boolean;
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Reads of custom entities (decision D43): the query class of the entity
3
+ * (`@ObjectModel.query.implementedBy`) is called with the request of the OData read — filter as
4
+ * ABAP SQL condition and as ranges, sort elements, paging, requested elements, count — and
5
+ * returns the rows through `io_response->set_data`, as in ABAP Cloud.
6
+ */
7
+ import { isUuid } from "@open-rap/model";
8
+ import { developmentUser } from "../auth/user.js";
9
+ import { abapGlobal, appendRow, component, getAbapValue, rowsOf } from "../abap/convert.js";
10
+ import { literalToCanonical } from "../values.js";
11
+ import { currentReader } from "./access.js";
12
+ import { badRequest, notImplemented, ODataError } from "./errors.js";
13
+ const SQL_OPERATORS = { eq: "=", ne: "<>", gt: ">", ge: ">=", lt: "<", le: "<=" };
14
+ const RANGE_OPTIONS = { eq: "EQ", ne: "NE", gt: "GT", ge: "GE", lt: "LT", le: "LE" };
15
+ /** A canonical value in the internal format of ABAP (dates YYYYMMDD, booleans X…). */
16
+ export function abapText(t, value) {
17
+ if (value === null)
18
+ return "";
19
+ if (typeof value === "boolean")
20
+ return value ? "X" : "";
21
+ const text = String(value);
22
+ switch (t.kind) {
23
+ case "dats":
24
+ return text.replace(/-/g, "");
25
+ case "tims":
26
+ return text.replace(/:/g, "");
27
+ case "raw":
28
+ return isUuid(t) ? text.replace(/-/g, "").toUpperCase() : text.toUpperCase();
29
+ case "timestamp":
30
+ return text.replace(/[-:T]/g, "").replace(/\..*$/, "").replace(/Z$/, "");
31
+ case "timestampl": {
32
+ const [main = "", fraction = ""] = text.replace(/Z$/, "").split(".");
33
+ return `${main.replace(/[-:T]/g, "")}.${fraction.padEnd(7, "0").slice(0, 7)}`;
34
+ }
35
+ case "utclong":
36
+ return text.replace(/Z$/, "");
37
+ case "bool":
38
+ return text === "true" || text === "X" ? "X" : "";
39
+ default:
40
+ return text;
41
+ }
42
+ }
43
+ const quote = (text) => `'${text.replace(/'/g, "''")}'`;
44
+ export class CustomQueries {
45
+ service;
46
+ db;
47
+ rap;
48
+ /** The rows handed over by io_response of the running queries (innermost last). */
49
+ running = [];
50
+ constructor(service, db, rap) {
51
+ this.service = service;
52
+ this.db = db;
53
+ this.rap = rap;
54
+ const kernel = abapGlobal().Classes["ZRAP_EML"];
55
+ kernel.query_data = async (input) => {
56
+ const current = this.running[this.running.length - 1];
57
+ if (current !== undefined) {
58
+ // a copy: the query class may reuse its table
59
+ current.rows = rowsOf(input.data).map((row) => row.clone());
60
+ }
61
+ };
62
+ rap.customRead = async (entity, equalities) => {
63
+ const scope = { kind: "and", items: equalities.map((e) => ({ kind: "cmp", name: e.name, op: "eq", value: e.value })) };
64
+ const result = await this.run(entity, { scope: [scope], count: false, data: true, properties: entity.fields.map((f) => f.name) });
65
+ return result.rows;
66
+ };
67
+ kernel.query_total = async (input) => {
68
+ const current = this.running[this.running.length - 1];
69
+ if (current !== undefined) {
70
+ current.total = Number(input.total.get());
71
+ }
72
+ };
73
+ }
74
+ // -------------------------------------------------------------------------------------------
75
+ // conditions
76
+ type(entity, name) {
77
+ const field = entity.fields.find((f) => f.name === name);
78
+ if (field === undefined) {
79
+ throw new Error(`${entity.name} has no element ${name}`);
80
+ }
81
+ return field.type;
82
+ }
83
+ /** The element behind an OData property. */
84
+ fieldName(info, property) {
85
+ return this.service.property(info, property).field.name;
86
+ }
87
+ /** The condition of an OData $filter. */
88
+ condition(info, expr) {
89
+ switch (expr.kind) {
90
+ case "binary": {
91
+ if (expr.op === "and" || expr.op === "or") {
92
+ return { kind: expr.op, items: [this.condition(info, expr.left), this.condition(info, expr.right)] };
93
+ }
94
+ const [member, literal, op] = expr.left.kind === "member" && expr.right.kind === "literal"
95
+ ? [expr.left, expr.right, expr.op]
96
+ : expr.right.kind === "member" && expr.left.kind === "literal"
97
+ ? [expr.right, expr.left, { eq: "eq", ne: "ne", gt: "lt", ge: "le", lt: "gt", le: "ge" }[expr.op]]
98
+ : [undefined, undefined, expr.op];
99
+ if (member === undefined || literal === undefined) {
100
+ throw notImplemented("$filter of a custom entity: comparisons of an element with a literal");
101
+ }
102
+ return { kind: "cmp", name: this.element(info, member.path), op, value: this.literal(info, member.path, literal.literal) };
103
+ }
104
+ case "not":
105
+ return { kind: "not", item: this.condition(info, expr.operand) };
106
+ case "in": {
107
+ if (expr.operand.kind !== "member") {
108
+ throw notImplemented("$filter of a custom entity: in on an element");
109
+ }
110
+ const path = expr.operand.path;
111
+ return {
112
+ kind: "or",
113
+ items: expr.list.map((item) => {
114
+ if (item.kind !== "literal")
115
+ throw notImplemented("$filter of a custom entity: in with literals");
116
+ return { kind: "cmp", name: this.element(info, path), op: "eq", value: this.literal(info, path, item.literal) };
117
+ }),
118
+ };
119
+ }
120
+ case "call": {
121
+ const [subject, argument] = expr.args;
122
+ if (["contains", "startswith", "endswith"].includes(expr.name) && subject?.kind === "member" && argument?.kind === "literal") {
123
+ const text = String(argument.literal.value ?? "").replace(/[%_]/g, (c) => `\\${c}`);
124
+ const pattern = expr.name === "contains" ? `%${text}%` : expr.name === "startswith" ? `${text}%` : `%${text}`;
125
+ return { kind: "like", name: this.element(info, subject.path), pattern };
126
+ }
127
+ throw notImplemented(`$filter of a custom entity: the function ${expr.name}`);
128
+ }
129
+ case "member":
130
+ if (this.type(info.entity, this.element(info, expr.path)).kind === "bool") {
131
+ return { kind: "cmp", name: this.element(info, expr.path), op: "eq", value: true };
132
+ }
133
+ throw badRequest(`$filter: ${expr.path.join("/")} is not a boolean`);
134
+ default:
135
+ throw notImplemented("$filter of a custom entity: this expression");
136
+ }
137
+ }
138
+ /** The element of a property path of $filter. */
139
+ element(info, path) {
140
+ const name = path[0] ?? "";
141
+ if (path.length !== 1 || !info.properties.has(name)) {
142
+ throw badRequest(`$filter: ${info.type.name} has no property ${path.join("/")}`);
143
+ }
144
+ return this.fieldName(info, name);
145
+ }
146
+ literal(info, path, literal) {
147
+ const { property, field } = this.service.property(info, path[0] ?? "");
148
+ return literalToCanonical(field.type, property.edm, literal, property.name);
149
+ }
150
+ /** The condition as get_as_sql_string gives it: `( PRODUCTID = 'P1' AND … )`. */
151
+ sql(entity, cond) {
152
+ switch (cond.kind) {
153
+ case "cmp": {
154
+ const name = cond.name.toUpperCase();
155
+ if (cond.value === null) {
156
+ return cond.op === "ne" ? `${name} IS NOT NULL` : `${name} IS NULL`;
157
+ }
158
+ const text = abapText(this.type(entity, cond.name), cond.value);
159
+ const numeric = typeof cond.value === "number";
160
+ return `${name} ${SQL_OPERATORS[cond.op]} ${numeric ? text : quote(text)}`;
161
+ }
162
+ case "like":
163
+ return `${cond.name.toUpperCase()} ${cond.negated === true ? "NOT LIKE" : "LIKE"} ${quote(cond.pattern)}`;
164
+ case "not":
165
+ return `NOT ( ${this.sql(entity, cond.item)} )`;
166
+ default:
167
+ return `( ${cond.items.map((c) => this.sql(entity, c)).join(cond.kind === "and" ? " AND " : " OR ")} )`;
168
+ }
169
+ }
170
+ /**
171
+ * The condition as get_as_ranges gives it: one range table per element, the elements combined
172
+ * with AND, the lines of a range with OR. Undefined when it cannot be expressed so.
173
+ */
174
+ ranges(entity, cond) {
175
+ const result = new Map();
176
+ const conjuncts = cond.kind === "and" ? flattenAnd(cond) : [cond];
177
+ for (const conjunct of conjuncts) {
178
+ const lines = this.rangeLines(entity, conjunct);
179
+ if (lines === undefined)
180
+ return undefined;
181
+ const existing = result.get(lines.name);
182
+ if (existing === undefined) {
183
+ result.set(lines.name, lines.lines);
184
+ continue;
185
+ }
186
+ // the same element twice in an AND: an interval, else not expressible
187
+ const merged = interval(existing, lines.lines);
188
+ if (merged === undefined)
189
+ return undefined;
190
+ result.set(lines.name, merged);
191
+ }
192
+ return result;
193
+ }
194
+ rangeLines(entity, cond) {
195
+ switch (cond.kind) {
196
+ case "cmp":
197
+ if (cond.value === null)
198
+ return undefined;
199
+ return { name: cond.name.toUpperCase(), lines: [{ sign: "I", option: RANGE_OPTIONS[cond.op], low: abapText(this.type(entity, cond.name), cond.value), high: "" }] };
200
+ case "like": {
201
+ if (/\\[%_]/.test(cond.pattern))
202
+ return undefined;
203
+ return { name: cond.name.toUpperCase(), lines: [{ sign: cond.negated === true ? "E" : "I", option: "CP", low: cond.pattern.replace(/%/g, "*").replace(/_/g, "+"), high: "" }] };
204
+ }
205
+ case "not": {
206
+ const inner = this.rangeLines(entity, cond.item);
207
+ if (inner === undefined || inner.lines.length !== 1)
208
+ return undefined;
209
+ return { name: inner.name, lines: inner.lines.map((l) => ({ ...l, sign: l.sign === "I" ? "E" : "I" })) };
210
+ }
211
+ case "or": {
212
+ const parts = cond.items.flatMap((c) => (c.kind === "or" ? c.items : [c])).map((c) => this.rangeLines(entity, c));
213
+ if (parts.some((p) => p === undefined))
214
+ return undefined;
215
+ const names = new Set(parts.map((p) => p?.name));
216
+ if (names.size !== 1 || parts.some((p) => p?.lines.some((l) => l.sign === "E")))
217
+ return undefined;
218
+ return { name: parts[0]?.name ?? "", lines: parts.flatMap((p) => p?.lines ?? []) };
219
+ }
220
+ default:
221
+ return undefined;
222
+ }
223
+ }
224
+ // -------------------------------------------------------------------------------------------
225
+ // the call of the query class
226
+ /** Reads a custom entity of the service: rows keyed by OData property. */
227
+ async select(info, call) {
228
+ const orderby = (call.orderby ?? []).map((item) => {
229
+ const name = item.path[0] ?? "";
230
+ if (item.path.length !== 1 || !info.properties.has(name)) {
231
+ throw badRequest(`$orderby: ${info.type.name} has no property ${item.path.join("/")}`);
232
+ }
233
+ return { path: [this.fieldName(info, name)], descending: item.descending };
234
+ });
235
+ const result = await this.run(info.entity, { ...call, orderby, properties: call.properties.map((p) => this.fieldName(info, p)) });
236
+ const rows = result.rows.map((byField) => {
237
+ const row = {};
238
+ for (const [property, { field }] of info.properties) {
239
+ row[property] = byField[field.name] ?? null;
240
+ }
241
+ return row;
242
+ });
243
+ return result.total === undefined ? { rows } : { rows, total: result.total };
244
+ }
245
+ /**
246
+ * Calls the query class of a custom entity: rows keyed by element. Inside a LUW (the RAP
247
+ * runtime reading the instances of a BO), in that LUW; otherwise in a LUW of its own,
248
+ * serialized with the other ABAP work.
249
+ */
250
+ async run(entity, call) {
251
+ const user = currentReader() ?? developmentUser();
252
+ return this.rap.inLuw() ? this.call(entity, call) : this.rap.transaction(this.db(), user, "en", () => this.call(entity, call));
253
+ }
254
+ async call(entity, call) {
255
+ const queryClass = entity.queryClass;
256
+ const abap = abapGlobal();
257
+ const Query = queryClass === undefined ? undefined : abap.Classes[queryClass];
258
+ if (Query === undefined) {
259
+ throw new ODataError(500, "QUERY_CLASS", `${entity.name}: query class ${queryClass ?? "?"} not loaded`);
260
+ }
261
+ const request = await new abap.Classes["ZRAP_CL_QUERY_REQUEST"]().constructor_();
262
+ request.entity_id.set(entity.name.toUpperCase());
263
+ request.data_requested.set(call.data ? "X" : "");
264
+ request.count_requested.set(call.count ? "X" : "");
265
+ request.search_expression.set(call.search ?? "");
266
+ const paging = request.paging.get();
267
+ paging.offset.set(call.skip ?? 0);
268
+ paging.page_size.set(call.top ?? -1);
269
+ for (const name of call.properties) {
270
+ appendRow(request.requested_elements, (row) => row.set(name.toUpperCase()));
271
+ }
272
+ for (const item of call.orderby ?? []) {
273
+ appendRow(request.sort_elements, (row) => {
274
+ component(row, "element_name").set((item.path[0] ?? "").toUpperCase());
275
+ component(row, "descending").set(item.descending ? "X" : "");
276
+ });
277
+ }
278
+ const conditions = [...(call.scope ?? []), ...(call.filter === undefined ? [] : [call.filter])];
279
+ const filterCond = conditions.length === 0 ? undefined : conditions.length === 1 ? conditions[0] : { kind: "and", items: conditions };
280
+ if (filterCond !== undefined) {
281
+ const filter = request.filter.get();
282
+ filter.sql.set(this.sql(entity, filterCond));
283
+ const ranges = this.ranges(entity, filterCond);
284
+ if (ranges === undefined) {
285
+ filter.no_range.set("X");
286
+ }
287
+ else {
288
+ for (const [name, lines] of ranges) {
289
+ appendRow(filter.ranges, (pair) => {
290
+ component(pair, "name").set(name);
291
+ for (const line of lines) {
292
+ appendRow(component(pair, "range"), (r) => {
293
+ for (const [k, v] of Object.entries(line))
294
+ component(r, k).set(v);
295
+ });
296
+ }
297
+ });
298
+ }
299
+ }
300
+ }
301
+ const response = await new abap.Classes["ZRAP_CL_QUERY_RESPONSE"]().constructor_();
302
+ const instance = await new Query().constructor_();
303
+ const ref = (object) => new abap.types.ABAPObject().set(object);
304
+ const current = { entity, rows: [] };
305
+ this.running.push(current);
306
+ try {
307
+ await instance.if_rap_query_provider$select({ io_request: ref(request), io_response: ref(response) });
308
+ }
309
+ catch (error) {
310
+ if (error instanceof ODataError)
311
+ throw error;
312
+ throw new ODataError(500, "QUERY_FAILED", `${entity.name}: ${exceptionText(this.rap, error)}`);
313
+ }
314
+ finally {
315
+ this.running.pop();
316
+ }
317
+ const rows = current.rows
318
+ .map((abapRow) => {
319
+ const row = {};
320
+ for (const field of entity.fields) {
321
+ const value = component(abapRow, field.name);
322
+ row[field.name] = value === undefined ? null : getAbapValue(value, field.type);
323
+ }
324
+ return row;
325
+ })
326
+ // keys and navigations hold even if the query class ignores them
327
+ .filter((row) => (call.scope ?? []).every((c) => holds(row, c)));
328
+ const result = { rows: call.top === undefined || call.top < 0 ? rows : rows.slice(0, call.top) };
329
+ if (call.count) {
330
+ result.total = current.total ?? rows.length;
331
+ }
332
+ return result;
333
+ }
334
+ }
335
+ /** Whether a row meets a condition of a scope (equalities, and, or). */
336
+ export function holds(row, cond) {
337
+ switch (cond.kind) {
338
+ case "cmp":
339
+ return cond.op === "eq" ? row[cond.name] === cond.value : true;
340
+ case "and":
341
+ return cond.items.every((c) => holds(row, c));
342
+ case "or":
343
+ return cond.items.some((c) => holds(row, c));
344
+ default:
345
+ return true;
346
+ }
347
+ }
348
+ function flattenAnd(cond) {
349
+ return cond.kind === "and" ? cond.items.flatMap(flattenAnd) : [cond];
350
+ }
351
+ /** `x ge a and x le b` → `BT a b`. */
352
+ function interval(a, b) {
353
+ const [x, y] = [a[0], b[0]];
354
+ if (a.length !== 1 || b.length !== 1 || x === undefined || y === undefined || x.sign !== "I" || y.sign !== "I")
355
+ return undefined;
356
+ const lower = x.option === "GE" ? x : y.option === "GE" ? y : undefined;
357
+ const upper = x.option === "LE" ? x : y.option === "LE" ? y : undefined;
358
+ return lower !== undefined && upper !== undefined && lower !== upper ? [{ sign: "I", option: "BT", low: lower.low, high: upper.low }] : undefined;
359
+ }
360
+ /** The text of an exception raised by a query class (its own, its T100 text or that of its previous). */
361
+ function exceptionText(rap, error) {
362
+ if (error instanceof Error && !("zrap_text" in error)) {
363
+ return error.message;
364
+ }
365
+ const object = error;
366
+ let text = rap.bridge.exceptionText(object);
367
+ const previous = object?.previous?.get?.();
368
+ if (text === "An exception was raised" && previous !== undefined && previous !== null) {
369
+ text = rap.bridge.exceptionText(previous);
370
+ }
371
+ return text;
372
+ }
373
+ //# sourceMappingURL=custom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom.js","sourceRoot":"","sources":["../../src/odata/custom.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Draft (decision D54): the drafts of a draft BO (`with draft`) are kept in the draft tables, one
3
+ * per entity, with the administrative data of each draft (`rapt_draft_admin`). The OData service
4
+ * reads the active instances and the drafts together (key IsActiveEntity); this module runs the
5
+ * writes on drafts and the actions of the draft:
6
+ *
7
+ * - POST on the root collection creates a draft; POST through a composition of a draft creates a
8
+ * draft child; PATCH and DELETE change or remove drafts, without determinations or validations;
9
+ * - Edit copies an active instance and its compositions into a draft (exclusive: one draft per
10
+ * instance, in process by one user; a draft unchanged for 15 minutes may be taken over);
11
+ * - Activate applies the draft to the active instances through the managed runtime in the LUW of
12
+ * the request (creations, changes and deletions of the composition tree; determinations,
13
+ * validations and the saver run), then removes the draft;
14
+ * - Discard removes the draft, Resume takes it over again, Prepare returns it.
15
+ *
16
+ * Active instances that have a draft cannot be changed directly (409).
17
+ */
18
+ import { type Transaction } from "../rap/transaction.js";
19
+ import type { HandlerContext, ODataRequest, Target } from "./handler.js";
20
+ import type { Outcome, RapWriteHandler } from "./write.js";
21
+ /** A draft not changed for this long may be taken over by another user (SAP: 15 minutes). */
22
+ export declare const DRAFT_LOCK_MINUTES = 15;
23
+ export declare class DraftRuntime {
24
+ private readonly writes;
25
+ constructor(writes: RapWriteHandler);
26
+ private table;
27
+ private isDraftSet;
28
+ private where;
29
+ private rowOf;
30
+ private draft;
31
+ private children;
32
+ private insert;
33
+ /** The change time of the draft, and its ETag field (the ETag of a draft changes with it). */
34
+ private touch;
35
+ private admin;
36
+ private touchAdmin;
37
+ /** Removes a draft instance and the drafts of its compositions. */
38
+ private remove;
39
+ private removeDraft;
40
+ /** A BO `with collaborative draft` (D59). */
41
+ private collaborative;
42
+ /** Adds a user to the users of a collaborative draft (O: owner, E: editor). */
43
+ private addUser;
44
+ private isUser;
45
+ /** A new draft: its administrative data, and its owner for a collaborative draft. */
46
+ private newDraft;
47
+ private expired;
48
+ /** The draft must be in process by the user. */
49
+ private owned;
50
+ /** The key without IsActiveEntity, and its value (undefined: not given). */
51
+ private split;
52
+ /**
53
+ * The outcome of a request on a draft BO when it concerns drafts or the actions of the draft;
54
+ * undefined when the managed runtime handles it (an active instance), after the lock check.
55
+ */
56
+ route(tx: Transaction, request: ODataRequest, target: Target, ctx: HandlerContext, minimal: boolean): Promise<Outcome | undefined>;
57
+ /** An active instance with a draft cannot be changed directly. */
58
+ private checkNotLocked;
59
+ private checkEtag;
60
+ /** Values of a body for a draft: the fields a consumer may write (keys of a creation included). */
61
+ private draftValues;
62
+ private newRow;
63
+ private createRoot;
64
+ /** Deep insert in a draft: the children given inline. */
65
+ private createInline;
66
+ private foreignKey;
67
+ private createChild;
68
+ private update;
69
+ private action;
70
+ /** Copies an active instance and its compositions into the draft tables. */
71
+ private copy;
72
+ /** The fields of a draft the activation writes (not those the runtime computes). */
73
+ private writableFields;
74
+ private changed;
75
+ /** Applies a draft to the active instances; returns the key of the active root. */
76
+ private activate;
77
+ private activateChildren;
78
+ }