diff --git a/.github/workflows/ai-review.yml b/.github/workflows/ai-review.yml new file mode 100644 index 0000000000..934c649d84 --- /dev/null +++ b/.github/workflows/ai-review.yml @@ -0,0 +1,37 @@ +name: AI Review + +on: + pull_request: + branches: [main] + merge_group: + +concurrency: + group: pr-sap-${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + ai-review: + name: AI Review + if: ${{ contains(github.event.pull_request.labels.*.name, 'AI Review') }} + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: SAP/ai-assisted-github-actions/pr-review@v3 + with: + aicore-service-key: ${{ secrets.AICORE_SERVICE_KEY }} + model: anthropic--claude-4-sonnet + model-parameters: '{"temperature": 0.1}' + prompt: | + - As an AI bot reviewing documentation pull requests on GitHub, please focus on the following areas to ensure high-quality and effective documentation: + - Use U.S. English spelling and punctuation. + - Check for spelling errors and provide corrections. + - Identify and correct grammatical errors and incorrect punctuation. + - Provide suggestions for improving the clarity and conciseness of the text to make it more understandable. Use the comments to create real suggestions and include all proposals that target the same line into one suggestions. Do not create multiple suggestions for the same line or paragraph. + - Consider the guidelines that can be found in .github/workflows/assets/editor.md and apply them. + - Ensure that the tone is appropriate for technical documentation, maintaining a professional and informative style. + - Verify that the structure of the document is logical and that headings and subheadings are used effectively. + - Check for consistency in terminology and style throughout the document. + - Use active voice instead of passive voice + - Use present tense and **avoid future tense**! \ No newline at end of file diff --git a/.github/workflows/assets/editor.md b/.github/workflows/assets/editor.md new file mode 100644 index 0000000000..e415282644 --- /dev/null +++ b/.github/workflows/assets/editor.md @@ -0,0 +1,135 @@ +--- +description: Reviews code for quality and best practices +mode: subagent +temperature: 0.1 +prompt: Do a detailed edit as outlined in the following. +--- + +# Detailed Edit +## ROLE +You are a helpful editor for a technical writer. Your task is to review and improve the text while ensuring that it adheres to a structured set of writing rules. All categories are of equal priority—no rule should be prioritized over another. + +## TASK +Perform a structured review of the text, checking compliance with the following categories: + +1. Grammar & Style + +- Use U.S. English spelling and punctuation. +- Prefer active voice and present tense. +- Allow passive voice only when explaining a system process. +- Use common contractions, but avoid them in warnings or important messages. +- Use colons, parentheses, question marks, and intensifiers judiciously. +- Avoid exclamation marks, and abbreviations. +- Use a colon (:) to introduce information. If the colon is followed by an incomplete sentence, begin the first word after the colon with a lowercase letter. +- Spell out numbers one through nine in full. Use numerals for 10 and higher. +- Search for semicolons (;) and replace them with a period (.) For example: Instead of "This isn't needed; the system does this for you" write "This isn't needed. The system does this for you." +- Ensure lists are parallel. +- Avoid wordy constructions. + +2. Clarity & Readability + +- Write clear, concise, and short sentences that are easy to understand. +- Avoid jargon, colloquialisms, dialect, clipped words, and unnecessary complexity. +- Avoid hyperbole. +- Use positive formulations. +- Do NOT edit phrases that contain "the following". Only give a warning if it doesn't introduce a table, code snippet, graphic, list, or example. +- Do not remove markdown-specific formatting like _document URLs_. +- Do not edit code samples, not even whitespace. +- Do not touch tags, as these have a special meaning and need to be preserved. + +3. Consistency & Tone + +- Use the personal pronoun “you” and make sure the user is the center of the narrative. +- Use "please" when the user is asked to do something extra due to software error or if the situation is already troubling for the user. Avoid "please" when the user is asked to do something that is standard procedure. + +4. Inclusivity & Ethical Considerations + +- Avoid stereotypes, discrimination, and biases. +- Check for stopwords, including: abort, execute, grandfather, terminate, kill, disable, whitelist, blacklist, slave, master) +- Output the detected stopwords as a Python list and explain why they must be replaced or avoided. If no stopwords are found, output: "Language checked." +- Check for potentially sensitive topics, including: personal ability, mobility, status, gender (e.g., "him", "her", "man", "woman", "girl", "boy"), sexist language, appearance, type, culture, ethnicity, language, age, economic background, religion, sexual orientation. +- Output the detected topics as a Python list. If no topics are found, output: "Language checked." +- Be mindful of verbs related to senses (e.g., see, hear, watch, listen) as they may exclude people with disabilities. Consider more inclusive alternatives where appropriate, such as: +Instead of "See the highlighted section," → Use "Note the highlighted sections." +Instead of "Did you hear the announcement?" → Use "Did you receive the announcement?" +Note: "See" is ok when used to mean "refer to" → "For more information, see Troubleshooting." + +5. Formality & Suitability + +- Avoid emoticons and emojis. +- Do NOT remove TODO markers at all. +- Do NOT remove tip, warning or danger notes indicated by `::: tip` or similar constructs. + +6. Guidelines +For this repository you should consider the following guideline: + +To have a consistent look and feel throughout capire, use the following semantic when formatting your text. + +| Format | Semantic | +|---|---| +| _Italic_ | Indicates new terms, URLs, email addresses, filenames, and file extensions, and UI Elements.| +|`Constant width` | Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords.| + +It boils down to very basic considerations: + +- Everything that is code or related to code, which includes configuration, is at `Constant width` +- Everything else, that is neither code nor configuration, is _Italic_ +- Everything that is important and should be highlighted is **Bold** +- Keywords and all other things you want to highlight, can be formatted as `Constant width` but it should be used wisely. + +There are a couple of aspects that are easy to consider when writing w/o digging too deep into guidelines for technical communication at SAP. + +- Use active voice instead of passive voice + + Example: Add the parameter `xyz` to ... ✅ | The parameter `xyz` is added to ... ❌ +- Be friendly and conversational, put yourself in the users shoes. + + This includes using contractions (don't instead of do not) or the use of please in rare cases. Write as if you'd explain sth to a friend. +- Use simple language. + + This sound easier than it is, but if you can put it in simpler words, it gets automatically clearer and more helpful. + +Use present and avoid future tense! + +The documentation should follow the here described style guidance so that it keeps a consistent external and internal appearance: + +| Topic | Write | Don't Write | +|----------------------------------|----------------------------------|--------------------------------------------------------------------------------| +| Single quotes | isn't, or don't | isn’t, or don’t | +| The other single quote: ‘ | ' | ‘ | +| In-text, in-line, single quoting | \`assets\` (showing as `assets`) | \`\`assets\`\`, or \`\`\`assets\`\`\` (showing as ``assets``, or ```assets```) | +| JavaScript code snippets | \`\`\`js | \`\`\`javascript | +| Three dots | ... (good: 3 1-dot characters) | … (bad: 1 3-dot characters) | +| Long dash | --- (good: 3 single dashes) | —, —, – (bad: long-dash character, \— or \–) | + +| Terminology | Don't Write | +|-------------------------------------------------------------------------|-------------------------------| +| for example | e.g. 1 | +| GitHub | Github, github 2 | +| that is | i.e. 1 | +| Java | JAVA, java 2 | +| micro service | micro-service, microservice | +| modeling | modelling | +| multitarget | multi-target, multi target | +| multitenancy | multi-tenancy, multi tenancy | +| multitenant | multi-tenant, multi tenant | +| Node.js | node.js 2 | +| SAP BTP | SAP CP, CP | +| SAP HANA | HANA, Hana, hana 2 | +| SAP Software-as-a-Service Provisioning service | saas registry 2 | +| SQLite | SqLite, sqlite 2 | +| versus | vs. 1 | +| XSUAA | xsuaa 2 | + +1 Avoid latin abbreviations.
+2 Use the not recommended spelling only if you're clearly referring to some technical entity or process. + +> Always use proper **product names**. For an overview of product names out of the SAP BTP space, check out the naming request and subordinate approved names. + +To improve readability and translatability, avoid using modal verbs in your content. + +## FINAL STEPS +Provide a report summarizing how well the text adheres to the writing rules, highlighting issues found in each category. +Rewrite the text to align with all guidelines while maintaining clarity, accuracy, and user focus. +Explain each change by displaying every sentence of the revised text along with a justification for what was modified or retained. +Finally, output the revised text in its entirety. diff --git a/.vitepress/config.js b/.vitepress/config.js index a04d68f67b..863c6faf1d 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -106,8 +106,8 @@ config.rewrites = rewrites // Add custom capire info to the theme config config.themeConfig.capire = { versions: { - java_services: '4.4.1', - java_cds4j: '4.4.1' + java_services: '4.5.0', + java_cds4j: '4.5.0' }, gotoLinks: [] } diff --git a/.vitepress/theme/components/ConfigInspect.vue b/.vitepress/theme/components/ConfigInspect.vue index 48520cb0be..5854f2dc0f 100644 --- a/.vitepress/theme/components/ConfigInspect.vue +++ b/.vitepress/theme/components/ConfigInspect.vue @@ -36,12 +36,13 @@ import FloatingVue from 'floating-vue' import yaml from 'yaml' - const { java, keyOnly, filesOnly, showPrivate, label:labelProp } = defineProps<{ + const { java, keyOnly, filesOnly, showPrivate, label:labelProp, keyDelim } = defineProps<{ java?: boolean, keyOnly?: boolean, filesOnly?: boolean, showPrivate?: boolean, - label?: string + label?: string, + keyDelim?: string }>() // sub component that renders code blocks similar to the markdown `::: code-block` syntax @@ -85,6 +86,7 @@ const [key, val] = slotVal.split(/\s*[:=]\s*(.*)/) // split on first `:` or `=` const label = labelProp || `${keyOnly ? key: slotVal}` + const keyDel = keyDelim ?? '.' const cfgKey = ref() const popperVisible = ref(false) @@ -114,25 +116,25 @@ let jsonVal if (typeof value === 'string' && value.trim().match(/^[[{].*[\]}]$/)) { try { jsonVal = JSON.parse(value) } catch {/*ignore*/ } } - const pkg = toJson(key, jsonVal ?? value) + const pkg = toJson(key, jsonVal ?? value, keyDel) pkgStr.value = JSON.stringify(pkg, null, 2) rcJsonStr.value = JSON.stringify(pkg.cds??{}, null, 2) rcJsStr.value = 'module.exports = ' + rcJsonStr.value.replace(/"(\w*?)":/g, '$1:') rcYmlStr.value = yaml.stringify(pkg.cds) - propStr.value = `${key}=${jsonVal ? JSON.stringify(jsonVal) : value}` - let envKey = key.replaceAll('_', '__').replaceAll('.', '_') + let envKey = key.replaceAll('_', '__').replaceAll(keyDel, '_') if (/^[a-z_]+$/.test(envKey)) envKey = envKey.toUpperCase() // only uppercase if not camelCase envStr.value = `${envKey}=${jsonVal ? JSON.stringify(jsonVal) : value}` + propStr.value = `${envKey}=${jsonVal ? JSON.stringify(jsonVal) : value}` javaAppyml.value = yaml.stringify(pkg) javaEnvStr.value = `-D${propStr.value}` }) -function toJson(key:string, value:string): Record { +function toJson(key:string, value:string, delim:string): Record { let res = {} - const parts = key.split('.') + const parts = key.split(delim) parts.reduce((r:Record, a, i) => { r[a] = r[a] || (i < parts.length-1 ? {} : value) return r[a]; diff --git a/.vitepress/theme/styles.scss b/.vitepress/theme/styles.scss index 29c198e614..e4e2722169 100644 --- a/.vitepress/theme/styles.scss +++ b/.vitepress/theme/styles.scss @@ -115,11 +115,11 @@ main { // Custom list styles for nested items ul { list-style-type: disc; // First level: filled circle - + ul { list-style-type: circle; // Second level: empty circle - - + + ul { list-style-type: square; // Third level: square } @@ -299,6 +299,11 @@ main { border-width: 0 0 0 7px; border-radius: 14px; + .learn-more { + margin-top: 10px; + margin-bottom: -5px; + } + &.note { background-color: #f6f6f6; border-color: #bbb; @@ -551,15 +556,14 @@ html.node { pre.log:focus { min-width: fit-content; padding-right: 40px; - z-index: 1; // draw over outline + z-index: 1; position: relative; // draw over outline } table:hover, table:focus { min-width: fit-content; } - tr { // make wide rows go over outline, not below it - z-index: 1; - position: relative; + tr { + z-index: 1; position: relative; // draw wide rows over outline } [class*='language-'] pre { overflow: hidden !important; diff --git a/advanced/fiori.md b/advanced/fiori.md index 1b1b2d27be..1c96d54e1e 100644 --- a/advanced/fiori.md +++ b/advanced/fiori.md @@ -1,5 +1,4 @@ --- -shorty: Fiori UIs synopsis: > CAP provides out-of-the-box support for SAP Fiori elements front ends. permalink: advanced/fiori @@ -9,7 +8,7 @@ impl-variants: true uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/e4a7559baf9f4e4394302442745edcd9.html --- -# Serving Fiori UIs +# Serving SAP Fiori UIs {{ $frontmatter.synopsis }} @@ -23,13 +22,13 @@ This guide explains how to add one or more SAP Fiori elements apps to a CAP proj ## SAP Fiori Preview -For entities exposed via OData V4 there is a _Fiori preview_ link on the index page. It dynamically serves an SAP Fiori Elements list page that allows you to quickly see the effect of annotation changes without having to create a UI application first. +For entities exposed via OData V4 there is a _Fiori preview_ link on the index page. It dynamically serves an SAP Fiori elements list page that allows you to quickly see the effect of annotation changes without having to create a UI application first. ::: details Be aware that this is **not meant for production**.
-The preview not meant as a replacement for a proper SAP Fiori Elements (UI5) application. +The preview is not meant as a replacement for a proper SAP Fiori elements (UI5) application. It is only active locally where the [development profile](../node.js/cds-env#profiles) is enabled. To also enable it in cloud deployments, for test or demo purposes maybe, set cds.fiori.preview:true. @@ -38,7 +37,7 @@ To also enable it in cloud deployments, for test or demo purposes maybe, set -The preview not meant as a replacement for a proper SAP Fiori Elements (UI5) application. +The preview is not meant as a replacement for a proper SAP Fiori elements (UI5) application. It is active by default, but disabled automatically in case the [production profile](../java/developing-applications/configuring#production-profile) is enabled. To also enable it in cloud deployments, for test or demo purposes maybe, set cds.index-page.enabled:true. @@ -744,4 +743,99 @@ Cache Control feature is currently supported on the Java runtime only.
+## Hierarchical Tree Views + +Recursive hierarchies are parent-child hierarchies, where each entity references its parent and through that defines the hierarchical structure. A common example is a company organization structure or HR reporting, where each employee entity references another employee as a direct report or manager. + +A generic hierarchy implementation for hierarchies is available on all relational datases supported by the CAP runtimes. + +::: warning +On H2, only small hierarchies should be used for performance reasons. +::: + +### Example +Let's assume we have the following domain model and its projection in a service: + +::: code-group +```cds [schema.cds] +namespace my.bookshop; + +entity Genres { //... + parent : Association to Genres; +} +``` +::: + +::: code-group +```cds [AdminService.cds] +service AdminService { + entity Genres as projection on my.bookshop.Genres; +} +``` +::: + + +Annotate/extend the entity in the service as follows: + +```cds +// declare a hierarchy with the qualifier "GenresHierarchy" +annotate AdminService.Genres with @Aggregation.RecursiveHierarchy #GenresHierarchy : { + NodeProperty : ID, // identifies a node, usually the key + ParentNavigationProperty : parent // navigates to a node's parent +}; + +extend AdminService.Genres with @( + // The computed properties expected by Fiori to be present in hierarchy entities + Hierarchy.RecursiveHierarchy #GenresHierarchy : { + LimitedDescendantCount : LimitedDescendantCount, + DistanceFromRoot : DistanceFromRoot, + DrillState : DrillState, + LimitedRank : LimitedRank + }, + // Disallow filtering on these properties from Fiori UIs + Capabilities.FilterRestrictions.NonFilterableProperties: [ + 'LimitedDescendantCount', 'DistanceFromRoot', 'DrillState', 'LimitedRank' + ], + // Disallow sorting on these properties from Fiori UIs + Capabilities.SortRestrictions.NonSortableProperties : [ + 'LimitedDescendantCount', 'DistanceFromRoot', 'DrillState', 'LimitedRank' + ], +) columns { // Ensure we can query these columns from the database + null as LimitedDescendantCount : Int16, + null as DistanceFromRoot : Int16, + null as DrillState : String, + null as LimitedRank : Int16 +}; +``` + +> Note: When naming the hierarchy qualifier, use the following pattern:
+> `Hierarchy` + +Configure the TreeTable in UI5's _manifest.json_ file: + +```jsonc + "sap.ui5": { ... + "routing": { ... + "targets": { ... + "GenresList": { ... + "options": { + "settings": { ... + "controlConfiguration": { + "@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "hierarchyQualifier": "GenresHierarchy", // [!code focus] + "type": "TreeTable" // [!code focus] + } + } + } + } + } + }, + }, + }, +``` + +> Note: use the `hierarchyQualifier` declared earlier +
+ diff --git a/advanced/hybrid-testing.md b/advanced/hybrid-testing.md index 6683a3fd2f..93d549ffd6 100644 --- a/advanced/hybrid-testing.md +++ b/advanced/hybrid-testing.md @@ -458,10 +458,10 @@ cds bind --to my-service,redis-cache:my-key,bookshop-xsuaa --credentials \ '{ "my-service": { "onpremise_proxy_host": "localhost" }, "redis-cache:my-key":{ "hostname": "localhost", "port": 1234 }}' ``` -Use the service instance name in combination with the option `--to-app-services` if you want to create bindings for all service instances of your application: +Use the service instance name in combination with the option `-a` if you want to create bindings for all service instances of your application: ```sh -cds bind --to-app-services bookshop-srv --credentials \ +cds bind -a bookshop-srv --credentials \ '{ "my-service": { "onpremise_proxy_host": "localhost" }, "redis-cache":{ "hostname": "localhost", "port": 1234 }}' ``` diff --git a/advanced/odata.md b/advanced/odata.md index e68b570f6e..95006c42b2 100644 --- a/advanced/odata.md +++ b/advanced/odata.md @@ -28,23 +28,25 @@ status: released OData is an OASIS standard that enhances plain REST with standardized system query options like `$select`, `$expand`, `$filter`, and others. The following table provides an overview of the feature coverage: -| Query Options | Remarks | Node.js | Java | -|----------------|-------------------------------------------|:------------:|:---------:| +| Query Options | Remarks | Node.js | Java | +|----------------|---------------------------------------------|:------------:|:---------:| | `$search` | Search in multiple/all text elements(1)| | | -| `$value` | Retrieves single rows/values | | | -| `$top`,`$skip` | Requests paginated results | | | -| `$filter` | Like SQL where clause | | | -| `$select` | Like SQL select clause | | | -| `$orderby` | Like SQL order by clause | | | -| `$count` | Gets number of rows for paged results | | | -| `$apply` | For [data aggregation](#data-aggregation) | | | -| `$expand` | Deep-read associated entities | | | -| [Lambda Operators](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361024) | Boolean expressions on a collection | | (2) | -| [Parameters Aliases](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_ParameterAliases) | Replace literal value in URL with parameter alias | | (3) | +| `$value` | Retrieves single rows/values | | | +| `$top`,`$skip` | Requests paginated results | | | +| `$filter` | Like SQL where clause | | | +| `$select` | Like SQL select clause | | | +| `$orderby` | Like SQL order by clause | | | +| `$count` | Gets number of rows for paged results | | | +| `$apply` | For [data aggregation](#data-aggregation) | | | +| `$expand` | Deep-read associated entities | | | +| `$compute` | Dynamic expressions for other query options | (2) | | +| [Lambda Operators](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361024) | Boolean expressions on a collection | | (3) | +| [Parameters Aliases](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_ParameterAliases) | Replace literal value in URL with parameter alias | | (4) | - (1) The elements to be searched are specified with the [`@cds.search` annotation](../guides/providing-services#searching-data). -- (2) The navigation path identifying the collection can only contain one segment. -- (3) Supported for key values and for parameters of functions only. +- (2) Node.js only supports a limited subset in `$select` query option. +- (3) The navigation path identifying the collection can only contain one segment. +- (4) Supported for key values and for parameters of functions only. System query options can also be applied to an [expanded navigation property](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361039) (nested within `$expand`): @@ -1028,6 +1030,7 @@ You can add further vocabularies to the translation process [using configuration | [@Common](https://github.com/SAP/odata-vocabularies/tree/main/vocabularies/Common.md){target="_blank"} | for all SAP vocabularies | | [@Communication](https://github.com/SAP/odata-vocabularies/tree/main/vocabularies/Communication.md){target="_blank"} | for annotating communication-relevant information | | [@DataIntegration](https://github.com/SAP/odata-vocabularies/tree/main/vocabularies/DataIntegration.md){target="_blank"} | for data integration | +| [@Hierarchy](https://github.com/SAP/odata-vocabularies/blob/main/vocabularies/Hierarchy.md){target="_blank"} | for hierarchies | | [@PDF](https://github.com/SAP/odata-vocabularies/tree/main/vocabularies/PDF.md){target="_blank"} | for PDF | | [@PersonalData](https://github.com/SAP/odata-vocabularies/tree/main/vocabularies/PersonalData.md){target="_blank"} | for annotating personal data | | [@Session](https://github.com/SAP/odata-vocabularies/tree/main/vocabularies/Session.md){target="_blank"} | for sticky sessions for data modification | @@ -1091,21 +1094,25 @@ If the `groupby` transformation only includes a subset of the entity keys, the r ### Transformations -| Transformation | Description | Node.js | Java | -|------------------------------|---------------------------------------------|:------------------:|:-----:| -| `filter` | filter by filter expression | | | -| `search` | filter by search term or expression | | | -| `groupby` | group by dimensions and aggregates values | | | -| `aggregate` | aggregate values | | | -| `compute` | add computed properties to the result set | | | -| `expand` | expand navigation properties | | | -| `concat` | append additional aggregation to the result | | | -| `skip` / `top` | paginate | | | -| `orderby` | sort the input set | | | -| `topcount`/`bottomcount` | retain highest/lowest _n_ values | | | -| `toppercent`/`bottompercent` | retain highest/lowest _p_% values | | | -| `topsum`/`bottomsum` | retain _n_ values limited by sum | | | - +| Transformation | Description | Node.js | Java | +|------------------------------|----------------------------------------------|:------------------:|:-----:| +| `filter` | filter by filter expression | | | +| `search` | filter by search term or expression | | | +| `groupby` | group by dimensions and aggregates values | | | +| `aggregate` | aggregate values | | | +| `compute` | add computed properties to the result set | | | +| `expand` | expand navigation properties | | | +| `concat` | append additional aggregation to the result | | | +| `skip` / `top` | paginate | | | +| `orderby` | sort the input set | | | +| `topcount`/`bottomcount` | retain highest/lowest _n_ values | | | +| `toppercent`/`bottompercent` | retain highest/lowest _p_% values | | | +| `topsum`/`bottomsum` | retain _n_ values limited by sum | | | +| `TopLevels` | retain only _n_ levels of a hierarchy | 2 | 1,2 | +| `ancestors/descendants` | retain ancestors/descendants of specific nodes | 2 | 1,2 | + +1 - supported on SAP HANA, H2 ad PostgreSQL only +2 - only to support requests from the UI5 Tree Table #### `concat` @@ -1137,7 +1144,6 @@ GET /Order(10)/books? This query groups the 500 most expensive books by author name and determines the price of the most expensive book per author. - ### Aggregation Methods | Aggregation Method | Description | Node.js | Java | @@ -1148,8 +1154,10 @@ This query groups the 500 most expensive books by author name and determines the | `average` | average of values | | | | `countdistinct` | count of distinct values | | | | custom method | custom aggregation method | | | +| custom aggregate | predefined custom aggregate | | | | `$count` | number of instances in input set | | | + ### Custom Aggregates Instead of explicitly using an expression with an aggregation method in the `aggregate` transformation, the client can use a _custom aggregate_. A custom aggregate can be considered as a virtual property that aggregates the input set. It's calculated on the server side. The client doesn't know _How_ the custom aggregate is calculated. @@ -1203,7 +1211,7 @@ entity Sales { } ``` -The CAP Java SDK exposes all properties annotated with `@Semantics.currencyCode` or `@Semantics.unitOfMeasure` as a [custom aggregate](../advanced/odata#custom-aggregates) with the property's name that returns: +All properties annotated with `@Semantics.currencyCode` or `@Semantics.unitOfMeasure` are exposed as a [custom aggregate](../advanced/odata#custom-aggregates) with the property's name that returns: * The property's value if it's unique within a group of dimensions * `null` otherwise @@ -1218,7 +1226,7 @@ A custom aggregate for a currency code or unit of measure should also be exposed | chain transformations | | | | chain transformations within group by | | | | `groupby` with `rollup`/`$all` | | | -| `$expand` result set of `$apply` | | | +| `$expand` result set of `$apply` | | | | `$filter`/`$search` result set | | | | sort result set with `$orderby` | | | | paginate result set with `$top`/`$skip` | | | diff --git a/cds/cdl.md b/cds/cdl.md index 4d10803e71..39fb01b314 100644 --- a/cds/cdl.md +++ b/cds/cdl.md @@ -41,7 +41,7 @@ The *Conceptual Definition Language (CDL)* is a human-readable language for defi ```cds namespace capire.bookshop; -using { managed, cuid } from `@sap/cds/common`; +using { managed, cuid } from '@sap/cds/common'; aspect primary : managed, cuid {} entity Books : primary { @@ -85,7 +85,7 @@ The following literals can be used in CDL (mostly as in JavaScript, Java, and SQ ```cds true , false , null // as in all common languages -11 , 2.4 , 1e3, 1.23e-11 // for numbers +11 , 2.4 , 1e3 , 1.23e-11 // for numbers 'A string''s literal' // for strings `A string\n paragraph` // for strings with escape sequences { foo:'boo', bar:'car' } // for records @@ -130,6 +130,10 @@ entity DocumentedEntity { } ``` +::: tip +These annotations are illustrative only and are not defined nor have any meaning beyond this example. +::: + Within those strings, escape sequences from JavaScript, such as `\t` or `\u0020`, are supported. Line endings are normalized. If you don't want a line ending at that position, end a line with a backslash (`\`). For string literals inside triple backticks, indentation is stripped and tagging is possible. @@ -238,7 +242,7 @@ context scoped { You can define types and entities with other definitions' names as prefixes: -```cds +```cds [prefixes.cds] namespace foo.bar; entity Foo {} //> foo.bar.Foo entity Foo.Bar {} //> foo.bar.Foo.Bar @@ -248,7 +252,7 @@ type Foo.Bar.Car {} //> foo.bar.Foo.Bar.Car #### Fully Qualified Names -A model ultimately is a collection of definitions with unique, fully qualified names. For example, the second model above would compile to this [CSN](./csn): +A model ultimately is a collection of definitions with unique, fully qualified names. For example, the model in `contexts.cds` would compile to the following [CSN](./csn): ::: code-group @@ -1878,7 +1882,7 @@ service MyOrders { ``` ::: tip -You can optionally add annotations such as `@readonly` or `@insertonly` to exposed entities, which, will be enforced by the CAP runtimes in Java and Node.js. +You can optionally add annotations such as `@readonly` or `@insertonly` to exposed entities, which will be enforced by the CAP runtimes in Java and Node.js. ::: Entities can be also exposed as views with parameters: diff --git a/cds/types.md b/cds/types.md index 7c5aeac693..12d16b5604 100644 --- a/cds/types.md +++ b/cds/types.md @@ -36,7 +36,7 @@ These types are used to define the structure of entities and services, and are m | `Decimal` (`prec`, `scale`) | A *decfloat* type is used if arguments are omitted | _DECIMAL_ | | `Double` | Floating point with binary mantissa | _DOUBLE_ | | `Date` | e.g. `2022-12-31` | _DATE_ | -| `Time` | e.g. `24:59:59` | _TIME_ | +| `Time` | e.g. `23:59:59` | _TIME_ | | `DateTime` | _sec_ precision | _TIMESTAMP_ | | `Timestamp` | _µs_ precision, with up to 7 fractional digits | _TIMESTAMP_ | | `String` (`length`) | Default *length*: 255; on HANA: 5000 (4)(5) | _NVARCHAR_ | @@ -46,13 +46,11 @@ These types are used to define the structure of entities and services, and are m | `Map` | Mapped to *NCLOB* for HANA. | *JSON* type | | `Vector` (`dimension `) | Requires SAP HANA Cloud QRC 1/2024, or later | _REAL_VECTOR_ | -These types are used to define the structure of entities and services, and are mapped to respective database types when the model is deployed. - > (1) Concrete mappings to specific databases may differ. > > (2) See also [Best Practices](../guides/domain-modeling#don-t-interpret-uuids). > -> (3) Not available on PostgreSQL and H2. +> (3) _SMALLINT_ on PostgreSQL and H2. > > (4) Productive apps should always use an explicit length. Use the default only for rapid prototyping. > diff --git a/get-started/in-a-nutshell.md b/get-started/in-a-nutshell.md index 822af6e0f5..9006891851 100644 --- a/get-started/in-a-nutshell.md +++ b/get-started/in-a-nutshell.md @@ -393,7 +393,7 @@ Create CSV files that already include some sample data: ```sh cds add data --records 10 ``` -[Find the full set of options here.](../tools/cds-cli.md#data){.learn-more} +[Find the full set of options in the CLI reference.](../tools/cds-cli.md#data){.learn-more} ::: @@ -781,7 +781,7 @@ Books book = persistenceService.run(byId).single(Books.class); ### Sample HTTP Requests -Test the implementation by submitting orders until you see the error messages. Create a file called _test.http_ and copy the request into it. +Test the implementation by submitting orders until you see the error messages. Create a file called _test.http_ and copy the request into it. Send requests from your IDE supporting `*.http` files with, for example, a [REST Client](/tools/cds-editors#add-useful-plugins). diff --git a/guides/assets/flows/xtravels-flow-extend.svg b/guides/assets/flows/xtravels-flow-extend.svg new file mode 100644 index 0000000000..55fde8c076 --- /dev/null +++ b/guides/assets/flows/xtravels-flow-extend.svg @@ -0,0 +1,4 @@ + + +OpenAcceptedWithdrawnacceptwithdrawCanceledreject \ No newline at end of file diff --git a/guides/assets/flows/xtravels-flow-previous.svg b/guides/assets/flows/xtravels-flow-previous.svg new file mode 100644 index 0000000000..ad2a583c85 --- /dev/null +++ b/guides/assets/flows/xtravels-flow-previous.svg @@ -0,0 +1,4 @@ + + +OpenInReviewAcceptedCanceled→ to previous statereviewacceptblockreopenBlockedrejectblockunblock \ No newline at end of file diff --git a/guides/assets/flows/xtravels-flow-simple.svg b/guides/assets/flows/xtravels-flow-simple.svg new file mode 100644 index 0000000000..24b2c46de4 --- /dev/null +++ b/guides/assets/flows/xtravels-flow-simple.svg @@ -0,0 +1,4 @@ + + +OpenAcceptedCanceledacceptreject \ No newline at end of file diff --git a/guides/databases-h2.md b/guides/databases-h2.md index 33be3587fa..d329dedf23 100644 --- a/guides/databases-h2.md +++ b/guides/databases-h2.md @@ -9,7 +9,7 @@ impl-variants: true For local development and testing, CAP Java supports the [H2](https://www.h2database.com/) database, which can be configured to run in-memory. -[Learn more about features and limitations of using CAP with H2](../java/cqn-services/persistence-services#h2){.learn-more} +[Learn more about features and limitations of using CAP with H2.](../java/cqn-services/persistence-services#h2){.learn-more}
@@ -28,28 +28,7 @@ Not supported for CAP Node.js. ## Setup & Configuration {.java} -### Using the Maven Archetype {.java} - -When a new CAP Java project is created with the [Maven Archetype](../java/developing-applications/building#the-maven-archetype) or with `cds init`, -H2 is automatically configured as in-memory database used for development and testing in the `default` profile. - -### Manual Configuration {.java} - -To use H2, just add a Maven dependency to the H2 JDBC driver: - -```xml - - com.h2database - h2 - runtime - -``` - -Next, configure the build to [create an initial _schema.sql_ file](../java/cqn-services/persistence-services#initial-database-schema-1) for H2 using `cds deploy --to h2 --dry`. - -In Spring, H2 is automatically initialized as in-memory database when the driver is present on the classpath. - -[Learn more about the configuration of H2 ](../java/cqn-services/persistence-services#h2){.learn-more} +There are various options of how to configure the [H2 database for local development and testing in CAP Java.](../java/developing-applications/testing#setup-configuration) ## Features {.java} @@ -61,4 +40,4 @@ CAP supports most of the major features on H2: * [Comparison Operators](../java/working-with-cql/query-api#comparison-operators) * [Predicate Functions](../java/working-with-cql/query-api#predicate-functions) -[Learn about features and limitations of H2](../java/cqn-services/persistence-services#h2){.learn-more} +[Learn about features and limitations of H2.](../java/cqn-services/persistence-services#h2){.learn-more} diff --git a/guides/databases.md b/guides/databases.md index 06f943fc58..784069076a 100644 --- a/guides/databases.md +++ b/guides/databases.md @@ -921,12 +921,12 @@ Instead, they protect the integrity of your data in the database layer against p ## Standard Database Functions -A specified set of standard functions - inspired by [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_StringandCollectionFunctions) and [SAP HANA](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/alphabetical-list-of-functions?locale=en-US) - is supported in a **database-agnostic**, hence portable way, and translated to the best-possible native SQL functions or polyfills during runtime (currently only Node.js) and for your CDL files. +A specified set of standard functions - inspired by [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_StringandCollectionFunctions) and [SAP HANA](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/alphabetical-list-of-functions?locale=en-US) - is supported in a **database-agnostic**, hence portable way. The functions are translated to the best-possible database-specific SQL expressions at runtime and also during compilation of your CDL files. ### OData standard functions -The `@sap/cds-compiler` and all CAP Node.js database services come with out of the box support for common OData functions. +The `@sap/cds-compiler` and the database services come with out of the box support for common OData functions. ::: warning Case Sensitivity The OData function mappings are case-sensitive and must be written as in the list below. @@ -1021,6 +1021,8 @@ For example, `startsWith` instead of `startswith` will be passed as-is to the da If you provide more than one argument, the `round` function may behave differently depending on the database. ::: +
+ #### Date and Time Functions - `year(x)`, `month(x)`, `day(x)`, `hour(x)`, `minute(x)`, `second(x)` @@ -1038,11 +1040,14 @@ For example, `startsWith` instead of `startswith` will be passed as-is to the da - `mindatetime()` Returns the earliest possible point in time: `'0001-01-01T00:00:00.000Z'`. +
+ #### Aggregate Functions - `min(x)`, `max(x)`, `sum(x)`, `average(x)`, `count(x)`, `countdistinct(x)` Standard aggregate functions used to calculate minimum, maximum, sum, average, count, and distinct count of values. +
### SAP HANA Functions @@ -1066,7 +1071,7 @@ For the SAP HANA functions, both usages are allowed: all-lowercase as given abov ### Special Runtime Functions -In addition to the OData and SAP HANA standard functions, the **CAP runtimes** provides special functions that are only available for runtime queries: +In addition to the OData and SAP HANA standard functions, the **CAP runtime** provides special functions that are only available for runtime queries: - `search(x, y)` Checks whether `y` is contained in any element of `x` (fuzzy matching may apply). @@ -1079,6 +1084,8 @@ In addition to the OData and SAP HANA standard functions, the **CAP runtimes** p - `now()` Returns the current timestamp. +
+ ## Using Native Features { #native-db-functions} In general, the CDS 2 SQL compiler doesn't 'understand' SQL functions but translates them to SQL generically as long as they follow the standard call syntax of `function(param1, param2)`. This allows you to use native database functions inside your CDS models. @@ -1191,4 +1198,4 @@ Once you have 2 non-HANA local databases, you need to have 2 distinct database c
-CAP samples demonstrate this in [@capire/bookstore](https://github.com/capire/bookstore/tree/main/db). \ No newline at end of file +CAP samples demonstrate this in [@capire/bookstore](https://github.com/capire/bookstore/tree/main/db). diff --git a/guides/deployment/cicd.md b/guides/deployment/cicd.md index d525289b6e..d28cde448d 100644 --- a/guides/deployment/cicd.md +++ b/guides/deployment/cicd.md @@ -31,7 +31,7 @@ cds add github-actions ### Deploy to Staging -The created workflows do a _Staging_ deployment for pushes on the `main` branch, for example after merging pull requests. +The created workflows do a _Staging_ deployment for pushes on the `main` branch, usually after merging pull requests. If no defaults are maintained in your GitHub org, a set of variables and secrets has to be provided. Open the repository and navigate here to maintain them: @@ -41,19 +41,19 @@ For a minimal deployment setup, these variables and secrets are required: #### Cloud Foundry -| **Type** | **Name** | **Note** | **Example** | -|------------|----------------|-----------|-------------------| -| Variable | `CF_API` | API URL | `https://api.cf.example.com` | -| | `CF_USERNAME` | Username | `user@example.com` | -| | `CF_ORG` | Org Name | `my-org` | -| | `CF_SPACE` | Space Name| `my-space` | -| Secret | `CF_PASSWORD` | Password | `********` | +| **Type** | **Name** | **Note** | **Example** | +|------------|----------------|------------|-------------------| +| Variable | `CF_API` | API URL | `https://api.cf.example.com` | +| | `CF_USERNAME` | Username | `user@example.com` | +| | `CF_ORG` | Org Name | `my-org` | +| | `CF_SPACE` | Space Name | `my-space` | +| Secret | `CF_PASSWORD` | Password | `********` | #### Kyma | **Type** | **Name** | **Note** | **Example** | |------------|----------------|-----------|-------------------| -| Secret | `KUBE_CONFIG` | Base64-encoded Kubernetes config | see below | +| Secret | `KUBE_CONFIG` | Base64-encoded Kubernetes config | see below | ::: details Example of a decoded `KUBE_CONFIG` @@ -80,7 +80,7 @@ contexts: user: ci-user current-context: ci-context ``` -[Learn more about configuring Kubernetes](./to-kyma#configure-kubernetes){.learn-more style="margin-top:20px"} +[Learn more about configuring Kubernetes](./to-kyma#configure-kubernetes){.learn-more} ::: @@ -107,7 +107,7 @@ You can now simply push any CAP project that was set up using `cds add github-ac For the actual release we want to override org-wide sandbox variables to deploy to a different subaccount/organization and database. -Go to `Settings` → `Environments` → `New environment` → enter "Production". +Go to **Settings** → **Environments** → **New environment** → enter "Production". Now override org-wide variables (e.g. `CF_ORG` and `CF_SPACE` in Cloud Foundry) to use a dedicated subaccount you created for the release deployment. diff --git a/guides/deployment/microservices.md b/guides/deployment/microservices.md index 0f72155024..60bdae144c 100644 --- a/guides/deployment/microservices.md +++ b/guides/deployment/microservices.md @@ -747,7 +747,7 @@ Before deploying you need to log in to Cloud Foundry: `cf login --sso` Start the deployment and build process: -``` +```sh cds up ``` diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index a343e5b052..746d9aa672 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -216,8 +216,6 @@ To enable multitenancy for production, run the following command: cds add multitenancy ``` -[Learn more about MTX services.](../multitenancy/#behind-the-scenes){.learn-more} -
::: tip You're set! @@ -279,11 +277,11 @@ While `cds build` is already ran as part of `mbt build` in `cds up`, you can als cds build --production ``` -[Learn more about running and customizing `cds build`.](custom-builds){.learn-more style="margin-top: 10px"} +[Learn more about running and customizing `cds build`.](custom-builds){.learn-more} ::: -[Got errors? See the troubleshooting guide.](../../get-started/troubleshooting#mta){.learn-more style="margin-top: 10px"} +[Got errors? See the troubleshooting guide.](../../get-started/troubleshooting#mta){.learn-more} [Learn how to reduce the MTA archive size **during development**.](../../get-started/troubleshooting#reduce-mta-size){.learn-more} This process can take some minutes and finally logs an output like this: @@ -384,6 +382,11 @@ sed -i 's/org.springframework.boot.loader.JarLauncher/-Dloader.main=com.sap.cds. ::: +## Next Up... + +You would then [set up your CI/CD](../deployment/cicd) for automating deployments, for example after merging pull requests. + + ---- +## Next Up... + +You would then [set up your CI/CD](../deployment/cicd) for automating deployments, for example after merging pull requests. + {style="margin-top:11em"} ## Deep Dives @@ -257,24 +260,13 @@ Specify the repository where you want to push the images: ... repository: ``` - ::: -Now, we use the `ctz` build tool to build all the images: - -```sh -ctz containerize.yaml -``` - -This will start containerizing your modules based on the configuration in _containerize.yaml_. After finishing, it will ask whether you want to push the images or not. Type `y` and press enter to push your images. You can also use the above command with `--push` flag to auto-confirm. If you want more logs, you can use the `--log` flag with the above command. - -[Learn more about the `ctz` build tool.](https://www.npmjs.com/package/ctz/){.learn-more style="margin-top:10px"} - ### Customize Helm Chart {#customize-helm-chart} #### About CAP Helm Charts {#about-cap-helm} -The following files are added to a _chart_ folder by executing `cds add helm`: +The following files are added to a _chart_ folder by executing `cds add kyma`: ```zsh chart/ @@ -323,7 +315,7 @@ imagePullSecret: # Kubernetes cluster ingress domain (used for application URLs) domain: -# Container image registry +# Container image registry where to pull the image from image: registry: ``` @@ -494,13 +486,6 @@ parametersFrom: ``` ::: -The `jsonParameters` key can also be specified using the `--set file` flag while installing/upgrading Helm release. For example, `jsonParameters` for the `xsuaa` property can be defined using the following command: - -```sh -helm install bookshop ./chart \ - --set-file xsuaa.jsonParameters=xs-security.json -``` - > You can explore more configuration options in the subchart's directory _gen/chart/charts/service-instance_. #### Configuration Options for Service Bindings @@ -573,18 +558,18 @@ srv: # Key is the target service, e.g. 'srv' Modifying the Helm chart allows you to customize it to your needs. However, this has consequences if you want to update with the latest changes from the CAP template. -You can run `cds add helm` again to update your Helm chart. It has the following behavior for modified files: +You can run `cds add kyma` again to update your Helm chart. It has the following behavior for modified files: -1. Your changes of the _chart/values.yaml_ and _chart/Chart.yaml_ will not be modified. Only new or missing properties will be added by `cds add helm`. +1. Your changes of the _chart/values.yaml_ and _chart/Chart.yaml_ will not be modified. Only new or missing properties will be added by `cds add kyma`. 2. To modify any of the generated files such as templates or subcharts, copy the files from _gen/chart_ folder and place it in the same level inside the _chart_ folder. After the next `cds build` executions the generated chart will have the modified files. 3. If you want to have some custom files such as templates or subcharts, you can place them in the _chart_ folder at the same level where you want them to be in _gen/chart_ folder. They will be copied as is. ### Extend -Instead of modifying consider extending the CAP Helm chart. Just make sure adding new files to the Helm chart does not conflict with `cds add helm`. +Instead of modifying consider extending the CAP Helm chart. Just make sure adding new files to the Helm chart does not conflict with `cds add kyma`. ::: tip Consider Kustomize -A modification-free approach to change files is to use [Kustomize](https://kustomize.io/) as a [post-processor](https://helm.sh/docs/topics/advanced/#post-rendering) for your Helm chart. This might be usable for small changes if you don't want to branch-out from the generated `cds add helm` content. +A modification-free approach to change files is to use [Kustomize](https://kustomize.io/) as a [post-processor](https://helm.sh/docs/topics/advanced/#post-rendering) for your Helm chart. This might be usable for small changes if you don't want to branch-out from the generated `cds add kyma` content. ::: diff --git a/guides/flows.md b/guides/flows.md new file mode 100644 index 0000000000..3d32fd547c --- /dev/null +++ b/guides/flows.md @@ -0,0 +1,132 @@ +--- +synopsis: > + Learn how to define and manage status-transition flows in your CDS models using annotations, without writing custom handlers. +#status: released +--- + +# Status-Transition Flows + +[...] + +## Extending Flows + +[...] + +### Example Use Case + +Consider a requirement where customers can withdraw from travel — for example, due to sickness — but only up to 24 hours before travel begins. This requires custom validation logic. + +The status transition diagram below shows the new state and transitions: +![](./assets/flows/xtravels-flow-extend.svg) + +First, add the `Withdrawn` status and the `withdrawTravel` action to the model: + +```cds +// db/schema.cds +entity TravelStatus : sap.common.CodeList { + key code : String(1) enum { + Open = 'O'; + Accepted = 'A'; + Canceled = 'X'; + Withdrawn = 'W'; // [!code highlight] + } +} + +// srv/travel-service.cds +service TravelService { + + // Define entity and actions + entity Travels as projection on db.Travels + actions { + action rejectTravel(); + action acceptTravel(); + action withdrawTravel(); // [!code highlight] + action deductDiscount( percent: Percentage not null ) returns Travels; + }; + + // Define flow through actions + annotate Travels with @flow.status: Status actions { + rejectTravel @from: #Open @to: #Canceled; + acceptTravel @from: #Open @to: #Accepted; + withdrawTravel @from: [#Open, #Accepted]; // [!code highlight] + deductDiscount @from: #Open; + }; + +} +``` + +Note that `withdrawTravel` has no `@to` annotation; you implement the transition in a custom handler. + + +### In Java + +Here is a custom Java implementation that enforces the 24-hour rule: + +```java +@Component +@ServiceName(TravelService_.CDS_NAME) +public class WithdrawTravelHandler implements EventHandler { + + private final PersistenceService persistenceService; + + public WithdrawTravelHandler(PersistenceService persistenceService) { + this.persistenceService = persistenceService; + } + + @Before(entity = Travel_.CDS_NAME) + public void check24HoursBeforeTravel(final TravelWithdrawTravelContext context, CqnStructuredTypeRef travelRef) { + Travel travel = ((ApplicationService) context.getService()).run( + Select.from(travelRef).columns(Travel_.BEGIN_DATE)).first(Travel.class) + .orElseThrow(() -> new ServiceException(ErrorStatuses.BAD_REQUEST, "TRAVEL_NOT_FOUND")); + + if (travel.beginDate().isBefore(LocalDate.now().minusDays(1))) { + context.getMessages().error("Travel can only be withdrawn up to 24 hours before travel begins."); + } + } + + @On(entity = Travel_.CDS_NAME) + public void onWithdrawTravel(final TravelWithdrawTravelContext context, CqnStructuredTypeRef travelRef) { + boolean isDraftTarget =DraftUtils.isDraftTarget( + travelRef, + context.getModel().findEntity(travelRef.targetSegment().id()).get(), + context.getModel()); + boolean isDraftEnabled = DraftUtils.isDraftEnabled(context.getTarget()); + var travel = Travel.create(); + travel.travelStatusCode(TravelStatusCode.WITHDRAWN); + if (isDraftTarget) { + ((DraftService) context.getService()).patchDraft(Update.entity(travelRef).data(travel)); + } else { + AnalysisResult analysis = CqnAnalyzer.create(context.getModel()).analyze(travelRef); + Map keys = analysis.targetKeyValues(); + if (isDraftEnabled) { + keys.remove(Drafts.IS_ACTIVE_ENTITY); + } + persistenceService.run(Update.entity(context.getTarget()).matching(keys).data(travel)); + } + context.setCompleted(); + } + +} +``` + +The custom `before` handler reads the travel's `BeginDate` and validates that withdrawal occurs within the allowed timeframe. The custom `on` handler updates the travel status to `Withdrawn` and marks the action as completed. + + + +The custom `on` handler updates the travel status to `Withdrawn` and marks the action as completed. + +::: warning TODO: we should actually do the following! +-> `withdrawTravel` should only have an additional before check. +::: + +While you could use the `@to` annotation with the default handler, omitting it signals that you implemented custom transition logic. + + +### In Node.js + +TODO diff --git a/guides/i18n.md b/guides/i18n.md index 30e7977a25..cdab641992 100644 --- a/guides/i18n.md +++ b/guides/i18n.md @@ -54,8 +54,8 @@ Then you can translate the texts in localized bundles, each with a language/loca ```sh _i18n/ - i18n.properties # dev main --› 'default fallback' - i18n_en.properties # English --› 'default language' + i18n.properties # dev main → 'default fallback' + i18n_en.properties # English → 'default language' i18n_de.properties # German i18n_zh_TW.properties # Traditional Chinese ... @@ -66,7 +66,7 @@ _i18n/ Recommendation is to put your properties files in a folder named `_i18n` in the root of your project, as in this example: -```txt +```zsh bookshop/ ├─ _i18n/ │ ├─ i18n_en.properties @@ -80,7 +80,7 @@ bookshop/ By default, text bundles are fetched from folders named *_i18n* or *i18n* in the neighborhood of models, i.e. all folders that contain `.cds` sources or parent folders thereof. For example, given the following project layout and sources: -```txt +```zsh bookshop/ ├─ app/ │ ├─ browse/ @@ -95,9 +95,9 @@ bookshop/ └─ readme.md ``` -We will be loading i18n bundles from all of these locations, if exist: +We will be loading i18n bundles from all of these locations, if existing: -```txt +```zsh bookshop/app/browse/_i18n bookshop/app/_i18n bookshop/srv/_i18n @@ -122,14 +122,13 @@ The format is as follows: | Book | Book | Buch | ... | | Books | Books | Bücher | ... | | ... | -{ style="width: auto"} With this CSV source: ```csv -key;en;de;zh_CN;... -Book;Book;Buch;... -Books;Books;Bücher;... +key,en,de,zh_CN,... +Book,Book,Buch,... +Books,Books,Bücher,... ... ``` @@ -187,7 +186,8 @@ Upon incoming requests at runtime, the user's preferred language is determined a 2. The value of the `sap-language` URL parameter, but only if it's `1Q`, `2Q` or `3Q` as described below. 3. The first entry from the request's `Accept-Language` header. 2. Narrow to normalized locales as described below. -::: tip + +::: tip Differences between Node.js and Java runtimes CAP Node.js accepts formats following the available standards of POSIX and RFC 1766, and transforms them into normalized locales. CAP Java only accepts language codes following the standard of RFC 1766 (or [IETF's BCP 47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt)). ::: @@ -233,7 +233,7 @@ In this example we removed `es_CO` and `es_MX` from the list, and added `pt_BR`. In CAP Java the preserved locales can be configured via the cds.locales.normalization.includeList [property](../java/developing-applications/properties#cds-locales-normalization). -::: warning *Note:* +::: warning *Note:* However this list is configured, ensure to have translations for the listed locales, as the fallback language will otherwise be `en`. ::: diff --git a/guides/localized-data.md b/guides/localized-data.md index 0537dabe48..9f85a10432 100644 --- a/guides/localized-data.md +++ b/guides/localized-data.md @@ -80,9 +80,6 @@ entity localized.Books as select from Books {*, coalesce (localized.descr, descr) as descr }; ``` -::: warning Note: -In contrast to former versions, with CDS compiler v2 we don't add such entities to CSN anymore, but only on generated SQL DDL output. -::: ### Resolving localized texts via views @@ -124,7 +121,9 @@ entity OpenBookView as select from Books {*} Include the `localized` association: ```cds -entity ClosedBookView as select from Books { ID, title, descr, localized }; +entity ClosedBookView as select from Books { + ID, title, descr, localized +}; ``` @@ -266,9 +265,9 @@ using { Books } from './books'; service CatalogService { entity BooksList as projection on Books { ID, title, price }; entity BooksDetails as projection on Books; - entity BooksShort as projection on Books { + entity BooksShort as projection on Books { ID, price, - substr(title, 0, 10) as title : localized String(10), + substr(title, 0, 10) as title : localized String(10), }; } ``` @@ -285,15 +284,16 @@ entity localized.CatalogService.BooksList as entity localized.CatalogService.BooksDetails as SELECT from localized.Books; - + entity localized.CatalogService.BooksShort as SELECT from localized.Books { ID, price, substr(title, 0, 10) as title : localized String(10), }; ``` -::: warning Note: -Note that these `localized.` entities are not part of CSN and aren't exposed through OData. -They are only generated for SQL. +::: warning `localized` entities are only generated for SQL + +They are not part of the CSN or exposed via OData. + ::: ### Read Operations @@ -312,7 +312,9 @@ service CatalogService { In Node.js applications, for requests with an `$expand` query option on entities annotated with `@cds.localized: false`, the expanded properties are not translated. ```http -GET /BooksDetails?$expand=authors //> all fields from authors are non-localized defaults, if BooksDetails is annotated with `@cds.localized: false` +// all fields from authors are non-localized defaults if BooksDetails +// is annotated with `@cds.localized: false` +GET /BooksDetails?$expand=authors ``` ### Write Operations @@ -320,7 +322,7 @@ GET /BooksDetails?$expand=authors //> all fields from authors are non-localized Since the corresponding text table is linked through composition, you can use deep inserts or upserts to fill in language-specific texts. ```http -POST /Entity HTTP/1.1 +POST /Entity HTTP/1.1 Content-Type: application/json { @@ -333,7 +335,7 @@ Content-Type: application/json If you want to add a language-specific text to an existing entity, perform a `POST` request to the text table of the entity through navigation. ```http -POST /Entity()/texts HTTP/1.1 +POST /Entity()/texts HTTP/1.1 Content-Type: application/json { @@ -346,7 +348,7 @@ Content-Type: application/json To update the language-specific texts of an entity along with the default fallback text, you can perform a deep update as a `PUT` or `PATCH` request to the entity through navigation. ```http -PUT/PATCH /Entity() HTTP/1.1 +PUT/PATCH /Entity() HTTP/1.1 Content-Type: application/json { @@ -359,15 +361,15 @@ Content-Type: application/json To update a single language-specific text field, perform a `PUT` or a `PATCH` request to the entity's text field via navigation. ```http -PUT/PATCH /Entity()/texts(ID=,locale='')/ HTTP/1.1 +PUT/PATCH /Entity()/texts(ID=,locale='')/ HTTP/1.1 Content-Type: application/json { - {"name": "Ein neuer Name"} ] + "name": "Ein neuer Name" } ``` -::: warning *Note:* +::: warning Language codes need to follow BCP 47 Accepted language codes in the `locale` property need to follow the [BCP 47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) standard but use __underscore__ (`_`) instead of __hyphen__ (`-`), for example `en_GB`. ::: @@ -376,7 +378,7 @@ Accepted language codes in the `locale` property need to follow the [BCP 47](htt To delete a locale's language-specific texts of an entity, perform a `DELETE` request to the entity's texts table through navigation. Specify the entity's key and the locale that you want to delete. ```http -DELETE /Entity()/texts(ID=,locale='') HTTP/1.1 +DELETE /Entity()/texts(ID=,locale='') HTTP/1.1 ``` ## Nested Localized Data @@ -413,12 +415,12 @@ For example, _Books.csv_ can look as follows: ::: code-group ```csv [Books.csv] -ID;title;descr;author_ID;stock;price;currency_code;genre_ID -201;Wuthering Heights;Wuthering Heights, Emily Brontë's only novel ...;101;12;11.11;GBP;11 -207;Jane Eyre;Jane Eyre is a novel by English writer ...;107;11;12.34;GBP;11 -251;The Raven;The Raven is a narrative poem by ...;150;333;13.13;USD;16 -252;Eleonora;Eleonora is a short story by ...;150;555;14;USD;16 -271;Catweazle;Catweazle is a British fantasy ...;170;22;150;JPY;13 +ID,title,descr,author_ID,stock,price,currency_code,genre_ID +201,Wuthering Heights,"Wuthering Heights, Emily Brontë's only novel ...",101,12,11.11,GBP,11 +207,Jane Eyre,Jane Eyre is a novel by English writer ...,107,11,12.34,GBP,11 +251,The Raven,The Raven is a narrative poem by ...,150,333,13.13,USD,16 +252,Eleonora,Eleonora is a short story by ...,150,555,14,USD,16 +271,Catweazle,Catweazle is a British fantasy ...,170,22,150,JPY,13 ... ``` ::: @@ -427,11 +429,11 @@ This is the corresponding _Books_texts.csv_: ::: code-group ```csv [Books_texts.csv] -ID;locale;title;descr -201;de;Sturmhöhe;Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman... -201;fr;Les Hauts de Hurlevent;Les Hauts de Hurlevent (titre original : Wuthering Heights)... -207;de;Jane Eyre;Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography)... -252;de;Eleonora;Eleonora ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841... +ID,locale,title,descr +201,de,Sturmhöhe,Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman... +201,fr,Les Hauts de Hurlevent,Les Hauts de Hurlevent (titre original : Wuthering Heights)... +207,de,Jane Eyre,Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography)... +252,de,Eleonora,Eleonora ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841... ... ``` ::: diff --git a/guides/multitenancy/index.md b/guides/multitenancy/index.md index e303290108..7eb9cfaddb 100644 --- a/guides/multitenancy/index.md +++ b/guides/multitenancy/index.md @@ -79,6 +79,9 @@ cds add multitenancy "requires": { "[production]": { "multitenancy": true + }, + "[with-mtx]": { + "multitenancy": true } } } @@ -721,25 +724,11 @@ cds add mta ``` ```sh [Kyma] -cds add helm,containerize -``` - -::: - -::: details Add xsuaa redirect for trial / extension landscapes -Add the following snippet to your _xs-security.json_ and adapt it to the landscape you're deploying to: - -```json - "oauth2-configuration": { - "redirect-uris": ["https://*.cfapps.us10-001.hana.ondemand.com/**"] - } +cds add kyma ``` ::: -[Learn more about configured BTP services for SaaS applications.](#behind-the-scenes){.learn-more} - - ::: code-group ```sh [Cloud Foundry] @@ -908,14 +897,14 @@ For faster turnaround cycles in development and testing, you can run the app loc To achieve this, bind your SaaS app and the MTX sidecar to its required cloud services, for example: ```sh -cds bind --to-app-services bookshop-srv +cds bind -a bookshop-srv ``` For testing the sidecar, make sure to run the command there as well: ```sh cd mtx/sidecar -cds bind --to-app-services bookshop-srv +cds bind -a bookshop-mtx ``` To generate the SAP HANA HDI files for deployment, go to your project root and run the build: @@ -1183,7 +1172,7 @@ modules: TENANT_HOST_PATTERN: ^(.*)-${default-uri} ``` -[Learn more about _Defining MTA Extension Descriptors_](https://help.sap.com/docs/btp/sap-business-technology-platform/defining-mta-extension-descriptors?q=The%20MTA%20Deployment%20Extension%20Descriptor){.learn-more style="margin-top: 10px;"} +[Learn more about _Defining MTA Extension Descriptors_](https://help.sap.com/docs/btp/sap-business-technology-platform/defining-mta-extension-descriptors?q=The%20MTA%20Deployment%20Extension%20Descriptor){.learn-more} ::: @@ -1219,8 +1208,8 @@ In this case, the application can use its static local model without requesting cds: model: provider: - extensibility: false // [!code focus] - toggles: false // [!code focus] + extensibility: false # [!code focus] + toggles: false # [!code focus] ``` @@ -1275,81 +1264,6 @@ The main task for the MTX sidecar is to serve `subscribe` and `upgrade` requests The CAP services runtime requests models from the sidecar only when you apply tenant-specific extensions. For Node.js projects, you have the option to run the MTX services embedded in the main app, instead of in a sidecar. - -### Behind the Scenes { #behind-the-scenes} - -With adding the MTX services, your project configuration is adapted at all relevant places. - -Configuration and dependencies are added to your _package.json_ and an _xs-security.json_ containing MTX-specific scopes and roles is created. {.node} - -Configuration and dependencies are added to your _.cdsrc.json_ and an _xs-security.json_ containing MTX-specific scopes and roles is created. {.java} - -For the MTA deployment service dependencies are added to the _mta.yaml_ file. Each SaaS application will have bindings to at least three SAP BTP service instances. - -| Service | Description | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| [Service Manager](https://help.sap.com/docs/SERVICEMANAGEMENT/09cc82baadc542a688176dce601398de/4e19b11211fe4ca2a266d3fdd4a72188.html) (`service-manager`) | CAP uses this service for creating a new SAP HANA Deployment Infrastructure (HDI) container for each tenant and for retrieving tenant-specific database connections. | -| [SaaS Provisioning Service](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/3971151ba22e4faa9b245943feecea54.html) (`saas-registry`) | To make a SaaS application available for subscription to SaaS consumer tenants, the application provider must register the application in the SAP BTP Cloud Foundry environment through the SaaS Provisioning Service. | -| [User Account and Authentication Service](https://help.sap.com/docs/CP_AUTHORIZ_TRUST_MNG) (`xsuaa`) | Binding information contains the OAuth client ID and client credentials. The XSUAA service can be used to validate the JSON Web Token (JWT) from requests and to retrieve the tenant context from the JWT.| - - - - - ## Next Steps diff --git a/guides/multitenancy/old-mtx-migration.md b/guides/multitenancy/old-mtx-migration.md index fdc81580db..5e46038677 100644 --- a/guides/multitenancy/old-mtx-migration.md +++ b/guides/multitenancy/old-mtx-migration.md @@ -420,7 +420,7 @@ See also [Extensibility configuration](./mtxs.md#extensibility-config) ### Verify Application Locally As first verification of your configuration changes, you can try to run your application locally in [hybrid mode](../../advanced/hybrid-testing#run-with-service-bindings). To bind all the service -that are bound to your existing application, you can call `cds bind --to-app-services `. Afterwards, you can run `cds run --profile hybrid --resolve-bindings`. +that are bound to your existing application, you can call `cds bind -a `. Afterwards, you can run `cds run --profile hybrid --resolve-bindings`. ### Migrate Tenant Content of Existing Applications diff --git a/guides/providing-services.md b/guides/providing-services.md index 0ad87f0e89..80f0a6f02e 100644 --- a/guides/providing-services.md +++ b/guides/providing-services.md @@ -940,9 +940,6 @@ The `@assert.target` check constraint relies on database locks to ensure accurat ::: -
- - ### Custom Error Messages The annotations `@assert.range`, `@assert.format`, and `@mandatory` also support custom error messages. Use the annotation `@.message` with an error text or [text bundle key](../guides/i18n#externalizing-texts-bundles) to specify a custom error message: @@ -1106,7 +1103,7 @@ service Sue { entity Foo { key ID:Integer } actions { function getStock() returns Integer; action order (x:Integer) returns Integer; - //bound to the collection and not a specific instance of Foo + // bound to the collection and not a specific instance of Foo action customCreate (in: many $self, x: String) returns Foo; // All parameters are optional by default, unless marked with `not null`: action discard (reason: String not null); @@ -1239,8 +1236,227 @@ Programmatic usage would look like this for Node.js: -

+## Status-Transition Flows + +The flow feature makes it easy to define and manage state transitions in your CDS models. +It ensures transitions are explicitly modeled, validated, and executed in a controlled and reliable way. +For more complex requirements, you can extend flows with custom event handlers. + + +### Enabling Flows + +Status-transition flows are supported by both CAP runtimes. + +In CAP Node.js support for flows is part of the CAP Node.js core (`@sap/cds`). + +For CAP Java, support for flows is provided by the feature [cds-feature-flow](https://central.sonatype.com/artifact/com.sap.cds/cds-feature-flow). Enable it by adding this dependency to your _srv/pom.xml_ file: + +```xml + + com.sap.cds + cds-feature-flow + runtime + +``` + +### Modeling Flows + +The following example, taken from [@capire/xtravels](https://github.com/capire/xtravels), shows the simplest way to model a flow. +The annotations in the service model are sufficient to define and use the flow. + +![A flow diagram showing three status states connected by arrows. The leftmost oval contains the word Open. An arrow labeled accept points from Open to an oval containing Accepted at the top right. Another arrow labeled reject points from Open to an oval containing Canceled at the bottom right. The diagram illustrates a simple state transition workflow where items can move from an open state to either accepted or canceled states.](./assets/flows/xtravels-flow-simple.svg) + +The following is an extract of the relevant parts of the domain model: + +::: details `db/schema.cds` +```cds [db/schema.cds] +// db/schema.cds +namespace sap.capire.travels; + +entity Travels : managed { + // [...] + Status : Association to TravelStatus default 'O'; + // [...] +} + +entity TravelStatus : sap.common.CodeList { + key code : String(1) enum { + Open = 'O'; + Accepted = 'A'; + Canceled = 'X'; + } +} +``` +::: + +```cds [srv/travel-service.cds] +// srv/travel-service.cds +service TravelService { + + // Define entity and actions + entity Travels as projection on db.Travels + actions { + action rejectTravel(); + action acceptTravel(); + action deductDiscount( percent: Percentage not null ) returns Travels; + }; + + // Define flow through actions (+ status check for "deductDiscount") + annotate Travels with @flow.status: Status actions { // [!code highlight] + rejectTravel @from: #Open @to: #Canceled; // [!code highlight] + acceptTravel @from: #Open @to: #Accepted; // [!code highlight] + deductDiscount @from: #Open; // [!code highlight] + }; // [!code highlight] + +} +``` + +No custom action handlers are needed for simple transitions—the flow feature's default handlers validate that the entry state is `Open` and transition the status to `Accepted` or `Canceled` accordingly. +For more complex scenarios, you can add custom handlers as explained later. + + +### Flow Annotations + +Flows consist of a _status element_ and a set of _flow actions_ that define transitions between states. + +#### Declare Flow Using `@flow.status` + +To model a flow, one of the entity fields needs to be annotated with `@flow.status`. +This field must be one of the following: + +- A String or Integer enum consisting of keys and values +- A String enum with only symbols +- A Codelist entity with the key `code` if localization is needed (`code` must be one of the two above) + +::: tip The status field should be `@readonly` and have a default value. +We recommend to always use `@flow.status` in combination with `@readonly`. +This ensures that the status element is immutable from the client side, giving the service provider full control over all state transitions. +As no initial state can be provided on `CREATE`, there should be a default value. +::: + +When you annotate `@flow.status: ` at the entity level (as in the example above), the annotation is propagated to the respective element, which is also automatically annotated with `@readonly`. + +**About the `@flow.status` annotation:** +- This annotation is **mandatory**. +- The annotated element must be either an enum or an association to a code list. +- Only one status element per entity is supported. +- Draft-enabled entities are supported, however flows are only applied to the active version. +- `null` is **not** a valid state—model your empty state explicitly. + +::: warning Only simple projections are supported +The entity must be _writable_, and renaming the status element is currently not supported. +::: + +After declaring `@flow.status`, use the following annotations on bound actions to model transitions: + +#### Model Transitions Using `@from` and `to` + +Both annotations are optional, but at least one is required to mark an action as a flow action. Use either one or both depending on your needs. When you use both, no custom handlers are needed—generic handlers are registered automatically. + +**`@from`** + +- Defines valid entry states for the action. +- Validates whether the entity is in a valid entry state before executing the action (the current state of the entity must be included in the states defined here). +- Can be a single value or an array of values (each element must be a value from the status enum). +- UI annotations to allow/disallow buttons and to refresh the page are automatically generated for UI5. + - Can be deactivated via cds.features.annotate_for_flows: false. + +**`@to`** + +- Defines the desired target state of the entity after executing the action. +- Changes the state of the entity to the value defined in this annotation after executing the action. +- Must be a single value from the status enum. + + + +### Generic Handlers + +Generic handlers are registered automatically, so no custom implementations are required for basic flows. + +#### `before` + +Based on the `@from` annotation, a handler validates that the entity is in a valid entry state - the current state must match one of the states specified in `@from`. +If validation fails, the request returns a `409 Conflict` HTTP status code with an appropriate error message. + +#### `on` + +In case of a `@to` declaration and if no custom handler is provided, an empty handler is registered that completes the action for void return types, ensuring the request passes through the generic handler stack. +This is an exception to the rule that actions must be implemented by the application. + +#### `after` + +Based on the `@to` annotation, a handler automatically updates the entity's status to the target state. +For example, if the current state is `Open` and the target state is `Accepted`, the handler updates the status to `Accepted` after action execution. +This ensures consistent state transitions without custom logic. + +::: tip Generic handlers are not executed for draft entities +For example, if you call `acceptTravel()` on a `Travels` entity that is currently being edited (in _inactive_ state), the call has no effect. +::: + + +### Reverting to Previous State + +You can use the target state `$flow.previous` to restore the previous state in a workflow. +The following example introduces a `Blocked` state with two possible previous states (`Open` and `InReview`) and an action `unblockTravel` that restores the previous state. +For instance, if `Blocked` was transitioned to from `Open`, calling `unblockTravel` transitions back to `Open`. The same applies for `InReview`. + +![The graphic is explained in the accompanying text.](./assets/flows/xtravels-flow-previous.svg) + +```cds [srv/travel-service.cds] +// srv/travel-service.cds +service TravelService { + + // Define entity and actions + entity Travels as projection on db.Travels + actions { + action reviewTravel(); + action reopenTravel(); + action blockTravel(); + action unblockTravel(); + action rejectTravel(); + action acceptTravel(); + action deductDiscount( percent: Percentage not null ) returns Travels; + }; + + // Define flow incl. "unblockTravel" that transitions to the previous state + annotate Travels with @flow.status: Status actions { + reviewTravel @from: #Open @to: #InReview; // [!code highlight] + reopenTravel @from: #InReview @to: #Open; // [!code highlight] + blockTravel @from: [#Open, #InReview] @to: #Blocked; // [!code highlight] + unblockTravel @from: #Blocked @to: $flow.previous; // [!code highlight] + rejectTravel @from: #InReview @to: #Canceled; + acceptTravel @from: #InReview @to: #Accepted; + deductDiscount @from: #Open; + }; + +} +``` + +Entities with flows that include at least one transition to `$flow.previous` are automatically extended with the `sap.common.FlowHistory` aspect, which includes `transitions_` composition that captures the history of state transitions. + +::: details The `transitions_` composition +The `transitions_` composition is meant as a technical artifact to implement transitioning to the previous state and not for exposing the transition history to business users, etc. +For such use cases, check out the [Change Tracking plugin](../plugins/index.md#change-tracking). + +The automatic entity extending described above can be deactivated via cds.features.history_for_flows: false. +If you do so, you need to add aspect `sap.common.FlowHistory` manually in order to use `@to: $flow.previous`! + +Automatic history capturing can, as an experimental feature, also be enabled for all entities with a flow definition via cds.features.history_for_flows: 'all'. + +The `transitions_` composition automatically appended to the base entity is also automatically excluded from all projections. +::: + + +### Extending Flows + +Flow annotations work well for basic flows. For more complex scenarios, implement custom event handlers. + +Common use cases for custom handlers: +- **Additional validation:** Implement a custom `before` handler when entry state validation depends on extra conditions +- **Non-void return types:** Implement a custom `on` handler when the action returns data +- **Conditional target states:** Implement a custom `on` or `after` handler (without `@to` annotation) when multiple target states depend on conditions + ## Serving Media Data diff --git a/guides/temporal-data.md b/guides/temporal-data.md index 64a4081025..6c91060341 100644 --- a/guides/temporal-data.md +++ b/guides/temporal-data.md @@ -158,7 +158,7 @@ READ requests without specifying any temporal query parameter will automatically For example, assumed the following OData query to read all employees with their current work assignments is processed on March 2019: -```cds +```http GET Employees? $expand=jobs($select=role&$expand=dept($select=name)) ``` @@ -188,7 +188,7 @@ The result set would be: We can run the same OData query as in the previous sample to read a snapshot data as valid on January 1, 2017 using the `sap-valid-at` query parameter: -```cds +```http GET Employees?sap-valid-at=date'2017-01-01' $expand=jobs($select=role&$expand=dept($select=name)) ``` @@ -218,7 +218,7 @@ Time-travel queries aren't supported on SQLite due to the lack of *session_conte We can run the same OData query as in the previous sample to read all history of data as valid since 2016 using the `sap-valid-from` query parameter: -```cds +```http GET Employees?sap-valid-from=date'2016-01-01' $expand=jobs($select=role&$expand=dept($select=name)) ``` @@ -238,7 +238,7 @@ The result set would be: > You would add `validFrom` in such time-period queries, for example: -```cds +```http GET Employees?sap-valid-from=date'2016-01-01' $expand=jobs($select=validFrom,role,dept/name) ``` @@ -265,7 +265,7 @@ entity Departments : temporal {/*...*/} When reading employees with all history since 2016, for example: -```cds +```http GET Employees?sap-valid-from=date'2016-01-01' $expand=jobs( $select=validFrom,role&$expand=dept( diff --git a/guides/using-services.md b/guides/using-services.md index ee2b400716..d4cd4de100 100644 --- a/guides/using-services.md +++ b/guides/using-services.md @@ -257,10 +257,10 @@ The CSV file needs to be added to the _db/data_ folder. {.java} ::: code-group ```csv [API_BUSINESS_PARTNER-A_BusinessPartner.csv] -BusinessPartner;BusinessPartnerFullName;BusinessPartnerIsBlocked -1004155;Williams Electric Drives;false -1004161;Smith Batteries Ltd;false -1004100;Johnson Automotive Supplies;true +BusinessPartner,BusinessPartnerFullName,BusinessPartnerIsBlocked +1004155,Williams Electric Drives,false +1004161,Smith Batteries Ltd,false +1004100,Johnson Automotive Supplies,true ``` ::: diff --git a/java/_menu.md b/java/_menu.md index 04e7b8b858..3baf3672bb 100644 --- a/java/_menu.md +++ b/java/_menu.md @@ -20,7 +20,6 @@ # [Messaging](messaging) # [Audit Logging](auditlog) # [Change Tracking](change-tracking) -# [State Transitions](../../java/flows) # [Transactional Outbox](outbox) # [Multitenancy](multitenancy) ## [Multitenancy (Classic)](multitenancy-classic) diff --git a/java/cds-data.md b/java/cds-data.md index 068f3d1bde..4ae07cc218 100644 --- a/java/cds-data.md +++ b/java/cds-data.md @@ -43,7 +43,7 @@ The [predefined CDS types](../cds/types) are mapped to Java types and as follows | `cds.Binary` | `byte[]` | | | `cds.LargeBinary` | `byte[]` | `java.io.InputStream` (1) if annotated with `@Core.MediaType` | | `cds.Vector` | `com.sap.cds.CdsVector` | for [vector embeddings](#vector-embeddings) | -| `cds.Map` | `java.util.Map` | for arbitrary [structured data](#structured-data)(2) | +| `cds.Map` | `java.util.Map` | for schemaless [structured data](#cds-map) | ### SAP HANA-Specific Data Types @@ -63,7 +63,6 @@ To facilitate using legacy CDS models, the following [SAP HANA-specific data typ > (1) Although the API to handle large objects is the same for every database, the streaming feature, however, is supported (and tested) in **SAP HANA**, **PostgreSQL**, and **H2**. See section [Database Support in Java](./cqn-services/persistence-services#database-support) for more details on database support and limitations. -> (2) Serialized as JSON to a CLOB column or JSONB column (on Postgres) ::: warning The framework isn't responsible for closing the stream when writing to the database. You decide when the stream is to be closed. If you forget to close the stream, the open stream can lead to a memory leak. @@ -71,10 +70,40 @@ The framework isn't responsible for closing the stream when writing to the datab These types are used for the values of CDS elements with primitive type. In the [Model Reflection API](./reflection-api), they're represented by the enum [CdsBaseType](https://javadoc.io/doc/com.sap.cds/cds4j-api/latest/com/sap/cds/reflect/CdsBaseType.html). +### Numeric Type Determination + +To have a consistent behavior across different databases, the CAP Java runtime applies numeric type determination in arithmetic expressions and numeric standard functions according to the following rules. + +::: tip +Use `type(CdsBaseType)` to explicitly set the result type if needed. +::: + +#### Arithmetic Expressions + +Arithmetic expressions promote numeric types according to the following precedence: + +**Type Precedence (highest to lowest):** +`cds.Double`, `hana.REAL`, `cds.Decimal`, `cds.Int64`, `cds.Int32`, `cds.Int16`, `cds.UInt8` + +- For addition, subtraction, and multiplication, the result type is the one with highest precedence among the operands. +- For division: + - If any operand is an approximate numeric type (`cds.Double`, `hana.REAL`), the result type is `cds.Double`. + - Otherwise, the result type is `cds.Decimal`, which provides higher accuracy for decimal fractions. + +#### Numeric Standard Functions + +Numeric aggregation and standard functions determine their result type based on the argument types: + +- **ceiling(x)**, **floor(x)**, **round(x)**: Return the same type as the input `x`. +- **min(x)**, **max(x)**, **sum(x)**: Aggregate functions return the same type as the argument `x`. +- **average(x)**: Returns `cds.Decimal` for exact numeric types and `cds.Double` for approximate numeric types. +- **count(x)**, **countdistinct(x)**: Return `cds.Int64`. + + ## Structured Data In CDS, structured data is used as payload of *Insert*, *Update*, and *Upsert* statements. Also the query result of *Select* may be structured. -CAP Java represents data of entities and structured types as `Map` and provides the `CdsData` interface as an extension of `Map` with additional convenience methods. +CAP Java represents data of entities, structured types, and elements of type [cds.Map](#cds-map) as `java.util.Map` and provides the `CdsData` interface as an extension of `Map` with additional convenience methods. In the following we use this CDS model: @@ -279,6 +308,26 @@ Avoid cyclic relationships between CdsData objects when using toJson.
+## Map Data { #cds-map } + +Elements of type `cds.Map` can be used to store arbitrary _schemaless_ [stuctured data](#structured-data). CAP Java represents data of elements of type `cds.Map` as `Map`. + +On the database, this data is serialized to [JSON](https://www.json.org/)(1). Only data types that are compatible with JSON can be stored and retrieved: + +| Java Type | JSON Type | +| ---------------------------------| --------------- | +| `java.lang.String` | `string` | +| `java.lang.Number`(2) | `number` | +| `java.lang.Boolean` | `true`, `false` | +| `java.util.Map` | `object` | +| `java.util.List` | `array` | +| `null` | `null` | + +> (1) Serialized as JSON to a CLOB column or JSONB column (on Postgres) + +> (2) The actual subclass of a `Number` is not preserved upon serialization and might change upon deserialization. + +Map data can be nested and may contain nested maps and lists, which are serialized to JSON objects and arrays, respectively. ## Vector Embeddings { #vector-embeddings } @@ -471,7 +520,7 @@ To support _hybrid_ access, like simultaneous typed _and_ generic access, the ac The name of the CDS element referred to by a getter or setter, is defined through `@CdsName` annotation. If the annotation is missing, it's determined by removing the get/set from the method name and lowercasing the first character. ::: -### Generated Accessor Interfaces {#generated-accessor-interfaces} +### Generated Accessor Interfaces For all structured types of the CDS model, accessor interfaces can be generated using the [CDS Maven Plugin](/java/assets/cds-maven-plugin-site/plugin-info.html). The generated accessor interfaces allow for hybrid access and easy serialization to JSON. Code generation is executed by default at build time and is configurable. @@ -1230,7 +1279,7 @@ diff.add(new Filter() { Filters cannot limit the nature of the changes your visitor will observe and are always positive. -### Deep Traversal {#cds-diff-processor-deep-traversal} +### Deep Traversal For documents that have a lot of associations or a compositions and are changed in a deep way you might want to see additions for each level separately. diff --git a/java/cqn-services/application-services.md b/java/cqn-services/application-services.md index 7d0a33ffe8..4c3be94e26 100644 --- a/java/cqn-services/application-services.md +++ b/java/cqn-services/application-services.md @@ -402,6 +402,12 @@ cds.application.services.CatalogService.serve: - 'odata-v2' ``` +Alternatively to the `@protocol` and `@protocols` annotation you can also use explicit protocol annotations like `@odata` (OData V4): + +```cds +@odata service CatalogService { ... } +``` + You can also disable serving a service if needed: ```cds diff --git a/java/cqn-services/persistence-services.md b/java/cqn-services/persistence-services.md index ec2c0250f6..9c84de9a0c 100644 --- a/java/cqn-services/persistence-services.md +++ b/java/cqn-services/persistence-services.md @@ -50,8 +50,7 @@ CAP Java SDK is tested on [PostgreSQL](https://www.postgresql.org/) 15 and suppo 1. No locale specific sorting. The sort order of queries behaves as configured on the database. 2. Write operations through CDS views are only supported for views that can be [resolved](../working-with-cql/query-execution#updatable-views) or are [updatable](https://www.postgresql.org/docs/14/sql-createview.html#SQL-CREATEVIEW-UPDATABLE-VIEWS) in PostgreSQL. -3. The CDS type `UInt8` can't be used with PostgreSQL, as there's no `TINYINT`. Use `Int16` instead. -4. [Multitenancy](../../guides/multitenancy/) and [extensibility](../../guides/extensibility/) aren't yet supported on PostgreSQL. +3. [Multitenancy](../../guides/multitenancy/) and [extensibility](../../guides/extensibility/) aren't yet supported on PostgreSQL. ### H2 Database @@ -62,8 +61,7 @@ CAP Java SDK is tested on [PostgreSQL](https://www.postgresql.org/) 15 and suppo 3. By default, views aren't updatable on H2. However, the CAP Java SDK supports some views to be updatable as described [here](../working-with-cql/query-execution#updatable-views). 4. Although referential and foreign key constraints are supported, H2 [doesn't support deferred checking](https://www.h2database.com/html/grammar.html#referential_action). As a consequence, schema SQL is never generated with referential constraints. 5. In [pessimistic locking](../working-with-cql/query-execution#pessimistic-locking), _shared_ locks are not supported but an _exclusive_ lock is used instead. -6. The CDS type `UInt8` can't be used with H2, as there is no `TINYINT`. Use `Int16` instead. -7. For regular expressions, H2's implementation is compatible with Java's: the matching behaviour is an equivalent of the `Matcher.find()` call for the given pattern. +6. For regular expressions, H2's implementation is compatible with Java's: the matching behaviour is an equivalent of the `Matcher.find()` call for the given pattern. ::: warning Support for localized and temporal data via session context variables requires H2 v2.2.x or later. diff --git a/java/developing-applications/testing.md b/java/developing-applications/testing.md index be578f2f39..95212c224b 100644 --- a/java/developing-applications/testing.md +++ b/java/developing-applications/testing.md @@ -255,3 +255,108 @@ public class CatalogServiceITest { ::: tip Check out the version in our [CAP Java bookshop sample project](https://github.com/SAP-samples/cloud-cap-samples-java/blob/main/srv/src/test/java/my/bookshop/CatalogServiceITest.java) for additional examples of integration testing. ::: + +## Testing with H2 + +**H2** is the preferred database for CAP Java applications, as it offers a combination of features that make it the best candidate for local development and testing: + +* **Concurrent access and locking** + + The database supports multiple concurrent connections and implements row-level locking, allowing safe parallel data access without data corruption or race conditions. + +* **Open Source and Java native** + + As an open-source database written entirely in Java, H2 offers transparency, flexibility, and the benefit of being maintained by an active community. Its Java implementation ensures optimal integration with Java-based applications and platforms. + +* **Administrative tools** + + H2 includes a built-in web console application, providing a user-friendly interface for database administration, query execution, and data inspection without requiring external tools. CAP Java applications configured with the H2 database expose the administration console under `http://localhost:8080/h2-console` (assuming default port `8080`). + +### Setup & Configuration + +#### Using the Maven Archetype + +When a new CAP Java project is created with the [Maven Archetype](../../java/developing-applications/building#the-maven-archetype) or with `cds init`, +H2 is automatically configured as in-memory database used for development and testing in the `default` profile. + +#### Manual Configuration + +To use H2, just add a Maven dependency to the H2 JDBC driver: + +```xml + + com.h2database + h2 + runtime + +``` + +Next, configure the build to [create an initial _schema.sql_ file](../../java/cqn-services/persistence-services#initial-database-schema-1) for H2 using `cds deploy --to h2 --dry`. + +In Spring, H2 is automatically initialized as in-memory database when the driver is present on the classpath. + +[Learn more about the configuration of H2.](../../java/cqn-services/persistence-services#h2){.learn-more} + +After performing the above mentioned configuration steps, the `application.yaml` should contain the following lines for `default` profile: +::: code-group +```yml [srv/src/main/resources/application.yaml] +spring: + config.activate.on-profile: default + sql.init.platform: h2 +cds: + data-source: + auto-config.enabled: false +``` +::: + +### H2 Limitations + +When developing a CAP Java application, it's important to understand the limits and constraints of the underlying database. Every database has its own performance characteristics, data type restrictions, indexing behavior, and transaction handling rules. + +Read more about known limitations in the H2 section of the [Persistence Services guide.](../../java/cqn-services/persistence-services#h2-database) + +::: warning Test local MTXS with H2 not possible +Besides the limitations mentioned above, it is not possible to use H2 database when it comes to testing multitenancy and extensibility (MTXS) scenarios on a local environment. +::: + +### Hybrid Testing - a way to overcome limitations + +Although CAP Java enables running and testing applications with a local H2 database, still there are cases when it is not possible, due to some limitations mentioned previously. In that case, hybrid testing capabilities help you to stay in a local development environment avoiding long turnaround times of cloud deployments. You just selectively connect to services in the cloud. + +The section [Hybrid Testing](../../advanced/hybrid-testing#run-cap-java-apps-with-service-bindings) describes the steps on how to configure and consume the remote services, including SAP HANA, in a local environment. + +### H2 and Spring Dev Tools Integration + +Most CAP Java projects use Spring Boot. To speed up the edit-compile-verify loop, the Spring Boot DevTools dependency is commonly added to the development classpath. DevTools provide automatic restart and LiveReload integration. For more details check the [Spring Dev Tools](https://docs.spring.io/spring-boot/reference/using/devtools.html) reference. + +The automatic restart and LiveReload provided by DevTools can cause an application restart that results in loss of state held by an in-memory H2 database. To avoid losing data between restarts during development, prefer the H2 file-based mode so the database is persisted on disk and survives DevTools restarts. The simplest `application.yaml` configuration would look as follows: + +::: code-group +```yml [srv/src/main/resources/application.yaml] +spring: + config.activate.on-profile: default + sql.init.platform: h2 + url: "jdbc:h2:file:/data/testdb" +cds: + data-source: + auto-config.enabled: false +``` +::: + +[Learn more about how to configure file-based H2.](https://www.h2database.com/html/features.html#embedded_databases){.learn-more} + +### Logging SQL to Console + +To view the generated SQL statements, which will be run on the H2 database, it is possible to switch to `DEBUG` log output by adding the following log-levels: + +::: code-group +```yml [srv/src/main/resources/application.yaml] +logging: + level: + com.sap.cds.persistence.sql: DEBUG +``` +::: + +This is beneficial, when you need to track runtime or a Java Application behavior. + +[Learn more about Predefined Loggers.](../../java/operating-applications/observability#predefined-loggers){.learn-more} diff --git a/java/event-handlers/changeset-contexts.md b/java/event-handlers/changeset-contexts.md index 60e65f7f6b..a468bd038f 100644 --- a/java/event-handlers/changeset-contexts.md +++ b/java/event-handlers/changeset-contexts.md @@ -181,4 +181,4 @@ A ChangeSet Context can always be marked as requiring a transaction, by calling Some Select queries will still require a transaction: - Select queries with a lock: These are treated like a modifying statement and will start a transaction. -- Select queries reading streamed media data: These are currently not automatically detected. The surrounding ChangeSet Context needs to be marked as transactional explicitly. If not done, `InputStream`s might be corrupted or closed when trying to read them after the connection was returned to the connection pool already. +- Select queries reading streamed media data: For these a transaction is started to avoid that `InputStream`s might be corrupted or closed when trying to read them after the connection was returned to the connection pool already. diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index 8652fa3e90..6ac3ca9446 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -60,6 +60,9 @@ public Result delegateToS4(ActiveReadEventContext context) { When setting `cds.drafts.persistence` to `split` only queries that are specified by the SAP Fiori draft orchestration are supported. ::: +### Aggregation Queries +Aggregating over active and inactive draft entities isn't supported. Queries with aggregation functions implicitly add `IsActiveEntity` as a part of the group-by clause, resulting in disjunct `active` and `inactive` rows being returned instead of aggregated rows. + ## Editing Drafts When users edit a draft-enabled entity in the frontend, the following requests are sent to the CAP Java backend. As an effect, draft-specific events are triggered, as described in the following table. The draft-specific events are defined by the [DraftService](https://www.javadoc.io/doc/com.sap.cds/cds-services-api/latest/com/sap/cds/services/draft/DraftService.html) interface. @@ -144,6 +147,10 @@ It's possible to create and update data directly without creating intermediate d These events have the same semantics as described in section [Handling CRUD events](./cqn-services/application-services#crudevents). +::: warning +Directly updating the active entity does **not** bypass the [Draft Lock](#draft-lock). If an existing draft locks the active entity, the system blocks any attempt to update it. This ensures that the system does not lose changes to the active entity when you subsequently activate a draft. +::: + ## Draft Lock { #draft-lock } An entity with a draft is locked from being edited by other users until either the draft is saved or a timeout is hit (15 minutes by default). You can configure this timeout by the following application configuration property: @@ -155,7 +162,7 @@ cds.drafts.cancellationTimeout: 1h You can turn off this feature completely by means of the application configuration property: ```yaml -cds.security.draftProtection.enabled: false +cds.security.authorization.draftProtection.enabled: false ``` ## Draft Garbage Collection { #draft-gc } diff --git a/java/messaging.md b/java/messaging.md index b2c781c57a..d53127ea23 100644 --- a/java/messaging.md +++ b/java/messaging.md @@ -721,7 +721,7 @@ private void handleError(MessagingErrorEventContext ctx) { } ``` -In a multi-tenant setup with several microservices, messages of a tenant not yet subscribed to the own microservice would be already received from the message queue. In this case, the message cannot be processed for the tenant because the tenant context is not yet available. By default, the standard error handler still acknowledges the message to prevent it from getting stuck in the message sequence. To change this behavior, the custom error handler from the example above can be extended by checking the exception type of the unknown tenant. +In a multitenant setup with several microservices, messages of a tenant not yet subscribed to the own microservice would be already received from the message queue. In this case, the message cannot be processed for the tenant because the tenant context is not yet available. By default, the standard error handler still acknowledges the message to prevent it from getting stuck in the message sequence. To change this behavior, the custom error handler from the example above can be extended by checking the exception type of the unknown tenant. ```java diff --git a/java/multitenancy.md b/java/multitenancy.md index 20585d1eaa..6b94ab62e5 100644 --- a/java/multitenancy.md +++ b/java/multitenancy.md @@ -397,7 +397,7 @@ See section [Multitenancy Configuration Properties](#mtx-properties) for more de ### Logging Support { #app-log-support} Logging service support gives you the capability to observe properly correlated requests between the different components of your CAP application in Kibana. -This is especially useful for multi-tenant aware applications that use the `MTX sidecar`. +This is especially useful for multitenant aware applications that use the `MTX sidecar`. Just enable either [`application-logs`](../java/operating-applications/observability#logging-service) service or [`cloud-logging`](../java/operating-applications/observability#open-telemetry) service for both, the Java service as well as for the `MTX sidecar`, to get correlated log messages from these components. The logs can be inspected in the corresponding front ends such as `Kibana`, `Cloud Logging Service` or `Dynatrace`. diff --git a/java/working-with-cql/query-api.md b/java/working-with-cql/query-api.md index b783766985..6b06cc8749 100644 --- a/java/working-with-cql/query-api.md +++ b/java/working-with-cql/query-api.md @@ -187,6 +187,32 @@ Select.from(BOOKS) Select.from(BOOKS).byParams("title", "author.name"); ``` +#### Filtering Map Data + +You can also filter by _content_ of [map data](../cds-data.md#cds-map) (i.e. elements of type `cds.Map`). + +Let's use this model as an example: + +```cds +entity Product : cuid { + name : String; + category : String; + details : Map; +} +``` + +The following query selects all products of category "tech" where the `details` map contains a sub-element `brand` with value "ACME": + +```java +Select.from(PRODUCTS) + .where(p -> p.category().eq("tech").and( + p.details().get("brand").eq("ACME"))); +``` + +::: warning Expensive for large datasets +Depending on the database, filtering by content of a map element can be expensive when applied on large datasets. Use additional filters on non-map elements to reduce the dataset. +::: + ### Parameters The [CQL](../../cds/cql) builders support [parameters](#expr-param) in the `where` clause and in infix filters for [parameterized execution](query-execution#parameterized-execution): @@ -536,6 +562,36 @@ Object authorId = book.get("author.Id"); // path access Only to-one associations that are mapped via the primary key elements of the target entity are supported on the select list. The execution is optimized and gives no guarantee that the target entity exists, if this is required use expand or enable [integrity constraints](../../guides/databases#database-constraints) on the database. ::: +#### Selecting Map Data + +You can also use elements of type [cds.Map](../cds-data.md#cds-map) on the select list. + +```cds +entity Product : cuid { + name : String; + category : String; + details : Map; +} +``` + +Considering the previous model, the following query selects the product's ID along with the details, which are returned as a `CdsData` map. + +```java +Select.from(PRODUCTS).columns(p -> p.ID(), p.details()); +``` + +##### Selecting Sub-Elements of Map Data + +You can also select sub-elements of a `cds.Map` via path expressions: + +```java +Select.from(PRODUCTS) + .columns(p-> p.ID(), + p-> p.details().get("brand")) + .where(p -> p.category().eq("tech")); +``` + +This query selects the sub-element `brand` of the `details` map element for all products of category "tech". ### Filtering and Searching { #filtering} @@ -556,6 +612,7 @@ entity Book { title : String; } ``` + In the following example, element `title` is included in `@cds.search`. Only this particular element is searchable then. ```cds @@ -610,6 +667,30 @@ Select.from("bookshop.Books") .search(term -> term.has("Allen").or(term.has("Heights"))); ``` +#### Search in Sub-Elements of Map Data + +You can search for values in sub-elements of a [cds.Map](../cds-data#cds-map) element by adding a path to the sub-element in the search scope: + +```cds +entity Product : cuid { + name : String; + category : String; + details : Map; +} +``` + +For example to search for products in the "tech" category having "ACME" within the `brand` sub-element of the `details` map: +```Java +Select.from(PRODUCT) + .search("ACME", List.of("details.brand")) + .where(p -> p.category().eq("tech")); +``` + +::: warning Expensive for large datasets +Searching within map element content can be expensive on large datasets. Use additional filters on non-map elements to reduce the dataset size. + +Including the entire map element in the search scope triggers a full-text search on its JSON representation, matching both sub-element names and values. This behavior can yield unexpected results. +::: #### Using `where` Clause {#where-clause} @@ -817,6 +898,31 @@ In this example, it's assumed that the total number of books is more or equal to The pagination isn't stateful. If rows are inserted or removed before a subsequent page is requested, the next page could contain rows that were already contained in a previous page or rows could be skipped. ::: +#### Sorting by Map Data + +You can also sort by _content_ of [map data](../cds-data.md#cds-map) (i.e. elements of type `cds.Map`). Considering this model + +```cds +entity Product : cuid { + name : String; + category : String; + details : Map; +} +``` + +This following query sorts products by category and additionally by the sub-element `brand` of the map element `details`. + +```java +Select.from(PRODUCTS) + .where(p -> p.category().eq("tech")) + .orderBy(p -> p.category().asc(), + p.to("details").get("brand").asc()); +``` + +::: warning Expensive for large datasets +Depending on the database, sorting by content of map data is expensive and can lead to poor performance when applied to large result sets. +::: + ### Pessimistic Locking { #write-lock} Use the `lock()` method to enforce [Pessimistic Locking](../../guides/providing-services#select-for-update). diff --git a/menu.md b/menu.md index 56e3f7a37a..53a289d38e 100644 --- a/menu.md +++ b/menu.md @@ -28,6 +28,7 @@ ### [Input Validation](guides/providing-services#input-validation) ### [Custom Logic](guides/providing-services#custom-logic) ### [Actions & Functions](guides/providing-services#actions-functions) + ### [Status-Transition Flows](guides/providing-services#status-transition-flows) ### [Serving Media Data](guides/providing-services#serving-media-data) ### [Best Practices](guides/providing-services#best-practices) @@ -55,7 +56,7 @@ ### [AsyncAPI](advanced/publishing-apis/asyncapi) ## [Serving UIs](advanced/fiori) - ### [Fiori UIs](advanced/fiori) + ### [SAP Fiori UIs](advanced/fiori) ## [Databases](guides/databases) diff --git a/node.js/authentication.md b/node.js/authentication.md index 2188408e94..99e253f179 100644 --- a/node.js/authentication.md +++ b/node.js/authentication.md @@ -486,7 +486,7 @@ Both caches are enabled by default. The _signature cache_ can be configured or deactivated via cds.requires.auth.config (which is passed through to `@sap/xssec`). -[Learn more about signature cache and its configuration.](https://www.npmjs.com/package/@sap/xssec#signature-cache)[.learn-more] +[Learn more about signature cache and its configuration.](https://www.npmjs.com/package/@sap/xssec#signature-cache){}.learn-more} The _token decode cache_, on the other hand, can only be configured programmatically during bootstrapping, for example in a [custom `server.js`](cds-server#custom-server-js) file, as follows: ```js diff --git a/node.js/best-practices.md b/node.js/best-practices.md index 90687f8123..218708d51e 100644 --- a/node.js/best-practices.md +++ b/node.js/best-practices.md @@ -333,7 +333,7 @@ The most important aspects for programming errors are: - Fail loudly: Do not hide errors and silently continue. Make sure that unexpected errors are correctly logged. Do not catch errors you can't handle. - Don't program in a defensive way: Concentrate on your business logic and only handle errors if you know that they occur. Only use `try`/`catch` blocks when necessary. -Never attempt to catch and handle unexpected errors, promise rejections, etc. If it's unexpected, you can't handle it correctly. If you could, it would be expected (and should already be handled). Even though your apps should be stateless, you can never be 100% certain that any shared resource wasn't affected by the unexpected error. Hence, you should never keep an app running after such an event, especially in multi-tenant apps that bear the risk of information disclosure. +Never attempt to catch and handle unexpected errors, promise rejections, etc. If it's unexpected, you can't handle it correctly. If you could, it would be expected (and should already be handled). Even though your apps should be stateless, you can never be 100% certain that any shared resource wasn't affected by the unexpected error. Hence, you should never keep an app running after such an event, especially in multitenant apps that bear the risk of information disclosure. This will make your code shorter, clearer, and simpler. diff --git a/node.js/cds-serve.md b/node.js/cds-serve.md index 470529e443..6f8f4f6e88 100644 --- a/node.js/cds-serve.md +++ b/node.js/cds-serve.md @@ -252,8 +252,11 @@ It adds the currently active model to the continuation. It's required for all ap ### .add(mw, pos?) {.method} Registers additional middlewares at the specified position. -`mw` must be a function that returns an express middleware. -`pos` specified the index or a relative position within the middleware chain. If not specified, the middleware is added to the end. +`mw` can be either of: +- a function that returns an express middleware +- an express middleware with the common _req_, _res_, _next_ arguments +- an array of express middlewares +`pos` specifies the index or a relative position within the middleware chain. If not specified, the middleware is added to the end. ```js cds.middlewares.add (mw, {at:0}) // to the front diff --git a/node.js/core-services.md b/node.js/core-services.md index 35d47f23e4..cac08dc897 100644 --- a/node.js/core-services.md +++ b/node.js/core-services.md @@ -282,7 +282,7 @@ await srv.update(Books,201).with({stock:111}) await srv.update(Books).set({discount:'10%'}).where({stock:{'>':111}}) ``` -[Emitting Asynchronous Event Messsages:](#srv-emit-event) +[Emitting Asynchronous Event Messages:](#srv-emit-event) ```js await srv.emit ('SomeEvent', {foo:'bar'}) @@ -882,7 +882,7 @@ All *cds.Services* are intrinsically events & messaging-enabled. The core implem ::: danger **PLEASE NOTE** -Although emitters do not handle any return values from consumers, it is necessary to always call them with `await`. Keep in mind that `srv.emit()` is an *`async`* method, it is **very important** to properly handle the returned *Promises* by using `await`. Not handing them will likely lead to invalid transaction states and deadlocks. +Although emitters do not handle any return values from consumers, it is necessary to always call them with `await`. Keep in mind that `srv.emit()` is an *`async`* method, it is **very important** to properly handle the returned *Promises* by using `await`. Not handling them will likely lead to invalid transaction states and deadlocks. ::: @@ -1049,7 +1049,7 @@ All matching `.before`, `.on`, and `.after` handlers are executed in correspondi - ***concurrently*** for instances of `cds.Event` - **`after`** handlers are always executed *concurrently* -In effect, for asynchronous event messages, that is, instances of `cds.Event`, sent via [`srv.emit()`](#srv-emit-event), all registered `.on` handlers are always executed. In contrast to that, for synchronous resuests, that is, instances of `cds.Requests` this is up to the individual handlers calling `next()`. See [`srv.on(request)`](#interceptor-stack-with-next) for an example. +In effect, for asynchronous event messages, that is, instances of `cds.Event`, sent via [`srv.emit()`](#srv-emit-event), all registered `.on` handlers are always executed. In contrast to that, for synchronous requests, that is, instances of `cds.Requests` this is up to the individual handlers calling `next()`. See [`srv.on(request)`](#interceptor-stack-with-next) for an example. diff --git a/node.js/events.md b/node.js/events.md index 8fdb54101b..650f4998dc 100644 --- a/node.js/events.md +++ b/node.js/events.md @@ -371,7 +371,7 @@ req.subject //> ... ```js SELECT.from(req.subject) //> returns the single target row UPDATE(req.subject)... //> updates the single target row -DELETEfrom(req.subject) //> deletes the single target row +DELETE.from(req.subject) //> deletes the single target row ``` > [!warning] @@ -482,7 +482,7 @@ This is a convenience variant of the [`req.reject()`](#req-reject) method, with ```tsx function req.reject ( - code? : number, + status? : number, message? : string, target? : string, args? : string[] diff --git a/node.js/fiori.md b/node.js/fiori.md index 249b783d52..4dbb46664e 100644 --- a/node.js/fiori.md +++ b/node.js/fiori.md @@ -77,14 +77,6 @@ As a result, a new entry to `MyEntity.drafts` is created. For logical reasons handlers for the `EDIT` event are registered on the active entity, i.e. `MyEntity` in the code above, not on the `MyEntity.drafts` entity. -You can also register handlers on the standard `CREATE` events for draft entities, which would be called whenever a new draft is created, be it via `NEW` or `EDIT`, like so: - -```js -srv.before('CREATE', MyEntity.drafts, /*...*/) -srv.after('CREATE', MyEntity.drafts, /*...*/) -srv.on('CREATE', MyEntity.drafts, /*...*/) -``` - ### `DISCARD` diff --git a/node.js/messaging.md b/node.js/messaging.md index ad40586d4d..74a18b65bb 100644 --- a/node.js/messaging.md +++ b/node.js/messaging.md @@ -432,7 +432,7 @@ Please see the plugin's [setup guide](https://github.com/cap-js/event-broker/blo `kind`: `advanced-event-mesh` -Use this if you want to communicate using [SAP Integration Suite, advanced event mesh](https://help.sap.com/docs/event-broker). +Use this if you want to communicate using [SAP Integration Suite, advanced event mesh](https://help.sap.com/docs/sap-integration-suite/advanced-event-mesh/). The integration with SAP Integration Suite, advanced event mesh is provided using the plugin [`@cap-js/advanced-event-mesh`](https://github.com/cap-js/advanced-event-mesh). Please see the plugin's [setup guide](https://github.com/cap-js/advanced-event-mesh/blob/main/README.md#setup) for more details. diff --git a/package-lock.json b/package-lock.json index a688484952..346c4660bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -189,7 +189,6 @@ "integrity": "sha512-PTAFMJOpVtJweExEYYgdmSCC6n4V/R+ctDL3fRQy77ulZM/p+zMLIQC9c7HCQE1zqpauvVck3f2zYSejaUTtrw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -358,7 +357,6 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "peerDependencies": { "@sap/cds": ">=9.0.0", "@sap/cds-dk": "^9", @@ -371,30 +369,30 @@ } }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.2.2.tgz", - "integrity": "sha512-W3FKgb89DwMuQEVWz0dPH9uZqC8w+ylpbtmXuevflw3SLtGPyllMvf/1T6tcqIkg3KEWoRYFxjpJWyoOjJkZGw==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.4.0.tgz", + "integrity": "sha512-Hm2gpMg/lRv4fKtiO2NfBiaJdFZVVb1V1a+IVhlD9qCuObLhCt60Oze2kD1dQzhbaIX756cs/eyxa5bQ5jihhQ==", "dev": true, "license": "MIT", "dependencies": { "@cspell/dict-ada": "^4.1.1", "@cspell/dict-al": "^1.1.1", - "@cspell/dict-aws": "^4.0.15", - "@cspell/dict-bash": "^4.2.1", - "@cspell/dict-companies": "^3.2.6", - "@cspell/dict-cpp": "^6.0.12", + "@cspell/dict-aws": "^4.0.16", + "@cspell/dict-bash": "^4.2.2", + "@cspell/dict-companies": "^3.2.7", + "@cspell/dict-cpp": "^6.0.15", "@cspell/dict-cryptocurrencies": "^5.0.5", "@cspell/dict-csharp": "^4.0.7", "@cspell/dict-css": "^4.0.18", "@cspell/dict-dart": "^2.3.1", - "@cspell/dict-data-science": "^2.0.10", + "@cspell/dict-data-science": "^2.0.12", "@cspell/dict-django": "^4.1.5", "@cspell/dict-docker": "^1.1.16", "@cspell/dict-dotnet": "^5.0.10", "@cspell/dict-elixir": "^4.0.8", - "@cspell/dict-en_us": "^4.4.20", - "@cspell/dict-en-common-misspellings": "^2.1.6", - "@cspell/dict-en-gb-mit": "^3.1.10", + "@cspell/dict-en_us": "^4.4.24", + "@cspell/dict-en-common-misspellings": "^2.1.8", + "@cspell/dict-en-gb-mit": "^3.1.14", "@cspell/dict-filetypes": "^3.0.14", "@cspell/dict-flutter": "^1.1.1", "@cspell/dict-fonts": "^4.0.5", @@ -402,10 +400,10 @@ "@cspell/dict-fullstack": "^3.2.7", "@cspell/dict-gaming-terms": "^1.1.2", "@cspell/dict-git": "^3.0.7", - "@cspell/dict-golang": "^6.0.23", + "@cspell/dict-golang": "^6.0.24", "@cspell/dict-google": "^1.0.9", "@cspell/dict-haskell": "^4.0.6", - "@cspell/dict-html": "^4.0.12", + "@cspell/dict-html": "^4.0.13", "@cspell/dict-html-symbol-entities": "^4.0.4", "@cspell/dict-java": "^5.0.12", "@cspell/dict-julia": "^1.1.1", @@ -415,48 +413,49 @@ "@cspell/dict-lorem-ipsum": "^4.0.5", "@cspell/dict-lua": "^4.0.8", "@cspell/dict-makefile": "^1.0.5", - "@cspell/dict-markdown": "^2.0.12", + "@cspell/dict-markdown": "^2.0.13", "@cspell/dict-monkeyc": "^1.0.11", "@cspell/dict-node": "^5.0.8", - "@cspell/dict-npm": "^5.2.18", - "@cspell/dict-php": "^4.0.15", + "@cspell/dict-npm": "^5.2.25", + "@cspell/dict-php": "^4.1.0", "@cspell/dict-powershell": "^5.0.15", "@cspell/dict-public-licenses": "^2.0.15", - "@cspell/dict-python": "^4.2.20", + "@cspell/dict-python": "^4.2.23", "@cspell/dict-r": "^2.1.1", "@cspell/dict-ruby": "^5.0.9", "@cspell/dict-rust": "^4.0.12", "@cspell/dict-scala": "^5.0.8", - "@cspell/dict-shell": "^1.1.1", - "@cspell/dict-software-terms": "^5.1.9", + "@cspell/dict-shell": "^1.1.2", + "@cspell/dict-software-terms": "^5.1.15", "@cspell/dict-sql": "^2.2.1", "@cspell/dict-svelte": "^1.0.7", "@cspell/dict-swift": "^2.0.6", "@cspell/dict-terraform": "^1.1.3", "@cspell/dict-typescript": "^3.2.3", - "@cspell/dict-vue": "^3.0.5" + "@cspell/dict-vue": "^3.0.5", + "@cspell/dict-zig": "^1.0.0" }, "engines": { "node": ">=20" } }, "node_modules/@cspell/cspell-json-reporter": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.2.2.tgz", - "integrity": "sha512-7nTqnnRCyQB+bTmIuBR4aRwV5JHymckmz1snCF+ItjDSvlc3qzjxldG8ao5zm34h+b/8YCvdMU9B92eHBt803w==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.4.0.tgz", + "integrity": "sha512-TpHY7t13xNhcZF9bwOfgVIhcyPDamMnxU/TBYhf4mPtXPLrZ5gBTg3UZh0/9Zn3naMjmJtngdsLvB2wai9xBlQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "9.2.2" + "@cspell/cspell-types": "9.4.0" }, "engines": { "node": ">=20" } }, "node_modules/@cspell/cspell-pipe": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.2.2.tgz", - "integrity": "sha512-YOdbp1uoKMkYy92qxMjoOxcqcR6LEVDus+72C4X9L8eJ2b+CBO3VaVqU16Y7OQGjYMnukYgB6eyTh8YFo9uBRw==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.4.0.tgz", + "integrity": "sha512-cI0sUe7SB99hJB1T6PhH/MpSrnml1kOekTCE+VH3Eb7zkVP5/mwJXs8BlufdvwBona+Cgkx6jeWlhFpxLc39Yg==", "dev": true, "license": "MIT", "engines": { @@ -464,9 +463,9 @@ } }, "node_modules/@cspell/cspell-resolver": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.2.2.tgz", - "integrity": "sha512-5tST2xoU8xbXihr1bdQ6pfcScQ3PkFpKKhFGClVfqS0yf/CKYURqzJlRDVjrFZsl+PT6tw/Jdt0E9Wwp1X1Qgw==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.4.0.tgz", + "integrity": "sha512-o9gbbdXlhxG2rqtGqQ7xZ8MGDDsPLbskBnTeuA++ix4Ch/HdjrBNmKReIGAEqJPfP+JGgoEKqFISHUDKAJ/ygQ==", "dev": true, "license": "MIT", "dependencies": { @@ -477,9 +476,9 @@ } }, "node_modules/@cspell/cspell-service-bus": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.2.2.tgz", - "integrity": "sha512-AxJuw/YPJkz1Ali5mA+OW9y4JiJzb2U7H4pGYq0nRB/mWwI/xtFjuWVkI+BhwrA2P6hHdifu0JdxSLqW4IYpPQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.4.0.tgz", + "integrity": "sha512-UottRlFPN6FGUfojx5HtUPZTeYXg2rf2HvO/HLh0KicirVYO16vFxTevg9MyOvw1EXSsDRz8ECANjiE7fnzBCQ==", "dev": true, "license": "MIT", "engines": { @@ -487,9 +486,9 @@ } }, "node_modules/@cspell/cspell-types": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.2.2.tgz", - "integrity": "sha512-/1dRFQ3sEY9Yo+f3w0A8MFJ0BOapQc1uFjlMF19c3uoD/e4PpNLpL1qXY4FeLWKDk1D9VT8SL93J+lIwEi5bvg==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.4.0.tgz", + "integrity": "sha512-vSpd50OfmthBH0aRFRLA2zJFtwli3ntHA0WAOJ8tIMLUCJgF3udooRXFeX3wR8ri69C9mc3864LC4inyRC/E9w==", "dev": true, "license": "MIT", "engines": { @@ -511,33 +510,33 @@ "license": "MIT" }, "node_modules/@cspell/dict-aws": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.15.tgz", - "integrity": "sha512-aPY7VVR5Os4rz36EaqXBAEy14wR4Rqv+leCJ2Ug/Gd0IglJpM30LalF3e2eJChnjje3vWoEC0Rz3+e5gpZG+Kg==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.16.tgz", + "integrity": "sha512-a681zShZbtTo947NvTYGLer95ZDQw1ROKvIFydak1e0OlfFCsNdtcYTupn0nbbYs53c9AO7G2DU8AcNEAnwXPA==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-bash": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.2.1.tgz", - "integrity": "sha512-SBnzfAyEAZLI9KFS7DUG6Xc1vDFuLllY3jz0WHvmxe8/4xV3ufFE3fGxalTikc1VVeZgZmxYiABw4iGxVldYEg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.2.2.tgz", + "integrity": "sha512-kyWbwtX3TsCf5l49gGQIZkRLaB/P8g73GDRm41Zu8Mv51kjl2H7Au0TsEvHv7jzcsRLS6aUYaZv6Zsvk1fOz+Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/dict-shell": "1.1.1" + "@cspell/dict-shell": "1.1.2" } }, "node_modules/@cspell/dict-companies": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.6.tgz", - "integrity": "sha512-cVWBk4DSUOthCsgOsoB+5L5F1Wk8lWGHnw5de75YCKSjOEV8/6kskwwDrPTIHkoGVzpIzIIQ/OdXhYwa2G+16A==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.7.tgz", + "integrity": "sha512-fEyr3LmpFKTaD0LcRhB4lfW1AmULYBqzg4gWAV0dQCv06l+TsA+JQ+3pZJbUcoaZirtgsgT3dL3RUjmGPhUH0A==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-cpp": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-6.0.12.tgz", - "integrity": "sha512-N4NsCTttVpMqQEYbf0VQwCj6np+pJESov0WieCN7R/0aByz4+MXEiDieWWisaiVi8LbKzs1mEj4ZTw5K/6O2UQ==", + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-6.0.15.tgz", + "integrity": "sha512-N7MKK3llRNoBncygvrnLaGvmjo4xzVr5FbtAc9+MFGHK6/LeSySBupr1FM72XDaVSIsmBEe7sDYCHHwlI9Jb2w==", "dev": true, "license": "MIT" }, @@ -560,8 +559,7 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.18.tgz", "integrity": "sha512-EF77RqROHL+4LhMGW5NTeKqfUd/e4OOv6EDFQ/UQQiFyWuqkEKyEz0NDILxOFxWUEVdjT2GQ2cC7t12B6pESwg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-dart": { "version": "2.3.1", @@ -571,9 +569,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-data-science": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.10.tgz", - "integrity": "sha512-vZSsz7845ugW6mY65966Ki2bMS/ZnAZoTVvpuXQ07a2rYxJhUC+6WuBMD80hFLlKwjC5T/5Llv4F/VlB00swpw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.12.tgz", + "integrity": "sha512-vI/mg6cI28IkFcpeINS7cm5M9HWemmXSTnxJiu3nmc4VAGx35SXIEyuLGBcsVzySvDablFYf4hsEpmg1XpVsUQ==", "dev": true, "license": "MIT" }, @@ -606,23 +604,23 @@ "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.4.20", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.20.tgz", - "integrity": "sha512-acAlX967bkrLwRhSJ8KGBCBUITMOe8+smwsShjei431vTB6tU5ZID6XDxR9hH/kDxfdiRTXAE8vkT3WJAHnc1Q==", + "version": "4.4.24", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.24.tgz", + "integrity": "sha512-JE+/H2YicHJTneRmgH4GSI21rS+1yGZVl1jfOQgl8iHLC+yTTMtCvueNDMK94CgJACzYAoCsQB70MqiFJJfjLQ==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-en-common-misspellings": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.1.6.tgz", - "integrity": "sha512-xV9yryOqZizbSqxRS7kSVRrxVEyWHUqwdY56IuT7eAWGyTCJNmitXzXa4p+AnEbhL+AB2WLynGVSbNoUC3ceFA==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.1.8.tgz", + "integrity": "sha512-vDsjRFPQGuAADAiitf82z9Mz3DcqKZi6V5hPAEIFkLLKjFVBcjUsSq59SfL59ElIFb76MtBO0BLifdEbBj+DoQ==", "dev": true, "license": "CC BY-SA 4.0" }, "node_modules/@cspell/dict-en-gb-mit": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.1.10.tgz", - "integrity": "sha512-oFandL5N4B55wmOd0hOAoyaiUZBkClQ1FPCkcAY/HMuq6zeCQE/oEK9lLGDmnzLGgWnTT7wd0KOSYUPTxWQaNQ==", + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.1.14.tgz", + "integrity": "sha512-b+vEerlHP6rnNf30tmTJb7JZnOq4WAslYUvexOz/L3gDna9YJN3bAnwRJ3At3bdcOcMG7PTv3Pi+C73IR22lNg==", "dev": true, "license": "MIT" }, @@ -676,9 +674,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-golang": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.23.tgz", - "integrity": "sha512-oXqUh/9dDwcmVlfUF5bn3fYFqbUzC46lXFQmi5emB0vYsyQXdNWsqi6/yH3uE7bdRE21nP7Yo0mR1jjFNyLamg==", + "version": "6.0.24", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.24.tgz", + "integrity": "sha512-rY7PlC3MsHozmjrZWi0HQPUl0BVCV0+mwK0rnMT7pOIXqOe4tWCYMULDIsEk4F0gbIxb5badd2dkCPDYjLnDgA==", "dev": true, "license": "MIT" }, @@ -697,20 +695,18 @@ "license": "MIT" }, "node_modules/@cspell/dict-html": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.12.tgz", - "integrity": "sha512-JFffQ1dDVEyJq6tCDWv0r/RqkdSnV43P2F/3jJ9rwLgdsOIXwQbXrz6QDlvQLVvNSnORH9KjDtenFTGDyzfCaA==", + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.13.tgz", + "integrity": "sha512-vHzk2xfqQYPvoXtQtywa6ekIonPrUEwe2uftjry3UNRNl89TtzLJVSkiymKJ3WMb+W/DwKXKIb1tKzcIS8ccIg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-html-symbol-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.4.tgz", "integrity": "sha512-afea+0rGPDeOV9gdO06UW183Qg6wRhWVkgCFwiO3bDupAoyXRuvupbb5nUyqSTsLXIKL8u8uXQlJ9pkz07oVXw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-java": { "version": "5.0.12", @@ -769,14 +765,14 @@ "license": "MIT" }, "node_modules/@cspell/dict-markdown": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-markdown/-/dict-markdown-2.0.12.tgz", - "integrity": "sha512-ufwoliPijAgWkD/ivAMC+A9QD895xKiJRF/fwwknQb7kt7NozTLKFAOBtXGPJAB4UjhGBpYEJVo2elQ0FCAH9A==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-markdown/-/dict-markdown-2.0.13.tgz", + "integrity": "sha512-rFeGikf+lVlywEp7giATUfi8myFeee6jqgbUgtdIdl/OBmRBPe5m7mKNk7yMItMZe8ICrwMxFwJy5OeTnrr6QA==", "dev": true, "license": "MIT", "peerDependencies": { "@cspell/dict-css": "^4.0.18", - "@cspell/dict-html": "^4.0.12", + "@cspell/dict-html": "^4.0.13", "@cspell/dict-html-symbol-entities": "^4.0.4", "@cspell/dict-typescript": "^3.2.3" } @@ -796,16 +792,16 @@ "license": "MIT" }, "node_modules/@cspell/dict-npm": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.18.tgz", - "integrity": "sha512-uJV1T7y9ifFysO22XmxjU7y95c+02lfCZHNsTYHw2KOL6tLjc3XK/i0xt9iGLkPpcxwNJSCdu13UpjXZGqce/Q==", + "version": "5.2.25", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.25.tgz", + "integrity": "sha512-jxhVxM3+ilxbum/N2ejAvVuvet1OrGeW1fD7GagAkHU/2zlzINZkJLDtXk6v1WHUjigfhiAsois3puobv/2A1A==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-php": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.0.15.tgz", - "integrity": "sha512-iepGB2gtToMWSTvybesn4/lUp4LwXcEm0s8vasJLP76WWVkq1zYjmeS+WAIzNgsuURyZ/9mGqhS0CWMuo74ODw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.1.0.tgz", + "integrity": "sha512-dTDeabyOj7eFvn2Q4Za3uVXM2+SzeFMqX8ly2P0XTo4AzbCmI2hulFD/QIADwWmwiRrInbbf8cxwFHNIYrXl4w==", "dev": true, "license": "MIT" }, @@ -824,13 +820,13 @@ "license": "MIT" }, "node_modules/@cspell/dict-python": { - "version": "4.2.20", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.20.tgz", - "integrity": "sha512-c1wbfb3MDMSY4UTNdGnA18NkrcX6cMlYER0HSpGYh2jLK43gS1QL3j2B49qgnRYfcLUp4xgeA05vzCQsjGbwuQ==", + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.23.tgz", + "integrity": "sha512-c0C//tmG4PZWeONtTBPXa6q0ylfz3/BgEcHAR1L0BPWjNUIzTyx9J+hEIUCPYf7eAPeYjaDuTvYlg11igXXE4Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/dict-data-science": "^2.0.10" + "@cspell/dict-data-science": "^2.0.12" } }, "node_modules/@cspell/dict-r": { @@ -862,16 +858,16 @@ "license": "MIT" }, "node_modules/@cspell/dict-shell": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-shell/-/dict-shell-1.1.1.tgz", - "integrity": "sha512-T37oYxE7OV1x/1D4/13Y8JZGa1QgDCXV7AVt3HLXjn0Fe3TaNDvf5sU0fGnXKmBPqFFrHdpD3uutAQb1dlp15g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-shell/-/dict-shell-1.1.2.tgz", + "integrity": "sha512-WqOUvnwcHK1X61wAfwyXq04cn7KYyskg90j4lLg3sGGKMW9Sq13hs91pqrjC44Q+lQLgCobrTkMDw9Wyl9nRFA==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-software-terms": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.1.9.tgz", - "integrity": "sha512-lpiSpS1iTF2n8barqVkPmhe5qXs5291IqcDUPr5ttFRxPMZ7pgrMUdvcdNUdkajymjDOyWfUNhdYXW7JndThZw==", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.1.15.tgz", + "integrity": "sha512-93VqazVvVtHuKY7seGxbfdtrnPBgZ/hZ/NmFFkBRhkRL6NavaQ6U2QsHpnlVEZN5km3DmaQy1X4ZcvNoSTK/ZQ==", "dev": true, "license": "MIT" }, @@ -908,8 +904,7 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.3.tgz", "integrity": "sha512-zXh1wYsNljQZfWWdSPYwQhpwiuW0KPW1dSd8idjMRvSD0aSvWWHoWlrMsmZeRl4qM4QCEAjua8+cjflm41cQBg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-vue": { "version": "3.0.5", @@ -918,14 +913,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@cspell/dict-zig": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-zig/-/dict-zig-1.0.0.tgz", + "integrity": "sha512-XibBIxBlVosU06+M6uHWkFeT0/pW5WajDRYdXG2CgHnq85b0TI/Ks0FuBJykmsgi2CAD3Qtx8UHFEtl/DSFnAQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@cspell/dynamic-import": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.2.2.tgz", - "integrity": "sha512-RHQLp0iYcWuK0MGiUBA6dgEOCdI29kZTiBRVcJM/Pzvhvs8j9pzBTkMesZAJ7XOSFz2kU+skRMBsFd774dmYTA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.4.0.tgz", + "integrity": "sha512-d2fjLjzrKGUIn5hWK8gMuyAh2pqXSxBqOHpU1jR3jxbrO3MilunKNijaSstv7CZn067Jpc36VfaKQodaXNZzUA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "9.2.2", + "@cspell/url": "9.4.0", "import-meta-resolve": "^4.2.0" }, "engines": { @@ -933,9 +935,9 @@ } }, "node_modules/@cspell/filetypes": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.2.2.tgz", - "integrity": "sha512-oM+cqipbZ4PNxQcKP9sKOeRKBG+oM3NKO3To1FyxYxvnUG7DukW2yH6BS0/GUY7qK+oSftuq5d6DXEAl9wzbEQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.4.0.tgz", + "integrity": "sha512-RMrYHkvPF0tHVFM+T4voEhX9sfYQrd/mnNbf6+O4CWUyLCz4NQ5H9yOgEIJwEcLu4y3NESGXFef/Jn5xo0CUfg==", "dev": true, "license": "MIT", "engines": { @@ -943,9 +945,9 @@ } }, "node_modules/@cspell/strong-weak-map": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.2.2.tgz", - "integrity": "sha512-Z7rd7NwHaoH/d/Ds97Rv042WS9PgpVdqgO2X0ehYZmgj2E0LIq2MTkIJMheUrSn37D0PW/suroKh6hN15pJtpQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.4.0.tgz", + "integrity": "sha512-ui7mlXYmqElS/SmRubPBNWdkQVWgWbB6rjCurc+0owYXlnweItAMHTxC8mCWM/Au22SF1dB/JR8QBELFXLkTjQ==", "dev": true, "license": "MIT", "engines": { @@ -953,9 +955,9 @@ } }, "node_modules/@cspell/url": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.2.2.tgz", - "integrity": "sha512-gvLprhrArvLP/rnC8b766dA80EXwBbzXqb9tNDRk1esQV7d3uS1Ftk1970MRlAfLg1pG6V+3C4UrB6WOB/rMCQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.4.0.tgz", + "integrity": "sha512-nt88P6m20AaVbqMxsyPf8KqyWPaFEW2UANi0ijBxc2xTkD2KiUovxfZUYW6NMU9XBYZlovT5LztkEhst2yBcSA==", "dev": true, "license": "MIT", "engines": { @@ -1486,22 +1488,22 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz", - "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.16.0" + "@eslint/core": "^0.17.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", - "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1560,12 +1562,11 @@ } }, "node_modules/@eslint/js": { - "version": "9.38.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", - "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1584,13 +1585,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", - "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.16.0", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { @@ -1716,24 +1717,6 @@ "node": "20 || >=22" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -1741,44 +1724,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@parcel/watcher": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", @@ -2398,12 +2343,11 @@ ] }, "node_modules/@sap/cds": { - "version": "9.4.4", - "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-9.4.4.tgz", - "integrity": "sha512-JJCHeEJF4xzFyZSf2ToocvVE9dyHfNLTRXOauOxlmpfyaLg97G7Qp+L4bD132eB0onBG9bQj3eH8DzBm0hVvIw==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-9.5.1.tgz", + "integrity": "sha512-rMvDSRytjqYQolB0pg8tiBlpS9kKGcleRhpZmBGUmSncbbwnotKYTKoDyMCWkflS8P9/Jq9YfY1qhK+fduHCVA==", "dev": true, "license": "SEE LICENSE IN LICENSE", - "peer": true, "dependencies": { "@sap/cds-compiler": "^6.3", "@sap/cds-fiori": "^2", @@ -2714,17 +2658,16 @@ "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.24.tgz", - "integrity": "sha512-Mbrt4SRlXSTWryOnHAh2d4UQ/E7n9lZyGSi6KgX+4hkuL9soYbLOVXVhnk/ODp12YsGc95f4pOvqywJ6kngUwg==", + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", - "@types/serve-static": "*" + "@types/serve-static": "^1" } }, "node_modules/@types/express-serve-static-core": { @@ -2882,17 +2825,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz", - "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.1.tgz", + "integrity": "sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/typescript-estree": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "debug": "^4.3.4" }, "engines": { @@ -2908,14 +2850,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", - "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.1.tgz", + "integrity": "sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.46.2", - "@typescript-eslint/types": "^8.46.2", + "@typescript-eslint/tsconfig-utils": "^8.48.1", + "@typescript-eslint/types": "^8.48.1", "debug": "^4.3.4" }, "engines": { @@ -2930,14 +2872,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", - "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.1.tgz", + "integrity": "sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2" + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2948,9 +2890,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", - "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.1.tgz", + "integrity": "sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==", "dev": true, "license": "MIT", "engines": { @@ -2965,9 +2907,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", - "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz", + "integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==", "dev": true, "license": "MIT", "engines": { @@ -2979,21 +2921,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", - "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.1.tgz", + "integrity": "sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.46.2", - "@typescript-eslint/tsconfig-utils": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", + "@typescript-eslint/project-service": "8.48.1", + "@typescript-eslint/tsconfig-utils": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", + "tinyglobby": "^0.2.15", "ts-api-utils": "^2.1.0" }, "engines": { @@ -3008,13 +2949,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", - "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz", + "integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/types": "8.48.1", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -3369,6 +3310,7 @@ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -3383,7 +3325,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3434,7 +3375,6 @@ "integrity": "sha512-8VJKIzheeI9cjuVJhU1hYEVetOTe7LvA+CujAI7yqvYsPtZfVEvv1pg9AeFNtHBg/ZoSLGU5LPijhcY5l3Ea9g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@algolia/abtesting": "1.4.0", "@algolia/client-abtesting": "5.38.0", @@ -3475,19 +3415,6 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3500,7 +3427,8 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/array-timsort": { "version": "1.0.3", @@ -3532,6 +3460,7 @@ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -3557,6 +3486,7 @@ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -3566,7 +3496,8 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/boolbase": { "version": "1.0.0", @@ -3591,6 +3522,7 @@ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -3604,6 +3536,7 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -3614,6 +3547,7 @@ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -3628,6 +3562,7 @@ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -3798,9 +3733,9 @@ } }, "node_modules/commander": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz", - "integrity": "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", "dev": true, "license": "MIT", "engines": { @@ -3835,6 +3770,7 @@ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "safe-buffer": "5.2.1" }, @@ -3848,6 +3784,7 @@ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -3858,6 +3795,7 @@ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -3867,7 +3805,8 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/copy-anything": { "version": "3.0.5", @@ -3908,26 +3847,27 @@ } }, "node_modules/cspell": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.2.2.tgz", - "integrity": "sha512-D9jxXlYWIxUw4IjicxrmK83n5BzuQVZaIhsDsfRiH7iP4F71gDtKR9b+UgmXevvseN7OH4LkdyaPKzjNliGAbg==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.4.0.tgz", + "integrity": "sha512-ZvXO+EY/G0/msu7jwRiVk0sXL/zB7DMJLBvjSUrK82uVbDoDxHwXxUuOz2UVnk2+J61//ldIZrjxVK8KMvaJlg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-json-reporter": "9.2.2", - "@cspell/cspell-pipe": "9.2.2", - "@cspell/cspell-types": "9.2.2", - "@cspell/dynamic-import": "9.2.2", - "@cspell/url": "9.2.2", + "@cspell/cspell-json-reporter": "9.4.0", + "@cspell/cspell-pipe": "9.4.0", + "@cspell/cspell-types": "9.4.0", + "@cspell/dynamic-import": "9.4.0", + "@cspell/url": "9.4.0", + "ansi-regex": "^6.2.2", "chalk": "^5.6.2", "chalk-template": "^1.1.2", - "commander": "^14.0.1", - "cspell-config-lib": "9.2.2", - "cspell-dictionary": "9.2.2", - "cspell-gitignore": "9.2.2", - "cspell-glob": "9.2.2", - "cspell-io": "9.2.2", - "cspell-lib": "9.2.2", + "commander": "^14.0.2", + "cspell-config-lib": "9.4.0", + "cspell-dictionary": "9.4.0", + "cspell-gitignore": "9.4.0", + "cspell-glob": "9.4.0", + "cspell-io": "9.4.0", + "cspell-lib": "9.4.0", "fast-json-stable-stringify": "^2.1.0", "flatted": "^3.3.3", "semver": "^7.7.3", @@ -3945,47 +3885,47 @@ } }, "node_modules/cspell-config-lib": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.2.2.tgz", - "integrity": "sha512-Fp3jdFxb5gxcQP146TfNVmDqXKfm3xmcEUr1K829DmAFwhc7s+/pCRjhBPoGfQt6U7ugpxjkSx2gGKSbLhp7Mg==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.4.0.tgz", + "integrity": "sha512-CvQKSmK/DRIf3LpNx2sZth65pHW2AHngZqLkH3DTwnAPbiCAsE0XvCrVhvDfCNu/6uJIaa+NVHSs8GOf//DHBQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "9.2.2", + "@cspell/cspell-types": "9.4.0", "comment-json": "^4.4.1", - "smol-toml": "^1.4.2", - "yaml": "^2.8.1" + "smol-toml": "^1.5.2", + "yaml": "^2.8.2" }, "engines": { "node": ">=20" } }, "node_modules/cspell-dictionary": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.2.2.tgz", - "integrity": "sha512-lnoCFoCAaiFJi+Hz22t+tdTj76jyTA76EYFKhmf/dbj5UO6kVy8by08uFfUbbMaC9Oi09YHnI62P/e+LBx1v8Q==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.4.0.tgz", + "integrity": "sha512-c2qscanRZChoHZFYI7KpvBMdy8i6wNwl2EflcNRrFiFOq67t9CgxLe54PafaqhrHGpBc8nElaZKciLvjj6Uscw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "9.2.2", - "@cspell/cspell-types": "9.2.2", - "cspell-trie-lib": "9.2.2", - "fast-equals": "^5.3.2" + "@cspell/cspell-pipe": "9.4.0", + "@cspell/cspell-types": "9.4.0", + "cspell-trie-lib": "9.4.0", + "fast-equals": "^5.3.3" }, "engines": { "node": ">=20" } }, "node_modules/cspell-gitignore": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.2.2.tgz", - "integrity": "sha512-Idx3IVKTpnGoyRlkj8F/lSWtWiJpqLhXmZglTzfGWxzbik8E0aQmSyT3blbNWhZL/K1JqlTjbSiAICVMoWTkhA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.4.0.tgz", + "integrity": "sha512-HMrzLmJBUMSpaMMkltlTAz/aVOrHxixyhKfg5WbFCJ5JYZO6Qu3/JU3wRoOFoud9449wRjLkvrGmbbL2+vO6Lw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "9.2.2", - "cspell-glob": "9.2.2", - "cspell-io": "9.2.2" + "@cspell/url": "9.4.0", + "cspell-glob": "9.4.0", + "cspell-io": "9.4.0" }, "bin": { "cspell-gitignore": "bin.mjs" @@ -3995,13 +3935,13 @@ } }, "node_modules/cspell-glob": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.2.2.tgz", - "integrity": "sha512-6mhUk4iLu5YzY9PE86ZyAjNFjM7TD8Oh4btJ7ZV+edzJjdVjFugXWyefPXCGNfuvpaJqpuoLDwMvNHJxUmLwbg==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.4.0.tgz", + "integrity": "sha512-Q87Suj9oXrhoKck15qWorCizBjMNxG/k3NjnhKIAMrF+PdUa1Mpl0MOD+hqV1Wvwh1UHcIMYCP3bR3XpBbNx+Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "9.2.2", + "@cspell/url": "9.4.0", "picomatch": "^4.0.3" }, "engines": { @@ -4009,14 +3949,14 @@ } }, "node_modules/cspell-grammar": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.2.2.tgz", - "integrity": "sha512-m0aozo5gjZYL5Vm3/9D0/yLZJTsVJAP8VeRVljN4u5T7w+WY+LsnvKSZhnkOvsT3kCJDhcKEkMVkCo8d/7EcAQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.4.0.tgz", + "integrity": "sha512-ie7OQ4Neflo+61bMzoLR7GtlZfMBAm2KL1U4iNqh15wUE5fDbvXeN15H5lu+gcO8BwYvC5wxZknw1x62/J8+3Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "9.2.2", - "@cspell/cspell-types": "9.2.2" + "@cspell/cspell-pipe": "9.4.0", + "@cspell/cspell-types": "9.4.0" }, "bin": { "cspell-grammar": "bin.mjs" @@ -4026,43 +3966,43 @@ } }, "node_modules/cspell-io": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.2.2.tgz", - "integrity": "sha512-Rpky4woeB6/1VUCk7DtRm94A6c5XRbhcj5dUZh851EpZ0ItEz3S9+MhkX8g1sTVkDg6Hln1pu+Nbm9dFIpGkGA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.4.0.tgz", + "integrity": "sha512-8w30dqlO54H9w6WGlvZhHI5kytVbF3bYPqKJAZLWKEO36L2mdpf6/abx/FA4yVLJ56wmH1x0N0ZK32wNRl5C6A==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-service-bus": "9.2.2", - "@cspell/url": "9.2.2" + "@cspell/cspell-service-bus": "9.4.0", + "@cspell/url": "9.4.0" }, "engines": { "node": ">=20" } }, "node_modules/cspell-lib": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.2.2.tgz", - "integrity": "sha512-ksy+5vCSZz7ECUDlLA8ZGNEcWmnzl5bMe4IEPHAMaPFY3iWNsG7dXBrae1dj/b/3HqVqOdXPdwjnGAyZciissg==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.4.0.tgz", + "integrity": "sha512-ajjioE59IEDNUPawfaBpiMfGC32iKPkuYd4T9ftguuef8VvyKRifniiUi1nxwGgAhzSfxHvWs7qdT+29Pp5TMQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-bundled-dicts": "9.2.2", - "@cspell/cspell-pipe": "9.2.2", - "@cspell/cspell-resolver": "9.2.2", - "@cspell/cspell-types": "9.2.2", - "@cspell/dynamic-import": "9.2.2", - "@cspell/filetypes": "9.2.2", - "@cspell/strong-weak-map": "9.2.2", - "@cspell/url": "9.2.2", + "@cspell/cspell-bundled-dicts": "9.4.0", + "@cspell/cspell-pipe": "9.4.0", + "@cspell/cspell-resolver": "9.4.0", + "@cspell/cspell-types": "9.4.0", + "@cspell/dynamic-import": "9.4.0", + "@cspell/filetypes": "9.4.0", + "@cspell/strong-weak-map": "9.4.0", + "@cspell/url": "9.4.0", "clear-module": "^4.1.2", - "cspell-config-lib": "9.2.2", - "cspell-dictionary": "9.2.2", - "cspell-glob": "9.2.2", - "cspell-grammar": "9.2.2", - "cspell-io": "9.2.2", - "cspell-trie-lib": "9.2.2", + "cspell-config-lib": "9.4.0", + "cspell-dictionary": "9.4.0", + "cspell-glob": "9.4.0", + "cspell-grammar": "9.4.0", + "cspell-io": "9.4.0", + "cspell-trie-lib": "9.4.0", "env-paths": "^3.0.0", - "gensequence": "^7.0.0", + "gensequence": "^8.0.8", "import-fresh": "^3.3.1", "resolve-from": "^5.0.0", "vscode-languageserver-textdocument": "^1.0.12", @@ -4074,15 +4014,15 @@ } }, "node_modules/cspell-trie-lib": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.2.2.tgz", - "integrity": "sha512-84L0Or6xkfnDMmxx2BtuaqsM4LOVCgnG4ZzMMgwQJU+9nSOAHs0ULNWQTHLbsCF+FFG/siILpUkIc3z+UxjGFw==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.4.0.tgz", + "integrity": "sha512-bySJTm8XDiJAoC1MDo4lE/KpSNxydo13ZETC8TF7Hb3rbWI1c6o5eZ4+i/tkG3M94OvKV91+MeAvoMCe7GGgAw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "9.2.2", - "@cspell/cspell-types": "9.2.2", - "gensequence": "^7.0.0" + "@cspell/cspell-pipe": "9.4.0", + "@cspell/cspell-types": "9.4.0", + "gensequence": "^8.0.8" }, "engines": { "node": ">=20" @@ -4170,6 +4110,7 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -4190,6 +4131,7 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -4229,6 +4171,7 @@ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -4238,26 +4181,13 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true, - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/emoji-regex-xs": { "version": "1.0.0", @@ -4272,6 +4202,7 @@ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -4308,6 +4239,7 @@ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" } @@ -4318,6 +4250,7 @@ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" } @@ -4328,6 +4261,7 @@ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -4379,7 +4313,8 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -4395,21 +4330,20 @@ } }, "node_modules/eslint": { - "version": "9.38.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz", - "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", + "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.1", - "@eslint/core": "^0.16.0", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.38.0", - "@eslint/plugin-kit": "^0.4.0", + "@eslint/js": "9.39.1", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -4456,16 +4390,16 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "10.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.5.1.tgz", - "integrity": "sha512-SbR9ZBUFKgvWAbq3RrdCtWaW0IKm6wwUiApxf3BVTNfqUIo4IQQmreMg2iHFJJ6C/0wss3LXURBJ1OwS/MhFcQ==", + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.6.2.tgz", + "integrity": "sha512-nA5yUs/B1KmKzvC42fyD0+l9Yd+LtEpVhWRbXuDj0e+ZURcTtyRbMDWUeJmTAh2wC6jC83raS63anNM2YT3NPw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", + "postcss-selector-parser": "^7.1.0", "semver": "^7.6.3", "xml-name-validator": "^4.0.0" }, @@ -4665,6 +4599,7 @@ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -4675,6 +4610,7 @@ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -4722,6 +4658,7 @@ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -4731,7 +4668,8 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/extend-shallow": { "version": "2.0.1", @@ -4754,45 +4692,15 @@ "license": "MIT" }, "node_modules/fast-equals": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.2.tgz", - "integrity": "sha512-6rxyATwPCkaFIL3JLqw8qXqMpIZ942pTX/tbQFkRsDGblS8tNGtlUauA/+mt6RUfqn/4MoEr+WDkYoIQbibWuQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.3.tgz", + "integrity": "sha512-/boTcHZeIAQ2r/tL11voclBHDeP9WPxLt+tyAbVSyyXuUFyh0Tne7gJZTqGbxnvj79TjLdCXLOY7UIPhyG5MTw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" } }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -4807,16 +4715,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -4861,6 +4759,7 @@ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4874,6 +4773,7 @@ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -4893,6 +4793,7 @@ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -4902,7 +4803,8 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/find-up": { "version": "5.0.0", @@ -4968,34 +4870,17 @@ "integrity": "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tabbable": "^6.2.0" } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -5006,6 +4891,7 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -5031,18 +4917,19 @@ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensequence": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-7.0.0.tgz", - "integrity": "sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==", + "version": "8.0.8", + "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-8.0.8.tgz", + "integrity": "sha512-omMVniXEXpdx/vKxGnPRoO2394Otlze28TyxECbFVyoSpZ9H3EO7lemjcB12OpQJzRW4e5tt/dL1rOxry6aMHg==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/get-intrinsic": { @@ -5051,6 +4938,7 @@ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -5076,6 +4964,7 @@ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -5084,30 +4973,6 @@ "node": ">= 0.4" } }, - "node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5121,22 +4986,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/global-directory": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", @@ -5172,6 +5021,7 @@ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" }, @@ -5235,6 +5085,7 @@ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" }, @@ -5248,6 +5099,7 @@ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -5327,6 +5179,7 @@ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5344,6 +5197,7 @@ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5434,7 +5288,8 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/ini": { "version": "4.1.1", @@ -5452,6 +5307,7 @@ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.10" } @@ -5513,16 +5369,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5553,6 +5399,7 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">=0.12.0" } @@ -5577,26 +5424,10 @@ "dev": true, "license": "ISC" }, - "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -5749,16 +5580,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/lru-cache": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", - "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/magic-string": { "version": "0.30.19", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", @@ -5806,9 +5627,9 @@ } }, "node_modules/markdownlint": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", - "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", + "version": "0.39.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.39.0.tgz", + "integrity": "sha512-Xt/oY7bAiHwukL1iru2np5LIkhwD19Y7frlsiDILK62v3jucXCD6JXlZlwMG12HZOR+roHIVuJZrfCkOhp6k3g==", "dev": true, "license": "MIT", "dependencies": { @@ -5829,23 +5650,24 @@ } }, "node_modules/markdownlint-cli": { - "version": "0.45.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.45.0.tgz", - "integrity": "sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==", + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.46.0.tgz", + "integrity": "sha512-4gxTNzPjpLnY7ftrEZD4flPY0QBkQLiqezb6KURFSkV+vPHFOsYw8OMtY6fu82Yt8ghtSrWegpYdq1ix25VFLQ==", "dev": true, "license": "MIT", "dependencies": { - "commander": "~13.1.0", - "glob": "~11.0.2", - "ignore": "~7.0.4", - "js-yaml": "~4.1.0", + "commander": "~14.0.2", + "deep-extend": "~0.6.0", + "ignore": "~7.0.5", + "js-yaml": "~4.1.1", "jsonc-parser": "~3.3.1", "jsonpointer": "~5.0.1", "markdown-it": "~14.1.0", - "markdownlint": "~0.38.0", - "minimatch": "~10.0.1", + "markdownlint": "~0.39.0", + "minimatch": "~10.1.1", "run-con": "~1.3.2", - "smol-toml": "~1.3.4" + "smol-toml": "~1.5.2", + "tinyglobby": "~0.2.15" }, "bin": { "markdownlint": "markdownlint.js" @@ -5854,16 +5676,6 @@ "node": ">=20" } }, - "node_modules/markdownlint-cli/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/markdownlint-cli/node_modules/ignore": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", @@ -5875,11 +5687,11 @@ } }, "node_modules/markdownlint-cli/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/brace-expansion": "^5.0.0" }, @@ -5890,19 +5702,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/markdownlint-cli/node_modules/smol-toml": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.4.tgz", - "integrity": "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, "node_modules/markdownlint-micromark": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz", @@ -5945,6 +5744,7 @@ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" } @@ -6197,6 +5997,7 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -6207,26 +6008,18 @@ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -6796,6 +6589,7 @@ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -6810,6 +6604,7 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">=8.6" }, @@ -6823,6 +6618,7 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "mime": "cli.js" }, @@ -6836,6 +6632,7 @@ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -6846,6 +6643,7 @@ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -6879,16 +6677,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/minisearch": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz", @@ -6949,6 +6737,7 @@ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -6980,6 +6769,7 @@ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" }, @@ -6993,6 +6783,7 @@ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ee-first": "1.1.1" }, @@ -7062,13 +6853,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, "node_modules/parent-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", @@ -7115,6 +6899,7 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -7146,29 +6931,13 @@ "node": ">=8" } }, - "node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/perfect-debounce": { "version": "1.0.0", @@ -7227,9 +6996,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "license": "MIT", "dependencies": { @@ -7278,6 +7047,7 @@ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -7312,6 +7082,7 @@ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { "side-channel": "^1.0.6" }, @@ -7322,33 +7093,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -7359,6 +7110,7 @@ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -7420,17 +7172,6 @@ "node": ">=8" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -7496,30 +7237,6 @@ "run-con": "cli.js" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7539,22 +7256,23 @@ "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/sass": { - "version": "1.93.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.93.2.tgz", - "integrity": "sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==", + "version": "1.94.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.94.2.tgz", + "integrity": "sha512-N+7WK20/wOr7CzA2snJcUSSNTCzeCGUTFY3OgeQP3mZ1aj9NMQ0mSTXwlrnd89j33zzQJGqIN52GIOmYrfq46A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -7611,6 +7329,7 @@ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -7636,6 +7355,7 @@ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -7645,7 +7365,8 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", @@ -7653,6 +7374,7 @@ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -7663,6 +7385,7 @@ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -7678,7 +7401,8 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/shebang-command": { "version": "2.0.0", @@ -7752,6 +7476,7 @@ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -7772,6 +7497,7 @@ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -7789,6 +7515,7 @@ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -7808,6 +7535,7 @@ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -7822,23 +7550,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/smol-toml": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.4.2.tgz", - "integrity": "sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.2.tgz", + "integrity": "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -7892,74 +7607,11 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/stringify-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", @@ -7975,46 +7627,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", @@ -8094,6 +7706,7 @@ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "is-number": "^7.0.0" }, @@ -8107,6 +7720,7 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.6" } @@ -8193,6 +7807,7 @@ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -8309,6 +7924,7 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -8336,6 +7952,7 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4.0" } @@ -8346,6 +7963,7 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -8386,7 +8004,6 @@ "integrity": "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -8529,7 +8146,6 @@ "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.22", "@vue/compiler-sfc": "3.5.22", @@ -8607,104 +8223,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/xdg-basedir": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", @@ -8729,9 +8247,9 @@ } }, "node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "dev": true, "license": "ISC", "bin": { @@ -8739,6 +8257,9 @@ }, "engines": { "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yocto-queue": { diff --git a/plugins/index.md b/plugins/index.md index d5eb5a76c9..7754fb3a6d 100644 --- a/plugins/index.md +++ b/plugins/index.md @@ -222,7 +222,7 @@ Features: - **Automatic Fiori Annotations for Upload Controls**: Streamlined user interactions with automatic SAP Fiori annotations that enhance upload controls, providing a more intuitive and seamless user experience. - **Support for SAP Document Management Service-Hosted Cloud Repository**: Leverage the robust capabilities of the SAP Document Management service-hosted cloud repository to store and manage your documents efficiently. - **Support for Third-Party CMIS-Compliant Repositories**: Integrate with third-party repositories that adhere to the Content Management Interoperability Services (CMIS) standard, offering flexibility and compatibility with various document management systems. -- **Intrinsic Multitenancy Handling**: Benefit from built-in multi-tenancy support, allowing for efficient management of multiple tenants without additional configuration. +- **Intrinsic Multitenancy Handling**: Benefit from built-in multitenancy support, allowing for efficient management of multiple tenants without additional configuration. - **Automated Onboarding and Offboarding of Repositories**: Simplify repository management with automated repository provisioning upon subscription and seamless repository removal upon unsubscription. Outlook: diff --git a/tools/apis/cds-add.md b/tools/apis/cds-add.md index 36da62a727..3743042886 100644 --- a/tools/apis/cds-add.md +++ b/tools/apis/cds-add.md @@ -83,7 +83,7 @@ Our `cds add postgres` will: 1. Register with `cds-dk` 2. Add a Dockerfile to start a PostgreSQL instance for development 3. Integrate with `cds add mta` for [Cloud Foundry](../../guides/deployment/to-cf) deployment -4. Integrate with `cds add helm` for [Kyma](../../guides/deployment/to-kyma) deployment +4. Integrate with `cds add kyma` for [Kyma](../../guides/deployment/to-kyma) deployment 5. Integrate with `cds help` Starting with 1, register the plugin: @@ -208,7 +208,7 @@ resources: # [!code ++] ``` ::: -Step 4 integrates with `cds add helm`: +Step 4 integrates with `cds add kyma`: ::: code-group ```js [lib/add.js] @@ -255,7 +255,7 @@ postgres: # [!code ++] ::: ::: tip Common integrations -Typically integrations are for deployment descriptors (`cds add mta` and `cds add helm`), security descriptors (`cds add xsuaa`), or changes that might impact your plugin configuration (`cds add multitenancy`). +Typically integrations are for deployment descriptors (`cds add mta` and `cds add kyma`), security descriptors (`cds add xsuaa`), or changes that might impact your plugin configuration (`cds add multitenancy`). ::: For step 5 we'll add some command-specific options to let users override the output path for the `pg.yaml` file when running `cds add postgres --out `: @@ -299,7 +299,7 @@ cds add my-facet -p @cap-js-community/example ::: details Install directly from your GitHub branch - For example, if your plugin's code is in `https://github.com/cap-js-community/example` on branch `cds-add` and registers the command `cds add my-facet`, then doing an integration test of your plugin with `@sap/cds-dk` in a single command: + For example, assume your plugin's code is in `https://github.com/cap-js-community/example` on branch `cds-add` and registers the command `cds add my-facet`. You could then do a real-world test of your `cds add` plugin in a single command: ```sh cds add my-facet -p @cap-js-community/example@git+https://github.com/cap-js-community/example#cds-add diff --git a/tools/assets/help/cds-add.out.md b/tools/assets/help/cds-add.out.md index 1fe04d8b36..85ced71c05 100644 --- a/tools/assets/help/cds-add.out.md +++ b/tools/assets/help/cds-add.out.md @@ -16,10 +16,7 @@ extension - extension project mta - Cloud Foundry deployment using mta.yaml cf-manifest - Cloud Foundry deployment using manifest files - helm - Kyma deployment using Helm charts - helm-unified-runtime - Kyma deployment using Unified Runtime Helm charts - containerize - containerization using ctz CLI - kyma - helm + containerize + kyma - Kyma deployment using Helm charts tiny-sample - minimal sample files sample - sample files including Fiori UI handler - handler stubs for service entities, actions and functions @@ -166,13 +163,6 @@ For Java, the default is 'handlers'. For Node.js, the default is 'srv'. - cds add helm - - --y - - If provided, the default values will be used for all prompts. - - cds add http --filter | -f diff --git a/tools/assets/help/cds-env-ls-requires-db.out.md b/tools/assets/help/cds-env-ls-requires-db.out.md index d7a3f016c5..6421a52fd1 100644 --- a/tools/assets/help/cds-env-ls-requires-db.out.md +++ b/tools/assets/help/cds-env-ls-requires-db.out.md @@ -5,4 +5,5 @@ requires.db.credentials.url = :memory: requires.db.impl = @cap-js/sqlite requires.db.kind = sqlite +requires.db.pool.max = 1 diff --git a/tools/assets/help/cds-env-requires-db.out.md b/tools/assets/help/cds-env-requires-db.out.md index 87a9f868d2..3ac6809326 100644 --- a/tools/assets/help/cds-env-requires-db.out.md +++ b/tools/assets/help/cds-env-requires-db.out.md @@ -7,6 +7,9 @@ "credentials": { "url": ":memory:" }, + "pool": { + "max": 1 + }, "kind": "sqlite" } diff --git a/tools/assets/help/cds-eval-env-requires-db.out.md b/tools/assets/help/cds-eval-env-requires-db.out.md index 41dde178d9..306b2ffcc7 100644 --- a/tools/assets/help/cds-eval-env-requires-db.out.md +++ b/tools/assets/help/cds-eval-env-requires-db.out.md @@ -5,6 +5,7 @@ { impl: '@cap-js/sqlite', credentials: { url: ':memory:' }, + pool: { max: 1 }, kind: 'sqlite' } diff --git a/tools/assets/help/cds-help.out.md b/tools/assets/help/cds-help.out.md index e7f753c2cb..1a6ea009f4 100644 --- a/tools/assets/help/cds-help.out.md +++ b/tools/assets/help/cds-help.out.md @@ -10,7 +10,6 @@ COMMANDS i | init jump-start cds-based projects a | add add a feature to an existing project - | gen generate models/data using a descriptive prompt [beta] m | import add models from external sources c | compile compile cds models to different outputs p | parse parses given cds models @@ -30,10 +29,10 @@ | logout logout from extensible multitenant SaaS app | pull pull base model of extensible SaaS app | push push extension to extensible SaaS app - t | lint run linter for env or model checks + | lint run linter for env or model checks v | version get detailed version information | completion add/remove cli completion for cds commands - ? | help get detailed usage information + h | help get detailed usage information Learn more about each command using: cds help <command> or diff --git a/tools/assets/help/cds-init.out.md b/tools/assets/help/cds-init.out.md index 404f93cb0c..bbb4099e51 100644 --- a/tools/assets/help/cds-init.out.md +++ b/tools/assets/help/cds-init.out.md @@ -23,10 +23,7 @@ extension - extension project mta - Cloud Foundry deployment using mta.yaml cf-manifest - Cloud Foundry deployment using manifest files - helm - Kyma deployment using Helm charts - helm-unified-runtime - Kyma deployment using Unified Runtime Helm charts - containerize - containerization using ctz CLI - kyma - helm + containerize + kyma - Kyma deployment using Helm charts tiny-sample - minimal sample files sample - sample files including Fiori UI handler - handler stubs for service entities, actions and functions diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index d472cf5402..6341e11d9b 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -4,15 +4,14 @@ | your-project | https://github.com/<your/repo> | | ---------------------- | --------------------------------------- | -| @sap/cds | 9.4.3 | -| @sap/cds-dk | -- missing -- | -| @sap/cds-compiler | 6.4.2 | -| @sap/cds-dk (global) | 9.4.1 | -| @sap/cds-fiori | 2.1.0 | -| @sap/cds-mtxs | 3.3.1 | +| @sap/cds | 9.5.1 | +| @sap/cds-compiler | 6.5.0 | +| @sap/cds-dk (global) | 9.5.0 | +| @sap/cds-fiori | 2.1.1 | +| @sap/cds-mtxs | 3.5.0 | | @cap-js/asyncapi | 1.0.3 | -| @cap-js/db-service | 2.5.1 | +| @cap-js/db-service | 2.7.0 | | @cap-js/openapi | 1.2.3 | -| @cap-js/sqlite | 2.0.3 | -| Node.js | v22.20.0 | +| @cap-js/sqlite | 2.1.0 | +| Node.js | v22.21.1 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index 1c407d30dd..9d04283d0c 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -2,15 +2,14 @@
 > cds version
 
-@sap/cds: 9.4.3
-@sap/cds-dk: undefined
-@sap/cds-compiler: 6.4.2
-@sap/cds-dk (global): 9.4.1
-@sap/cds-fiori: 2.1.0
-@sap/cds-mtxs: 3.3.1
+@sap/cds: 9.5.1
+@sap/cds-compiler: 6.5.0
+@sap/cds-dk (global): 9.5.0
+@sap/cds-fiori: 2.1.1
+@sap/cds-mtxs: 3.5.0
 @cap-js/asyncapi: 1.0.3
-@cap-js/db-service: 2.5.1
+@cap-js/db-service: 2.7.0
 @cap-js/openapi: 1.2.3
-@cap-js/sqlite: 2.0.3
-Node.js: v22.20.0
+@cap-js/sqlite: 2.1.0
+Node.js: v22.21.1
 
diff --git a/tools/console.md b/tools/console.md index a3e5541bb3..716dd7338d 100644 --- a/tools/console.md +++ b/tools/console.md @@ -116,7 +116,9 @@ Deploying your application is as simple as clicking through a guided dialog. CAP You can choose between two deployment modes: -- **In-App Deployment**: Uses pre-packaged CLI tools with the correct versions — no need to install anything locally. (Currently you still have to install [cds-dk](https://www.npmjs.com/package/@sap/cds-dk?activeTab=dependencies) manually, but we are working on it!) +- **In-App Deployment**: Uses pre-packaged CLI tools with the correct versions — no need to install anything locally. + > [!note] + > Currently you still have to locally install [cds-dk](https://www.npmjs.com/package/@sap/cds-dk?activeTab=dependencies), [mbt](https://sap.github.io/cloud-mta-build-tool/download/) and in case of windows [make](https://sap.github.io/cloud-mta-build-tool/makefile/), but we are working on it! - **CLI-Based Deployment**: Copy all necessary commands and run them in your own terminal. ### Designed for Simplicity