laterite 0.6.0 → 0.6.2

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/index.cjs CHANGED
@@ -666,6 +666,9 @@ var Ags4File = class _Ags4File {
666
666
  (0, import_node_fs.writeFileSync)(path, this.bytes);
667
667
  return path;
668
668
  }
669
+ toExcel(xlsxPath, opts = {}) {
670
+ return xlsxPath === void 0 ? toExcel(this.bytes, void 0, opts) : toExcel(this.bytes, xlsxPath, opts);
671
+ }
669
672
  // --- fluent verbs (validate / fix / diff) --------------------------------
670
673
  /** Resolve this handle to the `(source, opts)` the free fns take: the retained
671
674
  * read source (so line numbers match the original), or the re-emit for a
@@ -763,16 +766,7 @@ var Ags4File = class _Ags4File {
763
766
  * `read(f, { index })` consumes it to skip re-validation. Mirrors
764
767
  * `laterite.Ags4File.certify()`. */
765
768
  certify(path) {
766
- if (this.#report === void 0) {
767
- throw new Ags4Error(
768
- "call .validate() before .certify() \u2014 certify records a passed validation, it does not run one"
769
- );
770
- }
771
- if (!this.#report.isValid) {
772
- throw new Ags4Error(
773
- `cannot certify a file with ${this.#report.count} finding(s); fix them and re-validate clean first`
774
- );
775
- }
769
+ const report = this.#requireCleanValidation();
776
770
  const srcPath = this.#src?.path;
777
771
  const out = path ?? (srcPath !== void 0 ? `${srcPath}.idx` : void 0);
778
772
  if (out === void 0) {
@@ -793,9 +787,43 @@ var Ags4File = class _Ags4File {
793
787
  );
794
788
  }
795
789
  }
796
- const cert = import_native.Sidecar.assemble(
790
+ (0, import_node_fs.writeFileSync)(out, this.#mintCert(report).toJson());
791
+ return out;
792
+ }
793
+ /** Mint this file's `.ags.idx` certificate and return its **bytes** in memory —
794
+ * the filesystem-free twin of {@link certify}. Same precondition (a prior clean
795
+ * `.validate()`; it vouches for a passed validation, does not run one) and same
796
+ * output: the bytes are exactly what `certify` would write, so they interop with
797
+ * `read({ index })`, the CLI `--index`, and the browser cert. Ideal for handing
798
+ * the certificate straight to an upload/object store without a temp file — the
799
+ * certify analog of `transport.lockBytes`. Mirrors
800
+ * `laterite.Ags4File.certify_bytes()`. */
801
+ certifyBytes() {
802
+ return this.#mintCert(this.#requireCleanValidation()).toJson();
803
+ }
804
+ /** Shared precondition for `certify` / `certifyBytes`: a certificate vouches for
805
+ * a *passed* validation, so one must have run and found nothing. Returns the
806
+ * validated `Report` (narrowed non-undefined) for the minting step. */
807
+ #requireCleanValidation() {
808
+ if (this.#report === void 0) {
809
+ throw new Ags4Error(
810
+ "call .validate() before .certify() \u2014 certify records a passed validation, it does not run one"
811
+ );
812
+ }
813
+ if (!this.#report.isValid) {
814
+ throw new Ags4Error(
815
+ `cannot certify a file with ${this.#report.count} finding(s); fix them and re-validate clean first`
816
+ );
817
+ }
818
+ return this.#report;
819
+ }
820
+ /** Assemble the `Sidecar` certificate over the original source bytes, stamping
821
+ * the profile the last `.validate()` actually ran. `report` comes from
822
+ * `#requireCleanValidation`. */
823
+ #mintCert(report) {
824
+ return import_native.Sidecar.assemble(
797
825
  this.#sourceBytes(),
798
- this.#report.dictVersion,
826
+ report.dictVersion,
799
827
  (/* @__PURE__ */ new Date()).toISOString(),
800
828
  void 0,
801
829
  void 0,
@@ -803,8 +831,6 @@ var Ags4File = class _Ags4File {
803
831
  this.#lastCheckFiles,
804
832
  this.#lastForced
805
833
  );
806
- (0, import_node_fs.writeFileSync)(out, cert.toJson());
807
- return out;
808
834
  }
809
835
  // --- optional DuckDB engine (sql / at / connection) ----------------------
810
836
  async #getEngine() {
@@ -31689,9 +31715,13 @@ function parseValue2(raw, agsType) {
31689
31715
  var transport_exports = {};
31690
31716
  __export(transport_exports, {
31691
31717
  lock: () => lock,
31718
+ lockBytes: () => lockBytes,
31692
31719
  pack: () => pack,
31720
+ packBytes: () => packBytes,
31693
31721
  unlock: () => unlock,
31694
- unpack: () => unpack
31722
+ unlockBytes: () => unlockBytes,
31723
+ unpack: () => unpack,
31724
+ unpackBytes: () => unpackBytes
31695
31725
  });
31696
31726
  function pack(src, dest, level) {
31697
31727
  return (0, import_native.transportPack)(src, dest, level);
@@ -31705,6 +31735,18 @@ function lock(src, dest, password, level) {
31705
31735
  function unlock(src, dest, password) {
31706
31736
  return (0, import_native.transportUnlock)(src, dest, password);
31707
31737
  }
31738
+ function packBytes(data, level) {
31739
+ return (0, import_native.transportPackBytes)(data, level);
31740
+ }
31741
+ function unpackBytes(data) {
31742
+ return (0, import_native.transportUnpackBytes)(data);
31743
+ }
31744
+ function lockBytes(data, password, level) {
31745
+ return (0, import_native.transportLockBytes)(data, password, level);
31746
+ }
31747
+ function unlockBytes(data, password) {
31748
+ return (0, import_native.transportUnlockBytes)(data, password);
31749
+ }
31708
31750
 
31709
31751
  // ts/index.ts
31710
31752
  function read(source, opts = {}) {
@@ -31830,11 +31872,41 @@ function listRules2() {
31830
31872
  return JSON.parse((0, import_native.listRules)()).rules;
31831
31873
  }
31832
31874
  function fix(source, opts = {}) {
31875
+ if (opts.inPlace && opts.out !== void 0) {
31876
+ throw new TypeError("fix(): `inPlace` and `out` are mutually exclusive");
31877
+ }
31878
+ if (opts.only !== void 0 || opts.exclude !== void 0) {
31879
+ const fixable = new Set(listRules2().filter((r2) => r2.fixable).map((r2) => r2.rule));
31880
+ for (const [kw, labels] of [["only", opts.only], ["exclude", opts.exclude]]) {
31881
+ for (const label of labels ?? []) {
31882
+ if (!fixable.has(label)) {
31883
+ throw new TypeError(
31884
+ `fix(): ${kw} names rule "${label}", which is not fixable \u2014 see listRules() (fixable: true)`
31885
+ );
31886
+ }
31887
+ }
31888
+ }
31889
+ }
31833
31890
  const path = typeof source === "string" ? source : void 0;
31834
31891
  const data = typeof source === "string" || source == null ? void 0 : source;
31835
- const r = (0, import_native.fixFile)(path, opts.text, data, opts.dictVersion, opts.encoding, opts.risky);
31892
+ if (opts.inPlace && path === void 0) {
31893
+ throw makeError("bad_args", 5, "fix(): `inPlace` needs a path source; use `out` or `.save(path)`");
31894
+ }
31895
+ const r = (0, import_native.fixFile)(
31896
+ path,
31897
+ opts.text,
31898
+ data,
31899
+ opts.dictVersion,
31900
+ opts.encoding,
31901
+ opts.risky,
31902
+ opts.only,
31903
+ opts.exclude
31904
+ );
31836
31905
  if (!r.ok) throw makeError(r.errorKind ?? "", r.exitCode, r.error ?? "unknown error");
31837
- return new FixResult(r.fixed, r.residual, r.applied, r.dictVersion);
31906
+ const result = new FixResult(r.fixed, r.residual, r.applied, r.dictVersion);
31907
+ const dest = opts.inPlace ? path : opts.out;
31908
+ if (dest !== void 0) (0, import_node_fs4.writeFileSync)(dest, result.bytes);
31909
+ return result;
31838
31910
  }
31839
31911
  function diffBytes(x) {
31840
31912
  if (x instanceof Ags4File) return x.bytes;
@@ -31857,11 +31929,28 @@ function diff2(a, b, opts = {}) {
31857
31929
  throw fromNativeError(e);
31858
31930
  }
31859
31931
  }
31860
- function toExcel(agsPath, xlsxPath, opts = {}) {
31861
- return (0, import_native.ags4ToExcel)(agsPath, xlsxPath, opts.groups);
31932
+ function excelStatsOf(r) {
31933
+ return { sheetsWritten: r.sheetsWritten, rowsWritten: r.rowsWritten, warnings: r.warnings };
31934
+ }
31935
+ function toExcel(source, xlsxPath, opts = {}) {
31936
+ if (typeof source === "string" && xlsxPath !== void 0) {
31937
+ return (0, import_native.ags4ToExcel)(source, xlsxPath, opts.groups);
31938
+ }
31939
+ const agsBytes = typeof source === "string" ? (0, import_node_fs4.readFileSync)(source) : source;
31940
+ const r = (0, import_native.ags4BytesToXlsx)(agsBytes, opts.groups);
31941
+ if (xlsxPath === void 0) return r.bytes;
31942
+ (0, import_node_fs4.writeFileSync)(xlsxPath, r.bytes);
31943
+ return excelStatsOf(r);
31862
31944
  }
31863
- function fromExcel(xlsxPath, agsPath, opts = {}) {
31864
- return (0, import_native.excelToAgs4)(xlsxPath, agsPath, opts.formatNumericColumns);
31945
+ function fromExcel(source, agsPath, opts = {}) {
31946
+ if (typeof source === "string" && agsPath !== void 0) {
31947
+ return (0, import_native.excelToAgs4)(source, agsPath, opts.formatNumericColumns);
31948
+ }
31949
+ const xlsxBytes = typeof source === "string" ? (0, import_node_fs4.readFileSync)(source) : source;
31950
+ const r = (0, import_native.xlsxBytesToAgs4)(xlsxBytes, opts.formatNumericColumns);
31951
+ if (agsPath === void 0) return r.bytes;
31952
+ (0, import_node_fs4.writeFileSync)(agsPath, r.bytes);
31953
+ return excelStatsOf(r);
31865
31954
  }
31866
31955
  // Annotate the CommonJS export names for ESM import in node:
31867
31956
  0 && (module.exports = {
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Table } from 'apache-arrow';
2
- import { Finding, AppliedFix, ValidationReport, Sidecar, Reading, displayHint, PackStats, UnpackStats, ExcelStats } from '#native';
2
+ import { Finding, AppliedFix, ValidationReport, Sidecar, Reading, ExcelStats, displayHint, PackStats, UnpackStats } from '#native';
3
3
  export { AppliedFix, ExcelStats, Finding, GroupMeta, Sidecar, version } from '#native';
4
4
 
5
5
  /** One query result row — JS-native values (`getRowObjectsJS`: Dates, numbers,
@@ -239,6 +239,17 @@ declare class Ags4File {
239
239
  * @param path Filesystem path to write the UTF-8 AGS4 to.
240
240
  * @returns The same `path`, for chaining. */
241
241
  save(path: string): string;
242
+ /** Write this file's groups to an `.xlsx` workbook — one worksheet per group,
243
+ * from the spec-correct {@link bytes}. With `xlsxPath` given the workbook is
244
+ * written there and the conversion stats returned; omit it to get the `.xlsx`
245
+ * **bytes** back. Mirrors `laterite.Ags4File.to_excel()` and the free
246
+ * {@link toExcel}. `groups` fixes the worksheet order (default source order). */
247
+ toExcel(xlsxPath: string, opts?: {
248
+ groups?: string[];
249
+ }): ExcelStats;
250
+ toExcel(xlsxPath?: undefined, opts?: {
251
+ groups?: string[];
252
+ }): Buffer;
242
253
  /** The last `.validate()` outcome (`undefined` until validated). */
243
254
  get report(): Report | undefined;
244
255
  /** The `FixResult` on a handle returned by `.fix()` (`undefined` otherwise). */
@@ -273,6 +284,15 @@ declare class Ags4File {
273
284
  * `read(f, { index })` consumes it to skip re-validation. Mirrors
274
285
  * `laterite.Ags4File.certify()`. */
275
286
  certify(path?: string): string;
287
+ /** Mint this file's `.ags.idx` certificate and return its **bytes** in memory —
288
+ * the filesystem-free twin of {@link certify}. Same precondition (a prior clean
289
+ * `.validate()`; it vouches for a passed validation, does not run one) and same
290
+ * output: the bytes are exactly what `certify` would write, so they interop with
291
+ * `read({ index })`, the CLI `--index`, and the browser cert. Ideal for handing
292
+ * the certificate straight to an upload/object store without a temp file — the
293
+ * certify analog of `transport.lockBytes`. Mirrors
294
+ * `laterite.Ags4File.certify_bytes()`. */
295
+ certifyBytes(): Buffer;
276
296
  /** Run SQL over the file's groups by their clean names — e.g.
277
297
  * `await ags.sql("SELECT * FROM SAMP JOIN LOCA USING (LOCA_ID) WHERE …")`.
278
298
  * Any group may be referenced, so this loads them all into the engine.
@@ -4952,15 +4972,61 @@ declare function lock(src: string, dest: string, password: string, level?: numbe
4952
4972
  * @throws If the passphrase is wrong or the input is not a passphrase envelope.
4953
4973
  */
4954
4974
  declare function unlock(src: string, dest: string, password: string): UnpackStats;
4975
+ /**
4976
+ * zstd-compress `data` → bytes in memory (zstd only) — no filesystem. The
4977
+ * in-memory form of {@link pack}; the output is a standard zstd frame, so it
4978
+ * opens with {@link unpackBytes}, {@link unpack} (write it out first), or stock
4979
+ * `zstd`.
4980
+ *
4981
+ * @param data - The bytes to compress.
4982
+ * @param level - zstd level 1–22 (default 9).
4983
+ * @returns The compressed bytes.
4984
+ */
4985
+ declare function packBytes(data: Uint8Array, level?: number): Buffer;
4986
+ /**
4987
+ * zstd-decompress bytes → bytes in memory — the in-memory form of {@link unpack}.
4988
+ *
4989
+ * @param data - The zstd-compressed bytes (e.g. from {@link packBytes}).
4990
+ * @returns The decompressed bytes.
4991
+ */
4992
+ declare function unpackBytes(data: Uint8Array): Buffer;
4993
+ /**
4994
+ * zstd-compress + age-passphrase-encrypt `data` → bytes in memory — no plaintext
4995
+ * on disk. The in-memory form of {@link lock}, ideal for sealing sensitive data
4996
+ * you hold in memory (e.g. a fixed `Ags4File`'s `.bytes`) without ever writing
4997
+ * the plaintext out. The `.zst.age` envelope matches {@link lock}'s, so the
4998
+ * result opens with {@link unlockBytes}, {@link unlock}, `pyrage`, or the
4999
+ * browser, given the passphrase.
5000
+ *
5001
+ * @param data - The bytes to compress and encrypt.
5002
+ * @param password - The age passphrase. Required — there is no agent-key path.
5003
+ * @param level - zstd level 1–22 (default 9).
5004
+ * @returns The sealed bytes.
5005
+ */
5006
+ declare function lockBytes(data: Uint8Array, password: string, level?: number): Buffer;
5007
+ /**
5008
+ * age-passphrase-decrypt + zstd-decompress `.zst.age` bytes → bytes in memory —
5009
+ * the in-memory form of {@link unlock}.
5010
+ *
5011
+ * @param data - The sealed bytes (e.g. from {@link lockBytes}).
5012
+ * @param password - The age passphrase the envelope was sealed with.
5013
+ * @returns The original bytes.
5014
+ * @throws If the passphrase is wrong or the input is not a passphrase envelope.
5015
+ */
5016
+ declare function unlockBytes(data: Uint8Array, password: string): Buffer;
4955
5017
 
4956
5018
  declare const transport_PackStats: typeof PackStats;
4957
5019
  declare const transport_UnpackStats: typeof UnpackStats;
4958
5020
  declare const transport_lock: typeof lock;
5021
+ declare const transport_lockBytes: typeof lockBytes;
4959
5022
  declare const transport_pack: typeof pack;
5023
+ declare const transport_packBytes: typeof packBytes;
4960
5024
  declare const transport_unlock: typeof unlock;
5025
+ declare const transport_unlockBytes: typeof unlockBytes;
4961
5026
  declare const transport_unpack: typeof unpack;
5027
+ declare const transport_unpackBytes: typeof unpackBytes;
4962
5028
  declare namespace transport {
4963
- export { transport_PackStats as PackStats, transport_UnpackStats as UnpackStats, transport_lock as lock, transport_pack as pack, transport_unlock as unlock, transport_unpack as unpack };
5029
+ export { transport_PackStats as PackStats, transport_UnpackStats as UnpackStats, transport_lock as lock, transport_lockBytes as lockBytes, transport_pack as pack, transport_packBytes as packBytes, transport_unlock as unlock, transport_unlockBytes as unlockBytes, transport_unpack as unpack, transport_unpackBytes as unpackBytes };
4964
5030
  }
4965
5031
 
4966
5032
  interface ReadOptions {
@@ -5110,6 +5176,11 @@ interface RuleMeta {
5110
5176
  * `observations`).
5111
5177
  */
5112
5178
  declare function listRules(): RuleMeta[];
5179
+ /** The AGS Format Rule labels whose fixes {@link fix} can apply — the values for
5180
+ * `only` / `exclude`. Mirrors laterite-py's `FixableRule`; kept in lockstep with
5181
+ * the engine's `fixable_rules()` by a cross-surface drift gate
5182
+ * (`test_typed_choices.py`). Use {@link listRules} (`fixable: true`) at runtime. */
5183
+ type FixableRule = "1" | "2a" | "4" | "6" | "7" | "8" | "11a" | "11b";
5113
5184
  interface FixOptions {
5114
5185
  /** Repair in-memory `text` instead of a file path. */
5115
5186
  text?: string;
@@ -5119,6 +5190,18 @@ interface FixOptions {
5119
5190
  encoding?: string;
5120
5191
  /** Also apply the intent-guessing (risky) fixes, not just the safe set. */
5121
5192
  risky?: boolean;
5193
+ /** Apply *only* these rules' fixes (by {@link FixableRule} label); others are
5194
+ * left in place. The risk gate still applies, so a rule whose only fix is risky
5195
+ * needs `risky: true` even when named here. */
5196
+ only?: FixableRule[];
5197
+ /** Skip these rules' fixes. Combines with `only` (`only` narrows the set, then
5198
+ * `exclude` removes from it). */
5199
+ exclude?: FixableRule[];
5200
+ /** Write the repaired bytes back over the source file. Requires a path
5201
+ * `source`; mutually exclusive with `out`. Non-destructive by default. */
5202
+ inPlace?: boolean;
5203
+ /** Write the repaired bytes to this path. Mutually exclusive with `inPlace`. */
5204
+ out?: string;
5122
5205
  }
5123
5206
  /** Mechanically repair AGS4 — the headless twin of the browser's Fix engine.
5124
5207
  * `source` is a file path, raw `Uint8Array`/`Buffer` bytes, or (via `opts.text`)
@@ -5129,15 +5212,19 @@ interface FixOptions {
5129
5212
  * typography). The repaired bytes are re-validated, so `FixResult.findings` is
5130
5213
  * what could NOT be mechanically fixed.
5131
5214
  *
5132
- * Non-destructive: nothing is written here — the repaired bytes come back on the
5133
- * result (`.bytes` / `.text` / `.save(path)`), already UTF-8 with no BOM, so
5134
- * fixing a non-UTF-8 file also normalises its encoding. Mirrors `laterite.fix()`
5135
- * / `lat-check --fix`.
5215
+ * Non-destructive by default — the repaired bytes come back on the result
5216
+ * (`.bytes` / `.text` / `.save(path)`), already UTF-8 with no BOM, so fixing a
5217
+ * non-UTF-8 file also normalises its encoding. Pass `inPlace` to overwrite the
5218
+ * source or `out` to write elsewhere (the two are mutually exclusive). `only` /
5219
+ * `exclude` restrict which rules' fixes are applied. Mirrors `laterite.fix()` /
5220
+ * `lat-check --fix`.
5136
5221
  *
5137
5222
  * @param source - The AGS4 input: a filesystem path (`string`) or raw bytes
5138
5223
  * (`Uint8Array`/`Buffer`). Omit to repair `opts.text` instead.
5139
- * @param opts - {@link FixOptions} — `text` source, `risky` fixes, `dictVersion`
5224
+ * @param opts - {@link FixOptions} — `text` source, `risky` fixes, `only` /
5225
+ * `exclude` rule selection, `inPlace` / `out` write-back, `dictVersion`
5140
5226
  * override, and source `encoding`.
5227
+ * @throws {TypeError} If both `inPlace` and `out` are given.
5141
5228
  * @returns A {@link FixResult} carrying the repaired `bytes` (and `.text` /
5142
5229
  * `.save`), the `applied` fixes (with `fixesApplied` count), the residual
5143
5230
  * `findings` left after re-validation, and the resolved `dictVersion`.
@@ -5222,20 +5309,35 @@ type DiffSource = string | Uint8Array | Ags4File;
5222
5309
  */
5223
5310
  declare function diff(a: DiffSource, b: DiffSource, opts?: DiffOptions): RevisionDelta;
5224
5311
  /**
5225
- * Write an AGS4 file's groups to an `.xlsx` — one worksheet per group (the
5226
- * Node analog of Python's `to_excel`). `groups` forces the worksheet order;
5227
- * otherwise AGS4 source order is preserved. Returns the conversion stats.
5312
+ * Convert AGS4 to an `.xlsx` workbook — one worksheet per group (the Node analog
5313
+ * of Python's `to_excel`). `source` is an AGS4 file path or raw `Uint8Array`
5314
+ * bytes; `groups` forces the worksheet order (else AGS4 source order).
5315
+ *
5316
+ * With `xlsxPath` given the workbook is written there and the conversion stats
5317
+ * are returned; omit `xlsxPath` to get the `.xlsx` **bytes** back (the FS-free
5318
+ * form — an uploaded/in-memory AGS4 needn't hit disk). Bytes both ways drive the
5319
+ * same core the browser Excel tools use.
5228
5320
  */
5229
- declare function toExcel(agsPath: string, xlsxPath: string, opts?: {
5321
+ declare function toExcel(source: string | Uint8Array, xlsxPath: string, opts?: {
5230
5322
  groups?: string[];
5231
5323
  }): ExcelStats;
5324
+ declare function toExcel(source: string | Uint8Array, xlsxPath?: undefined, opts?: {
5325
+ groups?: string[];
5326
+ }): Buffer;
5232
5327
  /**
5233
- * Read an `.xlsx` back into an AGS4 file (the Node analog of `from_excel`).
5234
- * `formatNumericColumns` (default true) re-applies AGS4 numeric formatting to
5235
- * numeric-looking columns. Returns the conversion stats.
5328
+ * Convert an AGS4-shaped `.xlsx` workbook to AGS4 (the Node analog of
5329
+ * `from_excel`). `source` is an `.xlsx` file path or raw `Uint8Array` bytes;
5330
+ * `formatNumericColumns` (default true) re-applies AGS4 numeric formatting.
5331
+ *
5332
+ * With `agsPath` given the AGS4 is written there and the conversion stats are
5333
+ * returned; omit `agsPath` to get the AGS4 **bytes** back — so an uploaded `.xlsx`
5334
+ * never has to touch disk.
5236
5335
  */
5237
- declare function fromExcel(xlsxPath: string, agsPath: string, opts?: {
5336
+ declare function fromExcel(source: string | Uint8Array, agsPath: string, opts?: {
5238
5337
  formatNumericColumns?: boolean;
5239
5338
  }): ExcelStats;
5339
+ declare function fromExcel(source: string | Uint8Array, agsPath?: undefined, opts?: {
5340
+ formatNumericColumns?: boolean;
5341
+ }): Buffer;
5240
5342
 
5241
- export { AAVT, ABBR, ACVT, AELO, AFLK, AIVT, ALOS, APSV, ARTW, ASDI, ASNS, AWAD, Ags4Error, Ags4File, AgsGroup, AgsSubset, type AgsValue, BKFL, BadDictError, type BuildFinding, BuildResult, CBRG, CBRP, CBRT, CDIA, CHIS, CHOC, CMPG, CMPT, CONG, CONS, CORE, CPDG, CPDT, CPTG, CPTM, CPTP, CPTT, CPTY, CPTZ, CTRC, CTRD, CTRG, CTRP, CTRS, type CanonicalType, type CellDelta, DCPG, DCPT, DETL, DICT, DISC, DLOG, DMDG, DMDT, DMTG, DMTP, DMTT, DMTZ, DOBS, DPRB, DPRG, DREM, type DiffOptions, type DiffSource, ECTN, ELRG, ERES, ESCG, ESCT, type EmitOptions, FGHG, FGHI, FGHS, FGHT, FILE, FLSH, FRAC, FRST, FileNotFoundError, type Filter, type FixOptions, FixResult, GCHM, GEOL, GRAG, GRAT, type GroupData, type GroupDelta, GroupDescriptor, type GroupRows, HDIA, HDPH, HORN, type Heading, type HeadingStatus, ICBR, IDEN, IFID, IPEN, IPID, IPRG, IPRT, IRDX, IRES, ISAG, ISAT, ISPT, ISTA, ISTG, ISTR, ISTS, ITCH, IVAN, LBSG, LBST, LDEN, LDYN, LFCN, LLIN, LLPL, LNMC, LOCA, LPDN, LPEN, LRES, LSLT, LSTG, LSTT, LSWL, LTCH, LUCT, LVAN, MCVG, MCVT, MOND, MONG, MONS, NotAgs4Error, PIPE, PLTG, PLTT, PMMC, PMMD, PMMG, PMTD, PMTG, PMTL, PMTP, PMTZ, PREM, PROJ, PTIM, PTST, PUMG, PUMT, type QueryOptions, RCAG, RCAT, RCCV, RDEN, RELD, RESC, RESD, RESG, RESP, RESS, RPLT, RSCH, RSHR, RTEN, RUCS, RWCO, type ReadOptions, Report, type RevisionDelta, type Row, type RowDelta, type RuleFinding, type RuleMeta, type RuleObservation, SAMP, SCDG, SCDT, SCPG, SCPP, SCPT, SHBG, SHBT, STND, SUCT, StaleCertError, TNPC, TRAN, TREG, TREM, TRET, TRIG, TRIT, TYPE, UNIT, UnsupportedEditionError, type ValidateOptions, WADD, WETH, WGPG, WGPT, WINS, WSTD, WSTG, agsTypes, buildAgs4, diff, fix, fromExcel, listRules, read, registry, toExcel, transport, validate };
5343
+ export { AAVT, ABBR, ACVT, AELO, AFLK, AIVT, ALOS, APSV, ARTW, ASDI, ASNS, AWAD, Ags4Error, Ags4File, AgsGroup, AgsSubset, type AgsValue, BKFL, BadDictError, type BuildFinding, BuildResult, CBRG, CBRP, CBRT, CDIA, CHIS, CHOC, CMPG, CMPT, CONG, CONS, CORE, CPDG, CPDT, CPTG, CPTM, CPTP, CPTT, CPTY, CPTZ, CTRC, CTRD, CTRG, CTRP, CTRS, type CanonicalType, type CellDelta, DCPG, DCPT, DETL, DICT, DISC, DLOG, DMDG, DMDT, DMTG, DMTP, DMTT, DMTZ, DOBS, DPRB, DPRG, DREM, type DiffOptions, type DiffSource, ECTN, ELRG, ERES, ESCG, ESCT, type EmitOptions, FGHG, FGHI, FGHS, FGHT, FILE, FLSH, FRAC, FRST, FileNotFoundError, type Filter, type FixOptions, FixResult, type FixableRule, GCHM, GEOL, GRAG, GRAT, type GroupData, type GroupDelta, GroupDescriptor, type GroupRows, HDIA, HDPH, HORN, type Heading, type HeadingStatus, ICBR, IDEN, IFID, IPEN, IPID, IPRG, IPRT, IRDX, IRES, ISAG, ISAT, ISPT, ISTA, ISTG, ISTR, ISTS, ITCH, IVAN, LBSG, LBST, LDEN, LDYN, LFCN, LLIN, LLPL, LNMC, LOCA, LPDN, LPEN, LRES, LSLT, LSTG, LSTT, LSWL, LTCH, LUCT, LVAN, MCVG, MCVT, MOND, MONG, MONS, NotAgs4Error, PIPE, PLTG, PLTT, PMMC, PMMD, PMMG, PMTD, PMTG, PMTL, PMTP, PMTZ, PREM, PROJ, PTIM, PTST, PUMG, PUMT, type QueryOptions, RCAG, RCAT, RCCV, RDEN, RELD, RESC, RESD, RESG, RESP, RESS, RPLT, RSCH, RSHR, RTEN, RUCS, RWCO, type ReadOptions, Report, type RevisionDelta, type Row, type RowDelta, type RuleFinding, type RuleMeta, type RuleObservation, SAMP, SCDG, SCDT, SCPG, SCPP, SCPT, SHBG, SHBT, STND, SUCT, StaleCertError, TNPC, TRAN, TREG, TREM, TRET, TRIG, TRIT, TYPE, UNIT, UnsupportedEditionError, type ValidateOptions, WADD, WETH, WGPG, WGPT, WINS, WSTD, WSTG, agsTypes, buildAgs4, diff, fix, fromExcel, listRules, read, registry, toExcel, transport, validate };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Table } from 'apache-arrow';
2
- import { Finding, AppliedFix, ValidationReport, Sidecar, Reading, displayHint, PackStats, UnpackStats, ExcelStats } from '#native';
2
+ import { Finding, AppliedFix, ValidationReport, Sidecar, Reading, ExcelStats, displayHint, PackStats, UnpackStats } from '#native';
3
3
  export { AppliedFix, ExcelStats, Finding, GroupMeta, Sidecar, version } from '#native';
4
4
 
5
5
  /** One query result row — JS-native values (`getRowObjectsJS`: Dates, numbers,
@@ -239,6 +239,17 @@ declare class Ags4File {
239
239
  * @param path Filesystem path to write the UTF-8 AGS4 to.
240
240
  * @returns The same `path`, for chaining. */
241
241
  save(path: string): string;
242
+ /** Write this file's groups to an `.xlsx` workbook — one worksheet per group,
243
+ * from the spec-correct {@link bytes}. With `xlsxPath` given the workbook is
244
+ * written there and the conversion stats returned; omit it to get the `.xlsx`
245
+ * **bytes** back. Mirrors `laterite.Ags4File.to_excel()` and the free
246
+ * {@link toExcel}. `groups` fixes the worksheet order (default source order). */
247
+ toExcel(xlsxPath: string, opts?: {
248
+ groups?: string[];
249
+ }): ExcelStats;
250
+ toExcel(xlsxPath?: undefined, opts?: {
251
+ groups?: string[];
252
+ }): Buffer;
242
253
  /** The last `.validate()` outcome (`undefined` until validated). */
243
254
  get report(): Report | undefined;
244
255
  /** The `FixResult` on a handle returned by `.fix()` (`undefined` otherwise). */
@@ -273,6 +284,15 @@ declare class Ags4File {
273
284
  * `read(f, { index })` consumes it to skip re-validation. Mirrors
274
285
  * `laterite.Ags4File.certify()`. */
275
286
  certify(path?: string): string;
287
+ /** Mint this file's `.ags.idx` certificate and return its **bytes** in memory —
288
+ * the filesystem-free twin of {@link certify}. Same precondition (a prior clean
289
+ * `.validate()`; it vouches for a passed validation, does not run one) and same
290
+ * output: the bytes are exactly what `certify` would write, so they interop with
291
+ * `read({ index })`, the CLI `--index`, and the browser cert. Ideal for handing
292
+ * the certificate straight to an upload/object store without a temp file — the
293
+ * certify analog of `transport.lockBytes`. Mirrors
294
+ * `laterite.Ags4File.certify_bytes()`. */
295
+ certifyBytes(): Buffer;
276
296
  /** Run SQL over the file's groups by their clean names — e.g.
277
297
  * `await ags.sql("SELECT * FROM SAMP JOIN LOCA USING (LOCA_ID) WHERE …")`.
278
298
  * Any group may be referenced, so this loads them all into the engine.
@@ -4952,15 +4972,61 @@ declare function lock(src: string, dest: string, password: string, level?: numbe
4952
4972
  * @throws If the passphrase is wrong or the input is not a passphrase envelope.
4953
4973
  */
4954
4974
  declare function unlock(src: string, dest: string, password: string): UnpackStats;
4975
+ /**
4976
+ * zstd-compress `data` → bytes in memory (zstd only) — no filesystem. The
4977
+ * in-memory form of {@link pack}; the output is a standard zstd frame, so it
4978
+ * opens with {@link unpackBytes}, {@link unpack} (write it out first), or stock
4979
+ * `zstd`.
4980
+ *
4981
+ * @param data - The bytes to compress.
4982
+ * @param level - zstd level 1–22 (default 9).
4983
+ * @returns The compressed bytes.
4984
+ */
4985
+ declare function packBytes(data: Uint8Array, level?: number): Buffer;
4986
+ /**
4987
+ * zstd-decompress bytes → bytes in memory — the in-memory form of {@link unpack}.
4988
+ *
4989
+ * @param data - The zstd-compressed bytes (e.g. from {@link packBytes}).
4990
+ * @returns The decompressed bytes.
4991
+ */
4992
+ declare function unpackBytes(data: Uint8Array): Buffer;
4993
+ /**
4994
+ * zstd-compress + age-passphrase-encrypt `data` → bytes in memory — no plaintext
4995
+ * on disk. The in-memory form of {@link lock}, ideal for sealing sensitive data
4996
+ * you hold in memory (e.g. a fixed `Ags4File`'s `.bytes`) without ever writing
4997
+ * the plaintext out. The `.zst.age` envelope matches {@link lock}'s, so the
4998
+ * result opens with {@link unlockBytes}, {@link unlock}, `pyrage`, or the
4999
+ * browser, given the passphrase.
5000
+ *
5001
+ * @param data - The bytes to compress and encrypt.
5002
+ * @param password - The age passphrase. Required — there is no agent-key path.
5003
+ * @param level - zstd level 1–22 (default 9).
5004
+ * @returns The sealed bytes.
5005
+ */
5006
+ declare function lockBytes(data: Uint8Array, password: string, level?: number): Buffer;
5007
+ /**
5008
+ * age-passphrase-decrypt + zstd-decompress `.zst.age` bytes → bytes in memory —
5009
+ * the in-memory form of {@link unlock}.
5010
+ *
5011
+ * @param data - The sealed bytes (e.g. from {@link lockBytes}).
5012
+ * @param password - The age passphrase the envelope was sealed with.
5013
+ * @returns The original bytes.
5014
+ * @throws If the passphrase is wrong or the input is not a passphrase envelope.
5015
+ */
5016
+ declare function unlockBytes(data: Uint8Array, password: string): Buffer;
4955
5017
 
4956
5018
  declare const transport_PackStats: typeof PackStats;
4957
5019
  declare const transport_UnpackStats: typeof UnpackStats;
4958
5020
  declare const transport_lock: typeof lock;
5021
+ declare const transport_lockBytes: typeof lockBytes;
4959
5022
  declare const transport_pack: typeof pack;
5023
+ declare const transport_packBytes: typeof packBytes;
4960
5024
  declare const transport_unlock: typeof unlock;
5025
+ declare const transport_unlockBytes: typeof unlockBytes;
4961
5026
  declare const transport_unpack: typeof unpack;
5027
+ declare const transport_unpackBytes: typeof unpackBytes;
4962
5028
  declare namespace transport {
4963
- export { transport_PackStats as PackStats, transport_UnpackStats as UnpackStats, transport_lock as lock, transport_pack as pack, transport_unlock as unlock, transport_unpack as unpack };
5029
+ export { transport_PackStats as PackStats, transport_UnpackStats as UnpackStats, transport_lock as lock, transport_lockBytes as lockBytes, transport_pack as pack, transport_packBytes as packBytes, transport_unlock as unlock, transport_unlockBytes as unlockBytes, transport_unpack as unpack, transport_unpackBytes as unpackBytes };
4964
5030
  }
4965
5031
 
4966
5032
  interface ReadOptions {
@@ -5110,6 +5176,11 @@ interface RuleMeta {
5110
5176
  * `observations`).
5111
5177
  */
5112
5178
  declare function listRules(): RuleMeta[];
5179
+ /** The AGS Format Rule labels whose fixes {@link fix} can apply — the values for
5180
+ * `only` / `exclude`. Mirrors laterite-py's `FixableRule`; kept in lockstep with
5181
+ * the engine's `fixable_rules()` by a cross-surface drift gate
5182
+ * (`test_typed_choices.py`). Use {@link listRules} (`fixable: true`) at runtime. */
5183
+ type FixableRule = "1" | "2a" | "4" | "6" | "7" | "8" | "11a" | "11b";
5113
5184
  interface FixOptions {
5114
5185
  /** Repair in-memory `text` instead of a file path. */
5115
5186
  text?: string;
@@ -5119,6 +5190,18 @@ interface FixOptions {
5119
5190
  encoding?: string;
5120
5191
  /** Also apply the intent-guessing (risky) fixes, not just the safe set. */
5121
5192
  risky?: boolean;
5193
+ /** Apply *only* these rules' fixes (by {@link FixableRule} label); others are
5194
+ * left in place. The risk gate still applies, so a rule whose only fix is risky
5195
+ * needs `risky: true` even when named here. */
5196
+ only?: FixableRule[];
5197
+ /** Skip these rules' fixes. Combines with `only` (`only` narrows the set, then
5198
+ * `exclude` removes from it). */
5199
+ exclude?: FixableRule[];
5200
+ /** Write the repaired bytes back over the source file. Requires a path
5201
+ * `source`; mutually exclusive with `out`. Non-destructive by default. */
5202
+ inPlace?: boolean;
5203
+ /** Write the repaired bytes to this path. Mutually exclusive with `inPlace`. */
5204
+ out?: string;
5122
5205
  }
5123
5206
  /** Mechanically repair AGS4 — the headless twin of the browser's Fix engine.
5124
5207
  * `source` is a file path, raw `Uint8Array`/`Buffer` bytes, or (via `opts.text`)
@@ -5129,15 +5212,19 @@ interface FixOptions {
5129
5212
  * typography). The repaired bytes are re-validated, so `FixResult.findings` is
5130
5213
  * what could NOT be mechanically fixed.
5131
5214
  *
5132
- * Non-destructive: nothing is written here — the repaired bytes come back on the
5133
- * result (`.bytes` / `.text` / `.save(path)`), already UTF-8 with no BOM, so
5134
- * fixing a non-UTF-8 file also normalises its encoding. Mirrors `laterite.fix()`
5135
- * / `lat-check --fix`.
5215
+ * Non-destructive by default — the repaired bytes come back on the result
5216
+ * (`.bytes` / `.text` / `.save(path)`), already UTF-8 with no BOM, so fixing a
5217
+ * non-UTF-8 file also normalises its encoding. Pass `inPlace` to overwrite the
5218
+ * source or `out` to write elsewhere (the two are mutually exclusive). `only` /
5219
+ * `exclude` restrict which rules' fixes are applied. Mirrors `laterite.fix()` /
5220
+ * `lat-check --fix`.
5136
5221
  *
5137
5222
  * @param source - The AGS4 input: a filesystem path (`string`) or raw bytes
5138
5223
  * (`Uint8Array`/`Buffer`). Omit to repair `opts.text` instead.
5139
- * @param opts - {@link FixOptions} — `text` source, `risky` fixes, `dictVersion`
5224
+ * @param opts - {@link FixOptions} — `text` source, `risky` fixes, `only` /
5225
+ * `exclude` rule selection, `inPlace` / `out` write-back, `dictVersion`
5140
5226
  * override, and source `encoding`.
5227
+ * @throws {TypeError} If both `inPlace` and `out` are given.
5141
5228
  * @returns A {@link FixResult} carrying the repaired `bytes` (and `.text` /
5142
5229
  * `.save`), the `applied` fixes (with `fixesApplied` count), the residual
5143
5230
  * `findings` left after re-validation, and the resolved `dictVersion`.
@@ -5222,20 +5309,35 @@ type DiffSource = string | Uint8Array | Ags4File;
5222
5309
  */
5223
5310
  declare function diff(a: DiffSource, b: DiffSource, opts?: DiffOptions): RevisionDelta;
5224
5311
  /**
5225
- * Write an AGS4 file's groups to an `.xlsx` — one worksheet per group (the
5226
- * Node analog of Python's `to_excel`). `groups` forces the worksheet order;
5227
- * otherwise AGS4 source order is preserved. Returns the conversion stats.
5312
+ * Convert AGS4 to an `.xlsx` workbook — one worksheet per group (the Node analog
5313
+ * of Python's `to_excel`). `source` is an AGS4 file path or raw `Uint8Array`
5314
+ * bytes; `groups` forces the worksheet order (else AGS4 source order).
5315
+ *
5316
+ * With `xlsxPath` given the workbook is written there and the conversion stats
5317
+ * are returned; omit `xlsxPath` to get the `.xlsx` **bytes** back (the FS-free
5318
+ * form — an uploaded/in-memory AGS4 needn't hit disk). Bytes both ways drive the
5319
+ * same core the browser Excel tools use.
5228
5320
  */
5229
- declare function toExcel(agsPath: string, xlsxPath: string, opts?: {
5321
+ declare function toExcel(source: string | Uint8Array, xlsxPath: string, opts?: {
5230
5322
  groups?: string[];
5231
5323
  }): ExcelStats;
5324
+ declare function toExcel(source: string | Uint8Array, xlsxPath?: undefined, opts?: {
5325
+ groups?: string[];
5326
+ }): Buffer;
5232
5327
  /**
5233
- * Read an `.xlsx` back into an AGS4 file (the Node analog of `from_excel`).
5234
- * `formatNumericColumns` (default true) re-applies AGS4 numeric formatting to
5235
- * numeric-looking columns. Returns the conversion stats.
5328
+ * Convert an AGS4-shaped `.xlsx` workbook to AGS4 (the Node analog of
5329
+ * `from_excel`). `source` is an `.xlsx` file path or raw `Uint8Array` bytes;
5330
+ * `formatNumericColumns` (default true) re-applies AGS4 numeric formatting.
5331
+ *
5332
+ * With `agsPath` given the AGS4 is written there and the conversion stats are
5333
+ * returned; omit `agsPath` to get the AGS4 **bytes** back — so an uploaded `.xlsx`
5334
+ * never has to touch disk.
5236
5335
  */
5237
- declare function fromExcel(xlsxPath: string, agsPath: string, opts?: {
5336
+ declare function fromExcel(source: string | Uint8Array, agsPath: string, opts?: {
5238
5337
  formatNumericColumns?: boolean;
5239
5338
  }): ExcelStats;
5339
+ declare function fromExcel(source: string | Uint8Array, agsPath?: undefined, opts?: {
5340
+ formatNumericColumns?: boolean;
5341
+ }): Buffer;
5240
5342
 
5241
- export { AAVT, ABBR, ACVT, AELO, AFLK, AIVT, ALOS, APSV, ARTW, ASDI, ASNS, AWAD, Ags4Error, Ags4File, AgsGroup, AgsSubset, type AgsValue, BKFL, BadDictError, type BuildFinding, BuildResult, CBRG, CBRP, CBRT, CDIA, CHIS, CHOC, CMPG, CMPT, CONG, CONS, CORE, CPDG, CPDT, CPTG, CPTM, CPTP, CPTT, CPTY, CPTZ, CTRC, CTRD, CTRG, CTRP, CTRS, type CanonicalType, type CellDelta, DCPG, DCPT, DETL, DICT, DISC, DLOG, DMDG, DMDT, DMTG, DMTP, DMTT, DMTZ, DOBS, DPRB, DPRG, DREM, type DiffOptions, type DiffSource, ECTN, ELRG, ERES, ESCG, ESCT, type EmitOptions, FGHG, FGHI, FGHS, FGHT, FILE, FLSH, FRAC, FRST, FileNotFoundError, type Filter, type FixOptions, FixResult, GCHM, GEOL, GRAG, GRAT, type GroupData, type GroupDelta, GroupDescriptor, type GroupRows, HDIA, HDPH, HORN, type Heading, type HeadingStatus, ICBR, IDEN, IFID, IPEN, IPID, IPRG, IPRT, IRDX, IRES, ISAG, ISAT, ISPT, ISTA, ISTG, ISTR, ISTS, ITCH, IVAN, LBSG, LBST, LDEN, LDYN, LFCN, LLIN, LLPL, LNMC, LOCA, LPDN, LPEN, LRES, LSLT, LSTG, LSTT, LSWL, LTCH, LUCT, LVAN, MCVG, MCVT, MOND, MONG, MONS, NotAgs4Error, PIPE, PLTG, PLTT, PMMC, PMMD, PMMG, PMTD, PMTG, PMTL, PMTP, PMTZ, PREM, PROJ, PTIM, PTST, PUMG, PUMT, type QueryOptions, RCAG, RCAT, RCCV, RDEN, RELD, RESC, RESD, RESG, RESP, RESS, RPLT, RSCH, RSHR, RTEN, RUCS, RWCO, type ReadOptions, Report, type RevisionDelta, type Row, type RowDelta, type RuleFinding, type RuleMeta, type RuleObservation, SAMP, SCDG, SCDT, SCPG, SCPP, SCPT, SHBG, SHBT, STND, SUCT, StaleCertError, TNPC, TRAN, TREG, TREM, TRET, TRIG, TRIT, TYPE, UNIT, UnsupportedEditionError, type ValidateOptions, WADD, WETH, WGPG, WGPT, WINS, WSTD, WSTG, agsTypes, buildAgs4, diff, fix, fromExcel, listRules, read, registry, toExcel, transport, validate };
5343
+ export { AAVT, ABBR, ACVT, AELO, AFLK, AIVT, ALOS, APSV, ARTW, ASDI, ASNS, AWAD, Ags4Error, Ags4File, AgsGroup, AgsSubset, type AgsValue, BKFL, BadDictError, type BuildFinding, BuildResult, CBRG, CBRP, CBRT, CDIA, CHIS, CHOC, CMPG, CMPT, CONG, CONS, CORE, CPDG, CPDT, CPTG, CPTM, CPTP, CPTT, CPTY, CPTZ, CTRC, CTRD, CTRG, CTRP, CTRS, type CanonicalType, type CellDelta, DCPG, DCPT, DETL, DICT, DISC, DLOG, DMDG, DMDT, DMTG, DMTP, DMTT, DMTZ, DOBS, DPRB, DPRG, DREM, type DiffOptions, type DiffSource, ECTN, ELRG, ERES, ESCG, ESCT, type EmitOptions, FGHG, FGHI, FGHS, FGHT, FILE, FLSH, FRAC, FRST, FileNotFoundError, type Filter, type FixOptions, FixResult, type FixableRule, GCHM, GEOL, GRAG, GRAT, type GroupData, type GroupDelta, GroupDescriptor, type GroupRows, HDIA, HDPH, HORN, type Heading, type HeadingStatus, ICBR, IDEN, IFID, IPEN, IPID, IPRG, IPRT, IRDX, IRES, ISAG, ISAT, ISPT, ISTA, ISTG, ISTR, ISTS, ITCH, IVAN, LBSG, LBST, LDEN, LDYN, LFCN, LLIN, LLPL, LNMC, LOCA, LPDN, LPEN, LRES, LSLT, LSTG, LSTT, LSWL, LTCH, LUCT, LVAN, MCVG, MCVT, MOND, MONG, MONS, NotAgs4Error, PIPE, PLTG, PLTT, PMMC, PMMD, PMMG, PMTD, PMTG, PMTL, PMTP, PMTZ, PREM, PROJ, PTIM, PTST, PUMG, PUMT, type QueryOptions, RCAG, RCAT, RCCV, RDEN, RELD, RESC, RESD, RESG, RESP, RESS, RPLT, RSCH, RSHR, RTEN, RUCS, RWCO, type ReadOptions, Report, type RevisionDelta, type Row, type RowDelta, type RuleFinding, type RuleMeta, type RuleObservation, SAMP, SCDG, SCDT, SCPG, SCPP, SCPT, SHBG, SHBT, STND, SUCT, StaleCertError, TNPC, TRAN, TREG, TREM, TRET, TRIG, TRIT, TYPE, UNIT, UnsupportedEditionError, type ValidateOptions, WADD, WETH, WGPG, WGPT, WINS, WSTD, WSTG, agsTypes, buildAgs4, diff, fix, fromExcel, listRules, read, registry, toExcel, transport, validate };
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // ts/index.ts
8
- import { readFileSync as readFileSync2 } from "fs";
8
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync4 } from "fs";
9
9
  import { tableFromArrays, tableToIPC } from "apache-arrow";
10
10
 
11
11
  // ts/ags4-file.ts
@@ -235,8 +235,14 @@ import {
235
235
  transportUnpack,
236
236
  transportLock,
237
237
  transportUnlock,
238
+ transportPackBytes,
239
+ transportUnpackBytes,
240
+ transportLockBytes,
241
+ transportUnlockBytes,
238
242
  ags4ToExcel,
239
- excelToAgs4
243
+ excelToAgs4,
244
+ ags4BytesToXlsx,
245
+ xlsxBytesToAgs4
240
246
  } from "#native";
241
247
 
242
248
  // ts/report.ts
@@ -470,6 +476,9 @@ var Ags4File = class _Ags4File {
470
476
  writeFileSync(path, this.bytes);
471
477
  return path;
472
478
  }
479
+ toExcel(xlsxPath, opts = {}) {
480
+ return xlsxPath === void 0 ? toExcel(this.bytes, void 0, opts) : toExcel(this.bytes, xlsxPath, opts);
481
+ }
473
482
  // --- fluent verbs (validate / fix / diff) --------------------------------
474
483
  /** Resolve this handle to the `(source, opts)` the free fns take: the retained
475
484
  * read source (so line numbers match the original), or the re-emit for a
@@ -567,16 +576,7 @@ var Ags4File = class _Ags4File {
567
576
  * `read(f, { index })` consumes it to skip re-validation. Mirrors
568
577
  * `laterite.Ags4File.certify()`. */
569
578
  certify(path) {
570
- if (this.#report === void 0) {
571
- throw new Ags4Error(
572
- "call .validate() before .certify() \u2014 certify records a passed validation, it does not run one"
573
- );
574
- }
575
- if (!this.#report.isValid) {
576
- throw new Ags4Error(
577
- `cannot certify a file with ${this.#report.count} finding(s); fix them and re-validate clean first`
578
- );
579
- }
579
+ const report = this.#requireCleanValidation();
580
580
  const srcPath = this.#src?.path;
581
581
  const out = path ?? (srcPath !== void 0 ? `${srcPath}.idx` : void 0);
582
582
  if (out === void 0) {
@@ -597,9 +597,43 @@ var Ags4File = class _Ags4File {
597
597
  );
598
598
  }
599
599
  }
600
- const cert = Sidecar.assemble(
600
+ writeFileSync(out, this.#mintCert(report).toJson());
601
+ return out;
602
+ }
603
+ /** Mint this file's `.ags.idx` certificate and return its **bytes** in memory —
604
+ * the filesystem-free twin of {@link certify}. Same precondition (a prior clean
605
+ * `.validate()`; it vouches for a passed validation, does not run one) and same
606
+ * output: the bytes are exactly what `certify` would write, so they interop with
607
+ * `read({ index })`, the CLI `--index`, and the browser cert. Ideal for handing
608
+ * the certificate straight to an upload/object store without a temp file — the
609
+ * certify analog of `transport.lockBytes`. Mirrors
610
+ * `laterite.Ags4File.certify_bytes()`. */
611
+ certifyBytes() {
612
+ return this.#mintCert(this.#requireCleanValidation()).toJson();
613
+ }
614
+ /** Shared precondition for `certify` / `certifyBytes`: a certificate vouches for
615
+ * a *passed* validation, so one must have run and found nothing. Returns the
616
+ * validated `Report` (narrowed non-undefined) for the minting step. */
617
+ #requireCleanValidation() {
618
+ if (this.#report === void 0) {
619
+ throw new Ags4Error(
620
+ "call .validate() before .certify() \u2014 certify records a passed validation, it does not run one"
621
+ );
622
+ }
623
+ if (!this.#report.isValid) {
624
+ throw new Ags4Error(
625
+ `cannot certify a file with ${this.#report.count} finding(s); fix them and re-validate clean first`
626
+ );
627
+ }
628
+ return this.#report;
629
+ }
630
+ /** Assemble the `Sidecar` certificate over the original source bytes, stamping
631
+ * the profile the last `.validate()` actually ran. `report` comes from
632
+ * `#requireCleanValidation`. */
633
+ #mintCert(report) {
634
+ return Sidecar.assemble(
601
635
  this.#sourceBytes(),
602
- this.#report.dictVersion,
636
+ report.dictVersion,
603
637
  (/* @__PURE__ */ new Date()).toISOString(),
604
638
  void 0,
605
639
  void 0,
@@ -607,8 +641,6 @@ var Ags4File = class _Ags4File {
607
641
  this.#lastCheckFiles,
608
642
  this.#lastForced
609
643
  );
610
- writeFileSync(out, cert.toJson());
611
- return out;
612
644
  }
613
645
  // --- optional DuckDB engine (sql / at / connection) ----------------------
614
646
  async #getEngine() {
@@ -31493,9 +31525,13 @@ function parseValue2(raw, agsType) {
31493
31525
  var transport_exports = {};
31494
31526
  __export(transport_exports, {
31495
31527
  lock: () => lock,
31528
+ lockBytes: () => lockBytes,
31496
31529
  pack: () => pack,
31530
+ packBytes: () => packBytes,
31497
31531
  unlock: () => unlock,
31498
- unpack: () => unpack
31532
+ unlockBytes: () => unlockBytes,
31533
+ unpack: () => unpack,
31534
+ unpackBytes: () => unpackBytes
31499
31535
  });
31500
31536
  function pack(src, dest, level) {
31501
31537
  return transportPack(src, dest, level);
@@ -31509,6 +31545,18 @@ function lock(src, dest, password, level) {
31509
31545
  function unlock(src, dest, password) {
31510
31546
  return transportUnlock(src, dest, password);
31511
31547
  }
31548
+ function packBytes(data, level) {
31549
+ return transportPackBytes(data, level);
31550
+ }
31551
+ function unpackBytes(data) {
31552
+ return transportUnpackBytes(data);
31553
+ }
31554
+ function lockBytes(data, password, level) {
31555
+ return transportLockBytes(data, password, level);
31556
+ }
31557
+ function unlockBytes(data, password) {
31558
+ return transportUnlockBytes(data, password);
31559
+ }
31512
31560
 
31513
31561
  // ts/index.ts
31514
31562
  function read(source, opts = {}) {
@@ -31634,11 +31682,41 @@ function listRules2() {
31634
31682
  return JSON.parse(listRules()).rules;
31635
31683
  }
31636
31684
  function fix(source, opts = {}) {
31685
+ if (opts.inPlace && opts.out !== void 0) {
31686
+ throw new TypeError("fix(): `inPlace` and `out` are mutually exclusive");
31687
+ }
31688
+ if (opts.only !== void 0 || opts.exclude !== void 0) {
31689
+ const fixable = new Set(listRules2().filter((r2) => r2.fixable).map((r2) => r2.rule));
31690
+ for (const [kw, labels] of [["only", opts.only], ["exclude", opts.exclude]]) {
31691
+ for (const label of labels ?? []) {
31692
+ if (!fixable.has(label)) {
31693
+ throw new TypeError(
31694
+ `fix(): ${kw} names rule "${label}", which is not fixable \u2014 see listRules() (fixable: true)`
31695
+ );
31696
+ }
31697
+ }
31698
+ }
31699
+ }
31637
31700
  const path = typeof source === "string" ? source : void 0;
31638
31701
  const data = typeof source === "string" || source == null ? void 0 : source;
31639
- const r = fixFile(path, opts.text, data, opts.dictVersion, opts.encoding, opts.risky);
31702
+ if (opts.inPlace && path === void 0) {
31703
+ throw makeError("bad_args", 5, "fix(): `inPlace` needs a path source; use `out` or `.save(path)`");
31704
+ }
31705
+ const r = fixFile(
31706
+ path,
31707
+ opts.text,
31708
+ data,
31709
+ opts.dictVersion,
31710
+ opts.encoding,
31711
+ opts.risky,
31712
+ opts.only,
31713
+ opts.exclude
31714
+ );
31640
31715
  if (!r.ok) throw makeError(r.errorKind ?? "", r.exitCode, r.error ?? "unknown error");
31641
- return new FixResult(r.fixed, r.residual, r.applied, r.dictVersion);
31716
+ const result = new FixResult(r.fixed, r.residual, r.applied, r.dictVersion);
31717
+ const dest = opts.inPlace ? path : opts.out;
31718
+ if (dest !== void 0) writeFileSync4(dest, result.bytes);
31719
+ return result;
31642
31720
  }
31643
31721
  function diffBytes(x) {
31644
31722
  if (x instanceof Ags4File) return x.bytes;
@@ -31661,11 +31739,28 @@ function diff2(a, b, opts = {}) {
31661
31739
  throw fromNativeError(e);
31662
31740
  }
31663
31741
  }
31664
- function toExcel(agsPath, xlsxPath, opts = {}) {
31665
- return ags4ToExcel(agsPath, xlsxPath, opts.groups);
31742
+ function excelStatsOf(r) {
31743
+ return { sheetsWritten: r.sheetsWritten, rowsWritten: r.rowsWritten, warnings: r.warnings };
31744
+ }
31745
+ function toExcel(source, xlsxPath, opts = {}) {
31746
+ if (typeof source === "string" && xlsxPath !== void 0) {
31747
+ return ags4ToExcel(source, xlsxPath, opts.groups);
31748
+ }
31749
+ const agsBytes = typeof source === "string" ? readFileSync2(source) : source;
31750
+ const r = ags4BytesToXlsx(agsBytes, opts.groups);
31751
+ if (xlsxPath === void 0) return r.bytes;
31752
+ writeFileSync4(xlsxPath, r.bytes);
31753
+ return excelStatsOf(r);
31666
31754
  }
31667
- function fromExcel(xlsxPath, agsPath, opts = {}) {
31668
- return excelToAgs4(xlsxPath, agsPath, opts.formatNumericColumns);
31755
+ function fromExcel(source, agsPath, opts = {}) {
31756
+ if (typeof source === "string" && agsPath !== void 0) {
31757
+ return excelToAgs4(source, agsPath, opts.formatNumericColumns);
31758
+ }
31759
+ const xlsxBytes = typeof source === "string" ? readFileSync2(source) : source;
31760
+ const r = xlsxBytesToAgs4(xlsxBytes, opts.formatNumericColumns);
31761
+ if (agsPath === void 0) return r.bytes;
31762
+ writeFileSync4(agsPath, r.bytes);
31763
+ return excelStatsOf(r);
31669
31764
  }
31670
31765
  export {
31671
31766
  AAVT,
package/index.d.ts CHANGED
@@ -92,6 +92,13 @@ export declare class Sidecar {
92
92
  get fyi(): number
93
93
  }
94
94
 
95
+ /**
96
+ * AGS4 bytes → `.xlsx` workbook bytes (one worksheet per group). `orderedKeys`
97
+ * forces the worksheet order; otherwise AGS4 source order. The bytes twin of
98
+ * `ags4ToExcel`.
99
+ */
100
+ export declare function ags4BytesToXlsx(data: Uint8Array, orderedKeys?: Array<string> | undefined | null): ExcelBytesResult
101
+
95
102
  /**
96
103
  * Write an AGS4 file's groups to an `.xlsx` — one worksheet per group.
97
104
  * `orderedKeys` forces the worksheet order; otherwise AGS4 source order.
@@ -155,6 +162,19 @@ export interface EmitResult {
155
162
  fixesApplied: number
156
163
  }
157
164
 
165
+ /**
166
+ * An in-memory Excel conversion result: the produced `bytes` (an `.xlsx`
167
+ * workbook or an `.ags` document) plus the same conversion stats. The bytes
168
+ * twin of the path functions, so an uploaded workbook / a fixed handle needn't
169
+ * hit disk — the same FS-free cores the browser surface uses.
170
+ */
171
+ export interface ExcelBytesResult {
172
+ bytes: Buffer
173
+ sheetsWritten: number
174
+ rowsWritten: number
175
+ warnings: Array<string>
176
+ }
177
+
158
178
  /** The outcome of an Excel conversion (mirrors `laterite_excel::ExcelStats`). */
159
179
  export interface ExcelStats {
160
180
  /** Worksheets written (AGS4→XLSX) or read (XLSX→AGS4). */
@@ -182,12 +202,14 @@ export interface Finding {
182
202
 
183
203
  /**
184
204
  * Mechanically repair an AGS4 file (`path`) / `text` / `data`: apply the SAFE
185
- * fixes (plus the risky set when `includeRisky`), re-validate, and return the
186
- * fixed bytes + residual findings. Mirrors laterite-py's `fix()` /
187
- * `lat-check --fix`; the single `fix_document` orchestration is shared. The TS
188
- * layer wraps this into a `FixResult` (`.bytes` / `.text` / `.save(path)`).
205
+ * fixes (plus the risky set when `includeRisky`, narrowed by `only` / widened-
206
+ * back by `exclude`), re-validate, and return the fixed bytes + residual
207
+ * findings. Mirrors laterite-py's `fix()` / `lat-check --fix`; the single
208
+ * `fix_document_selective` orchestration is shared. The TS layer wraps this into
209
+ * a `FixResult` (`.bytes` / `.text` / `.save(path)`) and adds `inPlace` / `out`
210
+ * write-back on top.
189
211
  */
190
- export declare function fixFile(path?: string | undefined | null, text?: string | undefined | null, data?: Uint8Array | undefined | null, dictVersion?: string | undefined | null, encoding?: string | undefined | null, includeRisky?: boolean | undefined | null): FixReport
212
+ export declare function fixFile(path?: string | undefined | null, text?: string | undefined | null, data?: Uint8Array | undefined | null, dictVersion?: string | undefined | null, encoding?: string | undefined | null, includeRisky?: boolean | undefined | null, only?: Array<string> | undefined | null, exclude?: Array<string> | undefined | null): FixReport
191
213
 
192
214
  /**
193
215
  * The repair report — the Node mirror of laterite-py's `fix_file` dict. `ok` is
@@ -293,18 +315,36 @@ export declare function runCheck(path?: string | undefined | null, text?: string
293
315
  */
294
316
  export declare function transportLock(src: string, dest: string, password: string, level?: number | undefined | null): PackStats
295
317
 
318
+ /**
319
+ * zstd-compress, then age-encrypt `data` with `password` in memory → bytes —
320
+ * no plaintext on disk. `level` is 1–22 (default 9).
321
+ */
322
+ export declare function transportLockBytes(data: Uint8Array, password: string, level?: number | undefined | null): Buffer
323
+
296
324
  /** zstd-compress `src` → `dest`. `level` is 1–22 (default 9, the AGS sweet spot). */
297
325
  export declare function transportPack(src: string, dest: string, level?: number | undefined | null): PackStats
298
326
 
327
+ /** zstd-compress `data` in memory → bytes. `level` is 1–22 (default 9). */
328
+ export declare function transportPackBytes(data: Uint8Array, level?: number | undefined | null): Buffer
329
+
299
330
  /**
300
331
  * age-decrypt with `password`, then zstd-decompress → `dest`. Wrong passphrase
301
332
  * / non-passphrase envelopes surface as an error.
302
333
  */
303
334
  export declare function transportUnlock(src: string, dest: string, password: string): UnpackStats
304
335
 
336
+ /**
337
+ * age-decrypt with `password`, then zstd-decompress `data` in memory → bytes.
338
+ * Wrong passphrase / non-passphrase envelopes surface as an error.
339
+ */
340
+ export declare function transportUnlockBytes(data: Uint8Array, password: string): Buffer
341
+
305
342
  /** zstd-decompress `src` → `dest`. */
306
343
  export declare function transportUnpack(src: string, dest: string): UnpackStats
307
344
 
345
+ /** zstd-decompress `data` in memory → bytes (the twin of `transportPackBytes`). */
346
+ export declare function transportUnpackBytes(data: Uint8Array): Buffer
347
+
308
348
  /** Result of `transportUnpack` / `transportUnlock`: output size, elapsed seconds. */
309
349
  export interface UnpackStats {
310
350
  bytes: bigint
@@ -342,3 +382,10 @@ export interface ValidationReport {
342
382
 
343
383
  /** The crate version. */
344
384
  export declare function version(): string
385
+
386
+ /**
387
+ * `.xlsx` workbook bytes → AGS4 bytes. `formatNumericColumns` (default true)
388
+ * re-applies AGS4 numeric formatting to numeric-looking columns. The bytes twin
389
+ * of `excelToAgs4`.
390
+ */
391
+ export declare function xlsxBytesToAgs4(data: Uint8Array, formatNumericColumns?: boolean | undefined | null): ExcelBytesResult
package/index.js CHANGED
@@ -77,8 +77,8 @@ function requireNative() {
77
77
  try {
78
78
  const binding = require('@laterite/native-android-arm64')
79
79
  const bindingPackageVersion = require('@laterite/native-android-arm64/package.json').version
80
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
81
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
80
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
81
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
82
82
  }
83
83
  return binding
84
84
  } catch (e) {
@@ -93,8 +93,8 @@ function requireNative() {
93
93
  try {
94
94
  const binding = require('@laterite/native-android-arm-eabi')
95
95
  const bindingPackageVersion = require('@laterite/native-android-arm-eabi/package.json').version
96
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
97
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
96
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
97
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
98
98
  }
99
99
  return binding
100
100
  } catch (e) {
@@ -114,8 +114,8 @@ function requireNative() {
114
114
  try {
115
115
  const binding = require('@laterite/native-win32-x64-gnu')
116
116
  const bindingPackageVersion = require('@laterite/native-win32-x64-gnu/package.json').version
117
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
118
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
117
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
118
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
119
119
  }
120
120
  return binding
121
121
  } catch (e) {
@@ -130,8 +130,8 @@ function requireNative() {
130
130
  try {
131
131
  const binding = require('@laterite/native-win32-x64-msvc')
132
132
  const bindingPackageVersion = require('@laterite/native-win32-x64-msvc/package.json').version
133
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
134
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
133
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
134
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
135
135
  }
136
136
  return binding
137
137
  } catch (e) {
@@ -147,8 +147,8 @@ function requireNative() {
147
147
  try {
148
148
  const binding = require('@laterite/native-win32-ia32-msvc')
149
149
  const bindingPackageVersion = require('@laterite/native-win32-ia32-msvc/package.json').version
150
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
151
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
150
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
151
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
152
152
  }
153
153
  return binding
154
154
  } catch (e) {
@@ -163,8 +163,8 @@ function requireNative() {
163
163
  try {
164
164
  const binding = require('@laterite/native-win32-arm64-msvc')
165
165
  const bindingPackageVersion = require('@laterite/native-win32-arm64-msvc/package.json').version
166
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
167
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
166
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
167
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
168
168
  }
169
169
  return binding
170
170
  } catch (e) {
@@ -182,8 +182,8 @@ function requireNative() {
182
182
  try {
183
183
  const binding = require('@laterite/native-darwin-universal')
184
184
  const bindingPackageVersion = require('@laterite/native-darwin-universal/package.json').version
185
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
186
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
185
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
186
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
187
187
  }
188
188
  return binding
189
189
  } catch (e) {
@@ -198,8 +198,8 @@ function requireNative() {
198
198
  try {
199
199
  const binding = require('@laterite/native-darwin-x64')
200
200
  const bindingPackageVersion = require('@laterite/native-darwin-x64/package.json').version
201
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
202
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
201
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
202
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
203
203
  }
204
204
  return binding
205
205
  } catch (e) {
@@ -214,8 +214,8 @@ function requireNative() {
214
214
  try {
215
215
  const binding = require('@laterite/native-darwin-arm64')
216
216
  const bindingPackageVersion = require('@laterite/native-darwin-arm64/package.json').version
217
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
218
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
217
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
218
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
219
219
  }
220
220
  return binding
221
221
  } catch (e) {
@@ -234,8 +234,8 @@ function requireNative() {
234
234
  try {
235
235
  const binding = require('@laterite/native-freebsd-x64')
236
236
  const bindingPackageVersion = require('@laterite/native-freebsd-x64/package.json').version
237
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
237
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
239
239
  }
240
240
  return binding
241
241
  } catch (e) {
@@ -250,8 +250,8 @@ function requireNative() {
250
250
  try {
251
251
  const binding = require('@laterite/native-freebsd-arm64')
252
252
  const bindingPackageVersion = require('@laterite/native-freebsd-arm64/package.json').version
253
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
254
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
253
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
254
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
255
255
  }
256
256
  return binding
257
257
  } catch (e) {
@@ -271,8 +271,8 @@ function requireNative() {
271
271
  try {
272
272
  const binding = require('@laterite/native-linux-x64-musl')
273
273
  const bindingPackageVersion = require('@laterite/native-linux-x64-musl/package.json').version
274
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
275
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
274
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
275
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
276
276
  }
277
277
  return binding
278
278
  } catch (e) {
@@ -287,8 +287,8 @@ function requireNative() {
287
287
  try {
288
288
  const binding = require('@laterite/native-linux-x64-gnu')
289
289
  const bindingPackageVersion = require('@laterite/native-linux-x64-gnu/package.json').version
290
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
291
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
290
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
291
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
292
292
  }
293
293
  return binding
294
294
  } catch (e) {
@@ -305,8 +305,8 @@ function requireNative() {
305
305
  try {
306
306
  const binding = require('@laterite/native-linux-arm64-musl')
307
307
  const bindingPackageVersion = require('@laterite/native-linux-arm64-musl/package.json').version
308
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
309
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
308
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
309
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
310
310
  }
311
311
  return binding
312
312
  } catch (e) {
@@ -321,8 +321,8 @@ function requireNative() {
321
321
  try {
322
322
  const binding = require('@laterite/native-linux-arm64-gnu')
323
323
  const bindingPackageVersion = require('@laterite/native-linux-arm64-gnu/package.json').version
324
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
325
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
324
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
325
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
326
326
  }
327
327
  return binding
328
328
  } catch (e) {
@@ -339,8 +339,8 @@ function requireNative() {
339
339
  try {
340
340
  const binding = require('@laterite/native-linux-arm-musleabihf')
341
341
  const bindingPackageVersion = require('@laterite/native-linux-arm-musleabihf/package.json').version
342
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
343
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
342
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
343
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
344
344
  }
345
345
  return binding
346
346
  } catch (e) {
@@ -355,8 +355,8 @@ function requireNative() {
355
355
  try {
356
356
  const binding = require('@laterite/native-linux-arm-gnueabihf')
357
357
  const bindingPackageVersion = require('@laterite/native-linux-arm-gnueabihf/package.json').version
358
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
359
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
358
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
359
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
360
360
  }
361
361
  return binding
362
362
  } catch (e) {
@@ -373,8 +373,8 @@ function requireNative() {
373
373
  try {
374
374
  const binding = require('@laterite/native-linux-loong64-musl')
375
375
  const bindingPackageVersion = require('@laterite/native-linux-loong64-musl/package.json').version
376
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
377
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
376
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
377
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
378
378
  }
379
379
  return binding
380
380
  } catch (e) {
@@ -389,8 +389,8 @@ function requireNative() {
389
389
  try {
390
390
  const binding = require('@laterite/native-linux-loong64-gnu')
391
391
  const bindingPackageVersion = require('@laterite/native-linux-loong64-gnu/package.json').version
392
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
393
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
392
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
393
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
394
394
  }
395
395
  return binding
396
396
  } catch (e) {
@@ -407,8 +407,8 @@ function requireNative() {
407
407
  try {
408
408
  const binding = require('@laterite/native-linux-riscv64-musl')
409
409
  const bindingPackageVersion = require('@laterite/native-linux-riscv64-musl/package.json').version
410
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
411
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
410
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
411
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
412
412
  }
413
413
  return binding
414
414
  } catch (e) {
@@ -423,8 +423,8 @@ function requireNative() {
423
423
  try {
424
424
  const binding = require('@laterite/native-linux-riscv64-gnu')
425
425
  const bindingPackageVersion = require('@laterite/native-linux-riscv64-gnu/package.json').version
426
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
427
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
426
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
427
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
428
428
  }
429
429
  return binding
430
430
  } catch (e) {
@@ -440,8 +440,8 @@ function requireNative() {
440
440
  try {
441
441
  const binding = require('@laterite/native-linux-ppc64-gnu')
442
442
  const bindingPackageVersion = require('@laterite/native-linux-ppc64-gnu/package.json').version
443
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
444
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
443
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
444
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
445
445
  }
446
446
  return binding
447
447
  } catch (e) {
@@ -456,8 +456,8 @@ function requireNative() {
456
456
  try {
457
457
  const binding = require('@laterite/native-linux-s390x-gnu')
458
458
  const bindingPackageVersion = require('@laterite/native-linux-s390x-gnu/package.json').version
459
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
460
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
459
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
460
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
461
461
  }
462
462
  return binding
463
463
  } catch (e) {
@@ -476,8 +476,8 @@ function requireNative() {
476
476
  try {
477
477
  const binding = require('@laterite/native-openharmony-arm64')
478
478
  const bindingPackageVersion = require('@laterite/native-openharmony-arm64/package.json').version
479
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
479
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
481
481
  }
482
482
  return binding
483
483
  } catch (e) {
@@ -492,8 +492,8 @@ function requireNative() {
492
492
  try {
493
493
  const binding = require('@laterite/native-openharmony-x64')
494
494
  const bindingPackageVersion = require('@laterite/native-openharmony-x64/package.json').version
495
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
495
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
497
497
  }
498
498
  return binding
499
499
  } catch (e) {
@@ -508,8 +508,8 @@ function requireNative() {
508
508
  try {
509
509
  const binding = require('@laterite/native-openharmony-arm')
510
510
  const bindingPackageVersion = require('@laterite/native-openharmony-arm/package.json').version
511
- if (bindingPackageVersion !== '0.6.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
512
- throw new Error(`Native binding package version mismatch, expected 0.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
511
+ if (bindingPackageVersion !== '0.6.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
512
+ throw new Error(`Native binding package version mismatch, expected 0.6.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
513
513
  }
514
514
  return binding
515
515
  } catch (e) {
@@ -589,6 +589,7 @@ if (!nativeBinding) {
589
589
  module.exports = nativeBinding
590
590
  module.exports.Reading = nativeBinding.Reading
591
591
  module.exports.Sidecar = nativeBinding.Sidecar
592
+ module.exports.ags4BytesToXlsx = nativeBinding.ags4BytesToXlsx
592
593
  module.exports.ags4ToExcel = nativeBinding.ags4ToExcel
593
594
  module.exports.canonicalType = nativeBinding.canonicalType
594
595
  module.exports.diff = nativeBinding.diff
@@ -602,7 +603,12 @@ module.exports.parseValue = nativeBinding.parseValue
602
603
  module.exports.registryDictionaryJson = nativeBinding.registryDictionaryJson
603
604
  module.exports.runCheck = nativeBinding.runCheck
604
605
  module.exports.transportLock = nativeBinding.transportLock
606
+ module.exports.transportLockBytes = nativeBinding.transportLockBytes
605
607
  module.exports.transportPack = nativeBinding.transportPack
608
+ module.exports.transportPackBytes = nativeBinding.transportPackBytes
606
609
  module.exports.transportUnlock = nativeBinding.transportUnlock
610
+ module.exports.transportUnlockBytes = nativeBinding.transportUnlockBytes
607
611
  module.exports.transportUnpack = nativeBinding.transportUnpack
612
+ module.exports.transportUnpackBytes = nativeBinding.transportUnpackBytes
608
613
  module.exports.version = nativeBinding.version
614
+ module.exports.xlsxBytesToAgs4 = nativeBinding.xlsxBytesToAgs4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "laterite",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "AGS4 geotechnical data for Node.js — read, validate, produce, and query (the Node port of the laterite Python toolkit, Rust-backed).",
5
5
  "license": "MIT",
6
6
  "author": "niko86",
@@ -73,9 +73,9 @@
73
73
  "apache-arrow": "^21.1.0"
74
74
  },
75
75
  "optionalDependencies": {
76
- "@laterite/native-darwin-arm64": "0.6.0",
77
- "@laterite/native-linux-x64-gnu": "0.6.0",
78
- "@laterite/native-win32-x64-msvc": "0.6.0"
76
+ "@laterite/native-darwin-arm64": "0.6.2",
77
+ "@laterite/native-linux-x64-gnu": "0.6.2",
78
+ "@laterite/native-win32-x64-msvc": "0.6.2"
79
79
  },
80
80
  "peerDependencies": {
81
81
  "@duckdb/node-api": ">=1.5.0"