Skip to content

Commit f36b7c0

Browse files
committed
feat: infer sheet context based on provided schema & selected columns
1 parent 4820d7f commit f36b7c0

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

example.xlsx

-9.59 KB
Binary file not shown.

src/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import xlsx, { type IColumn, type IJsonSheet, getWorksheetColumnWidths } from 'j
33
import type { CellStyle } from 'xlsx-js-style'
44
import XLSX from 'xlsx-js-style'
55
import { deepmerge } from 'deepmerge-ts'
6-
import type { CellValue, Column, ColumnGroup, ExcelSchema, GenericObject, NestedPaths, Not, Sheet, TransformersMap, ValueTransformer } from './types'
6+
import type { CellValue, Column, ColumnGroup, ExcelSchema, GenericObject, NestedPaths, Not, SchemaColumnKeys, Sheet, TransformersMap, ValueTransformer } from './types'
77
import { formatKey, getPropertyFromPath, getSheetCellKey } from './utils'
88

99
export class ExcelSchemaBuilder<
@@ -85,7 +85,7 @@ export class ExcelSchemaBuilder<
8585
}
8686

8787
export class ExcelBuilder<UsedSheetKeys extends string = never> {
88-
private sheets: Array<Sheet<any, ExcelSchema<any, any, any>>> = []
88+
private sheets: Array<Sheet<any, ExcelSchema<any, any, any>, any, any>> = []
8989

9090
public static create(): ExcelBuilder {
9191
return new ExcelBuilder()
@@ -95,9 +95,11 @@ export class ExcelBuilder<UsedSheetKeys extends string = never> {
9595
Key extends string,
9696
T extends GenericObject,
9797
Schema extends ExcelSchema<T, any, string>,
98+
ColKeys extends SchemaColumnKeys<Schema>,
99+
SelectCols extends { [key in ColKeys]?: boolean } = {},
98100
>(
99101
key: Not<Key, UsedSheetKeys>,
100-
sheet: Omit<Sheet<T, Schema>, 'sheetKey'>,
102+
sheet: Omit<Sheet<T, Schema, ColKeys, SelectCols>, 'sheetKey'>,
101103
): ExcelBuilder<UsedSheetKeys | Key> {
102104
if (this.sheets.some(s => s.sheetKey === key))
103105
throw new Error(`Sheet with key '${key}' already exists.`)

src/types.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export type TypeFromPath<T extends GenericObject, Path extends string> =
2727
: never
2828
: never
2929

30+
export type AllKeysMatch<T extends object, U> = {
31+
[K in keyof T]: T[K] extends U ? true : false;
32+
}[keyof T] extends true ? true : false
33+
3034
export type CellValue = string | number | boolean | null | undefined | Date
3135

3236
export type ValueTransformer = (value: any) => CellValue
@@ -109,12 +113,36 @@ export type SchemaColumnKeys<
109113
export type Sheet<
110114
T extends GenericObject,
111115
Schema extends ExcelSchema<T, any, string, any>,
116+
ColumnKeys extends SchemaColumnKeys<Schema>,
117+
SelectColsMap extends { [key in ColumnKeys]?: boolean } | never,
118+
SelectedCols extends string = ExtractSelectedColumns<ColumnKeys, SelectColsMap>,
119+
ContextMap extends { [key: string]: any } = ExtractContextMap<Schema>,
120+
SelectedContextMap extends ExtractSelectedContext<ContextMap, SelectedCols> = ExtractSelectedContext<ContextMap, SelectedCols>,
112121
> = {
113122
sheetKey: string
114123
schema: Schema
115124
data: T[]
116-
select?: { [K in SchemaColumnKeys<Schema>]?: boolean }
125+
select?: SelectColsMap
117126
context?: {}
118-
} & (Schema extends ExcelSchema<T, any, any, infer Ctx>
119-
? keyof Ctx extends never ? {} : { context: Ctx }
120-
: {})
127+
} & (keyof SelectedContextMap extends never ? {} : { context: SelectedContextMap })
128+
129+
export type ExtractContextMap<
130+
Schema extends ExcelSchema<any, any, string, any>,
131+
> = Schema extends ExcelSchema<any, any, any, infer Ctx> ? Ctx : {}
132+
133+
export type ExtractSelectedColumns<
134+
ColKeys extends string,
135+
SelectCols extends { [key in ColKeys]?: boolean },
136+
> = keyof SelectCols extends never ? ColKeys :
137+
AllKeysMatch<SelectCols, false> extends true
138+
? Exclude<ColKeys, keyof SelectCols>
139+
: {
140+
[K in ColKeys]: SelectCols[K] extends true ? K : never;
141+
}[ColKeys]
142+
143+
export type ExtractSelectedContext<
144+
ContextMap extends { [key: string]: any },
145+
SelectedCols extends string,
146+
> = {
147+
[K in keyof ContextMap as K extends SelectedCols ? K : never]: ContextMap[K];
148+
}

test/index.test.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,25 @@ describe('should', () => {
9999
.sheet('sheet1', {
100100
data: users,
101101
schema: assessmentExport,
102+
select: {
103+
'group:org': true,
104+
},
102105
context: {
103106
'group:org': organizations,
104-
105107
},
108+
106109
})
107110
.sheet('sheet2', {
108111
data: users,
109112
schema: assessmentExport,
110113
select: {
111-
firstName: true,
112-
lastName: true,
113-
email: true,
114-
// 'group:org': true,
114+
'firstName': true,
115+
'lastName': false,
116+
'email': false,
117+
'group:org': false,
115118
},
116119
context: {
117-
'group:org': organizations,
118-
120+
// 'group:org': organizations,
119121
},
120122
})
121123
.sheet('sheet3', {

0 commit comments

Comments
 (0)