@origints/xlsx 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,24 @@
1
- import { StepBuilder, ArraySpec, ObjectSpec, ExtractSpec, Spec, SpecLike } from '@origints/core';
2
- import { XlsxStep, Direction } from './xlsx-spec';
1
+ import { StepBuilder, ArraySpec, ObjectSpec, ExtractSpec, Spec, SpecLike, VariableRefSpec } from '@origints/core';
2
+ import { XlsxStep, Direction, FindAllExtract } from './xlsx-spec';
3
3
  import { CellPred, SheetPred, RowPred } from './xlsx-predicate-spec';
4
+ /**
5
+ * Options for eachSlice iteration.
6
+ */
7
+ export interface EachSliceOptions {
8
+ /** Number of columns/rows per group (default: 1). When > 1, each slice anchors at every Nth position. */
9
+ readonly groupSize?: number;
10
+ }
11
+ /**
12
+ * Constraints for findAll to narrow the search area.
13
+ */
14
+ export interface FindAllConstraints {
15
+ readonly inRow?: number;
16
+ readonly inCol?: number;
17
+ readonly startRow?: number;
18
+ readonly endRow?: number;
19
+ readonly startCol?: number;
20
+ readonly endCol?: number;
21
+ }
4
22
  /**
5
23
  * Spec builder at the cell level — terminal extraction and navigation methods.
6
24
  */
@@ -58,9 +76,11 @@ export declare class XlsxCellSB extends StepBuilder<XlsxStep, 'xlsx'> {
58
76
  * Each slice is passed as an XlsxSliceSB to the mapper, providing
59
77
  * header-relative column/row access via colWhere/rowWhere.
60
78
  * The mapper can return a Spec, a FluentSpec, or a plain record (auto-wrapped to ObjectSpec).
79
+ *
80
+ * @param options - Optional `{ groupSize: N }` to step by N columns/rows per slice
61
81
  */
62
- eachSlice<T extends Spec>(direction: Direction, while_: RowPred, itemMapper: (slice: XlsxSliceSB) => T): ArraySpec<T>;
63
- eachSlice(direction: Direction, while_: RowPred, itemMapper: (slice: XlsxSliceSB) => Record<string, SpecLike>): ArraySpec<ObjectSpec>;
82
+ eachSlice<T extends Spec>(direction: Direction, while_: RowPred, itemMapper: (slice: XlsxSliceSB) => T, options?: EachSliceOptions): ArraySpec<T>;
83
+ eachSlice(direction: Direction, while_: RowPred, itemMapper: (slice: XlsxSliceSB) => Record<string, SpecLike>, options?: EachSliceOptions): ArraySpec<ObjectSpec>;
64
84
  }
65
85
  /**
66
86
  * XLSX extract type for column definitions.
@@ -91,6 +111,10 @@ export declare class XlsxSliceSB extends StepBuilder<XlsxStep, 'xlsx'> {
91
111
  col(offset: number): XlsxCellSB;
92
112
  /** Access a row by 0-based offset from the anchor (for rotated tables) */
93
113
  row(offset: number): XlsxCellSB;
114
+ /** Navigate to a column whose index comes from a bound variable's CellPosition.col */
115
+ colAt(ref: VariableRefSpec): XlsxCellSB;
116
+ /** Navigate to a row whose index comes from a bound variable's CellPosition.row */
117
+ rowAt(ref: VariableRefSpec): XlsxCellSB;
94
118
  /**
95
119
  * Extract multiple columns at once, producing an ObjectSpec.
96
120
  *
@@ -186,6 +210,17 @@ export declare class XlsxSheetSB extends StepBuilder<XlsxStep, 'xlsx'> {
186
210
  findInRow(rowIndex: number, predicate: CellPred): XlsxCellSB;
187
211
  /** Find the first cell matching the predicate in the specified column */
188
212
  findInCol(colIndex: number, predicate: CellPred): XlsxCellSB;
213
+ /**
214
+ * Find all cells matching a predicate, returning CellPosition[].
215
+ * Use with forEach/flatForEach to iterate over discovered positions.
216
+ *
217
+ * @example
218
+ * ```ts
219
+ * const headers = $.firstSheet().findAll(cell.equals('Revenue'))
220
+ * flatForEach(headers, 'hdr', fromRef('hdr').down().eachSlice('down', hasData, ...))
221
+ * ```
222
+ */
223
+ findAll(predicate: CellPred, constraints?: FindAllConstraints): ExtractSpec<XlsxStep, FindAllExtract>;
189
224
  /** Find the first cell matching the predicate in the specified range */
190
225
  findInRange(rangeRef: string, predicate: CellPred): XlsxCellSB;
191
226
  /** Navigate to a range by address (e.g., "A1:C10") */
@@ -218,3 +253,17 @@ export declare class XlsxSpecBuilder extends StepBuilder<XlsxStep, 'xlsx'> {
218
253
  /** Find a sheet matching the predicate */
219
254
  findSheet(predicate: SheetPred): XlsxSheetSB;
220
255
  }
256
+ /**
257
+ * Create a cell-level spec builder starting from a variable-bound CellPosition.
258
+ * Use with forEach/flatForEach over findAll results to navigate from discovered positions.
259
+ *
260
+ * @example
261
+ * ```ts
262
+ * forEach(
263
+ * $.firstSheet().findAll(cell.equals('Revenue')),
264
+ * 'hdr',
265
+ * fromRef('hdr').down().string()
266
+ * )
267
+ * ```
268
+ */
269
+ export declare function fromRef(ref: string, path?: readonly (string | number)[]): XlsxCellSB;
@@ -72,6 +72,15 @@ export type XlsxStep = {
72
72
  readonly kind: 'rowWhere';
73
73
  readonly headerRef: Spec;
74
74
  readonly predicate: CellPredicateSpec;
75
+ } | {
76
+ readonly kind: 'fromRef';
77
+ readonly ref: string;
78
+ readonly path?: readonly (string | number)[];
79
+ } | {
80
+ readonly kind: 'colAtRef';
81
+ readonly ref: string;
82
+ readonly path?: readonly (string | number)[];
83
+ readonly component: 'col' | 'row';
75
84
  } | {
76
85
  readonly kind: 'range';
77
86
  readonly ref: string;
@@ -103,6 +112,32 @@ export interface EachSliceExtract {
103
112
  readonly kind: 'eachSlice';
104
113
  readonly direction: Direction;
105
114
  readonly while: RowPredicateSpec;
115
+ readonly groupSize?: number;
116
+ }
117
+ /**
118
+ * Position of a cell in a workbook, used as a variable-bound value
119
+ * from findAll for dynamic navigation.
120
+ */
121
+ export interface CellPosition {
122
+ readonly row: number;
123
+ readonly col: number;
124
+ readonly sheetName?: string;
125
+ }
126
+ /**
127
+ * Specification for finding all cells matching a predicate.
128
+ * Returns CellPosition[] at runtime.
129
+ */
130
+ export interface FindAllExtract {
131
+ readonly kind: 'findAll';
132
+ readonly predicate: CellPredicateSpec;
133
+ readonly constraints?: {
134
+ readonly inRow?: number;
135
+ readonly inCol?: number;
136
+ readonly startRow?: number;
137
+ readonly endRow?: number;
138
+ readonly startCol?: number;
139
+ readonly endCol?: number;
140
+ };
106
141
  }
107
142
  /**
108
143
  * The terminal extraction type for an XLSX value.
@@ -111,7 +146,7 @@ export interface EachSliceExtract {
111
146
  * - Range-level (produce arrays): 'rows', 'cells'
112
147
  * - Cell-level (produce arrays): EachCellExtract, EachSliceExtract
113
148
  */
114
- export type XlsxExtract = 'string' | 'number' | 'boolean' | 'date' | 'value' | 'formula' | 'rows' | 'cells' | EachCellExtract | EachSliceExtract;
149
+ export type XlsxExtract = 'string' | 'number' | 'boolean' | 'date' | 'value' | 'formula' | 'rows' | 'cells' | EachCellExtract | EachSliceExtract | FindAllExtract;
115
150
  /**
116
151
  * A complete XLSX extraction spec.
117
152
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@origints/xlsx",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "XLSX parsing for Origins with full traceability to sheets, ranges, and cells.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -50,7 +50,7 @@
50
50
  "xlsx": "^0.18.5"
51
51
  },
52
52
  "peerDependencies": {
53
- "@origints/core": "^0.3.0"
53
+ "@origints/core": "^0.4.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@origints/core": "workspace:*",