@bilig/workbook 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1 @@
1
+ MIT
package/README.md ADDED
@@ -0,0 +1,346 @@
1
+ # @bilig/workbook
2
+
3
+ Agent-first workbook model API and transport-neutral workbook operation language for bilig.
4
+
5
+ Build `@bilig/workbook` so an agent would love using it: simple, generic,
6
+ predictable, inspectable, verifiable, and never dependent on hardcoded business
7
+ models or human spreadsheet UI assumptions.
8
+
9
+ Use this package when a consumer needs to describe workbook work without taking a
10
+ dependency on the engine, app server, transport, or replica-state implementation.
11
+
12
+ The public surface stays generic:
13
+
14
+ - `defineModel`
15
+ - `buildWorkbookActionPlan`
16
+ - `planWorkbookAction`
17
+ - `inspectModel`
18
+ - `collectWorkbookRefs`
19
+ - `findTable`, `findColumn`, `findRange`, `findName`, `findRows`
20
+ - `find`
21
+ - `check`
22
+ - `describeModel`
23
+ - `describeRef`
24
+ - `describePlan`
25
+ - `describePlanResult`
26
+ - `describeRunResult`
27
+ - `describeRuntimeRequirements`
28
+ - `verifyPlan`
29
+ - `verifyModel`
30
+ - `runWorkbookPlan`
31
+ - `runWorkbookAction`
32
+ - `verifyWorkbookReadbacks`
33
+ - `normalizeWorkbookActionInputDescription`
34
+ - `workbookPlanIssueCodes`
35
+ - `isWorkbookPlanIssueCode`
36
+ - `workbookReadbackIssueCodes`
37
+ - `isWorkbookReadbackIssueCode`
38
+ - `workbookRunErrorCodes`
39
+ - `isWorkbookRunErrorCode`
40
+ - `formula`
41
+ - `workbook.addOp(op, { target?, message? })` inside model actions
42
+ - `WorkbookModel`
43
+ - `WorkbookAction`
44
+ - `WorkbookActionConfig`
45
+ - `WorkbookActionDefinition`
46
+ - `WorkbookActionContext`
47
+ - `WorkbookCheckContext`
48
+ - `WorkbookFindWorkbook`
49
+ - `WorkbookCheckWorkbook`
50
+ - `WorkbookActionWorkbook`
51
+ - `WorkbookModelWorkbook`
52
+ - `WorkbookFindNamespace`
53
+ - `WorkbookActionInput`
54
+ - `WorkbookActionInputDescription`
55
+ - `WorkbookActionInputDescriptionKind`
56
+ - `WorkbookActionInspection`
57
+ - `WorkbookAddOpOptions`
58
+ - `WorkbookActionPlanResult`
59
+ - `WorkbookModelDescription`
60
+ - `WorkbookRefDescription`
61
+ - `WorkbookActionPlanDescription`
62
+ - `WorkbookActionPlanResultDescription`
63
+ - `WorkbookRunResultDescription`
64
+ - `WorkbookUndoRefDescription`
65
+ - `WorkbookAppliedSummaryDescription`
66
+ - `WorkbookRuntimeRequirements`
67
+ - `WorkbookRuntimeRequirement`
68
+ - `WorkbookRuntimeCapability`
69
+ - `WorkbookRuntimeMaterialization`
70
+ - `WorkbookRuntimePreview`
71
+ - `WorkbookPlanVerification`
72
+ - `WorkbookPlanIssue`
73
+ - `WorkbookPlanIssueCode`
74
+ - `WorkbookModelVerification`
75
+ - `WorkbookModelActionVerification`
76
+ - `WorkbookModelVerificationOptions`
77
+ - `WorkbookRunAdapter`
78
+ - `WorkbookRunApplyResult`
79
+ - `WorkbookCellReadback`
80
+ - `WorkbookRunReadback`
81
+ - `WorkbookReadbackVerification`
82
+ - `WorkbookReadbackIssue`
83
+ - `WorkbookReadbackIssueCode`
84
+ - `WorkbookCheckExpectation`
85
+ - `WorkbookCheckExpectationDescription`
86
+ - `WorkbookCustomCheckOptions`
87
+ - `WorkbookReadbackCheckOptions`
88
+ - `WorkbookRawFormulaOptions`
89
+ - `WorkbookRunResult`
90
+ - `WorkbookAppliedSummary`
91
+ - `WorkbookRunError`
92
+ - `WorkbookRunErrorCode`
93
+ - `WorkbookCheckResult`
94
+
95
+ The low-level operation language remains available:
96
+
97
+ - `WorkbookOp`
98
+ - `WorkbookTxn`
99
+ - `EngineOp`
100
+ - `EngineOpBatch`
101
+ - `isEngineOpBatch`
102
+
103
+ Formula helpers create portable formula expressions with `@bilig/formula`.
104
+ Calculation and workbook execution stay in `@bilig/core` and the app runtime.
105
+ Use `planWorkbookAction` when an action name comes from an agent or user input;
106
+ it returns `planned` or structured `failed` results instead of requiring
107
+ exception control flow.
108
+ Actions can also accept a JSON-safe input:
109
+
110
+ ```ts
111
+ import { defineModel } from '@bilig/workbook'
112
+
113
+ export const model = defineModel({
114
+ name: 'custom-writer',
115
+
116
+ find(workbook) {
117
+ return {
118
+ output: workbook.findRange({ sheetName: 'Sheet1', address: 'B2' }),
119
+ }
120
+ },
121
+
122
+ actions: {
123
+ write({ refs, workbook, input }) {
124
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
125
+ throw new Error('input object required')
126
+ }
127
+ const value = input.value
128
+ if (typeof value !== 'number') {
129
+ throw new Error('numeric value required')
130
+ }
131
+ workbook.writeValue(refs.output, value)
132
+ },
133
+ },
134
+ })
135
+ ```
136
+
137
+ `planWorkbookAction(model, "write", { value: 12 })` clones and canonicalizes
138
+ that input into the plan so an agent can inspect exactly what was requested.
139
+ Inputs must be plain JSON values: strings, finite numbers, booleans, `null`,
140
+ arrays without holes, and plain objects. When an action object declares input
141
+ metadata, `planWorkbookAction` validates the provided value against the declared
142
+ JSON kind, required fields, and array item kind before `find`, `checks`, or the
143
+ action body run. This stays intentionally small: it is a dependency-free guard
144
+ for agent handoff, not a model-specific schema framework.
145
+ Use `verifyModel(model, { inputs: { write: { value: 12 } } })` when whole-model
146
+ verification needs parameters for specific actions.
147
+
148
+ Actions can also be plain action objects when an agent needs a richer manifest
149
+ without running workbook code:
150
+
151
+ ```ts
152
+ actions: {
153
+ write: {
154
+ description: 'Write a consumer-provided value',
155
+ input: {
156
+ kind: 'object',
157
+ fields: {
158
+ value: { kind: 'number', required: true },
159
+ },
160
+ },
161
+ run({ refs, workbook, input }) {
162
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
163
+ throw new Error('input object required')
164
+ }
165
+ const value = input.value
166
+ if (typeof value !== 'number') {
167
+ throw new Error('numeric value required')
168
+ }
169
+ workbook.writeValue(refs.output, value)
170
+ },
171
+ },
172
+ }
173
+ ```
174
+
175
+ Input descriptions support boring JSON kinds: `json`, `object`, `array`,
176
+ `string`, `number`, `boolean`, and `null`. `object` descriptions may list sorted
177
+ `fields`; `array` descriptions may list `items`; any description may be marked
178
+ `required`. `normalizeWorkbookActionInputDescription` trims text, rejects
179
+ malformed metadata, returns frozen data, and keeps the package free of `zod`,
180
+ `effect`, or model-specific validators.
181
+
182
+ Formula expressions also keep their workbook inputs separate from their formula
183
+ text. A planned `writeFormula` command includes both the parseable formula
184
+ string and the generic model refs it used, so an agent can inspect what the
185
+ action depends on without reverse-parsing placeholder names.
186
+ For formulas outside the small helper set, use
187
+ `formula.raw(source, { inputs })`; the source stays parseable while the
188
+ declared refs remain inspectable and verifiable. These inputs are a declared
189
+ dependency contract for agents, not parser-discovered proof that every formula
190
+ reference has been mapped to a model ref.
191
+
192
+ Known single-cell `workbook.format(ref, { numberFormat })` actions compile to
193
+ concrete `setCellFormat` ops. Use `numberFormat: null` to plan an explicit
194
+ format clear. Style patches remain high-level intent until the runtime resolves
195
+ style ids.
196
+ Use `workbook.addOp(op, { target?, message? })` inside model actions when a
197
+ consumer needs the existing low-level workbook operation language directly. The
198
+ op is runtime-guarded with `isWorkbookOp`, cloned into `plan.ops`, and kept in
199
+ the command log so agents can inspect it without depending on `@bilig/core`.
200
+ When a `target` is supplied for an address or range op, `verifyPlan` checks that
201
+ the op touches the same range. For op kinds without an inferable range, `target`
202
+ is still useful for logs and approvals but cannot prove the affected cells by
203
+ itself.
204
+
205
+ Action plans expose `refsUsed`, a flat deduped list of workbook refs found in
206
+ the consumer-defined `refs` object. Use `collectWorkbookRefs` directly when an
207
+ agent needs to inspect refs from any nested consumer shape.
208
+ Use `findTable`, `findColumn`, `findRange`, `findName`, and `findRows` directly
209
+ when an agent or test needs the same generic refs outside a model callback. The
210
+ same helpers are also available as a frozen `find` namespace with short aliases
211
+ such as `find.table(...)`, `find.range(...)`, and `find.rows(...)`.
212
+ Selector helpers trim text, canonicalize cell addresses, and reject empty table
213
+ names, column names, named ranges, headers, invalid range addresses, invalid row
214
+ operators, and non-finite row predicate values before a plan reaches runtime.
215
+ `findRows` refs include the predicate value in their stable id so two
216
+ consumer-defined row selectors do not collapse during dedupe, while labels stay
217
+ human-readable for agent logs.
218
+ Refs are frozen data objects. Ergonomic helpers like `table.column()` and
219
+ `rows.column()` remain available, but they are non-enumerable so JSON
220
+ inspection, object keys, and plan descriptions stay data-first.
221
+ For table-backed rows, use `rows.column("Amount")` to target only that column in
222
+ the matching rows. Runtime adapters can materialize row-filtered columns into
223
+ the exact cells to read, write, format, clear, or use as row-wise formula inputs
224
+ without hardcoding a business model.
225
+ Use `check.exists(ref)` and `check.noFormulaErrors(ref)` directly when an agent
226
+ or test needs the same generic planned checks outside a model callback.
227
+ Use `check.valueEquals(ref, value)` and `check.formulaEquals(ref, formula)` for
228
+ single-cell readback expectations. Use `check.valuesEqual(ref, rows)` and
229
+ `check.formulasEqual(ref, rows)` when the target may resolve to a range, table
230
+ column, or row-filtered column. `formulaEquals` stores normalized formula text
231
+ plus explicit model refs used by that formula, so an agent can inspect the
232
+ post-action proof target without depending on a rendered spreadsheet UI.
233
+ Use `check.custom({ kind, message, target, refs })` for consumer-defined
234
+ invariants; the package does not need to know what the model means. `target`
235
+ names the main ref, and `refs` names any supporting refs the invariant depends
236
+ on so agents can describe and verify the full check contract.
237
+
238
+ Model callback phases are deliberately scoped. `find(workbook)` receives only
239
+ the find API; `checks({ workbook })` receives find helpers plus `workbook.check`;
240
+ actions receive find helpers, checks, and mutation planning methods. That keeps
241
+ discovery and proof declaration separate from workbook mutation intent.
242
+
243
+ Use `describeModel` when an agent needs a JSON-safe manifest of model name,
244
+ model description, sorted action names, per-action descriptions, optional input
245
+ descriptions, and whether model-level checks exist without running `find`,
246
+ checks, or actions.
247
+ Use `describeRef` and `describePlan` when an agent needs JSON-safe intent for
248
+ logs, comparisons, approvals, or runtime handoff. Descriptions keep the same
249
+ generic action input, refs, commands, checks, changes, and ops, but omit
250
+ consumer-private `refs` object shape and helper functions such as
251
+ `table.column()`.
252
+ Use `describePlanResult` when the same JSON-safe handoff is needed for either
253
+ planned or failed action planning.
254
+ Use `describeRunResult` after execution when an agent needs the same JSON-safe
255
+ shape for `done` or `failed` run results. It preserves changed summaries,
256
+ checks, errors, and undo ops, but describes workbook refs without helper
257
+ functions such as `table.column()` or `rows.column()`.
258
+ Run errors use a stable `WorkbookRunErrorCode` union rather than arbitrary
259
+ strings. Use the frozen `workbookRunErrorCodes` list and `isWorkbookRunErrorCode`
260
+ guard when an adapter, logger, or approval layer needs to branch on known
261
+ failure classes. Runtime adapters should use `apply_failed` for apply
262
+ exceptions and `runtime_rejected` for intentional runtime refusal with a
263
+ specific message instead of inventing new public codes.
264
+ Planning and readback failures expose the same kind of boring machine contract:
265
+ use `workbookPlanIssueCodes` with `isWorkbookPlanIssueCode`, and
266
+ `workbookReadbackIssueCodes` with `isWorkbookReadbackIssueCode`, when an agent
267
+ needs to branch before or after runtime handoff without guessing string values.
268
+ Use `describeRuntimeRequirements(plan)` before runtime handoff when an agent
269
+ needs to inspect what the adapter must do. It returns a JSON-safe list of
270
+ generic `apply`, `read`, and `verify` requirements with boring capabilities
271
+ such as `writeFormula`, `writeValue`, `format`, `clear`, `applyOp`, `read`, and
272
+ `verifyCheck`. Apply requirements also say whether the command is already backed
273
+ by a concrete op, is a provided low-level op, or needs runtime materialization.
274
+ Every requirement has a stable `path` such as `commands[0]`, `checks[2]`, or
275
+ `ops[1]`; read requirements include the machine-readable expectation. It does
276
+ not execute anything and it does not import the engine.
277
+
278
+ Use `verifyPlan` before runtime handoff when an agent needs to prove a planned
279
+ action is internally consistent. It checks for non-JSON-safe action input,
280
+ unresolved refs, unparsable formulas, duplicate resolved refs, and missing
281
+ concrete ops for write, clear, and number-format commands that already target a
282
+ known single cell. Custom check targets and supporting refs must also resolve
283
+ through the model's `refsUsed` contract. Formula readback expectation inputs
284
+ must also resolve through `refsUsed`, and expectation formulas must be parseable.
285
+ Checks must start as `planned`; consumer code cannot mark a check passed or
286
+ failed before runtime proof.
287
+ Low-level `addOp` commands must contain valid `WorkbookOp` values, must still
288
+ appear in `plan.ops`, and must match their declared `target` when the op exposes
289
+ a concrete address or range.
290
+ Use `verifyModel` to plan and verify every action in a consumer-defined model
291
+ with one JSON-safe result. Pass `inputs` when specific actions require
292
+ parameters.
293
+
294
+ Use `runWorkbookPlan(plan, adapter)` or
295
+ `runWorkbookAction(model, actionName, adapter, input)` when an agent needs a
296
+ generic apply-and-prove loop. The adapter owns runtime execution and semantic
297
+ readback:
298
+
299
+ ```ts
300
+ const result = await runWorkbookAction(model, 'write', {
301
+ apply(plan) {
302
+ return runtime.apply(plan.ops)
303
+ },
304
+ read(targets) {
305
+ return runtime.read(targets)
306
+ },
307
+ })
308
+ ```
309
+
310
+ `runWorkbookAction` plans the action, runs `verifyPlan`, calls
311
+ optional `adapter.preview(plan)`, calls `adapter.apply(plan)`, then evaluates
312
+ `valueEquals`, `valuesEqual`, `formulaEquals`, and `formulasEqual` checks
313
+ against `adapter.read(targets, plan)`.
314
+ It never imports the engine, headless runtime, app server, or UI. If static
315
+ verification fails, the apply adapter is not called. If preview is available,
316
+ successful results include an `applied` summary with the materialized op count
317
+ and ops that the adapter preview produced. If a readback expectation is missing,
318
+ duplicated, or mismatched, the returned `WorkbookRunResult` is `failed` with
319
+ deterministic error codes such as `readback_missing`, `duplicate_readback`,
320
+ `value_mismatch`, `values_mismatch`, `formula_mismatch`, or
321
+ `formulas_mismatch`; errors preserve structured `path`, `target`, `check`,
322
+ `expected`, and `actual` fields where available.
323
+ Runtime outputs are validated too: malformed preview, apply, or readback
324
+ payloads fail as `invalid_runtime_result` instead of being treated as proof.
325
+ Formula readbacks are exact: adapters should return formula text in the same
326
+ normalized no-leading-`=` form produced by `formula.source`.
327
+ `adapter.apply` only applies the plan and may return an undo ref; it cannot
328
+ drop, replace, or prove checks.
329
+ Adapters provide `verifyChecks(checks, plan)` to prove non-readback checks such
330
+ as `exists`, `noFormulaErrors`, and consumer-defined `custom` invariants. The
331
+ verifier must return the same checks in the same order and may only change
332
+ `status`; changing `kind`, `target`, `refs`, `expectation`, or `message` fails
333
+ the run as `invalid_check_verification`. If any verified check is `failed`, the
334
+ run returns `failed` with `check_failed`. If any check remains `planned` after
335
+ readback and adapter verification, the run returns `failed` with
336
+ `check_not_verified`; `status: "done"` means every planned check has proof.
337
+
338
+ When running against Bilig's engine, use `createWorkbookRunAdapter(engine)` from
339
+ `@bilig/core`. The adapter materializes generic `plan.commands` into engine
340
+ operations, previews the exact materialized ops, applies additional `plan.ops`
341
+ that are not already represented by materialized commands, reads single-cell and
342
+ multi-cell expectation targets, and verifies generic `exists` and
343
+ `noFormulaErrors` checks
344
+ without adding workbook-specific business models to this package. If the engine
345
+ captures undo, the run result includes `undo.ops` in the same portable
346
+ operation language.
@@ -0,0 +1,26 @@
1
+ import { type LiteralInput } from '@bilig/protocol';
2
+ import type { WorkbookRef } from './find.js';
3
+ import { type WorkbookFormulaOperand } from './formula.js';
4
+ import type { WorkbookCheckResult } from './result.js';
5
+ export interface WorkbookCustomCheckOptions {
6
+ readonly kind: string;
7
+ readonly message: string;
8
+ readonly target?: WorkbookRef;
9
+ readonly refs?: readonly WorkbookRef[];
10
+ }
11
+ export interface WorkbookReadbackCheckOptions {
12
+ readonly message?: string;
13
+ }
14
+ export interface WorkbookCheckApi {
15
+ readonly exists: (target: WorkbookRef) => WorkbookCheckResult;
16
+ readonly noFormulaErrors: (target: WorkbookRef) => WorkbookCheckResult;
17
+ readonly valueEquals: (target: WorkbookRef, value: LiteralInput, options?: WorkbookReadbackCheckOptions) => WorkbookCheckResult;
18
+ readonly valuesEqual: (target: WorkbookRef, values: readonly (readonly LiteralInput[])[], options?: WorkbookReadbackCheckOptions) => WorkbookCheckResult;
19
+ readonly formulaEquals: (target: WorkbookRef, value: WorkbookFormulaOperand, options?: WorkbookReadbackCheckOptions) => WorkbookCheckResult;
20
+ readonly formulasEqual: (target: WorkbookRef, formulas: readonly (readonly (string | null)[])[], options?: WorkbookReadbackCheckOptions) => WorkbookCheckResult;
21
+ readonly custom: (options: WorkbookCustomCheckOptions) => WorkbookCheckResult;
22
+ }
23
+ export declare function createWorkbookCheckResult(kind: string, target: WorkbookRef, message: string): WorkbookCheckResult;
24
+ export declare function createWorkbookCustomCheck(options: WorkbookCustomCheckOptions): WorkbookCheckResult;
25
+ export declare function createWorkbookCheckApi(record?: (check: WorkbookCheckResult) => void): WorkbookCheckApi;
26
+ export declare const check: WorkbookCheckApi;
package/dist/check.js ADDED
@@ -0,0 +1,158 @@
1
+ import { isLiteralInput } from '@bilig/protocol';
2
+ import { formula } from './formula.js';
3
+ export function createWorkbookCheckResult(kind, target, message) {
4
+ return createWorkbookCustomCheck({ kind, target, message });
5
+ }
6
+ function requiredText(value, name) {
7
+ const trimmed = value.trim();
8
+ if (trimmed === '') {
9
+ throw new Error(`Workbook check ${name} cannot be empty`);
10
+ }
11
+ return trimmed;
12
+ }
13
+ function checkedLiteralInput(value) {
14
+ if (!isLiteralInput(value)) {
15
+ throw new Error('Workbook readback value must be a finite JSON literal');
16
+ }
17
+ return value;
18
+ }
19
+ function checkedLiteralMatrix(values) {
20
+ if (!Array.isArray(values)) {
21
+ throw new Error('Workbook readback values must be an array of rows');
22
+ }
23
+ let width;
24
+ return Object.freeze(values.map((row, rowIndex) => {
25
+ if (!Array.isArray(row)) {
26
+ throw new Error(`Workbook readback values row ${rowIndex.toString()} must be an array`);
27
+ }
28
+ width ??= row.length;
29
+ if (row.length !== width) {
30
+ throw new Error('Workbook readback values must be rectangular');
31
+ }
32
+ return Object.freeze(row.map(checkedLiteralInput));
33
+ }));
34
+ }
35
+ function checkedFormulaMatrix(formulas) {
36
+ if (!Array.isArray(formulas)) {
37
+ throw new Error('Workbook readback formulas must be an array of rows');
38
+ }
39
+ let width;
40
+ return Object.freeze(formulas.map((row, rowIndex) => {
41
+ if (!Array.isArray(row)) {
42
+ throw new Error(`Workbook readback formulas row ${rowIndex.toString()} must be an array`);
43
+ }
44
+ width ??= row.length;
45
+ if (row.length !== width) {
46
+ throw new Error('Workbook readback formulas must be rectangular');
47
+ }
48
+ return Object.freeze(row.map((formulaText) => {
49
+ if (formulaText !== null && typeof formulaText !== 'string') {
50
+ throw new Error('Workbook readback formula must be a string or null');
51
+ }
52
+ return formulaText;
53
+ }));
54
+ }));
55
+ }
56
+ function refKey(ref) {
57
+ return `${ref.kind}:${ref.id}`;
58
+ }
59
+ function uniqueRefs(refs) {
60
+ if (refs === undefined) {
61
+ return undefined;
62
+ }
63
+ const seen = new Set();
64
+ const unique = [];
65
+ for (const ref of refs) {
66
+ const key = refKey(ref);
67
+ if (seen.has(key)) {
68
+ continue;
69
+ }
70
+ seen.add(key);
71
+ unique.push(ref);
72
+ }
73
+ return unique.length === 0 ? undefined : unique;
74
+ }
75
+ function createWorkbookCheck(options) {
76
+ const refs = uniqueRefs(options.refs);
77
+ return {
78
+ status: 'planned',
79
+ kind: requiredText(options.kind, 'kind'),
80
+ ...(options.target !== undefined ? { target: options.target } : {}),
81
+ ...(refs !== undefined ? { refs } : {}),
82
+ message: requiredText(options.message, 'message'),
83
+ ...(options.expectation !== undefined ? { expectation: options.expectation } : {}),
84
+ };
85
+ }
86
+ export function createWorkbookCustomCheck(options) {
87
+ return createWorkbookCheck(options);
88
+ }
89
+ export function createWorkbookCheckApi(record) {
90
+ function planned(options) {
91
+ const check = createWorkbookCheck(options);
92
+ record?.(check);
93
+ return check;
94
+ }
95
+ return {
96
+ exists(target) {
97
+ return planned({ kind: 'exists', target, message: `${target.label} exists` });
98
+ },
99
+ noFormulaErrors(target) {
100
+ return planned({ kind: 'noFormulaErrors', target, message: `${target.label} has no formula errors` });
101
+ },
102
+ valueEquals(target, value, options = {}) {
103
+ const expected = checkedLiteralInput(value);
104
+ return planned({
105
+ kind: 'valueEquals',
106
+ target,
107
+ message: options.message ?? `${target.label} equals ${JSON.stringify(expected)}`,
108
+ expectation: {
109
+ kind: 'valueEquals',
110
+ value: expected,
111
+ },
112
+ });
113
+ },
114
+ valuesEqual(target, values, options = {}) {
115
+ const expected = checkedLiteralMatrix(values);
116
+ return planned({
117
+ kind: 'valuesEqual',
118
+ target,
119
+ message: options.message ?? `${target.label} values equal ${JSON.stringify(expected)}`,
120
+ expectation: {
121
+ kind: 'valuesEqual',
122
+ values: expected,
123
+ },
124
+ });
125
+ },
126
+ formulaEquals(target, value, options = {}) {
127
+ const source = formula.source(value);
128
+ const inputs = formula.inputs(value);
129
+ return planned({
130
+ kind: 'formulaEquals',
131
+ target,
132
+ message: options.message ?? `${target.label} formula equals ${source}`,
133
+ expectation: {
134
+ kind: 'formulaEquals',
135
+ formula: source,
136
+ inputs,
137
+ },
138
+ });
139
+ },
140
+ formulasEqual(target, formulas, options = {}) {
141
+ const expected = checkedFormulaMatrix(formulas);
142
+ return planned({
143
+ kind: 'formulasEqual',
144
+ target,
145
+ message: options.message ?? `${target.label} formulas equal ${JSON.stringify(expected)}`,
146
+ expectation: {
147
+ kind: 'formulasEqual',
148
+ formulas: expected,
149
+ },
150
+ });
151
+ },
152
+ custom(options) {
153
+ return planned(options);
154
+ },
155
+ };
156
+ }
157
+ export const check = createWorkbookCheckApi();
158
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}