@sap/cds 9.3.1 → 9.4.2
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/CHANGELOG.md +54 -3
- package/_i18n/i18n_vi.properties +113 -0
- package/_i18n/messages.properties +106 -17
- package/_i18n/messages_ar.properties +194 -0
- package/_i18n/messages_bg.properties +194 -0
- package/_i18n/messages_cs.properties +194 -0
- package/_i18n/messages_da.properties +194 -0
- package/_i18n/messages_de.properties +194 -0
- package/_i18n/messages_el.properties +194 -0
- package/_i18n/messages_en.properties +194 -0
- package/_i18n/messages_en_US_saptrc.properties +194 -0
- package/_i18n/messages_es.properties +194 -0
- package/_i18n/messages_es_MX.properties +194 -0
- package/_i18n/messages_fi.properties +194 -0
- package/_i18n/messages_fr.properties +194 -0
- package/_i18n/messages_he.properties +194 -0
- package/_i18n/messages_hr.properties +194 -0
- package/_i18n/messages_hu.properties +194 -0
- package/_i18n/messages_it.properties +194 -0
- package/_i18n/messages_ja.properties +194 -0
- package/_i18n/messages_kk.properties +194 -0
- package/_i18n/messages_ko.properties +194 -0
- package/_i18n/messages_ms.properties +194 -0
- package/_i18n/messages_nl.properties +194 -0
- package/_i18n/messages_no.properties +194 -0
- package/_i18n/messages_pl.properties +194 -0
- package/_i18n/messages_pt.properties +194 -0
- package/_i18n/messages_ro.properties +194 -0
- package/_i18n/messages_ru.properties +194 -0
- package/_i18n/messages_sh.properties +194 -0
- package/_i18n/messages_sk.properties +194 -0
- package/_i18n/messages_sl.properties +194 -0
- package/_i18n/messages_sv.properties +194 -0
- package/_i18n/messages_th.properties +194 -0
- package/_i18n/messages_tr.properties +194 -0
- package/_i18n/messages_uk.properties +194 -0
- package/_i18n/messages_vi.properties +194 -0
- package/_i18n/messages_zh_CN.properties +194 -0
- package/_i18n/messages_zh_TW.properties +194 -0
- package/bin/serve.js +9 -1
- package/common.cds +9 -1
- package/lib/compile/cds-compile.js +1 -0
- package/lib/compile/etc/properties.js +1 -0
- package/lib/compile/for/flows.js +70 -4
- package/lib/compile/for/nodejs.js +1 -1
- package/lib/compile/minify.js +84 -56
- package/lib/compile/to/csn.js +2 -0
- package/lib/compile/to/yaml.js +1 -1
- package/lib/env/cds-requires.js +3 -0
- package/lib/i18n/bundles.js +8 -1
- package/lib/i18n/files.js +5 -1
- package/lib/i18n/index.js +1 -5
- package/lib/i18n/localize.js +4 -2
- package/lib/index.js +1 -1
- package/lib/ql/SELECT.js +16 -19
- package/lib/req/validate.js +10 -5
- package/lib/srv/bindings.js +1 -1
- package/lib/srv/cds-serve.js +1 -1
- package/lib/srv/middlewares/auth/ias-auth.js +3 -2
- package/lib/srv/middlewares/auth/jwt-auth.js +3 -2
- package/lib/srv/protocols/hcql.js +8 -6
- package/lib/srv/srv-dispatch.js +4 -8
- package/lib/srv/srv-handlers.js +28 -1
- package/lib/utils/colors.js +54 -49
- package/libx/_runtime/common/generic/flows.js +79 -12
- package/libx/_runtime/fiori/lean-draft.js +10 -2
- package/libx/_runtime/messaging/common-utils/connections.js +31 -18
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -2
- package/libx/_runtime/messaging/redis-messaging.js +1 -1
- package/libx/_runtime/ucl/Service.js +5 -5
- package/libx/http/body-parser.js +10 -1
- package/libx/odata/ODataAdapter.js +10 -7
- package/libx/odata/middleware/error.js +3 -0
- package/libx/odata/parse/afterburner.js +13 -16
- package/libx/odata/parse/multipartToJson.js +3 -1
- package/libx/rest/middleware/parse.js +1 -1
- package/package.json +1 -1
- package/server.js +1 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Input Validation
|
|
2
|
+
|
|
3
|
+
#XMSG: Enter a value between 0 and 100. // Implementation still provides 3 values
|
|
4
|
+
ASSERT_RANGE=\u8F93\u5165\u4E00\u4E2A\u4ECB\u4E8E {1} \u548C {2} \u4E4B\u95F4\u7684\u503C\u3002
|
|
5
|
+
#XMSG: Enter a valuematching the pattern /^abc/.
|
|
6
|
+
ASSERT_FORMAT=\u8F93\u5165\u4E00\u4E2A\u7B26\u5408\u6A21\u5F0F {1} \u7684\u503C\u3002
|
|
7
|
+
#XMSG: Enter one of the allowed values: High,Medium,Low. // Implementation still provides 2 values
|
|
8
|
+
ASSERT_ENUM=\u8F93\u5165\u5176\u4E2D\u4E00\u4E2A\u5141\u8BB8\u7684\u503C\uFF1A{1}\u3002
|
|
9
|
+
#XMSG: Provide the missing value. // Error text displayed on a field, in case a mandatory value is not set.
|
|
10
|
+
ASSERT_MANDATORY=\u63D0\u4F9B\u7F3A\u5C11\u7684\u503C\u3002
|
|
11
|
+
#XMSG: Target with this key doesn't exist.
|
|
12
|
+
ASSERT_TARGET=\u5177\u6709\u6B64\u952E\u503C\u7684\u76EE\u6807\u4E0D\u5B58\u5728\u3002
|
|
13
|
+
|
|
14
|
+
# Aggregating Error
|
|
15
|
+
|
|
16
|
+
#XMSG
|
|
17
|
+
MULTIPLE_ERRORS=\u51FA\u73B0\u591A\u4E2A\u9519\u8BEF\uFF0C\u8BF7\u53C2\u9605\u4E0B\u9762\u7684\u8BE6\u7EC6\u4FE1\u606F\u3002
|
|
18
|
+
|
|
19
|
+
# Input format
|
|
20
|
+
|
|
21
|
+
#NOTR
|
|
22
|
+
ASSERT_VALID_ELEMENT=Element is not valid
|
|
23
|
+
#NOTR
|
|
24
|
+
ASSERT_DATA_TYPE=Value {0} is not a valid {1}
|
|
25
|
+
#NOTR
|
|
26
|
+
ASSERT_ARRAY=Value must be an array
|
|
27
|
+
|
|
28
|
+
# Status Codes
|
|
29
|
+
|
|
30
|
+
#NOTR
|
|
31
|
+
400=Bad Request
|
|
32
|
+
#NOTR
|
|
33
|
+
401=Unauthorized
|
|
34
|
+
#NOTR
|
|
35
|
+
403=Forbidden
|
|
36
|
+
#NOTR
|
|
37
|
+
404=Not Found
|
|
38
|
+
#NOTR
|
|
39
|
+
405=Method Not Allowed
|
|
40
|
+
#NOTR
|
|
41
|
+
406=Not Acceptable
|
|
42
|
+
#NOTR
|
|
43
|
+
407=Proxy Authentication Required
|
|
44
|
+
#NOTR
|
|
45
|
+
408=Request Timeout
|
|
46
|
+
#NOTR
|
|
47
|
+
409=Conflict
|
|
48
|
+
#NOTR
|
|
49
|
+
410=Gone
|
|
50
|
+
#NOTR
|
|
51
|
+
411=Length Required
|
|
52
|
+
#NOTR
|
|
53
|
+
412=Precondition Failed
|
|
54
|
+
#NOTR
|
|
55
|
+
413=Payload Too Large
|
|
56
|
+
#NOTR
|
|
57
|
+
414=URI Too Long
|
|
58
|
+
#NOTR
|
|
59
|
+
415=Unsupported Media Type
|
|
60
|
+
#NOTR
|
|
61
|
+
416=Range Not Satisfiable
|
|
62
|
+
#NOTR
|
|
63
|
+
417=Expectation Failed
|
|
64
|
+
#NOTR
|
|
65
|
+
422=Unprocessable Content
|
|
66
|
+
#NOTR
|
|
67
|
+
424=Failed Dependency
|
|
68
|
+
#NOTR
|
|
69
|
+
428=Precondition Required
|
|
70
|
+
#NOTR
|
|
71
|
+
429=Too Many Requests
|
|
72
|
+
#NOTR
|
|
73
|
+
431=Request Header Fields Too Large
|
|
74
|
+
#NOTR
|
|
75
|
+
451=Unavailable For Legal Reasons
|
|
76
|
+
#NOTR
|
|
77
|
+
500=Internal Server Error
|
|
78
|
+
#NOTR
|
|
79
|
+
501=The server does not support the functionality required to fulfill the request
|
|
80
|
+
#NOTR
|
|
81
|
+
502=Bad Gateway
|
|
82
|
+
#NOTR
|
|
83
|
+
503=Service Unavailable
|
|
84
|
+
#NOTR
|
|
85
|
+
504=Gateway Timeout
|
|
86
|
+
|
|
87
|
+
# fragments
|
|
88
|
+
|
|
89
|
+
#NOTR
|
|
90
|
+
ENTITY=entity
|
|
91
|
+
#NOTR
|
|
92
|
+
TYPE=type
|
|
93
|
+
#NOTR
|
|
94
|
+
FUNCTION=function
|
|
95
|
+
#NOTR
|
|
96
|
+
ACTION=action
|
|
97
|
+
|
|
98
|
+
# db
|
|
99
|
+
|
|
100
|
+
#NOTR
|
|
101
|
+
NO_DATABASE_CONNECTION=No database connection
|
|
102
|
+
#NOTR
|
|
103
|
+
ENTITY_ALREADY_EXISTS=Entity already exists
|
|
104
|
+
#NOTR
|
|
105
|
+
ENTITY_LOCKED=Entity locked
|
|
106
|
+
#NOTR
|
|
107
|
+
UNIQUE_CONSTRAINT_VIOLATION=Unique constraint violation
|
|
108
|
+
#NOTR
|
|
109
|
+
FK_CONSTRAINT_VIOLATION=Foreign key constraint violation
|
|
110
|
+
|
|
111
|
+
# remote
|
|
112
|
+
|
|
113
|
+
#NOTR
|
|
114
|
+
INVALID_CONTENT_TYPE_ONLY_JSON=Invalid content type. Only "application/json" is supported.
|
|
115
|
+
|
|
116
|
+
# access control
|
|
117
|
+
|
|
118
|
+
#NOTR
|
|
119
|
+
INSERTABLE=insertable
|
|
120
|
+
#NOTR
|
|
121
|
+
READABLE=readable
|
|
122
|
+
#NOTR
|
|
123
|
+
UPDATABLE=updatable
|
|
124
|
+
#NOTR
|
|
125
|
+
DELETABLE=deletable
|
|
126
|
+
#NOTR
|
|
127
|
+
ENTITY_IS_INSERT_ONLY=Entity "{0}" is insert-only
|
|
128
|
+
#NOTR
|
|
129
|
+
ENTITY_IS_READ_ONLY=Entity "{0}" is read-only
|
|
130
|
+
#NOTR
|
|
131
|
+
ENTITY_IS_NOT_CRUD=Entity "{0}" is not {1}
|
|
132
|
+
#NOTR
|
|
133
|
+
ENTITY_IS_NOT_CRUD_VIA_NAVIGATION=Entity "{0}" is not {1} via navigation "{2}"
|
|
134
|
+
#NOTR
|
|
135
|
+
ENTITY_IS_AUTOEXPOSED=Entity "{0}" is not explicitly exposed as part of the service
|
|
136
|
+
#NOTR
|
|
137
|
+
ENTITY_IS_AUTOEXPOSE_READONLY=Entity "{0}" is explicitly exposed as readonly
|
|
138
|
+
#NOTR
|
|
139
|
+
EXPAND_IS_RESTRICTED=Navigation property "{0}" is not allowed for expand operation
|
|
140
|
+
|
|
141
|
+
# rest protocol adapter
|
|
142
|
+
|
|
143
|
+
#NOTR
|
|
144
|
+
INVALID_RESOURCE="{0}" is not a valid resource
|
|
145
|
+
#NOTR
|
|
146
|
+
INVALID_PARAMETER="{0}" is not a valid parameter
|
|
147
|
+
#NOTR
|
|
148
|
+
INVALID_PARAMETER_VALUE_TYPE=Parameter value for "{0}" must be of type "{1}"
|
|
149
|
+
#NOTR
|
|
150
|
+
INVALID_OPERATION_FOR_ENTITY=Entity "{0}" has no {1} "{2}"
|
|
151
|
+
#NOTR
|
|
152
|
+
NO_MATCHING_RESOURCE=The server has not found a resource matching the requested URI
|
|
153
|
+
#NOTR
|
|
154
|
+
INVALID_POST=POST is only allowed on resource collections and actions
|
|
155
|
+
#NOTR
|
|
156
|
+
INVALID_PUT=PUT is only allowed on a specific resource
|
|
157
|
+
#NOTR
|
|
158
|
+
INVALID_PATCH=PATCH is only allowed on a specific resource
|
|
159
|
+
#NOTR
|
|
160
|
+
INVALID_DELETE=DELETE is only supported on a specific resource
|
|
161
|
+
#NOTR
|
|
162
|
+
CRUD_VIA_NAVIGATION_NOT_SUPPORTED=CRUD via navigations is not yet supported
|
|
163
|
+
|
|
164
|
+
# OData protocol adapter
|
|
165
|
+
|
|
166
|
+
#NOTR
|
|
167
|
+
BATCH_TOO_MANY_REQ=Batch request contains too many requests
|
|
168
|
+
|
|
169
|
+
# draft
|
|
170
|
+
|
|
171
|
+
#NOTR
|
|
172
|
+
DRAFT_LOCKED_BY_ANOTHER_USER=The entity is locked by user "{0}"
|
|
173
|
+
#NOTR
|
|
174
|
+
DRAFT_ALREADY_EXISTS=A draft for this entity already exists
|
|
175
|
+
#NOTR
|
|
176
|
+
DRAFT_NOT_EXISTING=No draft for this entity exists
|
|
177
|
+
#NOTR
|
|
178
|
+
DRAFT_MODIFICATION_ONLY_VIA_ROOT=A draft-enabled entity can only be modified via its root entity
|
|
179
|
+
#NOTR
|
|
180
|
+
ACTIVE_MODIFICATION_VIA_DRAFT=Active entities cannot be modified via draft request
|
|
181
|
+
#NOTR
|
|
182
|
+
DRAFT_ACTIVE_DELETE_FORBIDDEN_DRAFT_EXISTS=Entity cannot be deleted because a draft exists
|
|
183
|
+
|
|
184
|
+
# singleton
|
|
185
|
+
|
|
186
|
+
#NOTR
|
|
187
|
+
SINGLETON_NOT_NULLABLE=The singleton entity is not nullable
|
|
188
|
+
|
|
189
|
+
# flows
|
|
190
|
+
|
|
191
|
+
#XMSG: Action "acceptTravel" requires "travelStatus" to be "Open".
|
|
192
|
+
INVALID_FLOW_TRANSITION_SINGLE=\u64CD\u4F5C "{0}" \u8981\u6C42 "{1}" \u5FC5\u987B\u4E3A "{2}"\u3002
|
|
193
|
+
#XMSG: Action "cancelTravel" requires "travelStatus" to be one of the following values: Open,Accepted.
|
|
194
|
+
INVALID_FLOW_TRANSITION_MULTI=\u64CD\u4F5C "{0}" \u8981\u6C42 "{1}" \u5FC5\u987B\u4E3A\u4EE5\u4E0B\u503C\u4E4B\u4E00\uFF1A{2}\u3002
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Input Validation
|
|
2
|
+
|
|
3
|
+
#XMSG: Enter a value between 0 and 100. // Implementation still provides 3 values
|
|
4
|
+
ASSERT_RANGE=\u8ACB\u8F38\u5165\u4ECB\u65BC {1} \u5230 {2} \u4E4B\u9593\u7684\u503C\u3002
|
|
5
|
+
#XMSG: Enter a valuematching the pattern /^abc/.
|
|
6
|
+
ASSERT_FORMAT=\u8ACB\u8F38\u5165\u7B26\u5408\u6A21\u5F0F {1} \u7684\u503C\u3002
|
|
7
|
+
#XMSG: Enter one of the allowed values: High,Medium,Low. // Implementation still provides 2 values
|
|
8
|
+
ASSERT_ENUM=\u8ACB\u8F38\u5165\u5176\u4E2D\u4E00\u500B\u5141\u8A31\u7684\u503C\uFF1A{1}\u3002
|
|
9
|
+
#XMSG: Provide the missing value. // Error text displayed on a field, in case a mandatory value is not set.
|
|
10
|
+
ASSERT_MANDATORY=\u8ACB\u63D0\u4F9B\u7F3A\u5C11\u7684\u503C\u3002
|
|
11
|
+
#XMSG: Target with this key doesn't exist.
|
|
12
|
+
ASSERT_TARGET=\u542B\u6709\u6B64\u9375\u503C\u7684\u76EE\u6A19\u4E0D\u5B58\u5728\u3002
|
|
13
|
+
|
|
14
|
+
# Aggregating Error
|
|
15
|
+
|
|
16
|
+
#XMSG
|
|
17
|
+
MULTIPLE_ERRORS=\u767C\u751F\u591A\u500B\u932F\u8AA4\uFF0C\u8ACB\u67E5\u770B\u4E0B\u65B9\u8A73\u7D30\u8CC7\u6599\u3002
|
|
18
|
+
|
|
19
|
+
# Input format
|
|
20
|
+
|
|
21
|
+
#NOTR
|
|
22
|
+
ASSERT_VALID_ELEMENT=Element is not valid
|
|
23
|
+
#NOTR
|
|
24
|
+
ASSERT_DATA_TYPE=Value {0} is not a valid {1}
|
|
25
|
+
#NOTR
|
|
26
|
+
ASSERT_ARRAY=Value must be an array
|
|
27
|
+
|
|
28
|
+
# Status Codes
|
|
29
|
+
|
|
30
|
+
#NOTR
|
|
31
|
+
400=Bad Request
|
|
32
|
+
#NOTR
|
|
33
|
+
401=Unauthorized
|
|
34
|
+
#NOTR
|
|
35
|
+
403=Forbidden
|
|
36
|
+
#NOTR
|
|
37
|
+
404=Not Found
|
|
38
|
+
#NOTR
|
|
39
|
+
405=Method Not Allowed
|
|
40
|
+
#NOTR
|
|
41
|
+
406=Not Acceptable
|
|
42
|
+
#NOTR
|
|
43
|
+
407=Proxy Authentication Required
|
|
44
|
+
#NOTR
|
|
45
|
+
408=Request Timeout
|
|
46
|
+
#NOTR
|
|
47
|
+
409=Conflict
|
|
48
|
+
#NOTR
|
|
49
|
+
410=Gone
|
|
50
|
+
#NOTR
|
|
51
|
+
411=Length Required
|
|
52
|
+
#NOTR
|
|
53
|
+
412=Precondition Failed
|
|
54
|
+
#NOTR
|
|
55
|
+
413=Payload Too Large
|
|
56
|
+
#NOTR
|
|
57
|
+
414=URI Too Long
|
|
58
|
+
#NOTR
|
|
59
|
+
415=Unsupported Media Type
|
|
60
|
+
#NOTR
|
|
61
|
+
416=Range Not Satisfiable
|
|
62
|
+
#NOTR
|
|
63
|
+
417=Expectation Failed
|
|
64
|
+
#NOTR
|
|
65
|
+
422=Unprocessable Content
|
|
66
|
+
#NOTR
|
|
67
|
+
424=Failed Dependency
|
|
68
|
+
#NOTR
|
|
69
|
+
428=Precondition Required
|
|
70
|
+
#NOTR
|
|
71
|
+
429=Too Many Requests
|
|
72
|
+
#NOTR
|
|
73
|
+
431=Request Header Fields Too Large
|
|
74
|
+
#NOTR
|
|
75
|
+
451=Unavailable For Legal Reasons
|
|
76
|
+
#NOTR
|
|
77
|
+
500=Internal Server Error
|
|
78
|
+
#NOTR
|
|
79
|
+
501=The server does not support the functionality required to fulfill the request
|
|
80
|
+
#NOTR
|
|
81
|
+
502=Bad Gateway
|
|
82
|
+
#NOTR
|
|
83
|
+
503=Service Unavailable
|
|
84
|
+
#NOTR
|
|
85
|
+
504=Gateway Timeout
|
|
86
|
+
|
|
87
|
+
# fragments
|
|
88
|
+
|
|
89
|
+
#NOTR
|
|
90
|
+
ENTITY=entity
|
|
91
|
+
#NOTR
|
|
92
|
+
TYPE=type
|
|
93
|
+
#NOTR
|
|
94
|
+
FUNCTION=function
|
|
95
|
+
#NOTR
|
|
96
|
+
ACTION=action
|
|
97
|
+
|
|
98
|
+
# db
|
|
99
|
+
|
|
100
|
+
#NOTR
|
|
101
|
+
NO_DATABASE_CONNECTION=No database connection
|
|
102
|
+
#NOTR
|
|
103
|
+
ENTITY_ALREADY_EXISTS=Entity already exists
|
|
104
|
+
#NOTR
|
|
105
|
+
ENTITY_LOCKED=Entity locked
|
|
106
|
+
#NOTR
|
|
107
|
+
UNIQUE_CONSTRAINT_VIOLATION=Unique constraint violation
|
|
108
|
+
#NOTR
|
|
109
|
+
FK_CONSTRAINT_VIOLATION=Foreign key constraint violation
|
|
110
|
+
|
|
111
|
+
# remote
|
|
112
|
+
|
|
113
|
+
#NOTR
|
|
114
|
+
INVALID_CONTENT_TYPE_ONLY_JSON=Invalid content type. Only "application/json" is supported.
|
|
115
|
+
|
|
116
|
+
# access control
|
|
117
|
+
|
|
118
|
+
#NOTR
|
|
119
|
+
INSERTABLE=insertable
|
|
120
|
+
#NOTR
|
|
121
|
+
READABLE=readable
|
|
122
|
+
#NOTR
|
|
123
|
+
UPDATABLE=updatable
|
|
124
|
+
#NOTR
|
|
125
|
+
DELETABLE=deletable
|
|
126
|
+
#NOTR
|
|
127
|
+
ENTITY_IS_INSERT_ONLY=Entity "{0}" is insert-only
|
|
128
|
+
#NOTR
|
|
129
|
+
ENTITY_IS_READ_ONLY=Entity "{0}" is read-only
|
|
130
|
+
#NOTR
|
|
131
|
+
ENTITY_IS_NOT_CRUD=Entity "{0}" is not {1}
|
|
132
|
+
#NOTR
|
|
133
|
+
ENTITY_IS_NOT_CRUD_VIA_NAVIGATION=Entity "{0}" is not {1} via navigation "{2}"
|
|
134
|
+
#NOTR
|
|
135
|
+
ENTITY_IS_AUTOEXPOSED=Entity "{0}" is not explicitly exposed as part of the service
|
|
136
|
+
#NOTR
|
|
137
|
+
ENTITY_IS_AUTOEXPOSE_READONLY=Entity "{0}" is explicitly exposed as readonly
|
|
138
|
+
#NOTR
|
|
139
|
+
EXPAND_IS_RESTRICTED=Navigation property "{0}" is not allowed for expand operation
|
|
140
|
+
|
|
141
|
+
# rest protocol adapter
|
|
142
|
+
|
|
143
|
+
#NOTR
|
|
144
|
+
INVALID_RESOURCE="{0}" is not a valid resource
|
|
145
|
+
#NOTR
|
|
146
|
+
INVALID_PARAMETER="{0}" is not a valid parameter
|
|
147
|
+
#NOTR
|
|
148
|
+
INVALID_PARAMETER_VALUE_TYPE=Parameter value for "{0}" must be of type "{1}"
|
|
149
|
+
#NOTR
|
|
150
|
+
INVALID_OPERATION_FOR_ENTITY=Entity "{0}" has no {1} "{2}"
|
|
151
|
+
#NOTR
|
|
152
|
+
NO_MATCHING_RESOURCE=The server has not found a resource matching the requested URI
|
|
153
|
+
#NOTR
|
|
154
|
+
INVALID_POST=POST is only allowed on resource collections and actions
|
|
155
|
+
#NOTR
|
|
156
|
+
INVALID_PUT=PUT is only allowed on a specific resource
|
|
157
|
+
#NOTR
|
|
158
|
+
INVALID_PATCH=PATCH is only allowed on a specific resource
|
|
159
|
+
#NOTR
|
|
160
|
+
INVALID_DELETE=DELETE is only supported on a specific resource
|
|
161
|
+
#NOTR
|
|
162
|
+
CRUD_VIA_NAVIGATION_NOT_SUPPORTED=CRUD via navigations is not yet supported
|
|
163
|
+
|
|
164
|
+
# OData protocol adapter
|
|
165
|
+
|
|
166
|
+
#NOTR
|
|
167
|
+
BATCH_TOO_MANY_REQ=Batch request contains too many requests
|
|
168
|
+
|
|
169
|
+
# draft
|
|
170
|
+
|
|
171
|
+
#NOTR
|
|
172
|
+
DRAFT_LOCKED_BY_ANOTHER_USER=The entity is locked by user "{0}"
|
|
173
|
+
#NOTR
|
|
174
|
+
DRAFT_ALREADY_EXISTS=A draft for this entity already exists
|
|
175
|
+
#NOTR
|
|
176
|
+
DRAFT_NOT_EXISTING=No draft for this entity exists
|
|
177
|
+
#NOTR
|
|
178
|
+
DRAFT_MODIFICATION_ONLY_VIA_ROOT=A draft-enabled entity can only be modified via its root entity
|
|
179
|
+
#NOTR
|
|
180
|
+
ACTIVE_MODIFICATION_VIA_DRAFT=Active entities cannot be modified via draft request
|
|
181
|
+
#NOTR
|
|
182
|
+
DRAFT_ACTIVE_DELETE_FORBIDDEN_DRAFT_EXISTS=Entity cannot be deleted because a draft exists
|
|
183
|
+
|
|
184
|
+
# singleton
|
|
185
|
+
|
|
186
|
+
#NOTR
|
|
187
|
+
SINGLETON_NOT_NULLABLE=The singleton entity is not nullable
|
|
188
|
+
|
|
189
|
+
# flows
|
|
190
|
+
|
|
191
|
+
#XMSG: Action "acceptTravel" requires "travelStatus" to be "Open".
|
|
192
|
+
INVALID_FLOW_TRANSITION_SINGLE=\u52D5\u4F5C "{0}" \u9700\u8981 "{1}" \u662F "{2}"\u3002
|
|
193
|
+
#XMSG: Action "cancelTravel" requires "travelStatus" to be one of the following values: Open,Accepted.
|
|
194
|
+
INVALID_FLOW_TRANSITION_MULTI=\u52D5\u4F5C "{0}" \u9700\u8981 "{1}" \u662F\u4E0B\u5217\u5176\u4E2D\u4E00\u500B\u503C\uFF1A{2}\u3002
|
package/bin/serve.js
CHANGED
|
@@ -8,7 +8,7 @@ module.exports = exports = Object.assign ( serve, {
|
|
|
8
8
|
'--project', '--projects',
|
|
9
9
|
'--in-memory', '--in-memory?',
|
|
10
10
|
'--mocked', '--with-mocks', '--with-bindings', '--resolve-bindings',
|
|
11
|
-
'--watch',
|
|
11
|
+
'--watch', '--with-mtx',
|
|
12
12
|
],
|
|
13
13
|
shortcuts: [ '-s', undefined, '-2', '-a', '-w', undefined, undefined, '-p' ],
|
|
14
14
|
help: `
|
|
@@ -75,6 +75,10 @@ module.exports = exports = Object.assign ( serve, {
|
|
|
75
75
|
You can use *cds watch* as shortcut, which is equivalent to:
|
|
76
76
|
*cds serve --with-mocks --in-memory? --watch --project ...*
|
|
77
77
|
|
|
78
|
+
*--with-mtx*
|
|
79
|
+
|
|
80
|
+
A shortcut for _--profile with-mtx_ to enable MTX features.
|
|
81
|
+
|
|
78
82
|
*--workers* <number> | true
|
|
79
83
|
|
|
80
84
|
Spawns <number> of worker processes in a cluster to handle incoming requests.
|
|
@@ -168,6 +172,10 @@ async function serve (all=[], o={}) {
|
|
|
168
172
|
// let plugins know about the CLI
|
|
169
173
|
cds.cli = { command: 'serve', argv: all, options: o }
|
|
170
174
|
|
|
175
|
+
// Enable mtx features also in dev mode, if asked to
|
|
176
|
+
if (o['with-mtx'])
|
|
177
|
+
process.env.CDS_ENV = process.env.CDS_ENV ? process.env.CDS_ENV + ',with-mtx' : 'with-mtx'
|
|
178
|
+
|
|
171
179
|
// Ensure loading plugins before calling cds.env!
|
|
172
180
|
await cds.plugins
|
|
173
181
|
|
package/common.cds
CHANGED
|
@@ -96,6 +96,15 @@ context sap.common {
|
|
|
96
96
|
aspect TextsAspect {
|
|
97
97
|
key locale: Locale;
|
|
98
98
|
}
|
|
99
|
+
|
|
100
|
+
aspect FlowHistory {
|
|
101
|
+
transitions_ : Composition of many {
|
|
102
|
+
key timestamp : managed:createdAt;
|
|
103
|
+
user : managed:createdBy;
|
|
104
|
+
status : String;
|
|
105
|
+
comment : String;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
99
108
|
}
|
|
100
109
|
|
|
101
110
|
|
|
@@ -130,7 +139,6 @@ aspect temporal {
|
|
|
130
139
|
validTo : Timestamp @cds.valid.to;
|
|
131
140
|
}
|
|
132
141
|
|
|
133
|
-
|
|
134
142
|
/**
|
|
135
143
|
* Canonical user ID
|
|
136
144
|
*/
|
|
@@ -7,6 +7,7 @@ const compile = module.exports = Object.assign (cds_compile, {
|
|
|
7
7
|
get java(){ return super.java = require('./for/java') }
|
|
8
8
|
get nodejs() { return super.nodejs = require('./for/nodejs') }
|
|
9
9
|
get lean_drafts() { return super.lean_drafts = require('./for/lean_drafts') }
|
|
10
|
+
get flows() { return super.flows = require('./for/flows') }
|
|
10
11
|
get odata() { return super.odata = require('./for/odata') }
|
|
11
12
|
get sql() { return super.sql = require('./for/sql') }
|
|
12
13
|
},
|
|
@@ -40,4 +40,5 @@ function string4 (raw) {
|
|
|
40
40
|
return raw
|
|
41
41
|
.replace(/''/g,"'") .replace(/^"(.*)"$/,"$1") .replace(/^'(.*)'$/,"$1")
|
|
42
42
|
.replace(/\\u[\dA-F]{4}/gi, (match) => String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16)))
|
|
43
|
+
.replace(/\\(.)/g, (_, seq) => ({ n: '\n', r: '\r', t: '\t', f: '\f' }[seq] ?? seq))
|
|
43
44
|
}
|
package/lib/compile/for/flows.js
CHANGED
|
@@ -8,17 +8,20 @@ const TO = '@to'
|
|
|
8
8
|
// backwards compat
|
|
9
9
|
const FLOW_FROM = '@flow.from'
|
|
10
10
|
const FLOW_TO = '@flow.to'
|
|
11
|
+
const FLOW_PREVIOUS = '$flow.previous'
|
|
11
12
|
|
|
12
13
|
const getFrom = action => {
|
|
13
14
|
let from = action[FROM] ?? action[FLOW_FROM]
|
|
14
|
-
|
|
15
|
-
return from.map(f => f['#'] ?? f['='] ?? f)
|
|
15
|
+
return Array.isArray(from) ? from : [from]
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function addOperationAvailableToActions(actions, statusEnum, statusElementName) {
|
|
19
19
|
for (const action of Object.values(actions)) {
|
|
20
20
|
const fromList = getFrom(action)
|
|
21
|
-
const conditions = fromList.map(from =>
|
|
21
|
+
const conditions = fromList.map(from => {
|
|
22
|
+
const value = from['#'] ? statusEnum[from['#']]?.val ?? statusEnum[from['#']]['$path'].at(-1) : from
|
|
23
|
+
return `$self.${statusElementName} = ${typeof value === 'string' ? `'${value}'` : value}`
|
|
24
|
+
})
|
|
22
25
|
const condition = `(${conditions.join(' OR ')})`
|
|
23
26
|
const parsedXpr = cds.parse.expr(condition)
|
|
24
27
|
action['@Core.OperationAvailable'] ??= {
|
|
@@ -99,4 +102,67 @@ function enhanceCSNwithFlowAnnotations4FE(csn) {
|
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
104
|
|
|
102
|
-
module.exports =
|
|
105
|
+
module.exports = function cds_compile_for_flows(csn) {
|
|
106
|
+
let flowHistory
|
|
107
|
+
|
|
108
|
+
for (const name in csn.definitions) {
|
|
109
|
+
const def = csn.definitions[name]
|
|
110
|
+
|
|
111
|
+
if (!def.kind || def.kind !== 'entity' || !def.actions || def.elements?.transitions_) continue
|
|
112
|
+
|
|
113
|
+
let history
|
|
114
|
+
if (cds.env.features.history_for_flows === 'all') {
|
|
115
|
+
for (const each in def.elements) {
|
|
116
|
+
if (def.elements[each]['@flow.status']) {
|
|
117
|
+
history = true
|
|
118
|
+
break
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
for (const each in def.actions) {
|
|
123
|
+
const action = def.actions[each]
|
|
124
|
+
if (action && (action[TO]?.['='] === FLOW_PREVIOUS || action[FLOW_TO]?.['='] === FLOW_PREVIOUS)) {
|
|
125
|
+
history = true
|
|
126
|
+
break
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!history) continue
|
|
131
|
+
|
|
132
|
+
flowHistory ??= csn.definitions['sap.common.FlowHistory']
|
|
133
|
+
if (!flowHistory) cds.error('Cannot find definition sap.common.FlowHistory')
|
|
134
|
+
|
|
135
|
+
const { elements: aspectElements } = flowHistory.elements.transitions_.targetAspect
|
|
136
|
+
|
|
137
|
+
def.includes ??= []
|
|
138
|
+
def.includes.push('sap.common.FlowHistory')
|
|
139
|
+
def.elements.transitions_ = JSON.parse(`{
|
|
140
|
+
"type": "cds.Composition",
|
|
141
|
+
"cardinality": { "max": "*" },
|
|
142
|
+
"targetAspect": { "elements": ${JSON.stringify(aspectElements)} },
|
|
143
|
+
"target": "${name}.transitions_",
|
|
144
|
+
"on": [{ "ref": ["transitions_", "up_"] }, "=", { "ref": ["$self"] }]
|
|
145
|
+
}`)
|
|
146
|
+
|
|
147
|
+
const def_keys = Object.keys(def.elements)
|
|
148
|
+
.filter(k => def.elements[k].key)
|
|
149
|
+
.map(k => ({ ref: [k] }))
|
|
150
|
+
csn.definitions[`${name}.transitions_`] = JSON.parse(`{
|
|
151
|
+
"kind": "entity",
|
|
152
|
+
"elements": {
|
|
153
|
+
"up_": {
|
|
154
|
+
"key": true,
|
|
155
|
+
"type": "cds.Association",
|
|
156
|
+
"cardinality": { "min": 1, "max": 1 },
|
|
157
|
+
"target": "${name}",
|
|
158
|
+
"keys": ${JSON.stringify(def_keys)},
|
|
159
|
+
"notNull": true
|
|
160
|
+
},
|
|
161
|
+
${JSON.stringify(aspectElements).slice(1, -1)}
|
|
162
|
+
}
|
|
163
|
+
}`)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports.enhanceCSNwithFlowAnnotations4FE = enhanceCSNwithFlowAnnotations4FE
|
|
168
|
+
module.exports.getFrom = getFrom
|
|
@@ -8,7 +8,7 @@ function _compile_for_nodejs (csn, o) {
|
|
|
8
8
|
let dsn = cds.compile.for.odata(min, o) //> creates a partial copy -> avoid any cds.linked() before
|
|
9
9
|
dsn = unfold_csn(dsn)
|
|
10
10
|
dsn = cds.linked(dsn)
|
|
11
|
-
cds.compile.for.lean_drafts(dsn
|
|
11
|
+
cds.compile.for.lean_drafts(dsn)
|
|
12
12
|
|
|
13
13
|
// @Common.Text → @cds.search
|
|
14
14
|
text_to_search: for (const name in dsn.definitions) {
|