@bilig/workbook 0.59.0 → 0.64.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.
@@ -0,0 +1,278 @@
1
+ import { isLiteralInput } from '@bilig/protocol';
2
+ import { describePlan, } from './describe.js';
3
+ import { hydrateWorkbookRef, isWorkbookRefData } from './find.js';
4
+ import { isWorkbookOp } from './guards.js';
5
+ import { isWorkbookActionInput, normalizeWorkbookActionInput } from './input.js';
6
+ function isRecord(value) {
7
+ return typeof value === 'object' && value !== null;
8
+ }
9
+ function hasString(value, key) {
10
+ return typeof value[key] === 'string';
11
+ }
12
+ function hasOptionalString(value, key) {
13
+ const entry = value[key];
14
+ return entry === undefined || typeof entry === 'string';
15
+ }
16
+ function isWorkbookRefDescription(value) {
17
+ return isWorkbookRefData(value);
18
+ }
19
+ function isFormulaLabelData(value) {
20
+ return isRecord(value) && hasString(value, 'name') && isWorkbookRefDescription(value['ref']);
21
+ }
22
+ function isFormulaLabelDataArray(value) {
23
+ return Array.isArray(value) && value.every(isFormulaLabelData);
24
+ }
25
+ function isRefDataArray(value) {
26
+ return Array.isArray(value) && value.every(isWorkbookRefDescription);
27
+ }
28
+ function isWorkbookActionCommandData(value) {
29
+ if (!isRecord(value) || !hasString(value, 'kind')) {
30
+ return false;
31
+ }
32
+ switch (value['kind']) {
33
+ case 'writeFormula':
34
+ return (isWorkbookRefDescription(value['target']) &&
35
+ typeof value['formula'] === 'string' &&
36
+ isRefDataArray(value['inputs']) &&
37
+ isFormulaLabelDataArray(value['labels']));
38
+ case 'writeValue':
39
+ return isWorkbookRefDescription(value['target']) && isLiteralInput(value['value']);
40
+ case 'format':
41
+ return (isWorkbookRefDescription(value['target']) &&
42
+ (value['style'] === undefined || isRecord(value['style'])) &&
43
+ (value['numberFormat'] === undefined || typeof value['numberFormat'] === 'string' || value['numberFormat'] === null));
44
+ case 'clear':
45
+ return isWorkbookRefDescription(value['target']);
46
+ case 'op':
47
+ return (isWorkbookOp(value['op']) &&
48
+ (value['target'] === undefined || isWorkbookRefDescription(value['target'])) &&
49
+ hasOptionalString(value, 'message'));
50
+ default:
51
+ return false;
52
+ }
53
+ }
54
+ function isChangeData(value) {
55
+ return (isRecord(value) &&
56
+ hasString(value, 'kind') &&
57
+ hasString(value, 'message') &&
58
+ (value['target'] === undefined || isWorkbookRefDescription(value['target'])));
59
+ }
60
+ function isCheckStatus(value) {
61
+ return value === 'planned' || value === 'passed' || value === 'failed';
62
+ }
63
+ function isCheckExpectationData(value) {
64
+ if (!isRecord(value) || !hasString(value, 'kind')) {
65
+ return false;
66
+ }
67
+ switch (value['kind']) {
68
+ case 'valueEquals':
69
+ return isLiteralInput(value['value']);
70
+ case 'formulaEquals':
71
+ return typeof value['formula'] === 'string' && isRefDataArray(value['inputs']) && isFormulaLabelDataArray(value['labels']);
72
+ default:
73
+ return false;
74
+ }
75
+ }
76
+ function isCheckData(value) {
77
+ return (isRecord(value) &&
78
+ isCheckStatus(value['status']) &&
79
+ hasString(value, 'kind') &&
80
+ hasString(value, 'message') &&
81
+ (value['target'] === undefined || isWorkbookRefDescription(value['target'])) &&
82
+ (value['refs'] === undefined || isRefDataArray(value['refs'])) &&
83
+ (value['expectation'] === undefined || isCheckExpectationData(value['expectation'])) &&
84
+ (value['proof'] === undefined || isWorkbookActionInput(value['proof'])));
85
+ }
86
+ export function isPlanData(value) {
87
+ return (isRecord(value) &&
88
+ hasString(value, 'modelName') &&
89
+ hasString(value, 'actionName') &&
90
+ (value['input'] === undefined || isWorkbookActionInput(value['input'])) &&
91
+ isRefDataArray(value['refsUsed']) &&
92
+ Array.isArray(value['commands']) &&
93
+ value['commands'].every(isWorkbookActionCommandData) &&
94
+ Array.isArray(value['ops']) &&
95
+ value['ops'].every(isWorkbookOp) &&
96
+ Array.isArray(value['changed']) &&
97
+ value['changed'].every(isChangeData) &&
98
+ Array.isArray(value['checks']) &&
99
+ value['checks'].every(isCheckData));
100
+ }
101
+ function planDataIssue(path, message) {
102
+ return Object.freeze({
103
+ code: 'invalid_plan_data',
104
+ path,
105
+ message,
106
+ });
107
+ }
108
+ function pushRequiredStringIssue(issues, value, key) {
109
+ if (typeof value[key] !== 'string') {
110
+ issues.push(planDataIssue(key, `Workbook plan data ${key} must be a string`));
111
+ }
112
+ }
113
+ function pushOptionalInputIssue(issues, value) {
114
+ if (value['input'] !== undefined && !isWorkbookActionInput(value['input'])) {
115
+ issues.push(planDataIssue('input', 'Workbook plan data input must be JSON-safe'));
116
+ }
117
+ }
118
+ function pushArrayIssues(issues, value, key, guard, label) {
119
+ const array = value[key];
120
+ if (!Array.isArray(array)) {
121
+ issues.push(planDataIssue(key, `Workbook plan data ${key} must be an array`));
122
+ return;
123
+ }
124
+ array.forEach((entry, index) => {
125
+ if (!guard(entry)) {
126
+ issues.push(planDataIssue(`${key}[${index}]`, `Workbook plan data ${label} at ${key}[${index}] is invalid`));
127
+ }
128
+ });
129
+ }
130
+ export function checkPlanData(value) {
131
+ if (!isRecord(value)) {
132
+ return {
133
+ status: 'invalid',
134
+ issues: Object.freeze([planDataIssue('plan', 'Workbook plan data must be an object')]),
135
+ };
136
+ }
137
+ const issues = [];
138
+ pushRequiredStringIssue(issues, value, 'modelName');
139
+ pushRequiredStringIssue(issues, value, 'actionName');
140
+ pushOptionalInputIssue(issues, value);
141
+ pushArrayIssues(issues, value, 'refsUsed', isWorkbookRefDescription, 'ref');
142
+ pushArrayIssues(issues, value, 'commands', isWorkbookActionCommandData, 'command');
143
+ pushArrayIssues(issues, value, 'ops', isWorkbookOp, 'op');
144
+ pushArrayIssues(issues, value, 'changed', isChangeData, 'change');
145
+ pushArrayIssues(issues, value, 'checks', isCheckData, 'check');
146
+ if (issues.length > 0) {
147
+ return {
148
+ status: 'invalid',
149
+ issues: Object.freeze(issues),
150
+ };
151
+ }
152
+ if (!isPlanData(value)) {
153
+ return {
154
+ status: 'invalid',
155
+ issues: Object.freeze([planDataIssue('plan', 'Workbook plan data is invalid')]),
156
+ };
157
+ }
158
+ return {
159
+ status: 'valid',
160
+ plan: value,
161
+ issues: Object.freeze([]),
162
+ };
163
+ }
164
+ function hydrateRef(ref) {
165
+ return hydrateWorkbookRef(ref);
166
+ }
167
+ function hydrateFormulaLabel(label) {
168
+ return Object.freeze({
169
+ name: label.name,
170
+ ref: hydrateRef(label.ref),
171
+ });
172
+ }
173
+ function hydrateCommand(command) {
174
+ switch (command.kind) {
175
+ case 'writeFormula':
176
+ return Object.freeze({
177
+ kind: 'writeFormula',
178
+ target: hydrateRef(command.target),
179
+ formula: command.formula,
180
+ inputs: Object.freeze(command.inputs.map(hydrateRef)),
181
+ labels: Object.freeze(command.labels.map(hydrateFormulaLabel)),
182
+ });
183
+ case 'writeValue':
184
+ return Object.freeze({
185
+ kind: 'writeValue',
186
+ target: hydrateRef(command.target),
187
+ value: command.value,
188
+ });
189
+ case 'format':
190
+ return Object.freeze({
191
+ kind: 'format',
192
+ target: hydrateRef(command.target),
193
+ ...(command.style !== undefined ? { style: Object.freeze(structuredClone(command.style)) } : {}),
194
+ ...(command.numberFormat !== undefined ? { numberFormat: command.numberFormat } : {}),
195
+ });
196
+ case 'clear':
197
+ return Object.freeze({
198
+ kind: 'clear',
199
+ target: hydrateRef(command.target),
200
+ });
201
+ case 'op':
202
+ return Object.freeze({
203
+ kind: 'op',
204
+ op: Object.freeze(structuredClone(command.op)),
205
+ ...(command.target !== undefined ? { target: hydrateRef(command.target) } : {}),
206
+ ...(command.message !== undefined ? { message: command.message } : {}),
207
+ });
208
+ }
209
+ }
210
+ function hydrateChange(change) {
211
+ return Object.freeze({
212
+ kind: change.kind,
213
+ ...(change.target !== undefined ? { target: hydrateRef(change.target) } : {}),
214
+ message: change.message,
215
+ });
216
+ }
217
+ function hydrateExpectation(expectation) {
218
+ switch (expectation.kind) {
219
+ case 'valueEquals':
220
+ return Object.freeze({
221
+ kind: 'valueEquals',
222
+ value: expectation.value,
223
+ });
224
+ case 'formulaEquals':
225
+ return Object.freeze({
226
+ kind: 'formulaEquals',
227
+ formula: expectation.formula,
228
+ inputs: Object.freeze(expectation.inputs.map(hydrateRef)),
229
+ labels: Object.freeze(expectation.labels.map(hydrateFormulaLabel)),
230
+ });
231
+ }
232
+ }
233
+ function hydrateCheck(check) {
234
+ const proof = check.proof === undefined ? undefined : normalizeWorkbookActionInput(check.proof);
235
+ return Object.freeze({
236
+ status: check.status,
237
+ kind: check.kind,
238
+ ...(check.target !== undefined ? { target: hydrateRef(check.target) } : {}),
239
+ ...(check.refs !== undefined ? { refs: Object.freeze(check.refs.map(hydrateRef)) } : {}),
240
+ message: check.message,
241
+ ...(check.expectation !== undefined ? { expectation: hydrateExpectation(check.expectation) } : {}),
242
+ ...(proof !== undefined ? { proof } : {}),
243
+ });
244
+ }
245
+ function cloneOp(op) {
246
+ return Object.freeze(structuredClone(op));
247
+ }
248
+ export function toPlanData(plan) {
249
+ return describePlan(plan);
250
+ }
251
+ export function hydratePlanData(data) {
252
+ const check = checkPlanData(data);
253
+ if (check.status === 'invalid') {
254
+ const [firstIssue] = check.issues;
255
+ throw new Error(firstIssue === undefined ? 'Workbook plan data is invalid' : `Workbook plan data is invalid: ${firstIssue.message}`);
256
+ }
257
+ const plan = check.plan;
258
+ const refsUsed = Object.freeze(plan.refsUsed.map(hydrateRef));
259
+ const input = plan.input === undefined ? undefined : normalizeWorkbookActionInput(plan.input);
260
+ return Object.freeze({
261
+ modelName: plan.modelName,
262
+ actionName: plan.actionName,
263
+ ...(input !== undefined ? { input } : {}),
264
+ refs: Object.freeze({ refsUsed }),
265
+ refsUsed,
266
+ commands: Object.freeze(plan.commands.map(hydrateCommand)),
267
+ ops: Object.freeze(plan.ops.map(cloneOp)),
268
+ changed: Object.freeze(plan.changed.map(hydrateChange)),
269
+ checks: Object.freeze(plan.checks.map(hydrateCheck)),
270
+ });
271
+ }
272
+ export function isHydratedPlan(value) {
273
+ return isRecord(value) && isRecord(value['refs']);
274
+ }
275
+ export function executablePlan(plan) {
276
+ return isHydratedPlan(plan) ? plan : hydratePlanData(plan);
277
+ }
278
+ //# sourceMappingURL=plan-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-data.js","sourceRoot":"","sources":["../src/plan-data.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import { type WorkbookRefDescription } from './describe.js';
2
- import type { WorkbookActionPlan } from './model.js';
2
+ import { type WorkbookExecutablePlan } from './plan-data.js';
3
3
  export type WorkbookRuntimeRequirementKind = 'apply' | 'read' | 'verify';
4
4
  export type WorkbookRuntimeCapability = 'writeFormula' | 'writeValue' | 'format' | 'clear' | 'applyOp' | 'read' | 'verifyCheck';
5
+ export declare const workbookRuntimeRequirementKinds: readonly ["apply", "read", "verify"];
6
+ export declare const workbookRuntimeCapabilities: readonly ["writeFormula", "writeValue", "format", "clear", "applyOp", "read", "verifyCheck"];
5
7
  export interface WorkbookRuntimeRequirement {
6
8
  readonly kind: WorkbookRuntimeRequirementKind;
7
9
  readonly capability: WorkbookRuntimeCapability;
@@ -19,4 +21,49 @@ export interface WorkbookRuntimeRequirements {
19
21
  readonly actionName: string;
20
22
  readonly requirements: readonly WorkbookRuntimeRequirement[];
21
23
  }
22
- export declare function describeRuntimeRequirements<Refs>(plan: WorkbookActionPlan<Refs>): WorkbookRuntimeRequirements;
24
+ export type WorkbookRuntimeRequirementsIssueCode = 'invalid_runtime_requirements';
25
+ export interface WorkbookRuntimeRequirementsIssue {
26
+ readonly code: WorkbookRuntimeRequirementsIssueCode;
27
+ readonly path: string;
28
+ readonly message: string;
29
+ }
30
+ export type WorkbookRuntimeRequirementsCheckResult = {
31
+ readonly status: 'valid';
32
+ readonly requirements: WorkbookRuntimeRequirements;
33
+ readonly issues: readonly [];
34
+ } | {
35
+ readonly status: 'invalid';
36
+ readonly issues: readonly WorkbookRuntimeRequirementsIssue[];
37
+ };
38
+ export type WorkbookRuntimeAdapterIssueCode = 'missing_apply' | 'missing_read' | 'missing_check_verifier';
39
+ export type WorkbookRuntimeAdapterMethod = 'apply' | 'read' | 'verifyChecks';
40
+ export interface WorkbookRuntimeAdapterIssue {
41
+ readonly code: WorkbookRuntimeAdapterIssueCode;
42
+ readonly capability: WorkbookRuntimeCapability;
43
+ readonly method: WorkbookRuntimeAdapterMethod;
44
+ readonly requirementIndexes: readonly number[];
45
+ readonly message: string;
46
+ }
47
+ export type WorkbookRuntimeAdapterCheckResult = {
48
+ readonly status: 'valid';
49
+ readonly modelName: string;
50
+ readonly actionName: string;
51
+ readonly requiredCapabilities: readonly WorkbookRuntimeCapability[];
52
+ readonly issues: readonly [];
53
+ } | {
54
+ readonly status: 'invalid';
55
+ readonly modelName: string;
56
+ readonly actionName: string;
57
+ readonly requiredCapabilities: readonly WorkbookRuntimeCapability[];
58
+ readonly issues: readonly WorkbookRuntimeAdapterIssue[];
59
+ };
60
+ export interface WorkbookRuntimeAdapterCandidate {
61
+ readonly apply?: unknown;
62
+ readonly read?: unknown;
63
+ readonly verifyChecks?: unknown;
64
+ }
65
+ export declare function isWorkbookRuntimeRequirementKind(value: unknown): value is WorkbookRuntimeRequirementKind;
66
+ export declare function isWorkbookRuntimeCapability(value: unknown): value is WorkbookRuntimeCapability;
67
+ export declare function describeRuntimeRequirements<Refs>(plan: WorkbookExecutablePlan<Refs>): WorkbookRuntimeRequirements;
68
+ export declare function checkRuntimeRequirements(value: unknown): WorkbookRuntimeRequirementsCheckResult;
69
+ export declare function checkRuntimeAdapter<Refs>(planOrRequirements: WorkbookExecutablePlan<Refs> | WorkbookRuntimeRequirements, adapter: WorkbookRuntimeAdapterCandidate): WorkbookRuntimeAdapterCheckResult;
@@ -1,4 +1,28 @@
1
1
  import { describeRef } from './describe.js';
2
+ import { isWorkbookRefData } from './find.js';
3
+ import { hydratePlanData, isHydratedPlan } from './plan-data.js';
4
+ export const workbookRuntimeRequirementKinds = Object.freeze([
5
+ 'apply',
6
+ 'read',
7
+ 'verify',
8
+ ]);
9
+ const WORKBOOK_RUNTIME_REQUIREMENT_KIND_SET = new Set(workbookRuntimeRequirementKinds);
10
+ export const workbookRuntimeCapabilities = Object.freeze([
11
+ 'writeFormula',
12
+ 'writeValue',
13
+ 'format',
14
+ 'clear',
15
+ 'applyOp',
16
+ 'read',
17
+ 'verifyCheck',
18
+ ]);
19
+ const WORKBOOK_RUNTIME_CAPABILITY_SET = new Set(workbookRuntimeCapabilities);
20
+ export function isWorkbookRuntimeRequirementKind(value) {
21
+ return typeof value === 'string' && WORKBOOK_RUNTIME_REQUIREMENT_KIND_SET.has(value);
22
+ }
23
+ export function isWorkbookRuntimeCapability(value) {
24
+ return typeof value === 'string' && WORKBOOK_RUNTIME_CAPABILITY_SET.has(value);
25
+ }
2
26
  function describedRef(ref) {
3
27
  return ref === undefined ? {} : { target: describeRef(ref) };
4
28
  }
@@ -158,7 +182,7 @@ function commandCoveredOpKeys(commands) {
158
182
  });
159
183
  return keys;
160
184
  }
161
- export function describeRuntimeRequirements(plan) {
185
+ function describeLiveRuntimeRequirements(plan) {
162
186
  const requirements = plan.commands.map(commandRequirement);
163
187
  const commandCoveredOps = commandCoveredOpKeys(plan.commands);
164
188
  plan.ops.forEach((op, opIndex) => {
@@ -191,4 +215,245 @@ export function describeRuntimeRequirements(plan) {
191
215
  requirements,
192
216
  };
193
217
  }
218
+ export function describeRuntimeRequirements(plan) {
219
+ if (isHydratedPlan(plan)) {
220
+ return describeLiveRuntimeRequirements(plan);
221
+ }
222
+ return describeLiveRuntimeRequirements(hydratePlanData(plan));
223
+ }
224
+ function isRecord(value) {
225
+ return typeof value === 'object' && value !== null;
226
+ }
227
+ function hasString(value, key) {
228
+ return typeof value[key] === 'string';
229
+ }
230
+ function hasOptionalString(value, key) {
231
+ const entry = value[key];
232
+ return entry === undefined || typeof entry === 'string';
233
+ }
234
+ function hasOptionalIndex(value, key) {
235
+ const entry = value[key];
236
+ return entry === undefined || (Number.isInteger(entry) && typeof entry === 'number' && entry >= 0);
237
+ }
238
+ function isWorkbookRefDescription(value) {
239
+ return isWorkbookRefData(value);
240
+ }
241
+ function isRefDescriptionArray(value) {
242
+ return Array.isArray(value) && value.every(isWorkbookRefDescription);
243
+ }
244
+ function capabilityMatchesKind(kind, capability) {
245
+ switch (kind) {
246
+ case 'apply':
247
+ return (capability === 'writeFormula' ||
248
+ capability === 'writeValue' ||
249
+ capability === 'format' ||
250
+ capability === 'clear' ||
251
+ capability === 'applyOp');
252
+ case 'read':
253
+ return capability === 'read';
254
+ case 'verify':
255
+ return capability === 'verifyCheck';
256
+ }
257
+ }
258
+ function isRuntimeRequirement(value) {
259
+ if (!isRecord(value) || !isWorkbookRuntimeRequirementKind(value['kind']) || !isWorkbookRuntimeCapability(value['capability'])) {
260
+ return false;
261
+ }
262
+ return (capabilityMatchesKind(value['kind'], value['capability']) &&
263
+ hasString(value, 'message') &&
264
+ hasOptionalIndex(value, 'commandIndex') &&
265
+ hasOptionalIndex(value, 'checkIndex') &&
266
+ hasOptionalIndex(value, 'opIndex') &&
267
+ hasOptionalString(value, 'opKind') &&
268
+ hasOptionalString(value, 'checkKind') &&
269
+ (value['target'] === undefined || isWorkbookRefDescription(value['target'])) &&
270
+ (value['refs'] === undefined || isRefDescriptionArray(value['refs'])));
271
+ }
272
+ function isRuntimeRequirements(value) {
273
+ return (isRecord(value) &&
274
+ hasString(value, 'modelName') &&
275
+ hasString(value, 'actionName') &&
276
+ Array.isArray(value['requirements']) &&
277
+ value['requirements'].every(isRuntimeRequirement));
278
+ }
279
+ function isRuntimeRequirementsCandidate(value) {
280
+ return isRecord(value) && Object.getOwnPropertyDescriptor(value, 'requirements') !== undefined;
281
+ }
282
+ function runtimeRequirementsIssue(path, message) {
283
+ return Object.freeze({
284
+ code: 'invalid_runtime_requirements',
285
+ path,
286
+ message,
287
+ });
288
+ }
289
+ function pushRequiredStringIssue(issues, value, key) {
290
+ if (typeof value[key] !== 'string') {
291
+ issues.push(runtimeRequirementsIssue(key, `Workbook runtime requirements ${key} must be a string`));
292
+ }
293
+ }
294
+ function pushOptionalIndexIssue(issues, value, key, path) {
295
+ if (!hasOptionalIndex(value, key)) {
296
+ issues.push(runtimeRequirementsIssue(`${path}.${key}`, `Workbook runtime requirement ${key} must be a non-negative integer`));
297
+ }
298
+ }
299
+ function pushOptionalStringIssue(issues, value, key, path) {
300
+ if (!hasOptionalString(value, key)) {
301
+ issues.push(runtimeRequirementsIssue(`${path}.${key}`, `Workbook runtime requirement ${key} must be a string`));
302
+ }
303
+ }
304
+ function pushRequirementIssues(issues, value, index) {
305
+ const path = `requirements[${index}]`;
306
+ if (!isRecord(value)) {
307
+ issues.push(runtimeRequirementsIssue(path, `Workbook runtime requirement at ${path} must be an object`));
308
+ return;
309
+ }
310
+ const kind = value['kind'];
311
+ const capability = value['capability'];
312
+ if (!isWorkbookRuntimeRequirementKind(kind)) {
313
+ issues.push(runtimeRequirementsIssue(`${path}.kind`, 'Workbook runtime requirement kind is invalid'));
314
+ }
315
+ if (!isWorkbookRuntimeCapability(capability)) {
316
+ issues.push(runtimeRequirementsIssue(`${path}.capability`, 'Workbook runtime requirement capability is invalid'));
317
+ }
318
+ if (isWorkbookRuntimeRequirementKind(kind) && isWorkbookRuntimeCapability(capability) && !capabilityMatchesKind(kind, capability)) {
319
+ issues.push(runtimeRequirementsIssue(`${path}.capability`, `Workbook runtime requirement capability ${capability} does not match kind ${kind}`));
320
+ }
321
+ if (!hasString(value, 'message')) {
322
+ issues.push(runtimeRequirementsIssue(`${path}.message`, 'Workbook runtime requirement message must be a string'));
323
+ }
324
+ pushOptionalIndexIssue(issues, value, 'commandIndex', path);
325
+ pushOptionalIndexIssue(issues, value, 'checkIndex', path);
326
+ pushOptionalIndexIssue(issues, value, 'opIndex', path);
327
+ pushOptionalStringIssue(issues, value, 'opKind', path);
328
+ pushOptionalStringIssue(issues, value, 'checkKind', path);
329
+ if (value['target'] !== undefined && !isWorkbookRefDescription(value['target'])) {
330
+ issues.push(runtimeRequirementsIssue(`${path}.target`, 'Workbook runtime requirement target must be workbook ref data'));
331
+ }
332
+ const refs = value['refs'];
333
+ if (refs !== undefined) {
334
+ if (!Array.isArray(refs)) {
335
+ issues.push(runtimeRequirementsIssue(`${path}.refs`, 'Workbook runtime requirement refs must be an array'));
336
+ return;
337
+ }
338
+ refs.forEach((ref, refIndex) => {
339
+ if (!isWorkbookRefDescription(ref)) {
340
+ issues.push(runtimeRequirementsIssue(`${path}.refs[${refIndex}]`, 'Workbook runtime requirement ref must be workbook ref data'));
341
+ }
342
+ });
343
+ }
344
+ }
345
+ export function checkRuntimeRequirements(value) {
346
+ if (!isRecord(value)) {
347
+ return {
348
+ status: 'invalid',
349
+ issues: Object.freeze([runtimeRequirementsIssue('requirements', 'Workbook runtime requirements must be an object')]),
350
+ };
351
+ }
352
+ const issues = [];
353
+ pushRequiredStringIssue(issues, value, 'modelName');
354
+ pushRequiredStringIssue(issues, value, 'actionName');
355
+ const requirements = value['requirements'];
356
+ if (!Array.isArray(requirements)) {
357
+ issues.push(runtimeRequirementsIssue('requirements', 'Workbook runtime requirements requirements must be an array'));
358
+ }
359
+ else {
360
+ requirements.forEach((requirement, index) => pushRequirementIssues(issues, requirement, index));
361
+ }
362
+ if (issues.length > 0) {
363
+ return {
364
+ status: 'invalid',
365
+ issues: Object.freeze(issues),
366
+ };
367
+ }
368
+ if (!isRuntimeRequirements(value)) {
369
+ return {
370
+ status: 'invalid',
371
+ issues: Object.freeze([runtimeRequirementsIssue('requirements', 'Workbook runtime requirements are invalid')]),
372
+ };
373
+ }
374
+ return {
375
+ status: 'valid',
376
+ requirements: value,
377
+ issues: Object.freeze([]),
378
+ };
379
+ }
380
+ function requirementsFor(input) {
381
+ if (isRuntimeRequirementsCandidate(input)) {
382
+ const check = checkRuntimeRequirements(input);
383
+ if (check.status === 'invalid') {
384
+ const [firstIssue] = check.issues;
385
+ throw new Error(firstIssue === undefined
386
+ ? 'Workbook runtime requirements are invalid'
387
+ : `Workbook runtime requirements are invalid: ${firstIssue.message}`);
388
+ }
389
+ return check.requirements;
390
+ }
391
+ return describeRuntimeRequirements(input);
392
+ }
393
+ function pushCapability(capabilities, capability) {
394
+ if (!capabilities.includes(capability)) {
395
+ capabilities.push(capability);
396
+ }
397
+ }
398
+ function requirementIndexesFor(requirements, capability) {
399
+ return requirements.flatMap((requirement, index) => (requirement.capability === capability ? [index] : []));
400
+ }
401
+ function hasMethod(adapter, method) {
402
+ return typeof adapter[method] === 'function';
403
+ }
404
+ function adapterIssue(requirements, code, capability, method) {
405
+ return Object.freeze({
406
+ code,
407
+ capability,
408
+ method,
409
+ requirementIndexes: Object.freeze(requirementIndexesFor(requirements, capability)),
410
+ message: `Adapter is missing ${method} for ${capability}`,
411
+ });
412
+ }
413
+ export function checkRuntimeAdapter(planOrRequirements, adapter) {
414
+ const requirements = requirementsFor(planOrRequirements);
415
+ const requiredCapabilities = [];
416
+ requirements.requirements.forEach((requirement) => {
417
+ pushCapability(requiredCapabilities, requirement.capability);
418
+ });
419
+ const issues = [];
420
+ const needsApply = requiredCapabilities.some((capability) => capability === 'writeFormula' ||
421
+ capability === 'writeValue' ||
422
+ capability === 'format' ||
423
+ capability === 'clear' ||
424
+ capability === 'applyOp');
425
+ if (needsApply && !hasMethod(adapter, 'apply')) {
426
+ const firstApplyCapability = requiredCapabilities.find((capability) => capability === 'writeFormula' ||
427
+ capability === 'writeValue' ||
428
+ capability === 'format' ||
429
+ capability === 'clear' ||
430
+ capability === 'applyOp');
431
+ if (firstApplyCapability !== undefined) {
432
+ issues.push(adapterIssue(requirements.requirements, 'missing_apply', firstApplyCapability, 'apply'));
433
+ }
434
+ }
435
+ if (requiredCapabilities.includes('read') && !hasMethod(adapter, 'read')) {
436
+ issues.push(adapterIssue(requirements.requirements, 'missing_read', 'read', 'read'));
437
+ }
438
+ if (requiredCapabilities.includes('verifyCheck') && !hasMethod(adapter, 'verifyChecks')) {
439
+ issues.push(adapterIssue(requirements.requirements, 'missing_check_verifier', 'verifyCheck', 'verifyChecks'));
440
+ }
441
+ const shared = {
442
+ modelName: requirements.modelName,
443
+ actionName: requirements.actionName,
444
+ requiredCapabilities: Object.freeze(requiredCapabilities),
445
+ };
446
+ if (issues.length > 0) {
447
+ return {
448
+ status: 'invalid',
449
+ ...shared,
450
+ issues: Object.freeze(issues),
451
+ };
452
+ }
453
+ return {
454
+ status: 'valid',
455
+ ...shared,
456
+ issues: Object.freeze([]),
457
+ };
458
+ }
194
459
  //# sourceMappingURL=requirements.js.map