@platforma-sdk/model 1.9.0 → 1.10.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.
@@ -47,6 +47,7 @@ type FieldMapOps = {
47
47
  export class TreeNodeAccessor {
48
48
  constructor(public readonly handle: AccessorHandle) {}
49
49
 
50
+ /** Shortcut for {@link resolveInput} */
50
51
  public resolve(
51
52
  ...steps: [
52
53
  Omit<FieldTraversalStep, 'errorIfFieldNotSet'> & {
@@ -54,8 +55,70 @@ export class TreeNodeAccessor {
54
55
  }
55
56
  ]
56
57
  ): TreeNodeAccessor;
58
+ /** Shortcut for {@link resolveInput} */
57
59
  public resolve(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined;
58
60
  public resolve(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined {
61
+ const transformedSteps = steps.map(
62
+ (s) =>
63
+ ({
64
+ assertFieldType: 'Input',
65
+ ...(typeof s === 'string' ? { field: s } : s)
66
+ }) satisfies FieldTraversalStep
67
+ );
68
+ return this.resolveWithCommon({}, ...transformedSteps);
69
+ }
70
+
71
+ /** If field type assertion is not specified for the step, default is Output. */
72
+ public resolveOutput(
73
+ ...steps: [
74
+ Omit<FieldTraversalStep, 'errorIfFieldNotSet'> & {
75
+ errorIfFieldNotAssigned: true;
76
+ }
77
+ ]
78
+ ): TreeNodeAccessor;
79
+ /** If field type assertion is not specified for the step, default is Output. */
80
+ public resolveOutput(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined;
81
+ public resolveOutput(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined {
82
+ const transformedSteps = steps.map(
83
+ (s) =>
84
+ ({
85
+ assertFieldType: 'Output',
86
+ ...(typeof s === 'string' ? { field: s } : s)
87
+ }) satisfies FieldTraversalStep
88
+ );
89
+ return this.resolveWithCommon({}, ...transformedSteps);
90
+ }
91
+
92
+ /** If field type assertion is not specified for the step, default is Input. */
93
+ public resolveInput(
94
+ ...steps: [
95
+ Omit<FieldTraversalStep, 'errorIfFieldNotSet'> & {
96
+ errorIfFieldNotAssigned: true;
97
+ }
98
+ ]
99
+ ): TreeNodeAccessor;
100
+ /** If field type assertion is not specified for the step, default is Input. */
101
+ public resolveInput(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined;
102
+ public resolveInput(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined {
103
+ const transformedSteps = steps.map(
104
+ (s) =>
105
+ ({
106
+ assertFieldType: 'Input',
107
+ ...(typeof s === 'string' ? { field: s } : s)
108
+ }) satisfies FieldTraversalStep
109
+ );
110
+ return this.resolveWithCommon({}, ...transformedSteps);
111
+ }
112
+
113
+ public resolveAny(
114
+ ...steps: [
115
+ Omit<FieldTraversalStep, 'errorIfFieldNotSet'> & {
116
+ errorIfFieldNotAssigned: true;
117
+ }
118
+ ]
119
+ ): TreeNodeAccessor;
120
+ public resolveAny(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined;
121
+ public resolveAny(...steps: (FieldTraversalStep | string)[]): TreeNodeAccessor | undefined {
59
122
  return this.resolveWithCommon({}, ...steps);
60
123
  }
61
124
 
@@ -1,5 +1,6 @@
1
1
  export * from './api';
2
2
  export * from './traversal_ops';
3
3
  export * from './accessor';
4
+ export * from './util';
4
5
  export { type ExtractFutureRefType } from './future';
5
6
  export { FutureRef } from './future';
@@ -46,8 +46,11 @@ export type GetFieldStep = CommonFieldTraverseOps & {
46
46
  errorIfFieldNotSet?: true;
47
47
 
48
48
  /**
49
- * Assert field type. Call will fail with exception if this assertion is not
50
- * fulfilled
49
+ * Assert field type.
50
+ * Call will fail with exception if this assertion is not fulfilled.
51
+ * The information about expectedFieldType is also used for stability
52
+ * calculation and field absence error generation, so it is always a good
53
+ * ide to specify it.
51
54
  * */
52
55
  assertFieldType?: FieldType;
53
56
  };
@@ -0,0 +1 @@
1
+ export * from './resource_map'
@@ -0,0 +1,74 @@
1
+ import { TreeNodeAccessor } from "../accessor";
2
+
3
+ export const ResourceMapResourceTypeName = 'PColumnData/ResourceMap';
4
+ export const ResourceMapResourcePartitionedTypeName = 'PColumnData/Partitioned/ResourceMap';
5
+
6
+ export type PColumnKey = (string | number)[];
7
+
8
+ export type PColumnResourceMapEntry<T> = {
9
+ key: PColumnKey;
10
+ value: T;
11
+ };
12
+
13
+ export type PColumnResourceMapData<T> = {
14
+ isComplete: boolean;
15
+ data: PColumnResourceMapEntry<T>[];
16
+ };
17
+
18
+ function populateResourceMapData<T>(
19
+ acc: TreeNodeAccessor | undefined,
20
+ resourceParser: (acc: TreeNodeAccessor) => T | undefined,
21
+ data: PColumnResourceMapEntry<T | undefined>[],
22
+ keyPrefix: PColumnKey = [],
23
+ addEntriesWithNoData: boolean
24
+ ): boolean {
25
+ if (acc === undefined) return false;
26
+ switch (acc.resourceType.name) {
27
+ case ResourceMapResourceTypeName: {
28
+ let isComplete = acc.getInputsLocked();
29
+ for (const keyStr of acc.listInputFields()) {
30
+ const value = acc.resolve({ field: keyStr, assertFieldType: 'Input' });
31
+ const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;
32
+ const converted = value === undefined ? undefined : resourceParser(value);
33
+ if (converted === undefined) isComplete = false;
34
+ if (converted !== undefined || addEntriesWithNoData) data.push({ key, value: converted });
35
+ }
36
+ return isComplete;
37
+ }
38
+ case ResourceMapResourcePartitionedTypeName: {
39
+ let isComplete = acc.getInputsLocked();
40
+ for (const keyStr of acc.listInputFields()) {
41
+ const value = acc.resolve({ field: keyStr, assertFieldType: 'Input' });
42
+ if (value === undefined) isComplete = false;
43
+ else {
44
+ const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;
45
+ const populateResult = populateResourceMapData(value, resourceParser, data, key, addEntriesWithNoData)
46
+ isComplete = isComplete && populateResult;
47
+ }
48
+ }
49
+ return isComplete;
50
+ }
51
+ default:
52
+ throw new Error(`Unknown resource type: ${acc.resourceType.name}`);
53
+ }
54
+ }
55
+
56
+ export function parseResourceMap<T>(
57
+ acc: TreeNodeAccessor | undefined,
58
+ resourceParser: (acc: TreeNodeAccessor) => T | undefined,
59
+ addEntriesWithNoData: false
60
+ ): PColumnResourceMapData<NonNullable<T>>;
61
+ export function parseResourceMap<T>(
62
+ acc: TreeNodeAccessor | undefined,
63
+ resourceParser: (acc: TreeNodeAccessor) => T | undefined,
64
+ addEntriesWithNoData: true
65
+ ): PColumnResourceMapData<T | undefined>;
66
+ export function parseResourceMap<T>(
67
+ acc: TreeNodeAccessor | undefined,
68
+ resourceParser: (acc: TreeNodeAccessor) => T | undefined,
69
+ addEntriesWithNoData: boolean = false
70
+ ): PColumnResourceMapData<T | undefined> {
71
+ const data: PColumnResourceMapEntry<T | undefined>[] = [];
72
+ const isComplete = populateResourceMapData(acc, resourceParser, data, [], addEntriesWithNoData);
73
+ return { isComplete, data };
74
+ }