logisheets-core 1.1.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.
Files changed (63) hide show
  1. package/dist/craft-interactions/index.d.ts +140 -0
  2. package/dist/craft-interactions/index.js +462 -0
  3. package/dist/field/index.d.ts +51 -0
  4. package/dist/field/index.js +70 -0
  5. package/dist/format/index.d.ts +21 -0
  6. package/dist/format/index.js +454 -0
  7. package/dist/index.d.ts +12 -0
  8. package/dist/index.js +17 -0
  9. package/dist/ops/index.d.ts +155 -0
  10. package/dist/ops/index.js +335 -0
  11. package/dist/permissions/index.d.ts +32 -0
  12. package/dist/permissions/index.js +74 -0
  13. package/dist/port.d.ts +9 -0
  14. package/dist/port.js +14 -0
  15. package/dist/selection/index.d.ts +1 -0
  16. package/dist/selection/index.js +1 -0
  17. package/dist/selection/model.d.ts +10 -0
  18. package/dist/selection/model.js +38 -0
  19. package/dist/strings/case.d.ts +2 -0
  20. package/dist/strings/case.js +6 -0
  21. package/dist/strings/char-code.d.ts +422 -0
  22. package/dist/strings/char-code.js +424 -0
  23. package/dist/strings/common_length.d.ts +4 -0
  24. package/dist/strings/common_length.js +28 -0
  25. package/dist/strings/contain.d.ts +4 -0
  26. package/dist/strings/contain.js +60 -0
  27. package/dist/strings/index.d.ts +5 -0
  28. package/dist/strings/index.js +5 -0
  29. package/dist/strings/judges.d.ts +3 -0
  30. package/dist/strings/judges.js +38 -0
  31. package/dist/strings/surrogate.d.ts +16 -0
  32. package/dist/strings/surrogate.js +30 -0
  33. package/dist/structured/index.d.ts +41 -0
  34. package/dist/structured/index.js +50 -0
  35. package/dist/transaction/index.d.ts +8 -0
  36. package/dist/transaction/index.js +11 -0
  37. package/dist/type-guard/index.d.ts +3 -0
  38. package/dist/type-guard/index.js +3 -0
  39. package/dist/type-guard/propterty.d.ts +1 -0
  40. package/dist/type-guard/propterty.js +3 -0
  41. package/dist/type-guard/string.d.ts +1 -0
  42. package/dist/type-guard/string.js +3 -0
  43. package/dist/type-guard/u8.d.ts +1 -0
  44. package/dist/type-guard/u8.js +3 -0
  45. package/dist/utils/a1notation.d.ts +18 -0
  46. package/dist/utils/a1notation.js +76 -0
  47. package/dist/utils/array.d.ts +2 -0
  48. package/dist/utils/array.js +12 -0
  49. package/dist/utils/clone.d.ts +2 -0
  50. package/dist/utils/clone.js +25 -0
  51. package/dist/utils/const.d.ts +7 -0
  52. package/dist/utils/const.js +8 -0
  53. package/dist/utils/equal.d.ts +1 -0
  54. package/dist/utils/equal.js +11 -0
  55. package/dist/utils/index.d.ts +6 -0
  56. package/dist/utils/index.js +6 -0
  57. package/dist/utils/uuid.d.ts +1 -0
  58. package/dist/utils/uuid.js +4 -0
  59. package/dist/validation/index.d.ts +34 -0
  60. package/dist/validation/index.js +60 -0
  61. package/dist/value/index.d.ts +9 -0
  62. package/dist/value/index.js +49 -0
  63. package/package.json +54 -0
@@ -0,0 +1,70 @@
1
+ // Field model + non-formula field constraints (required / unique).
2
+ //
3
+ // The field type model is lifted verbatim from the browser's block-composer so
4
+ // the App, the data-gateway craft, and a Node runtime all share one source of
5
+ // truth for what a field is. The constraint *checks* here are pure logic over
6
+ // values read through an injected port — the engine just supplies the values.
7
+ //
8
+ // Formula-based validation lives in ../validation; this module covers the two
9
+ // constraints that aren't formulas: `required` (no empty cells) and `unique`
10
+ // (no duplicate values within a field column).
11
+ import { isValueEmpty } from '../value/index.js';
12
+ const isEmpty = isValueEmpty;
13
+ /** Stable string key for duplicate detection. */
14
+ function valueKey(v) {
15
+ const x = v;
16
+ return `${x.type}:${String(x.value)}`;
17
+ }
18
+ /** The cell's value as the plain text used for membership comparison. */
19
+ function valueText(v) {
20
+ const x = v;
21
+ return String(x.value);
22
+ }
23
+ /**
24
+ * Check `required` and `unique` across every field column and return all
25
+ * violating cells. Pure: the caller supplies `getValue` (WorkbookOps wraps the
26
+ * engine), so this runs identically in the browser and on Node.
27
+ */
28
+ export function checkFieldConstraints(columns, getValue) {
29
+ const out = [];
30
+ for (const { field, cells, allowed } of columns) {
31
+ const seen = new Map();
32
+ const allowedSet = allowed ? new Set(allowed) : undefined;
33
+ for (const cell of cells) {
34
+ const v = getValue(cell.sheetIdx, cell.row, cell.col);
35
+ const empty = isEmpty(v);
36
+ if (field.required && empty) {
37
+ out.push({
38
+ ...cell,
39
+ kind: 'required',
40
+ message: `Field "${field.name}" is required`,
41
+ });
42
+ continue;
43
+ }
44
+ if (empty)
45
+ continue;
46
+ if (allowedSet && !allowedSet.has(valueText(v))) {
47
+ out.push({
48
+ ...cell,
49
+ kind: 'membership',
50
+ message: `Value "${valueText(v)}" is not an allowed option for field "${field.name}"`,
51
+ });
52
+ continue;
53
+ }
54
+ if (field.unique) {
55
+ const key = valueKey(v);
56
+ if (seen.has(key)) {
57
+ out.push({
58
+ ...cell,
59
+ kind: 'duplicate',
60
+ message: `Duplicate value in unique field "${field.name}"`,
61
+ });
62
+ }
63
+ else {
64
+ seen.set(key, cell);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ return out;
70
+ }
@@ -0,0 +1,21 @@
1
+ import type { Alignment, Payload, StPatternType, StBorderStyle, SelectedData } from 'logisheets-web';
2
+ export interface FontStyle {
3
+ bold?: boolean;
4
+ underline?: boolean;
5
+ italic?: boolean;
6
+ color?: string;
7
+ size?: number;
8
+ strike?: boolean;
9
+ }
10
+ export declare function generateFontPayload(sheetIdx: number, data: SelectedData, update: FontStyle): readonly Payload[];
11
+ export declare function generateAlgnmentPayload(sheetIdx: number, data: SelectedData, alignment: Alignment): readonly Payload[];
12
+ export declare function generateWrapTextPayload(sheetIdx: number, data: SelectedData, wrapText: boolean): readonly Payload[];
13
+ export declare function generateNumFmtPayload(sheetIdx: number, data: SelectedData, numFmt: string): readonly Payload[];
14
+ export declare function generatePatternFillPayload(sheetIdx: number, data: SelectedData, fgColor?: string, bgColor?: string, pattern?: StPatternType): readonly Payload[];
15
+ export type BatchUpdateType = 'all' | 'top' | 'bottom' | 'left' | 'right' | 'horizontal' | 'vertical' | 'outer' | 'inner' | 'clear';
16
+ export interface BorderBatchUpdate {
17
+ batch: BatchUpdateType;
18
+ color?: string;
19
+ borderType?: StBorderStyle;
20
+ }
21
+ export declare function generateBorderPayloads(sheetIdx: number, data: SelectedData, update: BorderBatchUpdate): readonly Payload[];
@@ -0,0 +1,454 @@
1
+ // Format payload generators — engine-neutral.
2
+ //
3
+ // These turn a selection (`SelectedData`) plus a style intent into the
4
+ // cell/line style-update payloads the engine applies. They are PURE LOGIC:
5
+ // they build plain payload objects and import only TYPES from logisheets-web,
6
+ // so they carry no runtime dependency and run identically in the browser and
7
+ // on Node. WorkbookOps wraps each one as a named operation (setFont, setBorder,
8
+ // ...); the host only supplies the current sheet index and the selection.
9
+ //
10
+ // Lifted out of the browser's src/components/toolbar/payload.ts so the Node
11
+ // runtime gets the same formatting operations.
12
+ // Local, type-narrowing equivalents of logisheets-web's getSelectedCellRange /
13
+ // getSelectedLines (which are runtime helpers); inlined here to keep this
14
+ // module free of any runtime import.
15
+ function selectedCellRange(v) {
16
+ return v.data?.ty === 'cellRange' ? v.data.d : undefined;
17
+ }
18
+ function selectedLines(v) {
19
+ return v.data?.ty === 'line' ? v.data.d : undefined;
20
+ }
21
+ function hexToColor(hex) {
22
+ let h = hex.startsWith('#') ? hex.slice(1) : hex;
23
+ // ARGB format (8 chars): skip the first 2 alpha chars
24
+ if (h.length === 8)
25
+ h = h.substring(2);
26
+ return {
27
+ red: parseInt(h.substring(0, 2), 16),
28
+ green: parseInt(h.substring(2, 4), 16),
29
+ blue: parseInt(h.substring(4, 6), 16),
30
+ };
31
+ }
32
+ function cellStyle(sheetIdx, row, col, ty) {
33
+ return { type: 'cellStyleUpdate', value: { sheetIdx, row, col, ty } };
34
+ }
35
+ function lineStyle(sheetIdx, from, to, row, ty) {
36
+ return { type: 'lineStyleUpdate', value: { sheetIdx, from, to, row, ty } };
37
+ }
38
+ export function generateFontPayload(sheetIdx, data, update) {
39
+ if (!data.data)
40
+ return [];
41
+ if (data.data.ty === 'cellRange') {
42
+ const cellTy = {};
43
+ if (update.bold !== undefined)
44
+ cellTy.setFontBold = update.bold;
45
+ if (update.underline !== undefined)
46
+ cellTy.setFontUnderline = update.underline ? 'single' : 'none';
47
+ if (update.italic !== undefined)
48
+ cellTy.setFontItalic = update.italic;
49
+ if (update.color)
50
+ cellTy.setFontColor = update.color;
51
+ if (update.size)
52
+ cellTy.setFontSize = update.size;
53
+ if (update.strike !== undefined)
54
+ cellTy.setFontStrike = update.strike;
55
+ const d = data.data.d;
56
+ const result = [];
57
+ for (let i = d.startRow; i <= d.endRow; i += 1)
58
+ for (let j = d.startCol; j <= d.endCol; j += 1)
59
+ result.push(cellStyle(sheetIdx, i, j, cellTy));
60
+ return result;
61
+ }
62
+ const d = data.data.d;
63
+ const lineTy = {};
64
+ if (update.bold !== undefined)
65
+ lineTy.setFontBold = update.bold;
66
+ if (update.underline !== undefined)
67
+ lineTy.setFontUnderline = update.underline ? 'single' : 'none';
68
+ if (update.italic !== undefined)
69
+ lineTy.setFontItalic = update.italic;
70
+ if (update.color)
71
+ lineTy.setFontColor = update.color;
72
+ return [lineStyle(sheetIdx, d.start, d.end, d.type === 'row', lineTy)];
73
+ }
74
+ export function generateAlgnmentPayload(sheetIdx, data, alignment) {
75
+ return generateForSelection(sheetIdx, data, { setAlignment: alignment });
76
+ }
77
+ export function generateWrapTextPayload(sheetIdx, data, wrapText) {
78
+ return generateForSelection(sheetIdx, data, { setAlignment: { wrapText } });
79
+ }
80
+ export function generateNumFmtPayload(sheetIdx, data, numFmt) {
81
+ return generateForSelection(sheetIdx, data, { setNumFmt: numFmt });
82
+ }
83
+ export function generatePatternFillPayload(sheetIdx, data, fgColor, bgColor, pattern) {
84
+ const fill = {};
85
+ if (fgColor)
86
+ fill.fgColor = hexToColor(fgColor);
87
+ if (bgColor)
88
+ fill.bgColor = hexToColor(bgColor);
89
+ if (pattern)
90
+ fill.patternType = pattern;
91
+ return generateForSelection(sheetIdx, data, { setPatternFill: fill });
92
+ }
93
+ /** Apply one `StyleUpdateType` across the selection (cell range or line). */
94
+ function generateForSelection(sheetIdx, data, ty) {
95
+ if (!data.data)
96
+ return [];
97
+ if (data.data.ty === 'cellRange') {
98
+ const d = data.data.d;
99
+ const result = [];
100
+ for (let i = d.startRow; i <= d.endRow; i += 1)
101
+ for (let j = d.startCol; j <= d.endCol; j += 1)
102
+ result.push(cellStyle(sheetIdx, i, j, ty));
103
+ return result;
104
+ }
105
+ const d = data.data.d;
106
+ return [lineStyle(sheetIdx, d.start, d.end, d.type === 'row', ty)];
107
+ }
108
+ export function generateBorderPayloads(sheetIdx, data, update) {
109
+ if (update.color) {
110
+ if (update.color.startsWith('#'))
111
+ update.color = update.color.slice(1);
112
+ update.color = update.color.toUpperCase();
113
+ }
114
+ const cellRange = selectedCellRange(data);
115
+ if (cellRange) {
116
+ return generateBorderBatchCellPayload(sheetIdx, cellRange.startRow, cellRange.endRow, cellRange.startCol, cellRange.endCol, update);
117
+ }
118
+ return generateBorderBatchLinePayload(sheetIdx, data, update);
119
+ }
120
+ function generateBorderBatchLinePayload(sheetIdx, data, update) {
121
+ const lineRange = selectedLines(data);
122
+ if (!lineRange)
123
+ return [];
124
+ const result = [];
125
+ const drawLeftBorder = () => {
126
+ if (lineRange.type === 'row')
127
+ return;
128
+ result.push(...generateLineDoubleBorderPayload(sheetIdx, lineRange.start, false, {
129
+ direction: 'left',
130
+ color: update.color,
131
+ borderType: update.borderType,
132
+ }));
133
+ };
134
+ const drawRightBorder = () => {
135
+ if (lineRange.type === 'row')
136
+ return;
137
+ result.push(...generateLineDoubleBorderPayload(sheetIdx, lineRange.end, false, {
138
+ direction: 'right',
139
+ color: update.color,
140
+ borderType: update.borderType,
141
+ }));
142
+ };
143
+ const drawTopBorder = () => {
144
+ if (lineRange.type !== 'row')
145
+ return;
146
+ result.push(...generateLineDoubleBorderPayload(sheetIdx, lineRange.start, true, {
147
+ direction: 'top',
148
+ color: update.color,
149
+ borderType: update.borderType,
150
+ }));
151
+ };
152
+ const drawBottomBorder = () => {
153
+ if (lineRange.type !== 'row')
154
+ return;
155
+ result.push(...generateLineDoubleBorderPayload(sheetIdx, lineRange.end, true, {
156
+ direction: 'bottom',
157
+ color: update.color,
158
+ borderType: update.borderType,
159
+ }));
160
+ };
161
+ const position = ['top', 'bottom', 'left', 'right'];
162
+ const drawInnerBorder = () => {
163
+ for (let i = lineRange.start; i <= lineRange.end; i += 1) {
164
+ position.forEach((p) => {
165
+ if (lineRange.type === 'row') {
166
+ if (p === 'top' && i === lineRange.start)
167
+ return;
168
+ if (p === 'bottom' && i === lineRange.end)
169
+ return;
170
+ }
171
+ if (lineRange.type === 'col') {
172
+ if (p === 'left' && i === lineRange.start)
173
+ return;
174
+ if (p === 'right' && i === lineRange.end)
175
+ return;
176
+ }
177
+ result.push(generateLineSingleBorderPayload(sheetIdx, i, lineRange.type === 'row', {
178
+ direction: p,
179
+ color: update.color,
180
+ borderType: update.borderType,
181
+ }));
182
+ });
183
+ }
184
+ };
185
+ switch (update.batch) {
186
+ case 'all':
187
+ drawInnerBorder();
188
+ drawTopBorder();
189
+ drawBottomBorder();
190
+ drawLeftBorder();
191
+ drawRightBorder();
192
+ break;
193
+ case 'top':
194
+ if (lineRange.type === 'col')
195
+ return [];
196
+ drawTopBorder();
197
+ break;
198
+ case 'bottom':
199
+ if (lineRange.type === 'col')
200
+ return [];
201
+ drawBottomBorder();
202
+ break;
203
+ case 'left':
204
+ if (lineRange.type === 'row')
205
+ return [];
206
+ drawLeftBorder();
207
+ break;
208
+ case 'right':
209
+ if (lineRange.type === 'row')
210
+ return [];
211
+ drawRightBorder();
212
+ break;
213
+ case 'horizontal':
214
+ drawInnerBorder();
215
+ break;
216
+ case 'vertical':
217
+ drawInnerBorder();
218
+ break;
219
+ case 'outer':
220
+ drawTopBorder();
221
+ drawBottomBorder();
222
+ drawLeftBorder();
223
+ drawRightBorder();
224
+ break;
225
+ case 'inner':
226
+ drawInnerBorder();
227
+ break;
228
+ case 'clear':
229
+ for (let i = lineRange.start; i <= lineRange.end; i += 1) {
230
+ position.forEach((d) => {
231
+ result.push(...generateLineDoubleBorderPayload(sheetIdx, i, lineRange.type === 'row', { direction: d, borderType: 'none' }));
232
+ });
233
+ }
234
+ }
235
+ return result;
236
+ }
237
+ function generateBorderBatchCellPayload(sheetIdx, fromRow, toRow, fromCol, toCol, update) {
238
+ const payloads = [];
239
+ const drawLeftBorder = () => {
240
+ for (let i = fromRow; i <= toRow; i += 1)
241
+ payloads.push(...generateDoubleBorderPayload(sheetIdx, i, fromCol, {
242
+ direction: 'left',
243
+ color: update.color,
244
+ borderType: update.borderType,
245
+ }));
246
+ };
247
+ const drawRightBorder = () => {
248
+ for (let i = fromRow; i <= toRow; i += 1)
249
+ payloads.push(...generateDoubleBorderPayload(sheetIdx, i, toCol, {
250
+ direction: 'right',
251
+ color: update.color,
252
+ borderType: update.borderType,
253
+ }));
254
+ };
255
+ const drawTopBorder = () => {
256
+ for (let j = fromCol; j <= toCol; j += 1)
257
+ payloads.push(...generateDoubleBorderPayload(sheetIdx, fromRow, j, {
258
+ direction: 'top',
259
+ color: update.color,
260
+ borderType: update.borderType,
261
+ }));
262
+ };
263
+ const drawBottomBorder = () => {
264
+ for (let j = fromCol; j <= toCol; j += 1)
265
+ payloads.push(...generateDoubleBorderPayload(sheetIdx, toRow, j, {
266
+ direction: 'bottom',
267
+ color: update.color,
268
+ borderType: update.borderType,
269
+ }));
270
+ };
271
+ const drawInnerBorder = (type) => {
272
+ for (let i = fromRow; i <= toRow; i += 1) {
273
+ for (let j = fromCol; j <= toCol; j += 1) {
274
+ if (j < toCol && (type === 'vertical' || type === 'all')) {
275
+ payloads.push(...generateDoubleBorderPayload(sheetIdx, i, j, {
276
+ direction: 'right',
277
+ color: update.color,
278
+ borderType: update.borderType,
279
+ }));
280
+ }
281
+ if (i < toRow && (type === 'horizontal' || type === 'all')) {
282
+ payloads.push(...generateDoubleBorderPayload(sheetIdx, i, j, {
283
+ direction: 'bottom',
284
+ color: update.color,
285
+ borderType: update.borderType,
286
+ }));
287
+ }
288
+ }
289
+ }
290
+ };
291
+ switch (update.batch) {
292
+ case 'all':
293
+ drawLeftBorder();
294
+ drawRightBorder();
295
+ drawTopBorder();
296
+ drawBottomBorder();
297
+ drawInnerBorder('all');
298
+ break;
299
+ case 'top':
300
+ drawTopBorder();
301
+ break;
302
+ case 'bottom':
303
+ drawBottomBorder();
304
+ break;
305
+ case 'left':
306
+ drawLeftBorder();
307
+ break;
308
+ case 'right':
309
+ drawRightBorder();
310
+ break;
311
+ case 'horizontal':
312
+ drawInnerBorder('horizontal');
313
+ break;
314
+ case 'vertical':
315
+ drawInnerBorder('vertical');
316
+ break;
317
+ case 'outer':
318
+ drawLeftBorder();
319
+ drawRightBorder();
320
+ drawTopBorder();
321
+ drawBottomBorder();
322
+ break;
323
+ case 'inner':
324
+ drawInnerBorder('all');
325
+ break;
326
+ case 'clear':
327
+ }
328
+ return payloads;
329
+ }
330
+ function generateLineDoubleBorderPayload(sheetIdx, line, row, update) {
331
+ const result = [
332
+ generateLineSingleBorderPayload(sheetIdx, line, row, {
333
+ direction: update.direction,
334
+ color: update.color,
335
+ borderType: update.borderType,
336
+ }),
337
+ ];
338
+ const direction = row ? 'top' : 'left';
339
+ const op = direction === 'top' ? 'bottom' : 'right';
340
+ if (line - 1 >= 0) {
341
+ result.push(generateLineSingleBorderPayload(sheetIdx, line - 1, row, {
342
+ direction: op,
343
+ color: update.color,
344
+ borderType: 'none',
345
+ }));
346
+ }
347
+ return result;
348
+ }
349
+ function generateLineSingleBorderPayload(sheetIdx, line, row, update) {
350
+ const ty = {};
351
+ switch (update.direction) {
352
+ case 'bottom':
353
+ if (!row)
354
+ break;
355
+ if (update.color)
356
+ ty.setBottomBorderColor = update.color;
357
+ if (update.borderType)
358
+ ty.setBottomBorderStyle = update.borderType;
359
+ break;
360
+ case 'top':
361
+ if (update.color)
362
+ ty.setTopBorderColor = update.color;
363
+ if (update.borderType)
364
+ ty.setTopBorderStyle = update.borderType;
365
+ break;
366
+ case 'left':
367
+ if (update.color)
368
+ ty.setLeftBorderColor = update.color;
369
+ if (update.borderType)
370
+ ty.setLeftBorderStyle = update.borderType;
371
+ break;
372
+ case 'right':
373
+ if (row)
374
+ break;
375
+ if (update.color)
376
+ ty.setRightBorderColor = update.color;
377
+ if (update.borderType)
378
+ ty.setRightBorderStyle = update.borderType;
379
+ break;
380
+ }
381
+ return lineStyle(sheetIdx, line, line, row, ty);
382
+ }
383
+ function generateDoubleBorderPayload(sheetIdx, row, col, update) {
384
+ const payload = generateSingleBorderPayload(sheetIdx, row, col, update);
385
+ let clear;
386
+ switch (update.direction) {
387
+ case 'bottom':
388
+ clear = getClearBorderPayload(sheetIdx, row + 1, col, 'top');
389
+ break;
390
+ case 'top':
391
+ if (row - 1 >= 0)
392
+ clear = getClearBorderPayload(sheetIdx, row - 1, col, 'bottom');
393
+ break;
394
+ case 'left':
395
+ if (col - 1 >= 0)
396
+ clear = getClearBorderPayload(sheetIdx, row, col - 1, 'right');
397
+ break;
398
+ case 'right':
399
+ clear = getClearBorderPayload(sheetIdx, row, col + 1, 'left');
400
+ break;
401
+ }
402
+ const result = [payload];
403
+ if (clear)
404
+ result.push(clear);
405
+ return result;
406
+ }
407
+ function generateSingleBorderPayload(sheetIdx, row, col, update) {
408
+ const ty = {};
409
+ switch (update.direction) {
410
+ case 'bottom':
411
+ if (update.color)
412
+ ty.setBottomBorderColor = update.color;
413
+ if (update.borderType)
414
+ ty.setBottomBorderStyle = update.borderType;
415
+ break;
416
+ case 'top':
417
+ if (update.color)
418
+ ty.setTopBorderColor = update.color;
419
+ if (update.borderType)
420
+ ty.setTopBorderStyle = update.borderType;
421
+ break;
422
+ case 'left':
423
+ if (update.color)
424
+ ty.setLeftBorderColor = update.color;
425
+ if (update.borderType)
426
+ ty.setLeftBorderStyle = update.borderType;
427
+ break;
428
+ case 'right':
429
+ if (update.color)
430
+ ty.setRightBorderColor = update.color;
431
+ if (update.borderType)
432
+ ty.setRightBorderStyle = update.borderType;
433
+ break;
434
+ }
435
+ return cellStyle(sheetIdx, row, col, ty);
436
+ }
437
+ function getClearBorderPayload(sheetIdx, row, col, direction) {
438
+ const ty = {};
439
+ switch (direction) {
440
+ case 'top':
441
+ ty.setTopBorderStyle = 'none';
442
+ break;
443
+ case 'bottom':
444
+ ty.setBottomBorderStyle = 'none';
445
+ break;
446
+ case 'left':
447
+ ty.setLeftBorderStyle = 'none';
448
+ break;
449
+ case 'right':
450
+ ty.setRightBorderStyle = 'none';
451
+ break;
452
+ }
453
+ return cellStyle(sheetIdx, row, col, ty);
454
+ }
@@ -0,0 +1,12 @@
1
+ export * from './port.js';
2
+ export * from './ops/index.js';
3
+ export * from './format/index.js';
4
+ export * from './craft-interactions/index.js';
5
+ export * from './validation/index.js';
6
+ export * from './field/index.js';
7
+ export * from './value/index.js';
8
+ export * from './strings/index.js';
9
+ export * from './type-guard/index.js';
10
+ export * from './utils/index.js';
11
+ export * from './transaction/index.js';
12
+ export * from './permissions/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ // logisheets-core — UI-free LogiSheets logic.
2
+ //
3
+ // Runs unchanged in the browser app and in a Node runtime. It depends on
4
+ // logisheets-web for TYPES only (see ./port); the concrete engine Client is
5
+ // injected by the host.
6
+ export * from './port.js';
7
+ export * from './ops/index.js';
8
+ export * from './format/index.js';
9
+ export * from './craft-interactions/index.js';
10
+ export * from './validation/index.js';
11
+ export * from './field/index.js';
12
+ export * from './value/index.js';
13
+ export * from './strings/index.js';
14
+ export * from './type-guard/index.js';
15
+ export * from './utils/index.js';
16
+ export * from './transaction/index.js';
17
+ export * from './permissions/index.js';