Skip to content

Commit

Permalink
[patch] preserve optional properties in SelectFrom
Browse files Browse the repository at this point in the history
  • Loading branch information
electrovir committed Dec 10, 2024
1 parent d0d5e51 commit bf4fd7d
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 70 deletions.
48 changes: 24 additions & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
4 changes: 2 additions & 2 deletions packages/assert/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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",
Expand Down
6 changes: 3 additions & 3 deletions packages/common/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function selectCollapsedFrom<
return collapseObject(selected, selectionSet) as PickCollapsedSelection<Full, Selection>;
}

function collapseObject(input: Readonly<AnyObject>, selectionSet: unknown): AnyObject {
function collapseObject(input: any, selectionSet: unknown): AnyObject {
if (shouldPreserveInSelectionSet(input)) {
return input;
}
Expand Down
36 changes: 36 additions & 0 deletions packages/common/src/augments/selection-set/select-from.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>;
};
};
};

assert
.tsType<
SelectFrom<
ExampleWithOptional,
{
b: true;
c: {
d: true;
e: true;
};
}
>
>()
.slowEquals<{
b?: number;
c: {
d?: RegExp;
e?: {
f?: Set<string>;
};
};
}>();
});

it('has proper types', () => {
selectFrom(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('PickSelection', () => {
>
>()
.equals<{
top:
top?:
| undefined
| {
mid: {low: string[]};
Expand Down
61 changes: 40 additions & 21 deletions packages/common/src/augments/selection-set/selection-set.ts
Original file line number Diff line number Diff line change
@@ -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}. */
Expand All @@ -21,6 +27,16 @@ export type GenericSelectionSet = {
[Key in PropertyKey]: unknown;
};

type MakeKeysOptional<Full extends AnyObject, T extends AnyObject> =
IsNever<Extract<OptionalKeysOf<Full>, keyof T>> extends true
? /** No optional keys. */
{[Key in keyof T]: T[Key]}
: IsNever<Extract<RequiredKeysOf<Full>, keyof T>> extends true
? /** Only optional keys. */ {[Key in keyof T]?: T[Key]}
: /** Optional and required keys. */ {
[Key in Extract<RequiredKeysOf<Full>, keyof T>]: T[Key];
} & {[Key in Extract<OptionalKeysOf<Full>, keyof T>]?: T[Key]};

/**
* Performs a SQL-like nested selection on an object, extracting the selected values. This produces
* the output type for `selectFrom`.
Expand All @@ -40,21 +56,24 @@ export type SelectFrom<
| SelectFrom<Extract<Element, AnyObject>, Selection, TsRecurse<Depth>>
| Exclude<Element, AnyObject>
)[]
: {
-readonly [Key in keyof Selection as Selection[Key] extends false
? never
: Key extends keyof Full
? Key
: never]:
| (Selection[Key] extends GenericSelectionSet
? SelectFrom<
NonNullable<Extract<Full[Key], AnyObject>>,
Selection[Key],
TsRecurse<Depth>
>
: Full[Key])
| Exclude<Full[Key], AnyObject>;
};
: 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<Extract<Full[Key], AnyObject>>,
Selection[Key],
TsRecurse<Depth>
>
: Full[Key])
| Exclude<Full[Key], AnyObject>;
}
>;

/**
* Defines a selection set for a given object type. This is used in {@link SelectFrom}.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
8 changes: 4 additions & 4 deletions packages/node/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -37,16 +37,16 @@
"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",
"type-fest": "^4.29.0",
"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",
Expand Down
10 changes: 5 additions & 5 deletions packages/scripts/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand All @@ -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"
},
Expand Down
Loading

0 comments on commit bf4fd7d

Please sign in to comment.