Skip to content

Commit 9b7b981

Browse files
committed
fix(cbjs): fix regression in cluster type when a property is a union
1 parent 3bc8f96 commit 9b7b981

File tree

5 files changed

+40
-36
lines changed

5 files changed

+40
-36
lines changed

packages/cbjs/src/services/kv/mutateIn/ChainableMutateIn.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ export class ChainableMutateIn<
166166
*/
167167
insert<
168168
const Path extends MutateInInsertPath<CollectionOptions<C>, Def>,
169-
Value extends MutateInInsertValue<CollectionOptions<C>, Def, NoInfer<Path>>,
169+
Value extends MutateInInsertValue<CollectionOptions<C>, Def, Path>,
170170
>(
171171
path: Path,
172-
value: NoInfer<Value>,
172+
value: Value,
173173
options?: MutateInInsertOptions
174174
): ChainableMutateIn<C, Key, [...SpecResults, undefined]> {
175175
const spec = MutateInSpec.insert(path, value, options);

packages/deploy/src/clusterChanges/applyCouchbaseClusterChanges.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Cluster, keyspacePath } from '@cbjsdev/cbjs';
22
import {
33
CouchbaseHttpApiConfig,
44
createQueryIndex,
5-
getUser,
65
updateQueryIndex,
76
updateUserPassword,
87
waitForBucket,

packages/shared/src/couchbase/clusterTypes/utils/path-utils.types.spec-d.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ describe('ReplaceCodeCompletion', () => {
541541
NoOptions,
542542
{ title: string; description?: string; metadata?: { tags: string[] } }
543543
>;
544+
544545
expectTypeOf<Test>().toEqualTypeOf<
545546
| ['title', string]
546547
| ['description', string]
@@ -1068,15 +1069,20 @@ describe('DocumentCodeCompletionTest', () => {
10681069

10691070
test('document with unions', () => {
10701071
type TestDoc = {
1071-
events: { type: 'a'; payload: 'pa' } | { type: 'b'; payload: 'pb' };
1072+
events:
1073+
| { type: 'a'; propA: { title: string } }
1074+
| { type: 'b'; propB: { status: string } };
10721075
};
10731076
type Test = DocumentCodeCompletionTest<'get', NoOptions, TestDoc>;
10741077

10751078
expectTypeOf<Test>().toEqualTypeOf<
10761079
| [``, TestDoc]
10771080
| [`events`, TestDoc['events']]
10781081
| [`events.type`, 'a' | 'b']
1079-
| [`events.payload`, 'pa' | 'pb']
1082+
| [`events.propA`, { title: string }]
1083+
| [`events.propA.title`, string]
1084+
| [`events.propB`, { status: string }]
1085+
| [`events.propB.status`, string]
10801086
>();
10811087
});
10821088
});

packages/shared/src/couchbase/clusterTypes/utils/path-utils.types.ts

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */
18-
import { IfStrict, IsNever, Not, Split } from '../../../misc/index.js';
18+
import { IfStrict, IsNever, Not, Split, UnionKeys } from '../../../misc/index.js';
1919
import { DefaultKeyspaceOptions } from '../cluster.types.js';
2020
import type { IsFuzzyDocument } from '../document.types.js';
2121
import {
@@ -123,7 +123,7 @@ type CCPerfectMatchPath<CC, UserPath> =
123123
* When the user path matches a string template, it doesn't mean the path is valid.
124124
* For example, given `[string, ...number[]]` for a `binary` operation, code completion path will include `arr[${number}]`.
125125
* So `arr[0]` will match the path, and yet, it is not a valid path because arr[0] is not a number.
126-
* Returns `true` if the path is valid.
126+
* @returns `true` if the path is valid.
127127
*/
128128
// prettier-ignore
129129
export type IsLegalPath<Op extends KvOperation, Options, Doc, Path> =
@@ -204,16 +204,14 @@ type PTO<
204204
Key,
205205
> =
206206
[FriendlyPath] extends [true] ?
207-
OptionFriendlyPathRecordKey<Options> extends true ?
208-
IsTemplateString<Key> extends true ?
209-
[true, `${ConcatPath<PathTo, OptionRecordFriendlyPlaceholder<Options>>}`] :
210-
[true, ConcatPath<PathTo, Key>] :
207+
IsTemplateString<Key> extends true ?
208+
[true, ConcatPath<PathTo, '#'>] :
211209
[true, ConcatPath<PathTo, Key>] :
212210
[FriendlyPath] extends [false] ?
213211
[false, ConcatPath<PathTo, Key>] :
214212
OptionFriendlyPathRecordKey<Options> extends true ?
215213
IsTemplateString<Key> extends true ?
216-
[false, `${ConcatPath<PathTo, Key>}`] | [true, ConcatPath<PathTo, OptionRecordFriendlyPlaceholder<Options>>] :
214+
[false, ConcatPath<PathTo, Key>] | [true, ConcatPath<PathTo, '#'>] :
217215
[boolean, ConcatPath<PathTo, Key>] :
218216
[boolean, ConcatPath<PathTo, Key>]
219217
;
@@ -233,15 +231,20 @@ export type Keys<T> =
233231

234232
// prettier-ignore
235233
export type Get<T, K> =
236-
K extends -1 ?
237-
T extends ReadonlyArray<unknown> ?
234+
T extends ReadonlyArray<unknown> ?
235+
K extends -1 ?
238236
ArrayLastElement<T> :
237+
K extends number ?
238+
T[K] :
239239
never :
240-
K extends keyof Extract<T, object> ?
241-
Extract<T, object>[K] :
240+
K extends string | number ?
241+
Extract<T, { [Key in K]?: unknown }>[K] :
242242
never
243243
;
244244

245+
type TG = Get<{ title?: string } | { status: string }, 'status'>;
246+
type TTG = Extract<{ title: string } | { status: string }, { [Key in 'title']: any }>
247+
245248
// prettier-ignore
246249
export type DocumentCodeCompletion<Op extends KvOperation, Options, T> =
247250
T extends object ?
@@ -251,18 +254,17 @@ export type DocumentCodeCompletion<Op extends KvOperation, Options, T> =
251254
never
252255
;
253256

254-
type BorrowId = `b::${string}`;
255-
type UserId = `user::${number}`;
256-
type User = {
257-
br?: Record<
258-
BorrowId,
259-
{
260-
at: number;
261-
}
262-
>;
263-
};
257+
type TestDoc = { title: string } | { status: string };
258+
type TBB = BuildBag<'get', NonNullable<unknown>, false, 'events', TestDoc, []>;
264259

265-
type TBB = BuildBag<'remove', DefaultKeyspaceOptions, boolean, '', User, []>;
260+
// prettier-ignore
261+
type TTK =
262+
Keys<TestDoc> extends infer KeyTuple ?
263+
KeyTuple extends [infer Key] ?
264+
Get<TestDoc, Key> :
265+
never :
266+
never
267+
;
266268

267269
// prettier-ignore
268270
type BuildBag<Op extends KvOperation, Options, FriendlyPath, PathToDoc, Doc, UnionStack extends ReadonlyArray<unknown>> =
@@ -272,16 +274,13 @@ type BuildBag<Op extends KvOperation, Options, FriendlyPath, PathToDoc, Doc, Uni
272274
Keys<Doc> extends infer KeyTuple ?
273275
KeyTuple extends [infer Key] ?
274276
Get<Doc, Key> extends infer SubDoc ?
275-
276277
PathToKey<Options, FriendlyPath, Doc, PathToDoc, Key> extends infer PTK ?
277278
PTK extends [infer BuildFriendly, infer Path] ?
278-
// [PTK, SubDoc] | (PTK extends [infer BuildFriendly, infer Path] ?
279-
BuildBag<Op, Options, BuildFriendly, Path, SubDoc, [
280-
...UnionStack,
281-
CodeCompletion<Op, BuildFriendly, Doc, Key, Path, SubDoc>
282-
]> :
283-
// never):
284-
never :
279+
BuildBag<Op, Options, BuildFriendly, Path, SubDoc, [
280+
...UnionStack,
281+
CodeCompletion<Op, BuildFriendly, Doc, Key, Path, SubDoc>
282+
]> :
283+
never :
285284
never :
286285
never :
287286
UnionStack :

packages/shared/src/couchbase/clusterTypes/utils/string-utils.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export type TimestampSeconds = `${number}`;
3737
export type IsTemplateString<T> =
3838
T extends string ?
3939
IsTemplateStringHead<T> extends true ? true : IsTemplateStringTail<T> :
40-
never
40+
false
4141
;
4242

4343
export type IsTemplateStringTail<T extends string> = `A${T}` extends T ? true : false;

0 commit comments

Comments
 (0)