@vuu-ui/vuu-data-test 4.1.2 → 4.2.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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.1.2",
2
+ "version": "4.2.0",
3
3
  "main": "./src/index.js",
4
4
  "author": "heswell",
5
5
  "license": "Apache-2.0",
@@ -8,13 +8,13 @@
8
8
  "type-defs": "node ../../scripts/build-type-defs.mjs"
9
9
  },
10
10
  "dependencies": {
11
- "@vuu-ui/vuu-data-local": "4.1.2",
12
- "@vuu-ui/vuu-utils": "4.1.2"
11
+ "@vuu-ui/vuu-data-local": "4.2.0",
12
+ "@vuu-ui/vuu-utils": "4.2.0"
13
13
  },
14
14
  "devDependencies": {
15
- "@vuu-ui/vuu-protocol-types": "4.1.2",
16
- "@vuu-ui/vuu-data-types": "4.1.2",
17
- "@vuu-ui/vuu-table-types": "4.1.2"
15
+ "@vuu-ui/vuu-protocol-types": "4.2.0",
16
+ "@vuu-ui/vuu-data-types": "4.2.0",
17
+ "@vuu-ui/vuu-table-types": "4.2.0"
18
18
  },
19
19
  "sideEffects": false,
20
20
  "files": [
@@ -22,6 +22,7 @@ class VuuModule {
22
22
  this.#sessionTableMessageColumn = sessionTableMessageColumn;
23
23
  ModuleContainer.register(this);
24
24
  }
25
+ validateEdit(_tableName, _column, _value) {}
25
26
  getTableSchema(tableName) {
26
27
  return this.schemas[tableName] ?? this.#sessionTableMap[tableName]?.schema;
27
28
  }
@@ -305,14 +306,20 @@ class VuuModule {
305
306
  const { column, data, key } = rpcRequest.params;
306
307
  const sessionTable = this.#sessionTableMap[viewPortId];
307
308
  let targetTable = sessionTable;
309
+ let sourceTableName = this.#sessionSourceTableMap[viewPortId];
308
310
  if (!targetTable) {
309
311
  const { dataSource } = this.getSubscriptionByViewport(viewPortId);
310
- if (dataSource.table) targetTable = this.tables[dataSource.table.table];
312
+ if (dataSource.table) {
313
+ sourceTableName = dataSource.table.table;
314
+ targetTable = this.tables[sourceTableName];
315
+ }
311
316
  }
312
317
  if (targetTable) try {
313
318
  const sessionRow = sessionTable?.findByKey(key);
314
319
  if (sessionRow?.[sessionTable.map.vuuAction] === "deleteRow") throw Error("editCell: cannot edit a deleted row");
315
320
  assertUpdateIsValid(targetTable.schema, column, data);
321
+ const validationError = void 0 === sourceTableName ? void 0 : this.validateEdit(sourceTableName, column, data);
322
+ if (void 0 !== validationError) throw Error(validationError);
316
323
  targetTable.update(key, column, data);
317
324
  if (sessionTable && sessionTable.findByKey(key)?.[sessionTable.map.vuuAction] !== "addRow") sessionTable.update(key, "vuuAction", "editCell");
318
325
  return {
@@ -460,6 +467,14 @@ class VuuModule {
460
467
  errorMessage: `addRow: no active session table for viewport ${viewPortId}`
461
468
  };
462
469
  const { data, key } = rpcRequest.params;
470
+ const sourceTableName = this.#sessionSourceTableMap[sessionTableName];
471
+ if (void 0 !== sourceTableName) for (const [column, value] of Object.entries(data)){
472
+ const validationError = this.validateEdit(sourceTableName, column, value);
473
+ if (void 0 !== validationError) return {
474
+ type: "ERROR_RESULT",
475
+ errorMessage: validationError
476
+ };
477
+ }
463
478
  const keyColumn = sessionTable.schema.key;
464
479
  const rowKey = data[keyColumn] ?? key ?? uuid();
465
480
  const rowData = {
@@ -39,6 +39,17 @@ const testEditColumns = [
39
39
  serverDataType: "long"
40
40
  }
41
41
  ];
42
+ const TEST_EDIT_VALIDATION_QUANTITY_MESSAGE = "quantity must be between 1 and 1000";
43
+ const TEST_EDIT_VALIDATION_PRICE_MESSAGE = "price must be greater than zero";
44
+ const validateTestEditValidation = (column, value)=>{
45
+ if ("quantity" === column) {
46
+ const quantity = Number(value);
47
+ if (!Number.isInteger(quantity) || quantity < 1 || quantity > 1000) return TEST_EDIT_VALIDATION_QUANTITY_MESSAGE;
48
+ } else if ("price" === column) {
49
+ const price = Number(value);
50
+ if (!(price > 0)) return TEST_EDIT_VALIDATION_PRICE_MESSAGE;
51
+ }
52
+ };
42
53
  class TestModule extends VuuModule {
43
54
  #schemas = {
44
55
  TestDates: {
@@ -185,6 +196,15 @@ class TestModule extends VuuModule {
185
196
  module: "TEST",
186
197
  table: "TestEdit"
187
198
  }
199
+ },
200
+ TestEditValidation: {
201
+ columns: testEditColumns,
202
+ key: "id",
203
+ rangeLimits: DEFAULT_RANGE_LIMITS,
204
+ table: {
205
+ module: "TEST",
206
+ table: "TestEditValidation"
207
+ }
188
208
  }
189
209
  };
190
210
  #tables = {
@@ -562,7 +582,49 @@ class TestModule extends VuuModule {
562
582
  withNanoMs(Date.now(), 5),
563
583
  1000000000000000005n
564
584
  ]
565
- ], buildDataColumnMap(this.#schemas, "TestEdit"))
585
+ ], buildDataColumnMap(this.#schemas, "TestEdit")),
586
+ TestEditValidation: TableContainer.createTable(this.#schemas.TestEditValidation, [
587
+ [
588
+ "VAL-001",
589
+ "Alpha",
590
+ 12,
591
+ 101.25,
592
+ true,
593
+ 1001
594
+ ],
595
+ [
596
+ "VAL-002",
597
+ "Bravo",
598
+ 24,
599
+ 202.5,
600
+ false,
601
+ 1002
602
+ ],
603
+ [
604
+ "VAL-003",
605
+ "Charlie",
606
+ 36,
607
+ 303.75,
608
+ true,
609
+ 1003
610
+ ],
611
+ [
612
+ "VAL-004",
613
+ "Delta",
614
+ 48,
615
+ 405,
616
+ true,
617
+ 1004
618
+ ],
619
+ [
620
+ "VAL-005",
621
+ "Echo",
622
+ 60,
623
+ 506.25,
624
+ false,
625
+ 1005
626
+ ]
627
+ ], buildDataColumnMap(this.#schemas, "TestEditValidation"))
566
628
  };
567
629
  constructor(){
568
630
  super("TEST");
@@ -577,6 +639,9 @@ class TestModule extends VuuModule {
577
639
  return this.#tables;
578
640
  }
579
641
  get visualLinks() {}
642
+ validateEdit(tableName, column, value) {
643
+ return "TestEditValidation" === tableName ? validateTestEditValidation(column, value) : void 0;
644
+ }
580
645
  }
581
646
  const testModule = new TestModule();
582
- export { testModule };
647
+ export { TEST_EDIT_VALIDATION_PRICE_MESSAGE, TEST_EDIT_VALIDATION_QUANTITY_MESSAGE, testModule };
@@ -1,5 +1,5 @@
1
1
  import type { DataSourceBase, DataSourceConfig, DataSourceRowWithBigint, DataSourceSubscribedMessage, DataSourceVisualLinkCreatedMessage, EditSessionMode, CopyOption, SessionDataSourceOverrides, SessionType, TableSchema } from "@vuu-ui/vuu-data-types";
2
- import type { VuuMenu, VuuLink, LinkDescriptorWithLabel, VuuRpcMenuResponse, VuuCreateVisualLink, VuuRemoveVisualLink, VuuRpcServiceRequest, RpcResultSuccess, RpcResultError, VuuRpcMenuRequest } from "@vuu-ui/vuu-protocol-types";
2
+ import type { VuuMenu, VuuRowDataItemType, VuuLink, LinkDescriptorWithLabel, VuuRpcMenuResponse, VuuCreateVisualLink, VuuRemoveVisualLink, VuuRpcServiceRequest, RpcResultSuccess, RpcResultError, VuuRpcMenuRequest } from "@vuu-ui/vuu-protocol-types";
3
3
  import { Table } from "../../Table";
4
4
  import { TickingArrayDataSource } from "../../TickingArrayDataSource";
5
5
  export interface IVuuModule<T extends string = string> {
@@ -38,6 +38,12 @@ export declare abstract class VuuModule<T extends string = string> implements IV
38
38
  protected abstract menuServices?: Record<T, RpcMenuService[] | undefined> | undefined;
39
39
  protected abstract services?: Record<T, RpcService[] | undefined> | undefined;
40
40
  protected abstract visualLinks?: Record<T, VuuLink[] | undefined>;
41
+ /**
42
+ * Server-side validation applied to every value submitted by editCell and
43
+ * addRow. `tableName` is the source table, also when the edit targets a
44
+ * session table. Return a message to reject the value, undefined to accept.
45
+ */
46
+ protected validateEdit(_tableName: T, _column: string, _value: VuuRowDataItemType): string | undefined;
41
47
  getTableSchema(tableName: string): Record<T, Readonly<TableSchema>>[T];
42
48
  getTableList(): string[];
43
49
  protected handlePostSubscribeActivities: ({ clientViewportId, tableSchema, }: DataSourceSubscribedMessage) => void;
@@ -1,7 +1,10 @@
1
1
  import { type RpcMenuService, VuuModule } from "../core/module/VuuModule";
2
2
  import { type Table } from "../Table";
3
3
  import type { TableSchema } from "@vuu-ui/vuu-data-types";
4
- export type TestTableName = "TestDates" | "TwoHundredColumns" | "LinkParent" | "LinkChild" | "ChartTable" | "MaxScrollEndTable" | "TestEditEmpty" | "TestEdit";
4
+ import type { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
5
+ export type TestTableName = "TestDates" | "TwoHundredColumns" | "LinkParent" | "LinkChild" | "ChartTable" | "MaxScrollEndTable" | "TestEditEmpty" | "TestEdit" | "TestEditValidation";
6
+ export declare const TEST_EDIT_VALIDATION_QUANTITY_MESSAGE = "quantity must be between 1 and 1000";
7
+ export declare const TEST_EDIT_VALIDATION_PRICE_MESSAGE = "price must be greater than zero";
5
8
  declare class TestModule extends VuuModule<TestTableName> {
6
9
  #private;
7
10
  constructor();
@@ -11,6 +14,7 @@ declare class TestModule extends VuuModule<TestTableName> {
11
14
  get schemas(): Record<TestTableName, TableSchema>;
12
15
  get tables(): Record<TestTableName, Table>;
13
16
  get visualLinks(): undefined;
17
+ protected validateEdit(tableName: TestTableName, column: string, value: VuuRowDataItemType): string | undefined;
14
18
  }
15
19
  export declare const testModule: TestModule;
16
20
  export {};