diff --git a/package-lock.json b/package-lock.json index efa74c13..a0e1dca7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@augment-vir/mono-repo-root", - "version": "31.1.0", + "version": "31.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@augment-vir/mono-repo-root", - "version": "31.1.0", + "version": "31.1.1", "hasInstallScript": true, "license": "(MIT or CC0 1.0)", "workspaces": [ @@ -18940,10 +18940,10 @@ }, "packages/assert": { "name": "@augment-vir/assert", - "version": "31.1.0", + "version": "31.1.1", "license": "(MIT or CC0 1.0)", "dependencies": { - "@augment-vir/core": "^31.1.0", + "@augment-vir/core": "^31.1.1", "@date-vir/duration": "^7.0.1", "deep-eql": "^5.0.2", "expect-type": "^1.1.0", @@ -18978,11 +18978,11 @@ }, "packages/common": { "name": "@augment-vir/common", - "version": "31.1.0", + "version": "31.1.1", "license": "(MIT or CC0 1.0)", "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/core": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/core": "^31.1.1", "@date-vir/duration": "^7.0.1", "ansi-styles": "^6.2.1", "json5": "^2.2.3", @@ -19017,7 +19017,7 @@ }, "packages/core": { "name": "@augment-vir/core", - "version": "31.1.0", + "version": "31.1.1", "license": "(MIT or CC0 1.0)", "dependencies": { "@date-vir/duration": "^7.0.1", @@ -19048,11 +19048,11 @@ }, "packages/node": { "name": "@augment-vir/node", - "version": "31.1.0", + "version": "31.1.1", "license": "(MIT or CC0 1.0)", "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", "@date-vir/duration": "^7.0.1", "ansi-styles": "^6.2.1", "terminate": "^2.8.0", @@ -19060,7 +19060,7 @@ "typed-event-target": "^4.0.2" }, "devDependencies": { - "@augment-vir/test": "^31.1.0", + "@augment-vir/test": "^31.1.1", "@prisma/client": "^5.22.0", "@types/node": "^22.10.0", "@web/dev-server-esbuild": "^1.0.3", @@ -19091,18 +19091,18 @@ }, "packages/scripts": { "name": "@augment-vir/scripts", - "version": "31.1.0", + "version": "31.1.1", "license": "(MIT or CC0 1.0)", "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", - "@augment-vir/node": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", + "@augment-vir/node": "^31.1.1", "@virmator/docs": "^13.10.3", "jsdom": "^25.0.1", "typedoc": "^0.27.0" }, "devDependencies": { - "@augment-vir/test": "^31.1.0", + "@augment-vir/test": "^31.1.1", "@types/jsdom": "^21.1.7", "@types/node": "^22.10.0" }, @@ -19112,11 +19112,11 @@ }, "packages/test": { "name": "@augment-vir/test", - "version": "31.1.0", + "version": "31.1.1", "license": "(MIT or CC0 1.0)", "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", "@open-wc/testing-helpers": "^3.0.1", "@virmator/test": "^13.10.3", "type-fest": "^4.29.0" @@ -19150,17 +19150,17 @@ }, "packages/web": { "name": "@augment-vir/web", - "version": "31.1.0", + "version": "31.1.1", "license": "(MIT or CC0 1.0)", "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", "@date-vir/duration": "^7.0.1", "html-spec-tags": "^2.2.1", "type-fest": "^4.29.0" }, "devDependencies": { - "@augment-vir/test": "^31.1.0", + "@augment-vir/test": "^31.1.1", "bowser": "^2.11.0", "typescript": "^5.6.3" }, diff --git a/package.json b/package.json index d125e8dd..34e5d547 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/mono-repo-root", - "version": "31.1.0", + "version": "31.1.1", "private": true, "homepage": "https://github.com/electrovir/augment-vir", "bugs": { diff --git a/packages/assert/package.json b/packages/assert/package.json index 3211ecf3..9a042da9 100644 --- a/packages/assert/package.json +++ b/packages/assert/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/assert", - "version": "31.1.0", + "version": "31.1.1", "description": "A collection of assertions for test and production code alike.", "keywords": [ "augment", @@ -41,7 +41,7 @@ "test:update": "npm test" }, "dependencies": { - "@augment-vir/core": "^31.1.0", + "@augment-vir/core": "^31.1.1", "@date-vir/duration": "^7.0.1", "deep-eql": "^5.0.2", "expect-type": "^1.1.0", diff --git a/packages/common/package.json b/packages/common/package.json index 330822c6..0912b8ab 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/common", - "version": "31.1.0", + "version": "31.1.1", "description": "A collection of augments, helpers types, functions, and classes for any JavaScript environment.", "keywords": [ "augment", @@ -39,8 +39,8 @@ "test:web": "virmator --no-deps test web" }, "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/core": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/core": "^31.1.1", "@date-vir/duration": "^7.0.1", "ansi-styles": "^6.2.1", "json5": "^2.2.3", diff --git a/packages/common/src/augments/selection-set/select-collapsed.ts b/packages/common/src/augments/selection-set/select-collapsed.ts index 362d8a69..1021478c 100644 --- a/packages/common/src/augments/selection-set/select-collapsed.ts +++ b/packages/common/src/augments/selection-set/select-collapsed.ts @@ -62,7 +62,7 @@ export function selectCollapsedFrom< return collapseObject(selected, selectionSet) as PickCollapsedSelection; } -function collapseObject(input: Readonly, selectionSet: unknown): AnyObject { +function collapseObject(input: any, selectionSet: unknown): AnyObject { if (shouldPreserveInSelectionSet(input)) { return input; } diff --git a/packages/common/src/augments/selection-set/select-from.test.ts b/packages/common/src/augments/selection-set/select-from.test.ts index 601483bb..a6f273c2 100644 --- a/packages/common/src/augments/selection-set/select-from.test.ts +++ b/packages/common/src/augments/selection-set/select-from.test.ts @@ -4,6 +4,42 @@ import {selectFrom} from './select-from.js'; import {SelectFrom} from './selection-set.js'; describe(selectFrom.name, () => { + it('preserves nested optional properties', () => { + type ExampleWithOptional = { + a: string; + b?: number; + c: { + d?: RegExp; + e?: { + f?: Set; + }; + }; + }; + + assert + .tsType< + SelectFrom< + ExampleWithOptional, + { + b: true; + c: { + d: true; + e: true; + }; + } + > + >() + .slowEquals<{ + b?: number; + c: { + d?: RegExp; + e?: { + f?: Set; + }; + }; + }>(); + }); + it('has proper types', () => { selectFrom( { diff --git a/packages/common/src/augments/selection-set/selection-set.test.ts b/packages/common/src/augments/selection-set/selection-set.test.ts index 44f6a21b..43a397ba 100644 --- a/packages/common/src/augments/selection-set/selection-set.test.ts +++ b/packages/common/src/augments/selection-set/selection-set.test.ts @@ -67,7 +67,7 @@ describe('PickSelection', () => { > >() .equals<{ - top: + top?: | undefined | { mid: {low: string[]}; diff --git a/packages/common/src/augments/selection-set/selection-set.ts b/packages/common/src/augments/selection-set/selection-set.ts index 7bd3769c..2ddc8cc5 100644 --- a/packages/common/src/augments/selection-set/selection-set.ts +++ b/packages/common/src/augments/selection-set/selection-set.ts @@ -1,10 +1,16 @@ -import type {AnyObject} from '@augment-vir/core'; -import {IsAny, IsNever, Primitive, UnionToIntersection} from 'type-fest'; +import {type AnyObject, type RequiredKeysOf} from '@augment-vir/core'; import { - TsRecurse, - TsRecursionStart, - TsRecursionTracker, - TsTooMuchRecursion, + type IsAny, + type IsNever, + type OptionalKeysOf, + type Primitive, + type UnionToIntersection, +} from 'type-fest'; +import { + type TsRecurse, + type TsRecursionStart, + type TsRecursionTracker, + type TsTooMuchRecursion, } from '../type/type-recursion.js'; /** All types that won't be recursed into when defining a {@link SelectionSet}. */ @@ -21,6 +27,16 @@ export type GenericSelectionSet = { [Key in PropertyKey]: unknown; }; +type MakeKeysOptional = + IsNever, keyof T>> extends true + ? /** No optional keys. */ + {[Key in keyof T]: T[Key]} + : IsNever, keyof T>> extends true + ? /** Only optional keys. */ {[Key in keyof T]?: T[Key]} + : /** Optional and required keys. */ { + [Key in Extract, keyof T>]: T[Key]; + } & {[Key in Extract, keyof T>]?: T[Key]}; + /** * Performs a SQL-like nested selection on an object, extracting the selected values. This produces * the output type for `selectFrom`. @@ -40,21 +56,24 @@ export type SelectFrom< | SelectFrom, Selection, TsRecurse> | Exclude )[] - : { - -readonly [Key in keyof Selection as Selection[Key] extends false - ? never - : Key extends keyof Full - ? Key - : never]: - | (Selection[Key] extends GenericSelectionSet - ? SelectFrom< - NonNullable>, - Selection[Key], - TsRecurse - > - : Full[Key]) - | Exclude; - }; + : MakeKeysOptional< + Full, + { + -readonly [Key in keyof Selection as Selection[Key] extends false + ? never + : Key extends keyof Full + ? Key + : never]: + | (Selection[Key] extends GenericSelectionSet + ? SelectFrom< + NonNullable>, + Selection[Key], + TsRecurse + > + : Full[Key]) + | Exclude; + } + >; /** * Defines a selection set for a given object type. This is used in {@link SelectFrom}. diff --git a/packages/core/package.json b/packages/core/package.json index 09b156cd..6884296d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/core", - "version": "31.1.0", + "version": "31.1.1", "description": "Core augment-vir augments. Use @augment-vir/common instead.", "homepage": "https://github.com/electrovir/augment-vir", "bugs": { diff --git a/packages/node/package.json b/packages/node/package.json index 7692c28b..1249d2c8 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/node", - "version": "31.1.0", + "version": "31.1.1", "description": "A collection of augments, helpers types, functions, and classes only for Node.js (backend) JavaScript environments.", "keywords": [ "augment", @@ -37,8 +37,8 @@ "test:update": "npm test" }, "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", "@date-vir/duration": "^7.0.1", "ansi-styles": "^6.2.1", "terminate": "^2.8.0", @@ -46,7 +46,7 @@ "typed-event-target": "^4.0.2" }, "devDependencies": { - "@augment-vir/test": "^31.1.0", + "@augment-vir/test": "^31.1.1", "@prisma/client": "^5.22.0", "@types/node": "^22.10.0", "@web/dev-server-esbuild": "^1.0.3", diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 83c9f15d..9951b233 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/scripts", - "version": "31.1.0", + "version": "31.1.1", "private": true, "homepage": "https://github.com/electrovir/augment-vir", "bugs": { @@ -24,15 +24,15 @@ "test:update": "npm test" }, "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", - "@augment-vir/node": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", + "@augment-vir/node": "^31.1.1", "@virmator/docs": "^13.10.3", "jsdom": "^25.0.1", "typedoc": "^0.27.0" }, "devDependencies": { - "@augment-vir/test": "^31.1.0", + "@augment-vir/test": "^31.1.1", "@types/jsdom": "^21.1.7", "@types/node": "^22.10.0" }, diff --git a/packages/test/package.json b/packages/test/package.json index a31cef3b..78a39fde 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/test", - "version": "31.1.0", + "version": "31.1.1", "description": "A universal testing suite that works with Mocha style test runners _and_ Node.js's built-in test runner.", "keywords": [ "test", @@ -42,8 +42,8 @@ "test:web": "virmator test --no-deps web 'src/test-web/**/*.test.ts' 'src/augments/universal-testing-suite/**/*.test.ts'" }, "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", "@open-wc/testing-helpers": "^3.0.1", "@virmator/test": "^13.10.3", "type-fest": "^4.29.0" diff --git a/packages/web/package.json b/packages/web/package.json index 98c311bf..9c616d0b 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@augment-vir/web", - "version": "31.1.0", + "version": "31.1.1", "description": "A collection of augments, helpers types, functions, and classes only for web (frontend) JavaScript environments.", "keywords": [ "augment", @@ -35,14 +35,14 @@ "test:update": "npm test" }, "dependencies": { - "@augment-vir/assert": "^31.1.0", - "@augment-vir/common": "^31.1.0", + "@augment-vir/assert": "^31.1.1", + "@augment-vir/common": "^31.1.1", "@date-vir/duration": "^7.0.1", "html-spec-tags": "^2.2.1", "type-fest": "^4.29.0" }, "devDependencies": { - "@augment-vir/test": "^31.1.0", + "@augment-vir/test": "^31.1.1", "bowser": "^2.11.0", "typescript": "^5.6.3" },