@sap/cds 8.8.2 → 8.9.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.
- package/CHANGELOG.md +46 -4
- package/_i18n/i18n_en_US_saptrc.properties +3 -0
- package/bin/colors.js +2 -0
- package/bin/test.js +103 -75
- package/eslint.config.mjs +16 -4
- package/lib/compile/for/lean_drafts.js +4 -0
- package/lib/compile/parse.js +26 -6
- package/lib/env/cds-env.js +3 -1
- package/lib/env/cds-requires.js +0 -3
- package/lib/env/schemas/cds-rc.js +11 -0
- package/lib/log/format/aspects/cls.js +2 -1
- package/lib/log/format/json.js +1 -1
- package/lib/plugins.js +2 -3
- package/lib/ql/SELECT.js +2 -1
- package/lib/ql/cds-ql.js +2 -0
- package/lib/ql/cds.ql-predicates.js +6 -4
- package/lib/ql/resolve.js +46 -0
- package/lib/req/validate.js +1 -0
- package/lib/srv/bindings.js +64 -43
- package/lib/srv/cds-connect.js +1 -1
- package/lib/srv/cds-serve.js +2 -2
- package/lib/srv/middlewares/auth/ias-auth.js +2 -0
- package/lib/srv/protocols/http.js +2 -2
- package/lib/srv/protocols/index.js +1 -1
- package/lib/srv/protocols/odata-v4.js +0 -1
- package/lib/srv/srv-tx.js +1 -1
- package/lib/test/cds-test.js +3 -4
- package/lib/utils/cds-utils.js +19 -19
- package/lib/utils/colors.js +46 -45
- package/lib/utils/csv-reader.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +1 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -1
- package/libx/_runtime/common/Service.js +4 -2
- package/libx/_runtime/common/composition/data.js +1 -2
- package/libx/_runtime/common/composition/tree.js +6 -4
- package/libx/_runtime/common/generic/sorting.js +6 -2
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +6 -7
- package/libx/_runtime/common/utils/differ.js +1 -1
- package/libx/_runtime/common/utils/draft.js +1 -1
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +6 -2
- package/libx/_runtime/common/utils/keys.js +13 -84
- package/libx/_runtime/common/utils/propagateForeignKeys.js +4 -3
- package/libx/_runtime/common/utils/resolveView.js +96 -102
- package/libx/_runtime/common/utils/rewriteAsterisks.js +1 -1
- package/libx/_runtime/common/utils/stream.js +2 -3
- package/libx/_runtime/db/utils/columns.js +1 -1
- package/libx/_runtime/fiori/lean-draft.js +11 -7
- package/libx/_runtime/messaging/common-utils/connections.js +6 -2
- package/libx/_runtime/messaging/kafka.js +3 -4
- package/libx/_runtime/remote/Service.js +13 -5
- package/libx/_runtime/remote/utils/client.js +1 -0
- package/libx/_runtime/ucl/Service.js +135 -126
- package/libx/common/utils/path.js +34 -22
- package/libx/odata/middleware/create.js +2 -0
- package/libx/odata/middleware/operation.js +8 -2
- package/libx/odata/middleware/parse.js +1 -1
- package/libx/odata/middleware/stream.js +1 -2
- package/libx/odata/middleware/update.js +2 -0
- package/libx/odata/parse/afterburner.js +17 -9
- package/libx/odata/parse/cqn2odata.js +3 -1
- package/libx/odata/parse/grammar.peggy +21 -19
- package/libx/odata/parse/parser.js +1 -1
- package/libx/odata/utils/metadata.js +8 -2
- package/libx/odata/utils/odataBind.js +36 -0
- package/libx/outbox/index.js +1 -0
- package/libx/rest/middleware/operation.js +9 -8
- package/libx/rest/middleware/parse.js +1 -0
- package/package.json +3 -3
- package/lib/i18n/resources.js +0 -150
package/lib/i18n/resources.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
const cds = require('..'), { path } = cds.utils
|
|
2
|
-
const LOG = cds.log('i18n')
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Instances of this class are used to fetch and read i18n resources from the file system.
|
|
6
|
-
*/
|
|
7
|
-
class I18nResources {
|
|
8
|
-
|
|
9
|
-
constructor (options) {
|
|
10
|
-
for (let each in options) super[each] = options[each]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* The folders to search for i18n files in. By default a shortcut to i18n.folders
|
|
16
|
-
* config but can be specified in constructor.
|
|
17
|
-
*/
|
|
18
|
-
get folders() {
|
|
19
|
-
return super.folders = cds.env.i18n.folders
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Returns the files basename to read properties from; default is `'i18n'`.
|
|
25
|
-
* @returns {string}
|
|
26
|
-
*/
|
|
27
|
-
get file() {
|
|
28
|
-
return super.file ??= cds.env.i18n.file
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Fetches all i18n files matching {@link file basename} in {@link folders} up to {@link roots}.
|
|
34
|
-
* @returns {Record<string,string[]>} a dictionary of files by folders.
|
|
35
|
-
*/
|
|
36
|
-
get files() {
|
|
37
|
-
|
|
38
|
-
// prepare the things we need below...
|
|
39
|
-
const { existsSync: exists, readdirSync: readdir } = cds.utils.fs
|
|
40
|
-
const _folders = I18nResources.folders ??= {}
|
|
41
|
-
const _entries = I18nResources.entries ??= {}
|
|
42
|
-
const basename = RegExp(`${this.file}[._]`)
|
|
43
|
-
const files_by_folders = {} // the result to be returned
|
|
44
|
-
|
|
45
|
-
// fetch relatively specified i18n.folders in the neighborhood of sources...
|
|
46
|
-
const relative_folders = this.folders.filter (f => f[0] !== '/')
|
|
47
|
-
if (relative_folders.length) {
|
|
48
|
-
const visited = {}, roots = this.roots, $sources = this.model?.$sources
|
|
49
|
-
const $sourcedirs = $sources ? [ ...new Set($sources.map(path.dirname)) ].reverse() : [ cds.home, cds.root ]
|
|
50
|
-
$sourcedirs.forEach (function _visit (dir) {
|
|
51
|
-
if (dir in visited) return; else visited[dir] = true
|
|
52
|
-
LOG.debug ('searching for i18n files in the neighborhood of', dir)
|
|
53
|
-
// is there an i18n folder in the currently visited directory?
|
|
54
|
-
for (let each of relative_folders) {
|
|
55
|
-
const f = path.join(dir,each), _exists = _folders[f] ??= exists(f)
|
|
56
|
-
if (_exists && _add_entries4(f)) return // stop at first match from i18n.folders
|
|
57
|
-
}
|
|
58
|
-
// else recurse up the folder hierarchy till reaching package roots ...
|
|
59
|
-
if (roots.includes(dir) || exists(path.join(dir,'package.json'))) return
|
|
60
|
-
else _visit (path.dirname(dir))
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// fetch fully specified i18n.folders, i.e., those starting with /
|
|
65
|
-
const specific_folders = this.folders.filter (f => f[0] === '/')
|
|
66
|
-
for (let f of specific_folders) {
|
|
67
|
-
const _exists = _folders[f] ??= exists(f)
|
|
68
|
-
_add_entries4 (_exists ? f : path.join(cds.root,f))
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// helper to add matching files from found folder, if any
|
|
72
|
-
function _add_entries4 (f) {
|
|
73
|
-
const files = (_entries[f] ??= readdir(f)) .filter (f => f.match(basename))
|
|
74
|
-
if (files.length) return files_by_folders[f] = files
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// finally return the collected files by folders
|
|
78
|
-
super.folders = Object.keys (files_by_folders)
|
|
79
|
-
return super.files = files_by_folders
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* The root directories up to which to search for {@link files `i18n.files`}.
|
|
85
|
-
*/
|
|
86
|
-
get roots() {
|
|
87
|
-
return super.roots = [ cds.env.i18n.root || cds.root ]
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Returns all locales for which translations are available in this.{@link files}.
|
|
93
|
-
* @returns {string[]}
|
|
94
|
-
*/
|
|
95
|
-
get locales() {
|
|
96
|
-
const unique_locales = new Set(), {path} = cds.utils
|
|
97
|
-
for (let [folder,files] of Object.entries(this.files)) {
|
|
98
|
-
for (let file of files) {
|
|
99
|
-
const { name, ext } = path.parse (file); switch (ext) {
|
|
100
|
-
case '.properties': unique_locales.add(/(?:_(\w+))?$/.exec(name)?.[1]||''); break
|
|
101
|
-
case '.json': for (let locale in _load_json(path.join(folder,file))) unique_locales.add(locale); break
|
|
102
|
-
case '.csv': return _load_csv (path.join(folder,file))[0].slice(1)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return super.locales = [...unique_locales]
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Loads content from all files for the given locale.
|
|
112
|
-
* @returns {entries[]} An array of entries, one for each file found.
|
|
113
|
-
*/
|
|
114
|
-
content4 (locale, suffix = locale?.replace(/-/g,'_')) {
|
|
115
|
-
const content = [], { file, files } = this
|
|
116
|
-
for (let folder in files) {
|
|
117
|
-
const all = this.content4[folder] ??= _load('json',folder) || _load('csv',folder)
|
|
118
|
-
if (all) { if (locale in all) content.push (all[locale]); continue }
|
|
119
|
-
const props = _load ('properties', folder, file + (suffix ? '_'+suffix : ''))
|
|
120
|
-
if (props) content.push (props)
|
|
121
|
-
}
|
|
122
|
-
function _load (kind, folder, basename = file) {
|
|
123
|
-
const entry = `${basename}.${kind}`; if (!files[folder].includes(entry)) return
|
|
124
|
-
const file = path.join (folder, entry)
|
|
125
|
-
try { switch (kind) {
|
|
126
|
-
case 'properties': return _load_properties (file)
|
|
127
|
-
case 'json': return _load_json (file)
|
|
128
|
-
case 'csv': return _load_csv (file)
|
|
129
|
-
}} finally {
|
|
130
|
-
LOG.debug ('read:', file)
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return content
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const _load_properties = cds.load.properties
|
|
139
|
-
const _load_json = require
|
|
140
|
-
const _load_csv = file => {
|
|
141
|
-
const csv = cds.load.csv(file); if (!csv) return
|
|
142
|
-
const [ header, ...rows ] = csv, all = {}
|
|
143
|
-
header.slice(1).forEach ((lang,i) => {
|
|
144
|
-
const entries = all[lang] = {}
|
|
145
|
-
for (let row of rows) if (row[i]) entries[row[0]] = row[i]
|
|
146
|
-
})
|
|
147
|
-
return all
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
module.exports = I18nResources
|