@alosha/xlsx 0.3.0 → 0.3.1

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.
package/dist/compat.js CHANGED
@@ -153,6 +153,14 @@ function reflectGet(target, prop) {
153
153
  }
154
154
  return wrap(value);
155
155
  }
156
+ function eachWithEmptyFilter(each, isEmpty, optsOrCb, maybeCb) {
157
+ const includeEmpty = typeof optsOrCb === "object" ? optsOrCb.includeEmpty === true : false;
158
+ const cb = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
159
+ each({ includeEmpty }, (item, n) => {
160
+ if (!includeEmpty && isEmpty(item)) return;
161
+ cb(wrap(item), n);
162
+ });
163
+ }
156
164
  function proxyCell(cell) {
157
165
  const cached = cellProxies.get(cell);
158
166
  if (cached) return cached;
@@ -188,6 +196,14 @@ function proxyRow(row) {
188
196
  const proxy = new Proxy(row, {
189
197
  get(target, prop) {
190
198
  if (prop === RAW) return target;
199
+ if (prop === "eachCell") {
200
+ return (optsOrCb, maybeCb) => eachWithEmptyFilter(
201
+ (o, cb) => target.eachCell(o, cb),
202
+ (cell) => cell.type === 0 /* Null */,
203
+ optsOrCb,
204
+ maybeCb
205
+ );
206
+ }
191
207
  return reflectGet(target, prop);
192
208
  },
193
209
  set(target, prop, value) {
@@ -203,6 +219,14 @@ function proxyColumn(column) {
203
219
  const proxy = new Proxy(column, {
204
220
  get(target, prop) {
205
221
  if (prop === RAW) return target;
222
+ if (prop === "eachCell") {
223
+ return (optsOrCb, maybeCb) => eachWithEmptyFilter(
224
+ (o, cb) => target.eachCell(o, cb),
225
+ (cell) => cell.type === 0 /* Null */,
226
+ optsOrCb,
227
+ maybeCb
228
+ );
229
+ }
206
230
  return reflectGet(target, prop);
207
231
  },
208
232
  set(target, prop, value) {
@@ -227,6 +251,14 @@ function proxyWorksheet(worksheet) {
227
251
  COMPAT_DEFER
228
252
  );
229
253
  }
254
+ if (prop === "eachRow") {
255
+ return (optsOrCb, maybeCb) => eachWithEmptyFilter(
256
+ (o, cb) => target.eachRow(o, cb),
257
+ (row) => !row.hasValues,
258
+ optsOrCb,
259
+ maybeCb
260
+ );
261
+ }
230
262
  return reflectGet(target, prop);
231
263
  },
232
264
  set(target, prop, value) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/compat/value-type.ts","../src/compat/style-compat.ts","../src/compat/workbook.ts","../src/compat/index.ts"],"names":[],"mappings":"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","file":"compat.js","sourcesContent":["// The ExcelJS `Enums.ValueType`/`FormulaType` bridge (docs/COMPAT-SPEC.md §3). Our `CellType`\n// shares names with ExcelJS's `ValueType` but not numbers; these maps translate between the two.\n// `FormulaType` numbering already matches ExcelJS 1:1, so it's a straight re-export.\n\nimport { CellType } from \"../model/index.js\";\n\n/** ExcelJS's `Enums.ValueType` numbering. */\nexport const ValueType = {\n Null: 0,\n Merge: 1,\n Number: 2,\n String: 3,\n Date: 4,\n Hyperlink: 5,\n Formula: 6,\n SharedString: 7,\n RichText: 8,\n Boolean: 9,\n Error: 10,\n} as const;\n\nexport type ValueType = (typeof ValueType)[keyof typeof ValueType];\n\nexport { FormulaType } from \"../model/index.js\";\n\nconst TO_EXCELJS_VALUE_TYPE: Record<CellType, ValueType> = {\n [CellType.Null]: ValueType.Null,\n [CellType.Number]: ValueType.Number,\n [CellType.String]: ValueType.String,\n [CellType.Boolean]: ValueType.Boolean,\n [CellType.Date]: ValueType.Date,\n [CellType.Error]: ValueType.Error,\n [CellType.RichText]: ValueType.RichText,\n [CellType.Hyperlink]: ValueType.Hyperlink,\n [CellType.Formula]: ValueType.Formula,\n [CellType.Merge]: ValueType.Merge,\n [CellType.SharedString]: ValueType.SharedString,\n};\n\nconst FROM_EXCELJS_VALUE_TYPE: Record<ValueType, CellType> = {\n [ValueType.Null]: CellType.Null,\n [ValueType.Merge]: CellType.Merge,\n [ValueType.Number]: CellType.Number,\n [ValueType.String]: CellType.String,\n [ValueType.Date]: CellType.Date,\n [ValueType.Hyperlink]: CellType.Hyperlink,\n [ValueType.Formula]: CellType.Formula,\n [ValueType.SharedString]: CellType.SharedString,\n [ValueType.RichText]: CellType.RichText,\n [ValueType.Boolean]: CellType.Boolean,\n [ValueType.Error]: CellType.Error,\n};\n\n/** `cell.type` in compat mode: our `CellType` → ExcelJS's `ValueType` number. */\nexport function toExcelJSValueType(cellType: CellType): ValueType {\n return TO_EXCELJS_VALUE_TYPE[cellType];\n}\n\n/** The inverse of {@link toExcelJSValueType}. */\nexport function fromExcelJSValueType(value: ValueType): CellType {\n return FROM_EXCELJS_VALUE_TYPE[value];\n}\n","// The style-precedence divergence the compat shim must emulate (docs/COMPAT-SPEC.md §4).\n//\n// The core resolver (`resolveCellStyle`) does a **deep field-level merge**: a lone `cell.font.bold`\n// coexists with an inherited `font.name`/`font.size`. ExcelJS instead replaces the **whole**\n// category — assigning `cell.font` discards every inherited font field. A migrated spreadsheet must\n// render identically, so the compat facade's style setters route through `applyExcelJsStyle`, which\n// applies ExcelJS whole-object-per-category semantics.\n//\n// This only affects the authoring path: on read, styles come back already fully-resolved per cell,\n// so there is no divergence to bridge there. The core `resolveCellStyle` is deliberately left\n// untouched — the divergence is emulated here, scoped to compat-constructed workbooks.\n\nimport type { Cell, Style } from \"../model/index.js\";\n\n/** The six independently-inheritable style categories, in the order the core resolver lists them. */\nconst STYLE_CATEGORIES = [\"numFmt\", \"font\", \"fill\", \"border\", \"alignment\", \"protection\"] as const;\n\n/**\n * Apply a style `patch` to `cell` with ExcelJS whole-object precedence: every category **present**\n * in the patch replaces the cell's inherited category **outright** (no field-level merge), while\n * categories absent from the patch keep their current (possibly inherited) value. A category set to\n * `undefined` in the patch clears it. The underlying model store is otherwise unchanged — the\n * serializer still dedups the final styles.\n */\nexport function applyExcelJsStyle(cell: Cell, patch: Style): void {\n const inherited = cell.style;\n const next: Style = {};\n for (const key of STYLE_CATEGORIES) {\n // A category the patch mentions comes from the patch (whole-object replacement); otherwise it is\n // inherited from the cell's current style. Either way we copy the value as-is, never merging its\n // fields into the inherited one — that field-merge is exactly the core behaviour we diverge from.\n copyCategory(next, Object.hasOwn(patch, key) ? patch : inherited, key);\n }\n cell.style = next;\n}\n\n/** Copy one style category from `source` to `target`, skipping it entirely when unset. */\nfunction copyCategory<K extends keyof Style>(target: Style, source: Style, key: K): void {\n const value = source[key];\n if (value !== undefined) target[key] = value;\n}\n","// The ExcelJS-faithful facade over the core model (docs/COMPAT-SPEC.md §5).\n//\n// Mechanism (§5 leaves it to the implementer, with one hard rule: it MUST NOT leak ExcelJS\n// semantics into the core `@alosha/xlsx` entry): a **Proxy tree**. `CompatWorkbook`'s constructor\n// returns a Proxy over a plain core `Workbook`; every model object reachable from it (worksheets,\n// rows, columns, cells) is wrapped on the way out. The proxies delegate everything by default and\n// override only the three documented divergences plus the deferred surface:\n//\n// 1. `cell.type` / `cell.effectiveType` report ExcelJS `ValueType` numbers (§3, Decision D1 = full\n// emulation) instead of our `CellType` numbers.\n// 2. cell style setters (`font`/`fill`/`border`/`alignment`/`protection`/`numFmt`) route through\n// `applyExcelJsStyle` — ExcelJS whole-object-per-category precedence (§4).\n// 3. the deferred surface (§6: stream/csv/images/tables/conditional-formatting/data-validation/\n// comments/defined-names/protection) throws `UnsupportedFeatureError` at the exact call, naming\n// the feature, rather than silently no-op'ing.\n//\n// Everything else — `addRow(array | object)`, `row.values` (1-based, empty `[0]`), `worksheet.columns\n// = [{header, key, width}]`, the `workbook.xlsx.*` I/O accessor — is already ExcelJS-shaped in the\n// core model (COMPAT-SPEC.md §2 \"already compatible\"), so the proxies pass it straight through. The\n// core classes are never mutated; the divergence lives entirely in these compat-only wrappers.\n\nimport { UnsupportedFeatureError } from \"../errors.js\";\nimport type { XlsxAccessor } from \"../index.js\";\nimport { Cell, Column, Row, Workbook, Worksheet } from \"../index.js\";\nimport type { Style } from \"../model/index.js\";\nimport { applyExcelJsStyle } from \"./style-compat.js\";\nimport { toExcelJSValueType } from \"./value-type.js\";\n\n/** The pointer appended to every compat `UnsupportedFeatureError` (§6). */\nexport const COMPAT_DEFER =\n \"not yet supported in @alosha/xlsx/compat; see https://github.com/avlisodraude/alosha-xlsx/issues\";\n\n/** Sentinel prop that unwraps a facade back to its raw target (used by {@link unwrap}). */\nconst RAW = Symbol(\"alosha.compat.raw\");\n\n/** The cell style categories whose setters must apply ExcelJS whole-object precedence (§4). */\nconst STYLE_SETTERS = new Set([\"numFmt\", \"font\", \"fill\", \"border\", \"alignment\", \"protection\"]);\n\n// --- deferred surface (§6) ----------------------------------------------------------------------\n\n/** A method stub that always throws, naming `feature`. */\nfunction thrower(feature: string): (...args: never[]) => never {\n return () => {\n throw new UnsupportedFeatureError(feature, COMPAT_DEFER);\n };\n}\n\n/** A namespace-shaped object (e.g. `workbook.csv`) whose every method throws. */\nfunction stubNamespace(prefix: string, methods: readonly string[]): Record<string, () => never> {\n const ns: Record<string, () => never> = {};\n for (const m of methods) ns[m] = thrower(`${prefix}.${m}`);\n return ns;\n}\n\nconst CSV_STUB = stubNamespace(\"workbook.csv\", [\n \"read\",\n \"readFile\",\n \"write\",\n \"writeFile\",\n \"writeBuffer\",\n]);\nconst DEFINED_NAMES_STUB = stubNamespace(\"workbook.definedNames\", [\n \"add\",\n \"remove\",\n \"getRanges\",\n \"forEach\",\n \"getNames\",\n]);\n\n/** Worksheet methods that don't exist in the core model and must fail loud in compat mode. */\nconst WORKSHEET_UNSUPPORTED = new Set([\n \"addImage\",\n \"getImages\",\n \"addBackgroundImage\",\n \"addTable\",\n \"getTable\",\n \"getTables\",\n \"addConditionalFormatting\",\n \"removeConditionalFormatting\",\n \"protect\",\n \"unprotect\",\n]);\n\n/** Streaming entry points hung off the ExcelJS namespace (`ExcelJS.stream.xlsx.*`); each throws. */\nexport const streamStub = {\n xlsx: {\n WorkbookWriter: class {\n constructor() {\n throw new UnsupportedFeatureError(\"stream.xlsx.WorkbookWriter\", COMPAT_DEFER);\n }\n },\n WorkbookReader: class {\n constructor() {\n throw new UnsupportedFeatureError(\"stream.xlsx.WorkbookReader\", COMPAT_DEFER);\n }\n },\n },\n} as const;\n\n// --- facade plumbing ----------------------------------------------------------------------------\n\n// One proxy per underlying object, so facade identity is stable (`ws.getCell('A1') === ws.getCell\n// ('A1')`) and re-wrapping is idempotent.\nconst workbookProxies = new WeakMap<Workbook, Workbook>();\nconst worksheetProxies = new WeakMap<Worksheet, Worksheet>();\nconst rowProxies = new WeakMap<Row, Row>();\nconst columnProxies = new WeakMap<Column, Column>();\nconst cellProxies = new WeakMap<Cell, Cell>();\n\n/** Wrap a value crossing the facade boundary on the way out: model objects become their proxies,\n * arrays are wrapped element-wise (preserving sparse holes, e.g. `row.values`), primitives pass. */\nfunction wrap(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(wrap);\n if (value instanceof Cell) return proxyCell(value);\n if (value instanceof Row) return proxyRow(value);\n if (value instanceof Column) return proxyColumn(value);\n if (value instanceof Worksheet) return proxyWorksheet(value);\n if (value instanceof Workbook) return proxyWorkbook(value);\n return value;\n}\n\n/** The inverse of {@link wrap} for a single value: a facade proxy back to its raw target. */\nfunction unwrap(value: unknown): unknown {\n if (value !== null && typeof value === \"object\") {\n const raw = (value as { [RAW]?: unknown })[RAW];\n if (raw !== undefined) return raw;\n }\n return value;\n}\n\n/** Transform one argument passed *into* a model method: unwrap facade args, and wrap the arguments\n * a user callback receives (so `eachRow`/`eachCell` hand back proxied rows/cells, not raw ones). */\nfunction mapArgIn(arg: unknown): unknown {\n if (typeof arg === \"function\") {\n const cb = arg as (...cbArgs: unknown[]) => unknown;\n return (...cbArgs: unknown[]) => cb(...cbArgs.map(wrap));\n }\n return unwrap(arg);\n}\n\n/** Default `get` behaviour shared by every facade: read the raw property, bind-and-wrap methods so\n * their return value (and callback args) cross the boundary, else wrap the plain value. */\nfunction reflectGet(target: object, prop: string | symbol): unknown {\n const value = Reflect.get(target, prop, target);\n if (typeof value === \"function\") {\n const fn = value as (...args: unknown[]) => unknown;\n return (...args: unknown[]) => wrap(fn.apply(target, args.map(mapArgIn)));\n }\n return wrap(value);\n}\n\n// --- the per-level proxies ----------------------------------------------------------------------\n\nfunction proxyCell(cell: Cell): Cell {\n const cached = cellProxies.get(cell);\n if (cached) return cached;\n const proxy = new Proxy(cell, {\n get(target, prop) {\n if (prop === RAW) return target;\n // Decision D1: compat cells always report ExcelJS ValueType numbers (§3).\n if (prop === \"type\") return toExcelJSValueType(target.type);\n if (prop === \"effectiveType\") return toExcelJSValueType(target.effectiveType);\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n // §4: assigning a style category replaces it whole-object, never field-merges.\n if (typeof prop === \"string\" && STYLE_SETTERS.has(prop)) {\n const patch: Style = {};\n (patch as Record<string, unknown>)[prop] = value;\n applyExcelJsStyle(target, patch);\n return true;\n }\n if (prop === \"note\") {\n throw new UnsupportedFeatureError(\"cell.note (comments)\", COMPAT_DEFER);\n }\n if (prop === \"dataValidation\") {\n throw new UnsupportedFeatureError(\"cell.dataValidation (data validation)\", COMPAT_DEFER);\n }\n return Reflect.set(target, prop, value, target);\n },\n });\n cellProxies.set(cell, proxy);\n return proxy;\n}\n\nfunction proxyRow(row: Row): Row {\n const cached = rowProxies.get(row);\n if (cached) return cached;\n const proxy = new Proxy(row, {\n get(target, prop) {\n if (prop === RAW) return target;\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n rowProxies.set(row, proxy);\n return proxy;\n}\n\nfunction proxyColumn(column: Column): Column {\n const cached = columnProxies.get(column);\n if (cached) return cached;\n const proxy = new Proxy(column, {\n get(target, prop) {\n if (prop === RAW) return target;\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n columnProxies.set(column, proxy);\n return proxy;\n}\n\nfunction proxyWorksheet(worksheet: Worksheet): Worksheet {\n const cached = worksheetProxies.get(worksheet);\n if (cached) return cached;\n const proxy = new Proxy(worksheet, {\n get(target, prop) {\n if (prop === RAW) return target;\n if (typeof prop === \"string\" && WORKSHEET_UNSUPPORTED.has(prop)) {\n return thrower(`worksheet.${prop}`);\n }\n if (prop === \"dataValidations\") {\n throw new UnsupportedFeatureError(\n \"worksheet.dataValidations (data validation)\",\n COMPAT_DEFER,\n );\n }\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n worksheetProxies.set(worksheet, proxy);\n return proxy;\n}\n\nfunction proxyWorkbook(workbook: Workbook): Workbook {\n const cached = workbookProxies.get(workbook);\n if (cached) return cached;\n const proxy = new Proxy(workbook, {\n get(target, prop) {\n if (prop === RAW) return target;\n // The I/O accessor is already ExcelJS-shaped; only rebind load/read/readFile so they resolve\n // to the *facade* (not the raw workbook), keeping the returned handle inside compat mode.\n if (prop === \"xlsx\") {\n const acc = Reflect.get(target, \"xlsx\", target) as XlsxAccessor;\n return {\n writeBuffer: (...args: Parameters<XlsxAccessor[\"writeBuffer\"]>) =>\n acc.writeBuffer(...args),\n writeFile: (...args: Parameters<XlsxAccessor[\"writeFile\"]>) => acc.writeFile(...args),\n load: async (...args: Parameters<XlsxAccessor[\"load\"]>) => {\n await acc.load(...args);\n return proxy;\n },\n readFile: async (...args: Parameters<XlsxAccessor[\"readFile\"]>) => {\n await acc.readFile(...args);\n return proxy;\n },\n read: async (...args: Parameters<XlsxAccessor[\"read\"]>) => {\n await acc.read(...args);\n return proxy;\n },\n } satisfies XlsxAccessor;\n }\n if (prop === \"csv\") return CSV_STUB;\n if (prop === \"definedNames\") return DEFINED_NAMES_STUB;\n if (prop === \"addImage\" || prop === \"getImage\") return thrower(`workbook.${prop}`);\n if (prop === \"media\") {\n throw new UnsupportedFeatureError(\"workbook.media (images)\", COMPAT_DEFER);\n }\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n workbookProxies.set(workbook, proxy);\n return proxy;\n}\n\n/**\n * The compat `Workbook`: an ExcelJS drop-in. `new CompatWorkbook()` builds a plain core workbook and\n * returns a facade Proxy over it — so `instanceof` still holds (the proxy's target *is* a Workbook),\n * while every reachable cell/row/column/worksheet reports ExcelJS semantics (§5).\n */\nexport class CompatWorkbook extends Workbook {\n constructor() {\n super();\n // A constructor may return an object in place of `this`; we deliberately return the facade\n // wrapping the fully-initialised core instance — the whole mechanism of the shim (§5). Cast:\n // the proxy's target is this CompatWorkbook, so `instanceof` still holds.\n // biome-ignore lint/correctness/noConstructorReturn: returning the facade Proxy is intentional.\n return proxyWorkbook(this) as CompatWorkbook;\n }\n}\n","/**\n * @alosha/xlsx/compat — the ExcelJS drop-in shim entry point (docs/COMPAT-SPEC.md).\n *\n * The default export is shaped like the `exceljs` namespace (`{ Workbook, ValueType, Enums, stream }`)\n * and the named `Workbook` is the ExcelJS-faithful facade (`CompatWorkbook`, §5): compat-constructed\n * workbooks report ExcelJS `ValueType` numbers, apply whole-object style precedence, and throw\n * `UnsupportedFeatureError` on the deferred surface (§6). An ExcelJS user changes one import.\n *\n * Re-exports from `../index.js` (not `../model/index.js`) so the `workbook.xlsx` accessor — attached\n * to `Workbook.prototype` as a side effect of loading the main entry — is present on compat workbooks.\n * The star export's plain `Workbook` is deliberately shadowed by the explicit `CompatWorkbook as\n * Workbook` re-export below (explicit named exports win over `export *`).\n */\n\nimport { FormulaType, ValueType } from \"./value-type.js\";\nimport { CompatWorkbook, streamStub } from \"./workbook.js\";\n\nexport * from \"../index.js\";\nexport { fromExcelJSValueType, toExcelJSValueType, ValueType } from \"./value-type.js\";\nexport { CompatWorkbook, CompatWorkbook as Workbook } from \"./workbook.js\";\n\n/** ExcelJS's `Enums` grouping (`import { Enums } from \"exceljs\"`). */\nexport const Enums = {\n ValueType,\n FormulaType,\n} as const;\n\n/** The ExcelJS-shaped default export: `import ExcelJS from \"@alosha/xlsx/compat\"`. */\nconst ExcelJS = {\n Workbook: CompatWorkbook,\n ValueType,\n FormulaType,\n Enums,\n stream: streamStub,\n};\n\nexport default ExcelJS;\n"]}
1
+ {"version":3,"sources":["../src/compat/value-type.ts","../src/compat/style-compat.ts","../src/compat/workbook.ts","../src/compat/index.ts"],"names":[],"mappings":";;;;AAOO,IAAM,SAAA,GAAY;AAAA,EACvB,IAAA,EAAM,CAAA;AAAA,EACN,KAAA,EAAO,CAAA;AAAA,EACP,MAAA,EAAQ,CAAA;AAAA,EACR,MAAA,EAAQ,CAAA;AAAA,EACR,IAAA,EAAM,CAAA;AAAA,EACN,SAAA,EAAW,CAAA;AAAA,EACX,OAAA,EAAS,CAAA;AAAA,EACT,YAAA,EAAc,CAAA;AAAA,EACd,QAAA,EAAU,CAAA;AAAA,EACV,OAAA,EAAS,CAAA;AAAA,EACT,KAAA,EAAO;AACT;AAMA,IAAM,qBAAA,GAAqD;AAAA,EACzD,CAAA,CAAA,cAAiB,SAAA,CAAU,IAAA;AAAA,EAC3B,CAAA,CAAA,gBAAmB,SAAA,CAAU,MAAA;AAAA,EAC7B,CAAA,CAAA,gBAAmB,SAAA,CAAU,MAAA;AAAA,EAC7B,CAAA,CAAA,iBAAoB,SAAA,CAAU,OAAA;AAAA,EAC9B,CAAA,CAAA,cAAiB,SAAA,CAAU,IAAA;AAAA,EAC3B,CAAA,CAAA,eAAkB,SAAA,CAAU,KAAA;AAAA,EAC5B,CAAA,CAAA,kBAAqB,SAAA,CAAU,QAAA;AAAA,EAC/B,CAAA,CAAA,mBAAsB,SAAA,CAAU,SAAA;AAAA,EAChC,CAAA,CAAA,iBAAoB,SAAA,CAAU,OAAA;AAAA,EAC9B,CAAA,CAAA,eAAkB,SAAA,CAAU,KAAA;AAAA,EAC5B,CAAA,EAAA,sBAAyB,SAAA,CAAU;AACrC,CAAA;AAEA,IAAM,uBAAA,GAAuD;AAAA,EAC3D,CAAC,UAAU,IAAI,GAAA,CAAA;AAAA,EACf,CAAC,UAAU,KAAK,GAAA,CAAA;AAAA,EAChB,CAAC,UAAU,MAAM,GAAA,CAAA;AAAA,EACjB,CAAC,UAAU,MAAM,GAAA,CAAA;AAAA,EACjB,CAAC,UAAU,IAAI,GAAA,CAAA;AAAA,EACf,CAAC,UAAU,SAAS,GAAA,CAAA;AAAA,EACpB,CAAC,UAAU,OAAO,GAAA,CAAA;AAAA,EAClB,CAAC,UAAU,YAAY,GAAA,EAAA;AAAA,EACvB,CAAC,UAAU,QAAQ,GAAA,CAAA;AAAA,EACnB,CAAC,UAAU,OAAO,GAAA,CAAA;AAAA,EAClB,CAAC,UAAU,KAAK,GAAA,CAAA;AAClB,CAAA;AAGO,SAAS,mBAAmB,QAAA,EAA+B;AAChE,EAAA,OAAO,sBAAsB,QAAQ,CAAA;AACvC;AAGO,SAAS,qBAAqB,KAAA,EAA4B;AAC/D,EAAA,OAAO,wBAAwB,KAAK,CAAA;AACtC;;;AC9CA,IAAM,mBAAmB,CAAC,QAAA,EAAU,QAAQ,MAAA,EAAQ,QAAA,EAAU,aAAa,YAAY,CAAA;AAShF,SAAS,iBAAA,CAAkB,MAAY,KAAA,EAAoB;AAChE,EAAA,MAAM,YAAY,IAAA,CAAK,KAAA;AACvB,EAAA,MAAM,OAAc,EAAC;AACrB,EAAA,KAAA,MAAW,OAAO,gBAAA,EAAkB;AAIlC,IAAA,YAAA,CAAa,IAAA,EAAM,OAAO,MAAA,CAAO,KAAA,EAAO,GAAG,CAAA,GAAI,KAAA,GAAQ,WAAW,GAAG,CAAA;AAAA,EACvE;AACA,EAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACf;AAGA,SAAS,YAAA,CAAoC,MAAA,EAAe,MAAA,EAAe,GAAA,EAAc;AACvF,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAG,CAAA;AACxB,EAAA,IAAI,KAAA,KAAU,MAAA,EAAW,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AACzC;;;ACXO,IAAM,YAAA,GACX,kGAAA;AAGF,IAAM,GAAA,0BAAa,mBAAmB,CAAA;AAGtC,IAAM,aAAA,mBAAgB,IAAI,GAAA,CAAI,CAAC,QAAA,EAAU,QAAQ,MAAA,EAAQ,QAAA,EAAU,WAAA,EAAa,YAAY,CAAC,CAAA;AAK7F,SAAS,QAAQ,OAAA,EAA8C;AAC7D,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,IAAI,uBAAA,CAAwB,OAAA,EAAS,YAAY,CAAA;AAAA,EACzD,CAAA;AACF;AAGA,SAAS,aAAA,CAAc,QAAgB,OAAA,EAAyD;AAC9F,EAAA,MAAM,KAAkC,EAAC;AACzC,EAAA,KAAA,MAAW,CAAA,IAAK,OAAA,EAAS,EAAA,CAAG,CAAC,CAAA,GAAI,QAAQ,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAA;AACzD,EAAA,OAAO,EAAA;AACT;AAEA,IAAM,QAAA,GAAW,cAAc,cAAA,EAAgB;AAAA,EAC7C,MAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,IAAM,kBAAA,GAAqB,cAAc,uBAAA,EAAyB;AAAA,EAChE,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGD,IAAM,qBAAA,uBAA4B,GAAA,CAAI;AAAA,EACpC,UAAA;AAAA,EACA,WAAA;AAAA,EACA,oBAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,0BAAA;AAAA,EACA,6BAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGM,IAAM,UAAA,GAAa;AAAA,EACxB,IAAA,EAAM;AAAA,IACJ,gBAAgB,MAAM;AAAA,MACpB,WAAA,GAAc;AACZ,QAAA,MAAM,IAAI,uBAAA,CAAwB,4BAAA,EAA8B,YAAY,CAAA;AAAA,MAC9E;AAAA,KACF;AAAA,IACA,gBAAgB,MAAM;AAAA,MACpB,WAAA,GAAc;AACZ,QAAA,MAAM,IAAI,uBAAA,CAAwB,4BAAA,EAA8B,YAAY,CAAA;AAAA,MAC9E;AAAA;AACF;AAEJ,CAAA;AAMA,IAAM,eAAA,uBAAsB,OAAA,EAA4B;AACxD,IAAM,gBAAA,uBAAuB,OAAA,EAA8B;AAC3D,IAAM,UAAA,uBAAiB,OAAA,EAAkB;AACzC,IAAM,aAAA,uBAAoB,OAAA,EAAwB;AAClD,IAAM,WAAA,uBAAkB,OAAA,EAAoB;AAI5C,SAAS,KAAK,KAAA,EAAyB;AACrC,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,IAAI,CAAA;AAC/C,EAAA,IAAI,KAAA,YAAiB,IAAA,EAAM,OAAO,SAAA,CAAU,KAAK,CAAA;AACjD,EAAA,IAAI,KAAA,YAAiB,GAAA,EAAK,OAAO,QAAA,CAAS,KAAK,CAAA;AAC/C,EAAA,IAAI,KAAA,YAAiB,MAAA,EAAQ,OAAO,WAAA,CAAY,KAAK,CAAA;AACrD,EAAA,IAAI,KAAA,YAAiB,SAAA,EAAW,OAAO,cAAA,CAAe,KAAK,CAAA;AAC3D,EAAA,IAAI,KAAA,YAAiB,QAAA,EAAU,OAAO,aAAA,CAAc,KAAK,CAAA;AACzD,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,OAAO,KAAA,EAAyB;AACvC,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC/C,IAAA,MAAM,GAAA,GAAO,MAA8B,GAAG,CAAA;AAC9C,IAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,GAAA;AAAA,EAChC;AACA,EAAA,OAAO,KAAA;AACT;AAIA,SAAS,SAAS,GAAA,EAAuB;AACvC,EAAA,IAAI,OAAO,QAAQ,UAAA,EAAY;AAC7B,IAAA,MAAM,EAAA,GAAK,GAAA;AACX,IAAA,OAAO,IAAI,MAAA,KAAsB,EAAA,CAAG,GAAG,MAAA,CAAO,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,EACzD;AACA,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB;AAIA,SAAS,UAAA,CAAW,QAAgB,IAAA,EAAgC;AAClE,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,MAAM,MAAM,CAAA;AAC9C,EAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC/B,IAAA,MAAM,EAAA,GAAK,KAAA;AACX,IAAA,OAAO,CAAA,GAAI,IAAA,KAAoB,IAAA,CAAK,EAAA,CAAG,KAAA,CAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAC,CAAC,CAAA;AAAA,EAC1E;AACA,EAAA,OAAO,KAAK,KAAK,CAAA;AACnB;AAQA,SAAS,mBAAA,CACP,IAAA,EACA,OAAA,EACA,QAAA,EACA,OAAA,EACM;AACN,EAAA,MAAM,eAAe,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,CAAS,iBAAiB,IAAA,GAAO,KAAA;AACrF,EAAA,MAAM,EAAA,GAAM,OAAO,QAAA,KAAa,UAAA,GAAa,QAAA,GAAW,OAAA;AAIxD,EAAA,IAAA,CAAK,EAAE,YAAA,EAAa,EAAG,CAAC,MAAM,CAAA,KAAM;AAClC,IAAA,IAAI,CAAC,YAAA,IAAgB,OAAA,CAAQ,IAAI,CAAA,EAAG;AACpC,IAAA,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,EAAG,CAAC,CAAA;AAAA,EAClB,CAAC,CAAA;AACH;AAIA,SAAS,UAAU,IAAA,EAAkB;AACnC,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,GAAA,CAAI,IAAI,CAAA;AACnC,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,IAAA,EAAM;AAAA,IAC5B,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,KAAK,OAAO,MAAA;AAEzB,MAAA,IAAI,IAAA,KAAS,MAAA,EAAQ,OAAO,kBAAA,CAAmB,OAAO,IAAI,CAAA;AAC1D,MAAA,IAAI,IAAA,KAAS,eAAA,EAAiB,OAAO,kBAAA,CAAmB,OAAO,aAAa,CAAA;AAC5E,MAAA,OAAO,UAAA,CAAW,QAAQ,IAAI,CAAA;AAAA,IAChC,CAAA;AAAA,IACA,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO;AAEvB,MAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,EAAG;AACvD,QAAA,MAAM,QAAe,EAAC;AACtB,QAAC,KAAA,CAAkC,IAAI,CAAA,GAAI,KAAA;AAC3C,QAAA,iBAAA,CAAkB,QAAQ,KAAK,CAAA;AAC/B,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,QAAA,MAAM,IAAI,uBAAA,CAAwB,sBAAA,EAAwB,YAAY,CAAA;AAAA,MACxE;AACA,MAAA,IAAI,SAAS,gBAAA,EAAkB;AAC7B,QAAA,MAAM,IAAI,uBAAA,CAAwB,uCAAA,EAAyC,YAAY,CAAA;AAAA,MACzF;AACA,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,OAAO,MAAM,CAAA;AAAA,IAChD;AAAA,GACD,CAAA;AACD,EAAA,WAAA,CAAY,GAAA,CAAI,MAAM,KAAK,CAAA;AAC3B,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,SAAS,GAAA,EAAe;AAC/B,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,GAAA,CAAI,GAAG,CAAA;AACjC,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,GAAA,EAAK;AAAA,IAC3B,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,KAAK,OAAO,MAAA;AAEzB,MAAA,IAAI,SAAS,UAAA,EAAY;AACvB,QAAA,OAAO,CACL,UACA,OAAA,KAEA,mBAAA;AAAA,UACE,CAAC,CAAA,EAAG,EAAA,KAAO,MAAA,CAAO,QAAA,CAAS,GAAG,EAAE,CAAA;AAAA,UAChC,CAAC,SAAS,IAAA,CAAK,IAAA,KAAA,CAAA;AAAA,UACf,QAAA;AAAA,UACA;AAAA,SACF;AAAA,MACJ;AACA,MAAA,OAAO,UAAA,CAAW,QAAQ,IAAI,CAAA;AAAA,IAChC,CAAA;AAAA,IACA,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO;AACvB,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,OAAO,MAAM,CAAA;AAAA,IAChD;AAAA,GACD,CAAA;AACD,EAAA,UAAA,CAAW,GAAA,CAAI,KAAK,KAAK,CAAA;AACzB,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,YAAY,MAAA,EAAwB;AAC3C,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA;AACvC,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,EAAQ;AAAA,IAC9B,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,KAAK,OAAO,MAAA;AAEzB,MAAA,IAAI,SAAS,UAAA,EAAY;AACvB,QAAA,OAAO,CACL,UACA,OAAA,KAEA,mBAAA;AAAA,UACE,CAAC,CAAA,EAAG,EAAA,KAAO,MAAA,CAAO,QAAA,CAAS,GAAG,EAAE,CAAA;AAAA,UAChC,CAAC,SAAS,IAAA,CAAK,IAAA,KAAA,CAAA;AAAA,UACf,QAAA;AAAA,UACA;AAAA,SACF;AAAA,MACJ;AACA,MAAA,OAAO,UAAA,CAAW,QAAQ,IAAI,CAAA;AAAA,IAChC,CAAA;AAAA,IACA,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO;AACvB,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,OAAO,MAAM,CAAA;AAAA,IAChD;AAAA,GACD,CAAA;AACD,EAAA,aAAA,CAAc,GAAA,CAAI,QAAQ,KAAK,CAAA;AAC/B,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAe,SAAA,EAAiC;AACvD,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,CAAI,SAAS,CAAA;AAC7C,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,SAAA,EAAW;AAAA,IACjC,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,KAAK,OAAO,MAAA;AACzB,MAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,qBAAA,CAAsB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC/D,QAAA,OAAO,OAAA,CAAQ,CAAA,UAAA,EAAa,IAAI,CAAA,CAAE,CAAA;AAAA,MACpC;AACA,MAAA,IAAI,SAAS,iBAAA,EAAmB;AAC9B,QAAA,MAAM,IAAI,uBAAA;AAAA,UACR,6CAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,IAAI,SAAS,SAAA,EAAW;AACtB,QAAA,OAAO,CACL,UACA,OAAA,KAEA,mBAAA;AAAA,UACE,CAAC,CAAA,EAAG,EAAA,KAAO,MAAA,CAAO,OAAA,CAAQ,GAAG,EAAE,CAAA;AAAA,UAC/B,CAAC,GAAA,KAAQ,CAAC,GAAA,CAAI,SAAA;AAAA,UACd,QAAA;AAAA,UACA;AAAA,SACF;AAAA,MACJ;AACA,MAAA,OAAO,UAAA,CAAW,QAAQ,IAAI,CAAA;AAAA,IAChC,CAAA;AAAA,IACA,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO;AACvB,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,OAAO,MAAM,CAAA;AAAA,IAChD;AAAA,GACD,CAAA;AACD,EAAA,gBAAA,CAAiB,GAAA,CAAI,WAAW,KAAK,CAAA;AACrC,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,cAAc,QAAA,EAA8B;AACnD,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,GAAA,CAAI,QAAQ,CAAA;AAC3C,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,QAAA,EAAU;AAAA,IAChC,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,KAAK,OAAO,MAAA;AAGzB,MAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,QAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,QAAQ,MAAM,CAAA;AAC9C,QAAA,OAAO;AAAA,UACL,aAAa,CAAA,GAAI,IAAA,KACf,GAAA,CAAI,WAAA,CAAY,GAAG,IAAI,CAAA;AAAA,UACzB,WAAW,CAAA,GAAI,IAAA,KAAgD,GAAA,CAAI,SAAA,CAAU,GAAG,IAAI,CAAA;AAAA,UACpF,IAAA,EAAM,UAAU,IAAA,KAA2C;AACzD,YAAA,MAAM,GAAA,CAAI,IAAA,CAAK,GAAG,IAAI,CAAA;AACtB,YAAA,OAAO,KAAA;AAAA,UACT,CAAA;AAAA,UACA,QAAA,EAAU,UAAU,IAAA,KAA+C;AACjE,YAAA,MAAM,GAAA,CAAI,QAAA,CAAS,GAAG,IAAI,CAAA;AAC1B,YAAA,OAAO,KAAA;AAAA,UACT,CAAA;AAAA,UACA,IAAA,EAAM,UAAU,IAAA,KAA2C;AACzD,YAAA,MAAM,GAAA,CAAI,IAAA,CAAK,GAAG,IAAI,CAAA;AACtB,YAAA,OAAO,KAAA;AAAA,UACT;AAAA,SACF;AAAA,MACF;AACA,MAAA,IAAI,IAAA,KAAS,OAAO,OAAO,QAAA;AAC3B,MAAA,IAAI,IAAA,KAAS,gBAAgB,OAAO,kBAAA;AACpC,MAAA,IAAI,IAAA,KAAS,cAAc,IAAA,KAAS,UAAA,SAAmB,OAAA,CAAQ,CAAA,SAAA,EAAY,IAAI,CAAA,CAAE,CAAA;AACjF,MAAA,IAAI,SAAS,OAAA,EAAS;AACpB,QAAA,MAAM,IAAI,uBAAA,CAAwB,yBAAA,EAA2B,YAAY,CAAA;AAAA,MAC3E;AACA,MAAA,OAAO,UAAA,CAAW,QAAQ,IAAI,CAAA;AAAA,IAChC,CAAA;AAAA,IACA,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO;AACvB,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,OAAO,MAAM,CAAA;AAAA,IAChD;AAAA,GACD,CAAA;AACD,EAAA,eAAA,CAAgB,GAAA,CAAI,UAAU,KAAK,CAAA;AACnC,EAAA,OAAO,KAAA;AACT;AAOO,IAAM,cAAA,GAAN,cAA6B,QAAA,CAAS;AAAA,EAC3C,WAAA,GAAc;AACZ,IAAA,KAAA,EAAM;AAKN,IAAA,OAAO,cAAc,IAAI,CAAA;AAAA,EAC3B;AACF;;;ACpVO,IAAM,KAAA,GAAQ;AAAA,EACnB,SAAA;AAAA,EACA;AACF;AAGA,IAAM,OAAA,GAAU;AAAA,EACd,QAAA,EAAU,cAAA;AAAA,EACV,SAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA,EAAQ;AACV,CAAA;AAEA,IAAO,cAAA,GAAQ","file":"compat.js","sourcesContent":["// The ExcelJS `Enums.ValueType`/`FormulaType` bridge (docs/COMPAT-SPEC.md §3). Our `CellType`\n// shares names with ExcelJS's `ValueType` but not numbers; these maps translate between the two.\n// `FormulaType` numbering already matches ExcelJS 1:1, so it's a straight re-export.\n\nimport { CellType } from \"../model/index.js\";\n\n/** ExcelJS's `Enums.ValueType` numbering. */\nexport const ValueType = {\n Null: 0,\n Merge: 1,\n Number: 2,\n String: 3,\n Date: 4,\n Hyperlink: 5,\n Formula: 6,\n SharedString: 7,\n RichText: 8,\n Boolean: 9,\n Error: 10,\n} as const;\n\nexport type ValueType = (typeof ValueType)[keyof typeof ValueType];\n\nexport { FormulaType } from \"../model/index.js\";\n\nconst TO_EXCELJS_VALUE_TYPE: Record<CellType, ValueType> = {\n [CellType.Null]: ValueType.Null,\n [CellType.Number]: ValueType.Number,\n [CellType.String]: ValueType.String,\n [CellType.Boolean]: ValueType.Boolean,\n [CellType.Date]: ValueType.Date,\n [CellType.Error]: ValueType.Error,\n [CellType.RichText]: ValueType.RichText,\n [CellType.Hyperlink]: ValueType.Hyperlink,\n [CellType.Formula]: ValueType.Formula,\n [CellType.Merge]: ValueType.Merge,\n [CellType.SharedString]: ValueType.SharedString,\n};\n\nconst FROM_EXCELJS_VALUE_TYPE: Record<ValueType, CellType> = {\n [ValueType.Null]: CellType.Null,\n [ValueType.Merge]: CellType.Merge,\n [ValueType.Number]: CellType.Number,\n [ValueType.String]: CellType.String,\n [ValueType.Date]: CellType.Date,\n [ValueType.Hyperlink]: CellType.Hyperlink,\n [ValueType.Formula]: CellType.Formula,\n [ValueType.SharedString]: CellType.SharedString,\n [ValueType.RichText]: CellType.RichText,\n [ValueType.Boolean]: CellType.Boolean,\n [ValueType.Error]: CellType.Error,\n};\n\n/** `cell.type` in compat mode: our `CellType` → ExcelJS's `ValueType` number. */\nexport function toExcelJSValueType(cellType: CellType): ValueType {\n return TO_EXCELJS_VALUE_TYPE[cellType];\n}\n\n/** The inverse of {@link toExcelJSValueType}. */\nexport function fromExcelJSValueType(value: ValueType): CellType {\n return FROM_EXCELJS_VALUE_TYPE[value];\n}\n","// The style-precedence divergence the compat shim must emulate (docs/COMPAT-SPEC.md §4).\n//\n// The core resolver (`resolveCellStyle`) does a **deep field-level merge**: a lone `cell.font.bold`\n// coexists with an inherited `font.name`/`font.size`. ExcelJS instead replaces the **whole**\n// category — assigning `cell.font` discards every inherited font field. A migrated spreadsheet must\n// render identically, so the compat facade's style setters route through `applyExcelJsStyle`, which\n// applies ExcelJS whole-object-per-category semantics.\n//\n// This only affects the authoring path: on read, styles come back already fully-resolved per cell,\n// so there is no divergence to bridge there. The core `resolveCellStyle` is deliberately left\n// untouched — the divergence is emulated here, scoped to compat-constructed workbooks.\n\nimport type { Cell, Style } from \"../model/index.js\";\n\n/** The six independently-inheritable style categories, in the order the core resolver lists them. */\nconst STYLE_CATEGORIES = [\"numFmt\", \"font\", \"fill\", \"border\", \"alignment\", \"protection\"] as const;\n\n/**\n * Apply a style `patch` to `cell` with ExcelJS whole-object precedence: every category **present**\n * in the patch replaces the cell's inherited category **outright** (no field-level merge), while\n * categories absent from the patch keep their current (possibly inherited) value. A category set to\n * `undefined` in the patch clears it. The underlying model store is otherwise unchanged — the\n * serializer still dedups the final styles.\n */\nexport function applyExcelJsStyle(cell: Cell, patch: Style): void {\n const inherited = cell.style;\n const next: Style = {};\n for (const key of STYLE_CATEGORIES) {\n // A category the patch mentions comes from the patch (whole-object replacement); otherwise it is\n // inherited from the cell's current style. Either way we copy the value as-is, never merging its\n // fields into the inherited one — that field-merge is exactly the core behaviour we diverge from.\n copyCategory(next, Object.hasOwn(patch, key) ? patch : inherited, key);\n }\n cell.style = next;\n}\n\n/** Copy one style category from `source` to `target`, skipping it entirely when unset. */\nfunction copyCategory<K extends keyof Style>(target: Style, source: Style, key: K): void {\n const value = source[key];\n if (value !== undefined) target[key] = value;\n}\n","// The ExcelJS-faithful facade over the core model (docs/COMPAT-SPEC.md §5).\n//\n// Mechanism (§5 leaves it to the implementer, with one hard rule: it MUST NOT leak ExcelJS\n// semantics into the core `@alosha/xlsx` entry): a **Proxy tree**. `CompatWorkbook`'s constructor\n// returns a Proxy over a plain core `Workbook`; every model object reachable from it (worksheets,\n// rows, columns, cells) is wrapped on the way out. The proxies delegate everything by default and\n// override only the three documented divergences plus the deferred surface:\n//\n// 1. `cell.type` / `cell.effectiveType` report ExcelJS `ValueType` numbers (§3, Decision D1 = full\n// emulation) instead of our `CellType` numbers.\n// 2. cell style setters (`font`/`fill`/`border`/`alignment`/`protection`/`numFmt`) route through\n// `applyExcelJsStyle` — ExcelJS whole-object-per-category precedence (§4).\n// 3. the deferred surface (§6: stream/csv/images/tables/conditional-formatting/data-validation/\n// comments/defined-names/protection) throws `UnsupportedFeatureError` at the exact call, naming\n// the feature, rather than silently no-op'ing.\n//\n// Everything else — `addRow(array | object)`, `row.values` (1-based, empty `[0]`), `worksheet.columns\n// = [{header, key, width}]`, the `workbook.xlsx.*` I/O accessor — is already ExcelJS-shaped in the\n// core model (COMPAT-SPEC.md §2 \"already compatible\"), so the proxies pass it straight through. The\n// core classes are never mutated; the divergence lives entirely in these compat-only wrappers.\n\nimport { UnsupportedFeatureError } from \"../errors.js\";\nimport type { XlsxAccessor } from \"../index.js\";\nimport { Cell, Column, Row, Workbook, Worksheet } from \"../index.js\";\nimport { CellType, type Style } from \"../model/index.js\";\nimport { applyExcelJsStyle } from \"./style-compat.js\";\nimport { toExcelJSValueType } from \"./value-type.js\";\n\n/** The pointer appended to every compat `UnsupportedFeatureError` (§6). */\nexport const COMPAT_DEFER =\n \"not yet supported in @alosha/xlsx/compat; see https://github.com/avlisodraude/alosha-xlsx/issues\";\n\n/** Sentinel prop that unwraps a facade back to its raw target (used by {@link unwrap}). */\nconst RAW = Symbol(\"alosha.compat.raw\");\n\n/** The cell style categories whose setters must apply ExcelJS whole-object precedence (§4). */\nconst STYLE_SETTERS = new Set([\"numFmt\", \"font\", \"fill\", \"border\", \"alignment\", \"protection\"]);\n\n// --- deferred surface (§6) ----------------------------------------------------------------------\n\n/** A method stub that always throws, naming `feature`. */\nfunction thrower(feature: string): (...args: never[]) => never {\n return () => {\n throw new UnsupportedFeatureError(feature, COMPAT_DEFER);\n };\n}\n\n/** A namespace-shaped object (e.g. `workbook.csv`) whose every method throws. */\nfunction stubNamespace(prefix: string, methods: readonly string[]): Record<string, () => never> {\n const ns: Record<string, () => never> = {};\n for (const m of methods) ns[m] = thrower(`${prefix}.${m}`);\n return ns;\n}\n\nconst CSV_STUB = stubNamespace(\"workbook.csv\", [\n \"read\",\n \"readFile\",\n \"write\",\n \"writeFile\",\n \"writeBuffer\",\n]);\nconst DEFINED_NAMES_STUB = stubNamespace(\"workbook.definedNames\", [\n \"add\",\n \"remove\",\n \"getRanges\",\n \"forEach\",\n \"getNames\",\n]);\n\n/** Worksheet methods that don't exist in the core model and must fail loud in compat mode. */\nconst WORKSHEET_UNSUPPORTED = new Set([\n \"addImage\",\n \"getImages\",\n \"addBackgroundImage\",\n \"addTable\",\n \"getTable\",\n \"getTables\",\n \"addConditionalFormatting\",\n \"removeConditionalFormatting\",\n \"protect\",\n \"unprotect\",\n]);\n\n/** Streaming entry points hung off the ExcelJS namespace (`ExcelJS.stream.xlsx.*`); each throws. */\nexport const streamStub = {\n xlsx: {\n WorkbookWriter: class {\n constructor() {\n throw new UnsupportedFeatureError(\"stream.xlsx.WorkbookWriter\", COMPAT_DEFER);\n }\n },\n WorkbookReader: class {\n constructor() {\n throw new UnsupportedFeatureError(\"stream.xlsx.WorkbookReader\", COMPAT_DEFER);\n }\n },\n },\n} as const;\n\n// --- facade plumbing ----------------------------------------------------------------------------\n\n// One proxy per underlying object, so facade identity is stable (`ws.getCell('A1') === ws.getCell\n// ('A1')`) and re-wrapping is idempotent.\nconst workbookProxies = new WeakMap<Workbook, Workbook>();\nconst worksheetProxies = new WeakMap<Worksheet, Worksheet>();\nconst rowProxies = new WeakMap<Row, Row>();\nconst columnProxies = new WeakMap<Column, Column>();\nconst cellProxies = new WeakMap<Cell, Cell>();\n\n/** Wrap a value crossing the facade boundary on the way out: model objects become their proxies,\n * arrays are wrapped element-wise (preserving sparse holes, e.g. `row.values`), primitives pass. */\nfunction wrap(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(wrap);\n if (value instanceof Cell) return proxyCell(value);\n if (value instanceof Row) return proxyRow(value);\n if (value instanceof Column) return proxyColumn(value);\n if (value instanceof Worksheet) return proxyWorksheet(value);\n if (value instanceof Workbook) return proxyWorkbook(value);\n return value;\n}\n\n/** The inverse of {@link wrap} for a single value: a facade proxy back to its raw target. */\nfunction unwrap(value: unknown): unknown {\n if (value !== null && typeof value === \"object\") {\n const raw = (value as { [RAW]?: unknown })[RAW];\n if (raw !== undefined) return raw;\n }\n return value;\n}\n\n/** Transform one argument passed *into* a model method: unwrap facade args, and wrap the arguments\n * a user callback receives (so `eachRow`/`eachCell` hand back proxied rows/cells, not raw ones). */\nfunction mapArgIn(arg: unknown): unknown {\n if (typeof arg === \"function\") {\n const cb = arg as (...cbArgs: unknown[]) => unknown;\n return (...cbArgs: unknown[]) => cb(...cbArgs.map(wrap));\n }\n return unwrap(arg);\n}\n\n/** Default `get` behaviour shared by every facade: read the raw property, bind-and-wrap methods so\n * their return value (and callback args) cross the boundary, else wrap the plain value. */\nfunction reflectGet(target: object, prop: string | symbol): unknown {\n const value = Reflect.get(target, prop, target);\n if (typeof value === \"function\") {\n const fn = value as (...args: unknown[]) => unknown;\n return (...args: unknown[]) => wrap(fn.apply(target, args.map(mapArgIn)));\n }\n return wrap(value);\n}\n\n/** ExcelJS parity for `eachRow`/`eachCell`: without `includeEmpty`, ExcelJS drops rows/cells that are\n * empty (never held a value, or were explicitly set to `null`), while our core model still yields any\n * row/cell ever touched via `getRow`/`getCell`. This bridges that gap on the compat iteration path —\n * `isEmpty` tests the raw model item, and surviving items are wrapped like every other facade boundary\n * (so callbacks receive proxied rows/cells, not raw ones). `includeEmpty: true` passes straight through\n * to the core's full enumeration. */\nfunction eachWithEmptyFilter<T>(\n each: (opts: { includeEmpty: boolean }, cb: (item: T, n: number) => void) => void,\n isEmpty: (item: T) => boolean,\n optsOrCb: { includeEmpty?: boolean } | ((item: unknown, n: number) => void),\n maybeCb?: (item: unknown, n: number) => void,\n): void {\n const includeEmpty = typeof optsOrCb === \"object\" ? optsOrCb.includeEmpty === true : false;\n const cb = (typeof optsOrCb === \"function\" ? optsOrCb : maybeCb) as (\n item: unknown,\n n: number,\n ) => void;\n each({ includeEmpty }, (item, n) => {\n if (!includeEmpty && isEmpty(item)) return;\n cb(wrap(item), n);\n });\n}\n\n// --- the per-level proxies ----------------------------------------------------------------------\n\nfunction proxyCell(cell: Cell): Cell {\n const cached = cellProxies.get(cell);\n if (cached) return cached;\n const proxy = new Proxy(cell, {\n get(target, prop) {\n if (prop === RAW) return target;\n // Decision D1: compat cells always report ExcelJS ValueType numbers (§3).\n if (prop === \"type\") return toExcelJSValueType(target.type);\n if (prop === \"effectiveType\") return toExcelJSValueType(target.effectiveType);\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n // §4: assigning a style category replaces it whole-object, never field-merges.\n if (typeof prop === \"string\" && STYLE_SETTERS.has(prop)) {\n const patch: Style = {};\n (patch as Record<string, unknown>)[prop] = value;\n applyExcelJsStyle(target, patch);\n return true;\n }\n if (prop === \"note\") {\n throw new UnsupportedFeatureError(\"cell.note (comments)\", COMPAT_DEFER);\n }\n if (prop === \"dataValidation\") {\n throw new UnsupportedFeatureError(\"cell.dataValidation (data validation)\", COMPAT_DEFER);\n }\n return Reflect.set(target, prop, value, target);\n },\n });\n cellProxies.set(cell, proxy);\n return proxy;\n}\n\nfunction proxyRow(row: Row): Row {\n const cached = rowProxies.get(row);\n if (cached) return cached;\n const proxy = new Proxy(row, {\n get(target, prop) {\n if (prop === RAW) return target;\n // ExcelJS parity: default `eachCell` skips empty cells (§ MIGRATION \"eachRow/eachCell\").\n if (prop === \"eachCell\") {\n return (\n optsOrCb: { includeEmpty?: boolean } | ((cell: unknown, n: number) => void),\n maybeCb?: (cell: unknown, n: number) => void,\n ) =>\n eachWithEmptyFilter<Cell>(\n (o, cb) => target.eachCell(o, cb),\n (cell) => cell.type === CellType.Null,\n optsOrCb,\n maybeCb,\n );\n }\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n rowProxies.set(row, proxy);\n return proxy;\n}\n\nfunction proxyColumn(column: Column): Column {\n const cached = columnProxies.get(column);\n if (cached) return cached;\n const proxy = new Proxy(column, {\n get(target, prop) {\n if (prop === RAW) return target;\n // ExcelJS parity: default `eachCell` skips empty cells (§ MIGRATION \"eachRow/eachCell\").\n if (prop === \"eachCell\") {\n return (\n optsOrCb: { includeEmpty?: boolean } | ((cell: unknown, n: number) => void),\n maybeCb?: (cell: unknown, n: number) => void,\n ) =>\n eachWithEmptyFilter<Cell>(\n (o, cb) => target.eachCell(o, cb),\n (cell) => cell.type === CellType.Null,\n optsOrCb,\n maybeCb,\n );\n }\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n columnProxies.set(column, proxy);\n return proxy;\n}\n\nfunction proxyWorksheet(worksheet: Worksheet): Worksheet {\n const cached = worksheetProxies.get(worksheet);\n if (cached) return cached;\n const proxy = new Proxy(worksheet, {\n get(target, prop) {\n if (prop === RAW) return target;\n if (typeof prop === \"string\" && WORKSHEET_UNSUPPORTED.has(prop)) {\n return thrower(`worksheet.${prop}`);\n }\n if (prop === \"dataValidations\") {\n throw new UnsupportedFeatureError(\n \"worksheet.dataValidations (data validation)\",\n COMPAT_DEFER,\n );\n }\n // ExcelJS parity: default `eachRow` skips empty rows (§ MIGRATION \"eachRow/eachCell\").\n if (prop === \"eachRow\") {\n return (\n optsOrCb: { includeEmpty?: boolean } | ((row: unknown, n: number) => void),\n maybeCb?: (row: unknown, n: number) => void,\n ) =>\n eachWithEmptyFilter<Row>(\n (o, cb) => target.eachRow(o, cb),\n (row) => !row.hasValues,\n optsOrCb,\n maybeCb,\n );\n }\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n worksheetProxies.set(worksheet, proxy);\n return proxy;\n}\n\nfunction proxyWorkbook(workbook: Workbook): Workbook {\n const cached = workbookProxies.get(workbook);\n if (cached) return cached;\n const proxy = new Proxy(workbook, {\n get(target, prop) {\n if (prop === RAW) return target;\n // The I/O accessor is already ExcelJS-shaped; only rebind load/read/readFile so they resolve\n // to the *facade* (not the raw workbook), keeping the returned handle inside compat mode.\n if (prop === \"xlsx\") {\n const acc = Reflect.get(target, \"xlsx\", target) as XlsxAccessor;\n return {\n writeBuffer: (...args: Parameters<XlsxAccessor[\"writeBuffer\"]>) =>\n acc.writeBuffer(...args),\n writeFile: (...args: Parameters<XlsxAccessor[\"writeFile\"]>) => acc.writeFile(...args),\n load: async (...args: Parameters<XlsxAccessor[\"load\"]>) => {\n await acc.load(...args);\n return proxy;\n },\n readFile: async (...args: Parameters<XlsxAccessor[\"readFile\"]>) => {\n await acc.readFile(...args);\n return proxy;\n },\n read: async (...args: Parameters<XlsxAccessor[\"read\"]>) => {\n await acc.read(...args);\n return proxy;\n },\n } satisfies XlsxAccessor;\n }\n if (prop === \"csv\") return CSV_STUB;\n if (prop === \"definedNames\") return DEFINED_NAMES_STUB;\n if (prop === \"addImage\" || prop === \"getImage\") return thrower(`workbook.${prop}`);\n if (prop === \"media\") {\n throw new UnsupportedFeatureError(\"workbook.media (images)\", COMPAT_DEFER);\n }\n return reflectGet(target, prop);\n },\n set(target, prop, value) {\n return Reflect.set(target, prop, value, target);\n },\n });\n workbookProxies.set(workbook, proxy);\n return proxy;\n}\n\n/**\n * The compat `Workbook`: an ExcelJS drop-in. `new CompatWorkbook()` builds a plain core workbook and\n * returns a facade Proxy over it — so `instanceof` still holds (the proxy's target *is* a Workbook),\n * while every reachable cell/row/column/worksheet reports ExcelJS semantics (§5).\n */\nexport class CompatWorkbook extends Workbook {\n constructor() {\n super();\n // A constructor may return an object in place of `this`; we deliberately return the facade\n // wrapping the fully-initialised core instance — the whole mechanism of the shim (§5). Cast:\n // the proxy's target is this CompatWorkbook, so `instanceof` still holds.\n // biome-ignore lint/correctness/noConstructorReturn: returning the facade Proxy is intentional.\n return proxyWorkbook(this) as CompatWorkbook;\n }\n}\n","/**\n * @alosha/xlsx/compat — the ExcelJS drop-in shim entry point (docs/COMPAT-SPEC.md).\n *\n * The default export is shaped like the `exceljs` namespace (`{ Workbook, ValueType, Enums, stream }`)\n * and the named `Workbook` is the ExcelJS-faithful facade (`CompatWorkbook`, §5): compat-constructed\n * workbooks report ExcelJS `ValueType` numbers, apply whole-object style precedence, and throw\n * `UnsupportedFeatureError` on the deferred surface (§6). An ExcelJS user changes one import.\n *\n * Re-exports from `../index.js` (not `../model/index.js`) so the `workbook.xlsx` accessor — attached\n * to `Workbook.prototype` as a side effect of loading the main entry — is present on compat workbooks.\n * The star export's plain `Workbook` is deliberately shadowed by the explicit `CompatWorkbook as\n * Workbook` re-export below (explicit named exports win over `export *`).\n */\n\nimport { FormulaType, ValueType } from \"./value-type.js\";\nimport { CompatWorkbook, streamStub } from \"./workbook.js\";\n\nexport * from \"../index.js\";\nexport { fromExcelJSValueType, toExcelJSValueType, ValueType } from \"./value-type.js\";\nexport { CompatWorkbook, CompatWorkbook as Workbook } from \"./workbook.js\";\n\n/** ExcelJS's `Enums` grouping (`import { Enums } from \"exceljs\"`). */\nexport const Enums = {\n ValueType,\n FormulaType,\n} as const;\n\n/** The ExcelJS-shaped default export: `import ExcelJS from \"@alosha/xlsx/compat\"`. */\nconst ExcelJS = {\n Workbook: CompatWorkbook,\n ValueType,\n FormulaType,\n Enums,\n stream: streamStub,\n};\n\nexport default ExcelJS;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alosha/xlsx",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "A modern TypeScript library for reading and writing XLSX spreadsheets, inspired by exceljs.",
5
5
  "keywords": [
6
6
  "xlsx",