From 7be6590a52d2ce2280c97c0cc92198697eda63a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:24:29 +0100 Subject: [PATCH 1/7] build(deps-dev): bump @sap/cds from 8.4.2 to 8.5.0 (#346) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1187acd8..e6e73017 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cap-js/cds-types", - "version": "0.7.0", + "version": "0.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cap-js/cds-types", - "version": "0.7.0", + "version": "0.8.0", "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { @@ -1276,10 +1276,11 @@ } }, "node_modules/@sap/cds": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.4.2.tgz", - "integrity": "sha512-wHiPU+PciyG6L7oGglUq22ji+aV5SFwef/gF/rnIheMirzxpDlHq+K8GwqmcrrFu3GWRioQGRe3rr8KAalOQrg==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.5.0.tgz", + "integrity": "sha512-mRiLBPcY5vC1xi21pPqzMtp1HY9FOOFajkiuSArqnwtiyp2fxqWVombuVE9lTB2UyBl9bL8XXwrpjzDftIbnBg==", "dev": true, + "license": "SEE LICENSE IN LICENSE", "dependencies": { "@sap/cds-compiler": ">=5.1", "@sap/cds-fiori": "^1", From 5eaec3875cb177efd766d23fdee220dafd2ec950 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 06:26:31 +0000 Subject: [PATCH 2/7] build(deps-dev): bump @eslint/js from 9.15.0 to 9.16.0 (#354) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e6e73017..2c992f80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -713,10 +713,11 @@ } }, "node_modules/@eslint/js": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", - "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2935,6 +2936,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", + "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", From 5ab52f1a53ee191dc7894c2d27d5e27a8d80b8b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 06:28:26 +0000 Subject: [PATCH 3/7] build(deps-dev): bump eslint from 9.15.0 to 9.16.0 (#355) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c992f80..69825b87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2850,17 +2850,18 @@ } }, "node_modules/eslint": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.15.0.tgz", - "integrity": "sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", + "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.9.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.15.0", + "@eslint/js": "9.16.0", "@eslint/plugin-kit": "^0.2.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -2936,16 +2937,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", - "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", From abef4b015fdd98d32d669b8ea9ab8e12d4ebbe94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 06:30:28 +0000 Subject: [PATCH 4/7] build(deps-dev): bump @types/node from 22.10.0 to 22.10.1 (#350) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.0 to 22.10.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69825b87..309e40cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1550,9 +1550,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { - "version": "22.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", - "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "license": "MIT", "dependencies": { "undici-types": "~6.20.0" From c534a242a9b523017dd70c80a0c9513ffb388123 Mon Sep 17 00:00:00 2001 From: Ludwig Stockbauer-Muhr <35834861+stockbal@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:54:13 +0100 Subject: [PATCH 5/7] feat: adds `log` to `cds.env` (#353) --- CHANGELOG.md | 1 + apis/env.d.ts | 8 ++++++++ test/typescript/apis/project/cds-env.ts | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7717216..18528b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). The format is based on [Keep a Changelog](http://keepachangelog.com/). ## Version 0.9.0 - tbd +- Adds missing properties for `log` in `cds.env` ## Version 0.8.0 - 24-11-26 diff --git a/apis/env.d.ts b/apis/env.d.ts index ba4a4c84..60ecda8b 100644 --- a/apis/env.d.ts +++ b/apis/env.d.ts @@ -1,3 +1,5 @@ +import { levels } from './log' + /** * Access to the configuration for Node.js runtime and tools. * The object is the effective result of configuration merged from various sources, @@ -14,6 +16,12 @@ export const env: { [key: string]: any, }, profiles: string[], + log: { + user: boolean, + levels: Record>, + als_custom_fields: Record, + cls_custom_fields: string[], + }, requires: env.Requires, folders: { app: string, diff --git a/test/typescript/apis/project/cds-env.ts b/test/typescript/apis/project/cds-env.ts index 433e8e92..83d92aee 100644 --- a/test/typescript/apis/project/cds-env.ts +++ b/test/typescript/apis/project/cds-env.ts @@ -9,6 +9,11 @@ env.folders.foo = '' env.build = '' env.hana = '' +env.log.levels['cli'] === 'debug' +env.log.cls_custom_fields.length +env.log.als_custom_fields['query'] === 0 +Object.keys(env.log.als_custom_fields) + env.requires.auth.kind = '' env.requires.auth.credentials!.url = '' env.requires.auth.credentials!.clientid = '' From 59216fbc34528aec0b1ad31a0b41d28a89e11c8b Mon Sep 17 00:00:00 2001 From: Ludwig Stockbauer-Muhr <35834861+stockbal@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:55:29 +0100 Subject: [PATCH 6/7] fix: use `Required` instead of `DeepRequired` in projection function (#349) Co-authored-by: Daniel O'Grady Co-authored-by: Daniel O'Grady <103028279+daogrady@users.noreply.github.com> --- CHANGELOG.md | 4 ++++ apis/internal/query.d.ts | 4 ++-- test/typescript/apis/project/cds-ql.ts | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18528b5f..9344930c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). ## Version 0.9.0 - tbd - Adds missing properties for `log` in `cds.env` +### Fixed + +- Use `Required` instead of `DeepRequired` in projection function to avoid complexity errors from TypeScript + ## Version 0.8.0 - 24-11-26 ### Fixed diff --git a/apis/internal/query.d.ts b/apis/internal/query.d.ts index 035558a9..9c89be20 100644 --- a/apis/internal/query.d.ts +++ b/apis/internal/query.d.ts @@ -3,7 +3,7 @@ import type { entity } from '../linked/classes' import type { column_expr, ref } from '../cqn' import type { ArrayConstructable, Constructable, SingularInstanceType, Unwrap, UnwrappedInstanceType } from './inference' import { ConstructedQuery } from '../ql' -import { KVPairs, DeepRequired } from './util' +import { KVPairs } from './util' // https://cap.cloud.sap/docs/node.js/cds-ql?q=projection#projection-functions type Projection = (e: QLExtensions : T>) => void @@ -168,7 +168,7 @@ export interface InUpsert { } // don't wrap QLExtensions in more QLExtensions (indirection to work around recursive definition) -export type QLExtensions = T extends QLExtensions_ ? T : QLExtensions_> +export type QLExtensions = T extends QLExtensions_ ? T : QLExtensions_> /** * QLExtensions are properties that are attached to entities in CQL contexts. diff --git a/test/typescript/apis/project/cds-ql.ts b/test/typescript/apis/project/cds-ql.ts index c9e09cac..9efe9247 100644 --- a/test/typescript/apis/project/cds-ql.ts +++ b/test/typescript/apis/project/cds-ql.ts @@ -213,6 +213,11 @@ SELECT.from(Foos).columns(f => { const number: QLExtensions = f.x }) +// deep projection nesting +SELECT.from(Foos, f => f.ref(r => r.ref(r => r.ref(r => { + const x: number = r.x +})))) + // @ts-expect-error invalid key of result line SELECT.from(Foos).columns(['entityIDColumn', 'parentIDColumn']).then(r => r[0].some) SELECT.from(Foos).columns(['entityIDColumn', 'parentIDColumn']).then(r => r[0].ref) From 3c27b65482212cea79fb485cd1f90b0abc055889 Mon Sep 17 00:00:00 2001 From: Ludwig Stockbauer-Muhr <35834861+stockbal@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:23:24 +0100 Subject: [PATCH 7/7] fix: add missing type inference to `.set`/`.with` of `UPDATE` (#352) --- CHANGELOG.md | 3 ++ apis/ql.d.ts | 41 ++++++++++++++------------ test/typescript/apis/project/cds-ql.ts | 34 +++++++++++++++++++-- test/typescript/apis/project/dummy.ts | 1 + 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9344930c..b5bbd134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). - Use `Required` instead of `DeepRequired` in projection function to avoid complexity errors from TypeScript +### Fixed +- Added missing type inference for `.set`/`.with` of `UPDATE` + ## Version 0.8.0 - 24-11-26 ### Fixed diff --git a/apis/ql.d.ts b/apis/ql.d.ts index d5490b8e..94827b0f 100644 --- a/apis/ql.d.ts +++ b/apis/ql.d.ts @@ -62,7 +62,7 @@ export declare class QL { & ((...entries: object[]) => UPSERT) & ((entries: object[]) => UPSERT) UPDATE: typeof UPDATE - & typeof UPDATE.entity<_TODO> + & typeof UPDATE.entity DELETE: typeof DELETE & ((...entries: object[]) => DELETE) & ((entries: object[]) => DELETE) @@ -231,34 +231,37 @@ export class DELETE extends ConstructedQuery { DELETE: CQN.DELETE['DELETE'] } +// operator for qbe expression +type QbeOp = '=' | '-=' | '+=' | '*=' | '/=' | '%=' export interface UPDATE extends Where, And, ByKey {} export class UPDATE extends ConstructedQuery { private constructor(); - // cds-typer plural - // FIXME: this returned UPDATE> before. should UPDATE.entity(...) return Book or Books? - static entity (entity: T, primaryKey?: PK): UPDATE> - - static entity (entity: EntityDescription, primaryKey?: PK): UPDATE - - static entity (entity: T, primaryKey?: PK): UPDATE - - // currently no easy way to restrict T from being a primitive type - static entity (entity: T, primaryKey?: PK): UPDATE - - // with (block: (e:T)=>void) : this - // set (block: (e:T)=>void) : this - set: TaggedTemplateQueryPart - & ((data: object) => this); - - with: TaggedTemplateQueryPart - & ((data: object) => this) + static entity: (TaggedTemplateQueryPart>) + // UPDATE> is used here so type inference in set/with has the property keys of the singular type + & ( (entity: T, primaryKey?: PK) => UPDATE>) + & ( (entity: T, primaryKey?: PK) => UPDATE>) + & ((entity: EntityDescription, primaryKey?: PK) => UPDATE) + & ( (entity: T, primaryKey?: PK) => UPDATE) + set: UpdateSet + with: UpdateSet + UPDATE: CQN.UPDATE['UPDATE'] } +/** + * Represents updatable block that can be passed to either `.set` or `.with` + * of an `UPDATE` query + */ +type UpdateSet = TaggedTemplateQueryPart + // simple value > title: 'Some Title' + // qbe expression > stock: { '-=': quantity } + // cqn expression > descr: {xpr: [{ref:[descr]}, '||', 'Some addition to descr.']} + & ((data: {[P in keyof T]?: T[P] | {[op in QbeOp]?: T[P]} | CQN.xpr}) => This) + export class CREATE extends ConstructedQuery { private constructor(); diff --git a/test/typescript/apis/project/cds-ql.ts b/test/typescript/apis/project/cds-ql.ts index 9efe9247..c0b7a4b9 100644 --- a/test/typescript/apis/project/cds-ql.ts +++ b/test/typescript/apis/project/cds-ql.ts @@ -1,4 +1,5 @@ import { QLExtensions } from '../../../../apis/ql' +import { linked } from '../../../../apis/models'; import { Foo, Foos, attach } from './dummy' // @ts-expect-error - only supposed to be used statically, constructors private @@ -94,11 +95,11 @@ ins.columns("x") // x was suggested by code completion ins.INSERT.into === "foo" INSERT.into("Bla").as(SELECT.from("Foo")) -let upd: UPDATE +let upd: UPDATE upd = UPDATE(Foo, 42) -upd.set({}) +upd.set({x:4}) upd = UPDATE.entity(Foos) -upd.set({}) +upd.set({x:1}) upd.UPDATE.entity === "foo" let ups:UPSERT @@ -283,3 +284,30 @@ INSERT.into('Foos').rows([[1,2,3]]) INSERT.into('Foos').rows([[1,2,3],[1,2]]) // @ts-expect-error INSERT.into('Foos').values([[1,2,3]]) + +// UPDATE: checks with typed classes +UPDATE(Foo, 42).set({ x: 4}).where({ x: 44 }) +UPDATE(Foos, 42).set({ x: 4}).where({ x: 44 }) +// @ts-expect-error - invalid property of Foo +UPDATE(Foos, 4).set({ aa: 4 }); +// @ts-expect-error - invalid property type of Foo.x +UPDATE(Foo).where({ x: 4 }).set({ x: 'asdf', ref: { x: 4 }}) +UPDATE(Foos).where({ x: 4 }).set({ x: 4, ref: { x: 4 }}) +UPDATE.entity(Foos).set({ x: 4}); + +UPDATE.entity(Foos).set({ + x: {'+=': 4 }, + ref: { x: 5 }, + y: { xpr: [{ ref: ["asdf"] }, "||", "asdf"] } +}); + +// @ts-expect-error - invalid operator of qbe expression +UPDATE(Foo).with({x: {'--': 4}}) + +// @ts-expect-error - invalid property name of xpr +UPDATE(Foos).with({x: {xpr: [{funcs: ""}]}}) + +// untyped, no syntax errors +UPDATE.entity("Foos").set({ test: {xp: "4"} }); +UPDATE.entity({} as linked.classes.entity).set({ asdf: 434 }); +UPDATE`Foos`.set`x = 4`.where`x > 10` \ No newline at end of file diff --git a/test/typescript/apis/project/dummy.ts b/test/typescript/apis/project/dummy.ts index 9f0762e4..f072d3ae 100644 --- a/test/typescript/apis/project/dummy.ts +++ b/test/typescript/apis/project/dummy.ts @@ -6,6 +6,7 @@ export class Foo { static readonly drafts: typeof Foo x: number = 42 + y?: string ref?: Foo refs?: Foo[] }