ballerina-core 1.0.10 → 1.0.12

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/main.ts CHANGED
@@ -95,6 +95,8 @@ export * from "./src/forms/domains/parser/state"
95
95
  export * from "./src/forms/domains/parser/template"
96
96
  export * from "./src/forms/domains/parser/coroutines/runner"
97
97
  export * from "./src/forms/domains/parser/domains/validator/state"
98
+ export * from "./src/forms/domains/parser/domains/built-ins/state"
99
+ export * from "./src/forms/domains/parser/domains/types/state"
98
100
  export * from "./src/forms/domains/launcher/domains/edit/state"
99
101
  export * from "./src/forms/domains/launcher/domains/edit/template"
100
102
  export * from "./src/forms/domains/launcher/domains/edit/coroutines/runner"
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "ballerina-core",
3
3
  "author": "Dr. Giuseppe Maggiore",
4
4
  "private": false,
5
- "version": "1.0.10",
5
+ "version": "1.0.12",
6
6
  "main": "main.ts",
7
7
  "dependencies": {
8
8
  "immutable": "^5.0.0-beta.5",
@@ -243,10 +243,10 @@ export const Coroutine = {
243
243
  return CoroutineStep.Result(nextState, step.result);
244
244
  else {
245
245
  if (step.excludeOthers) {
246
- console.log(
247
- `exclude others detected, killing ${ps.length - 1
248
- } other coroutines`
249
- );
246
+ // console.log(
247
+ // `exclude others detected, killing ${ps.length - 1
248
+ // } other coroutines`
249
+ // );
250
250
  return CoroutineStep.MapState(
251
251
  step.next([context, deltaT]),
252
252
  ((_) => thenMaybe(nextState, _) || id)
@@ -1,9 +1,37 @@
1
- import { FormValidationError } from "../../../parser/domains/validator/state"
1
+ import { merge } from 'immutable'
2
+
3
+ const INITIAL_CONFIG = {
4
+ types: {},
5
+ forms: {},
6
+ apis: {
7
+ enumOptions: {},
8
+ searchableStreams: {},
9
+ entities: {},
10
+ },
11
+ mappings: {},
12
+ launchers: {}
13
+ }
2
14
 
3
15
  export const FormsConfigMerger = {
4
16
  Default:{
5
- merge:(formsConfigs:any, errors:Array<FormValidationError>) : [any, Array<FormValidationError>] => {
6
- return null!
17
+ merge: (formsConfigs: any): any => {
18
+ if (!formsConfigs || formsConfigs.length === 0) {
19
+ return {...INITIAL_CONFIG};
20
+ }
21
+
22
+ return formsConfigs.reduce((acc: any, current: any) => {
23
+ return {
24
+ types: merge(acc.types, current.types),
25
+ forms: merge(acc.forms, current.forms),
26
+ apis: {
27
+ enumOptions: merge(acc.apis.enumOptions, current.apis.enumOptions),
28
+ searchableStreams: merge(acc.apis.searchableStreams, current.apis.searchableStreams),
29
+ entities: merge(acc.apis.entities, current.apis.entities),
30
+ },
31
+ mappings: merge(acc.mappings, current.mappings),
32
+ launchers: merge(acc.launchers, current.launchers),
33
+ }
34
+ }, {...INITIAL_CONFIG})
7
35
  }
8
36
  }
9
37
  }
@@ -1,6 +1,6 @@
1
- import { AsyncState, FormsConfig, Sum, Synchronize, Unit } from "../../../../../main"
1
+ import { AsyncState, builtInsFromFieldViews, FormsConfig, Sum, Synchronize, Unit } from "../../../../../main"
2
2
  import { CoTypedFactory } from "../../../../coroutines/builder"
3
- import { builtInsFromFieldViews, FormParsingResult, FormsParserContext, FormsParserState, parseForms } from "../state"
3
+ import { FormParsingResult, FormsParserContext, FormsParserState, parseForms } from "../state"
4
4
 
5
5
  export const LoadValidateAndParseFormsConfig = () => {
6
6
  const Co = CoTypedFactory<FormsParserContext, FormsParserState>()
@@ -9,13 +9,14 @@ export const LoadValidateAndParseFormsConfig = () => {
9
9
  Co.GetState().then(current =>
10
10
  Synchronize<Unit, FormParsingResult>(async() => {
11
11
  const formsConfig = await current.getFormsConfig()
12
- const builtIns = builtInsFromFieldViews(current.fieldViews)
12
+ const builtIns = builtInsFromFieldViews(current.fieldViews, current.fieldTypeConverters)
13
13
  const validationResult = FormsConfig.Default.validateAndParseAPIResponse(builtIns)(formsConfig)
14
14
  if (validationResult.kind == "r")
15
15
  return Sum.Default.right(validationResult.value)
16
16
  return parseForms(
17
17
  builtIns,
18
18
  current.containerFormView,
19
+ current.nestedContainerFormView,
19
20
  current.fieldViews,
20
21
  current.infiniteStreamSources,
21
22
  current.enumOptionsSources,
@@ -0,0 +1,189 @@
1
+ import { Map, List, Set, OrderedMap } from "immutable"
2
+ import { CollectionReference } from "../../../collection/domains/reference/state";
3
+ import { CollectionSelection } from "../../../collection/domains/selection/state";
4
+ import { BasicFun } from "../../../../../fun/state";
5
+ import { Option, Sum } from "../../../../../collections/domains/sum/state"
6
+ import { Type, TypeDefinition, TypeName } from "../../../../../../main";
7
+
8
+ export const PrimitiveTypes =
9
+ ["string",
10
+ "number",
11
+ "boolean",
12
+ "maybeBoolean",
13
+ "Date",
14
+ "CollectionReference"] as const
15
+ export type PrimitiveType = (typeof PrimitiveTypes)[number]
16
+
17
+ export const GenericTypes = [
18
+ "SingleSelection",
19
+ "MultiSelection",
20
+ "List"] as const
21
+ export type GenericType = (typeof GenericTypes)[number]
22
+
23
+ export type ApiConverter<T> = { fromAPIRawValue: BasicFun<any, T>, toAPIRawValue: BasicFun<T, any> }
24
+ export type ApiConverters = {
25
+ "string": ApiConverter<string>
26
+ "number": ApiConverter<number>
27
+ "boolean": ApiConverter<boolean>
28
+ "maybeBoolean": ApiConverter<boolean | undefined>
29
+ "Date": ApiConverter<Date>
30
+ "CollectionReference": ApiConverter<CollectionReference>
31
+ "SingleSelection": ApiConverter<CollectionSelection<any>>
32
+ "MultiSelection": ApiConverter<OrderedMap<string, any>>
33
+ "List": ApiConverter<List<any>>
34
+ }
35
+
36
+ export type PrimitiveBuiltIn = { renderers: Set<keyof BuiltIns["renderers"]>, apiConverters: ApiConverter<any>, defaultValue: any }
37
+ export type GenericBuiltIn = { defaultValue: any, apiConverters: ApiConverter<any> }
38
+ export type BuiltIns = {
39
+ primitives: Map<string, PrimitiveBuiltIn>;
40
+ generics: Map<string, GenericBuiltIn>;
41
+ renderers: {
42
+ boolean: Set<string>;
43
+ maybeBoolean: Set<string>;
44
+ number: Set<string>;
45
+ string: Set<string>;
46
+ date: Set<string>;
47
+ enumSingleSelection: Set<string>;
48
+ enumMultiSelection: Set<string>;
49
+ streamSingleSelection: Set<string>;
50
+ streamMultiSelection: Set<string>;
51
+ list: Set<string>;
52
+ };
53
+ };
54
+
55
+ export const builtInsFromFieldViews = (fieldViews: any, fieldTypeConverters: ApiConverters): BuiltIns => {
56
+ let builtins: BuiltIns = {
57
+ "primitives": Map<string, PrimitiveBuiltIn>([
58
+ ["string", { renderers: Set(["string"]), apiConverters: fieldTypeConverters["string"], defaultValue: "" }] as [string, PrimitiveBuiltIn],
59
+ ["number", { renderers: Set(["number"]), apiConverters: fieldTypeConverters["number"], defaultValue: 0 }] as [string, PrimitiveBuiltIn],
60
+ ["boolean", { renderers: Set(["boolean"]), apiConverters: fieldTypeConverters["boolean"], defaultValue: false }],
61
+ ["maybeBoolean", { renderers: Set(["maybeBoolean"]), apiConverters: fieldTypeConverters["maybeBoolean"], defaultValue: undefined }] as [string, PrimitiveBuiltIn],
62
+ ["date", { renderers: Set(["date"]), apiConverters: fieldTypeConverters["Date"], defaultValue: new Date(Date.now()) }] as [string, PrimitiveBuiltIn],
63
+ ["Date", { renderers: Set(["date"]), apiConverters: fieldTypeConverters["Date"], defaultValue: new Date(Date.now()) }] as [string, PrimitiveBuiltIn],
64
+ ["CollectionReference", { renderers: Set(["enumSingleSelection", "enumMultiSelection", "streamSingleSelection", "streamMultiSelection"]), apiConverters: fieldTypeConverters["CollectionReference"], defaultValue: CollectionReference.Default("", "") }] as [string, PrimitiveBuiltIn]
65
+ ]),
66
+ "generics": Map([
67
+ ["SingleSelection", { apiConverters: fieldTypeConverters["SingleSelection"], defaultValue: CollectionSelection().Default.right("no selection") }] as [string, GenericBuiltIn],
68
+ ["Multiselection", { apiConverters: fieldTypeConverters["SingleSelection"], defaultValue: Map() }] as [string, GenericBuiltIn],
69
+ ["List", { apiConverters: fieldTypeConverters["SingleSelection"], defaultValue: [] }] as [string, GenericBuiltIn]
70
+ ]),
71
+ "renderers": {
72
+ "boolean": Set(),
73
+ "maybeBoolean": Set(),
74
+ "date": Set(),
75
+ "enumMultiSelection": Set(),
76
+ "enumSingleSelection": Set(),
77
+ "streamMultiSelection": Set(),
78
+ "streamSingleSelection": Set(),
79
+ "number": Set(),
80
+ "string": Set(),
81
+ "list": Set(),
82
+ }
83
+ }
84
+ Object.keys(builtins.renderers).forEach((_categoryName) => {
85
+ const categoryName = _categoryName as keyof BuiltIns["renderers"]
86
+ if (categoryName in fieldViews) {
87
+ Object.keys(fieldViews[categoryName]).forEach(viewName => {
88
+ builtins.renderers[categoryName] = builtins.renderers[categoryName].add(viewName)
89
+ })
90
+ }
91
+ })
92
+ return builtins
93
+ }
94
+
95
+
96
+ export const defaultValue = (types:Map<TypeName, TypeDefinition>, builtIns:BuiltIns) => (t: TypeName): any => {
97
+ let primitive = builtIns.primitives.get(t)
98
+ if (primitive != undefined) {
99
+ return primitive.defaultValue
100
+ } else {
101
+ let generic = builtIns.generics.get(t)
102
+ if (generic != undefined) {
103
+ return generic.defaultValue
104
+ } else {
105
+ let custom = types.get(t)
106
+ if (custom != undefined) {
107
+ let res = {} as any
108
+ custom.fields.forEach((field, fieldName) => {
109
+ res[fieldName] = defaultValue(types, builtIns)(field.kind == "primitive" ? field.value : field.kind == "lookup" ? field.name : field.value)
110
+ }
111
+ )
112
+ return res
113
+ } else {
114
+ throw `cannot find type ${t} when resolving defaultValue`
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ export const fromAPIRawValue = (t:Type, types:Map<TypeName, TypeDefinition>, builtIns:BuiltIns, converters:ApiConverters) => (raw:any) : any => {
121
+ if (raw == undefined) {
122
+ console.error(`instantiating default value for type ${JSON.stringify(t)}: something is missing from the API response`)
123
+ return defaultValue(types, builtIns)(t.kind == "primitive" ? t.value : t.kind == "lookup" ? t.name : t.value)
124
+ }
125
+
126
+ if (t.kind == "primitive") {
127
+ return converters[t.value].fromAPIRawValue(raw)
128
+ } else if (t.kind == "application") { // application here means "generic type application"
129
+ if (t.value == "SingleSelection" && t.args.length == 1) {
130
+ let result = converters[t.value].fromAPIRawValue(raw)
131
+ result = CollectionSelection().Updaters.left(
132
+ fromAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))(result)
133
+ return result
134
+ }
135
+ if (t.value == "MultiSelection" && t.args.length == 1) {
136
+ let result = converters[t.value].fromAPIRawValue(raw)
137
+ result = result.map(fromAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
138
+ return result
139
+ }
140
+ if (t.value == "List" && t.args.length == 1) {
141
+ let result = converters[t.value].fromAPIRawValue(raw)
142
+ result = result.map(fromAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
143
+ return result
144
+ }
145
+ } else { // t.kind == lookup: we are dealing with a record/object
146
+ let result:any = {}
147
+ const tDef = types.get(t.name)!
148
+ tDef.fields.forEach((fieldType, fieldName) => {
149
+ result[fieldName] = fromAPIRawValue(fieldType, types, builtIns, converters)(raw[fieldName])
150
+ })
151
+ return result
152
+ }
153
+ console.error(`instantiating default value for type ${JSON.stringify(t)}: something is missing from the API response`)
154
+ return defaultValue(types, builtIns)(t.value)
155
+ }
156
+
157
+
158
+ export const toAPIRawValue = (t:Type, types:Map<TypeName, TypeDefinition>, builtIns:BuiltIns, converters:ApiConverters) => (raw:any) : any => {
159
+ if (t.kind == "primitive") {
160
+ // t.value == ""
161
+ return converters[t.value].toAPIRawValue(raw as never)
162
+ } else if (t.kind == "application") { // application here means "generic type application"
163
+ if (t.value == "SingleSelection" && t.args.length == 1) {
164
+ let result = converters[t.value].toAPIRawValue(raw)
165
+ result = CollectionSelection().Updaters.left(
166
+ toAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))(result)
167
+ return result
168
+ }
169
+ if (t.value == "MultiSelection" && t.args.length == 1) {
170
+ let result = converters[t.value].toAPIRawValue(raw)
171
+ result = result.map(toAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
172
+ return result
173
+ }
174
+ if (t.value == "List" && t.args.length == 1) {
175
+ let result = converters[t.value].toAPIRawValue(raw)
176
+ result = result.map(toAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
177
+ return result
178
+ }
179
+ } else { // t.kind == lookup: we are dealing with a record/object
180
+ let result:any = {}
181
+ const tDef = types.get(t.name)!
182
+ tDef.fields.forEach((fieldType, fieldName) => {
183
+ result[fieldName] = toAPIRawValue(fieldType, types, builtIns, converters)(raw[fieldName])
184
+ })
185
+ return result
186
+ }
187
+ console.error(`instantiating default value for type ${JSON.stringify(t)}: something is missing from the API response`)
188
+ return defaultValue(types, builtIns)(t.value)
189
+ }
@@ -0,0 +1,31 @@
1
+ import { OrderedMap } from "immutable";
2
+
3
+ export type FieldName = string;
4
+ export type TypeName = string;
5
+ export type TypeDefinition = {
6
+ extends: Array<TypeName>;
7
+ name: TypeName;
8
+ fields: OrderedMap<FieldName, Type>;
9
+ };
10
+ export type Type = {
11
+ kind: "lookup"; name: TypeName;
12
+ } | {
13
+ kind: "primitive"; value: "string" | "number" | "maybeBoolean" | "boolean" | "Date" | "CollectionReference";
14
+ } | {
15
+ kind: "application"; value: TypeName; args: Array<TypeName>;
16
+ };
17
+ export const Type = {
18
+ Default: {
19
+ lookup: (name: TypeName): Type => ({ kind: "lookup", name })
20
+ },
21
+ Operations: {
22
+ Equals: (fst: Type, snd: Type): boolean =>
23
+ fst.kind == "lookup" && snd.kind == "lookup" ? fst.name == snd.name :
24
+ fst.kind == "primitive" && snd.kind == "primitive" ? fst.value == snd.value :
25
+ fst.kind == "application" && snd.kind == "application" ?
26
+ fst.value == snd.value &&
27
+ fst.args.length == snd.args.length &&
28
+ fst.args.every((v, i) => v == snd.args[i]) :
29
+ false
30
+ }
31
+ }
@@ -1,35 +1,6 @@
1
1
  import { Set, Map, OrderedMap } from "immutable";
2
- import { BoolExpr, FormsConfigMerger, MappingPaths, Sum } from "../../../../../../main";
2
+ import { BoolExpr, BuiltIns, FieldName, FormsConfigMerger, MappingPaths, Sum, Type, TypeDefinition, TypeName } from "../../../../../../main";
3
3
 
4
- export type FieldName = string;
5
- export type TypeName = string;
6
- export type TypeDefinition = {
7
- extends: Array<TypeName>;
8
- name: TypeName;
9
- fields: OrderedMap<FieldName, Type>;
10
- };
11
- export type Type = {
12
- kind: "lookup"; name: TypeName;
13
- } | {
14
- kind: "primitive"; value: "string" | "number" | "maybeBoolean" | "boolean" | "Date" | "CollectionReference";
15
- } | {
16
- kind: "application"; value: TypeName; args: Array<TypeName>;
17
- };
18
- export const Type = {
19
- Default: {
20
- lookup: (name: TypeName): Type => ({ kind: "lookup", name })
21
- },
22
- Operations: {
23
- Equals: (fst: Type, snd: Type): boolean =>
24
- fst.kind == "lookup" && snd.kind == "lookup" ? fst.name == snd.name :
25
- fst.kind == "primitive" && snd.kind == "primitive" ? fst.value == snd.value :
26
- fst.kind == "application" && snd.kind == "application" ?
27
- fst.value == snd.value &&
28
- fst.args.length == snd.args.length &&
29
- fst.args.every((v, i) => v == snd.args[i]) :
30
- false
31
- }
32
- }
33
4
  export type FieldConfig = {
34
5
  renderer: string;
35
6
  label: string
@@ -91,37 +62,12 @@ export type FormsConfig = {
91
62
  };
92
63
  export type FormValidationError = string;
93
64
 
94
- export type PrimitiveBuiltIn = { renderers: Set<keyof BuiltIns["renderers"]>, defaultValue: any }
95
- export type GenericBuiltIn = { defaultValue: any }
96
- export type BuiltIns = {
97
- primitives: Map<string, PrimitiveBuiltIn>;
98
- generics: Map<string, GenericBuiltIn>;
99
- renderers: {
100
- BooleanViews: Set<string>;
101
- MaybeBooleanViews: Set<string>;
102
- NumberViews: Set<string>;
103
- StringViews: Set<string>;
104
- DateViews: Set<string>;
105
- EnumViews: Set<string>;
106
- EnumMultiselectViews: Set<string>;
107
- InfiniteStreamViews: Set<string>;
108
- InfiniteStreamMultiselectViews: Set<string>;
109
- ListViews: Set<string>;
110
- };
111
- };
112
-
113
65
  export type FormValidationResult = Sum<FormsConfig, Array<FormValidationError>>
114
66
  export const FormsConfig = {
115
67
  Default: {
116
- validateAndParseAPIResponse: (builtIns: BuiltIns) => (formsConfig: any): FormValidationResult => {
68
+ validateAndParseAPIResponse: (builtIns: BuiltIns) => (fc: any): FormValidationResult => {
117
69
  let errors: Array<FormValidationError> = [];
118
- if (Array.isArray(formsConfig)) {
119
- alert("formsConfig is an array!")
120
- const merged = FormsConfigMerger.Default.merge(formsConfig, errors)
121
- formsConfig = merged[0]
122
- errors = merged[0]
123
- }
124
-
70
+ const formsConfig = Array.isArray(fc) ? FormsConfigMerger.Default.merge(fc) : fc;
125
71
  let types: Map<TypeName, TypeDefinition> = Map();
126
72
  if ("types" in formsConfig == false) {
127
73
  errors.push("the formsConfig does not contain a 'types' field");
@@ -346,57 +292,59 @@ export const FormsConfig = {
346
292
  if (fieldTypeDef.value == "maybeBoolean") {
347
293
  // alert(JSON.stringify(fieldConfig["renderer"]))
348
294
  // alert(JSON.stringify(builtIns.renderers.MaybeBooleanViews))
349
- if (!builtIns.renderers.MaybeBooleanViews.has(fieldConfig["renderer"]))
295
+ if (!builtIns.renderers.maybeBoolean.has(fieldConfig["renderer"]))
350
296
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
351
297
  } else if (fieldTypeDef.value == "boolean") {
352
- if (!builtIns.renderers.BooleanViews.has(fieldConfig["renderer"]))
298
+ if (!builtIns.renderers.boolean.has(fieldConfig["renderer"]))
353
299
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
354
300
  } else if (fieldTypeDef.value == "number") {
355
- if (!builtIns.renderers.NumberViews.has(fieldConfig["renderer"]))
301
+ if (!builtIns.renderers.number.has(fieldConfig["renderer"]))
356
302
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
357
303
  } else if (fieldTypeDef.value == "string") {
358
- if (!builtIns.renderers.StringViews.has(fieldConfig["renderer"]))
304
+ if (!builtIns.renderers.string.has(fieldConfig["renderer"]))
359
305
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
360
306
  } else if (fieldTypeDef.value == "Date") {
361
- if (!builtIns.renderers.DateViews.has(fieldConfig["renderer"]))
307
+ if (!builtIns.renderers.date.has(fieldConfig["renderer"])) {
308
+ alert(JSON.stringify(builtIns.renderers))
362
309
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
363
- } else {
310
+ }
311
+ } else {
364
312
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
365
313
  }
366
314
  } else if (fieldTypeDef?.kind == "application") {
367
315
  if (fieldTypeDef?.value == "SingleSelection") {
368
- if (!builtIns.renderers.EnumViews.has(fieldConfig["renderer"]) &&
369
- !builtIns.renderers.InfiniteStreamViews.has(fieldConfig["renderer"]))
316
+ if (!builtIns.renderers.enumSingleSelection.has(fieldConfig["renderer"]) &&
317
+ !builtIns.renderers.streamSingleSelection.has(fieldConfig["renderer"]))
370
318
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
371
319
  } else if (fieldTypeDef?.value == "Multiselection") {
372
- if (!builtIns.renderers.EnumMultiselectViews.has(fieldConfig["renderer"]) &&
373
- !builtIns.renderers.InfiniteStreamMultiselectViews.has(fieldConfig["renderer"]))
320
+ if (!builtIns.renderers.enumMultiSelection.has(fieldConfig["renderer"]) &&
321
+ !builtIns.renderers.streamMultiSelection.has(fieldConfig["renderer"]))
374
322
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
375
323
  } else if (fieldTypeDef?.value == "List") {
376
- if (!builtIns.renderers.ListViews.has(fieldConfig["renderer"]))
324
+ if (!builtIns.renderers.list.has(fieldConfig["renderer"]))
377
325
  errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
378
326
  }
379
327
  if (fieldTypeDef.args.length < 1)
380
328
  errors.push(`field ${fieldName} of form ${formName} should have one type argument}`);
381
329
  else if (
382
- (builtIns.renderers.ListViews.has(fieldConfig["renderer"])) && "elementRenderer" in fieldConfig != true)
330
+ (builtIns.renderers.list.has(fieldConfig["renderer"])) && "elementRenderer" in fieldConfig != true)
383
331
  errors.push(`field ${fieldName} of form ${formName} is missing the 'elementRenderer' property`);
384
332
  else if (
385
- (builtIns.renderers.EnumMultiselectViews.has(fieldConfig["renderer"]) ||
386
- builtIns.renderers.EnumViews.has(fieldConfig["renderer"])) && "options" in fieldConfig != true)
333
+ (builtIns.renderers.enumMultiSelection.has(fieldConfig["renderer"]) ||
334
+ builtIns.renderers.enumSingleSelection.has(fieldConfig["renderer"])) && "options" in fieldConfig != true)
387
335
  errors.push(`field ${fieldName} of form ${formName} is missing the 'options' property`);
388
336
  else if (
389
- (builtIns.renderers.InfiniteStreamViews.has(fieldConfig["renderer"]) ||
390
- builtIns.renderers.InfiniteStreamMultiselectViews.has(fieldConfig["renderer"])) && "stream" in fieldConfig != true)
337
+ (builtIns.renderers.streamSingleSelection.has(fieldConfig["renderer"]) ||
338
+ builtIns.renderers.streamMultiSelection.has(fieldConfig["renderer"])) && "stream" in fieldConfig != true)
391
339
  errors.push(`field ${fieldName} of form ${formName} is missing the 'stream' property`);
392
- else if ((builtIns.renderers.EnumMultiselectViews.has(fieldConfig["renderer"]) ||
393
- builtIns.renderers.EnumViews.has(fieldConfig["renderer"])) && (enums.get(fieldConfig["options"])) != fieldTypeDef.args[0]) {
340
+ else if ((builtIns.renderers.enumMultiSelection.has(fieldConfig["renderer"]) ||
341
+ builtIns.renderers.enumSingleSelection.has(fieldConfig["renderer"])) && (enums.get(fieldConfig["options"])) != fieldTypeDef.args[0]) {
394
342
  if (enums.has(fieldConfig["options"]))
395
343
  errors.push(`field ${fieldName} of form ${formName} references an enum api with type ${enums.get(fieldConfig["options"])} when ${fieldTypeDef.args[0]} was expected`);
396
344
  else
397
345
  errors.push(`field ${fieldName} of form ${formName} references a non-existing enum api`);
398
- } else if ((builtIns.renderers.InfiniteStreamMultiselectViews.has(fieldConfig["renderer"]) ||
399
- builtIns.renderers.InfiniteStreamViews.has(fieldConfig["renderer"])) && (streams.get(fieldConfig["stream"])) != fieldTypeDef.args[0]) {
346
+ } else if ((builtIns.renderers.streamMultiSelection.has(fieldConfig["renderer"]) ||
347
+ builtIns.renderers.streamSingleSelection.has(fieldConfig["renderer"])) && (streams.get(fieldConfig["stream"])) != fieldTypeDef.args[0]) {
400
348
  if (streams.has(fieldConfig["stream"]))
401
349
  errors.push(`field ${fieldName} of form ${formName} references an api with type ${streams.get(fieldConfig["stream"])} when ${fieldTypeDef.args[0]} was expected`);
402
350
  else
@@ -415,7 +363,7 @@ export const FormsConfig = {
415
363
  Object.keys(configFormDef["fields"]).forEach(fieldName => {
416
364
  const fieldConfig = configFormDef["fields"][fieldName]
417
365
  const fieldTypeDef = formTypeDef?.fields.get(fieldName);
418
- if (fieldTypeDef && fieldTypeDef.kind == "application" && fieldTypeDef.value == "List" && (builtIns.renderers.ListViews.has(fieldConfig["renderer"]))) {
366
+ if (fieldTypeDef && fieldTypeDef.kind == "application" && fieldTypeDef.value == "List" && (builtIns.renderers.list.has(fieldConfig["renderer"]))) {
419
367
  let elementRenderer = fieldConfig["elementRenderer"]
420
368
  let elementType = fieldTypeDef.args[0]
421
369
  const rendererHasType = (elementRenderer: string, elementType: string): Array<string> => {
@@ -570,8 +518,8 @@ export const FormsConfig = {
570
518
  })
571
519
 
572
520
  if (errors.length > 0) {
573
- console.log("parsing errors")
574
- console.log(errors)
521
+ console.error("parsing errors")
522
+ console.error(errors)
575
523
  return Sum.Default.right(errors);
576
524
  }
577
525
 
@@ -1,5 +1,5 @@
1
1
  import { Collection, Map, OrderedMap, OrderedSet, Set } from "immutable";
2
- import { BoolExpr, Unit, PromiseRepo, Guid, LeafPredicatesEvaluators, Predicate, FormsConfig, BuiltIns, FormDef, Sum, BasicFun, Template, unit, EditFormState, EditFormTemplate, ApiErrors, CreateFormTemplate, EntityFormTemplate, SharedFormState, CreateFormState, Entity, EditFormContext, CreateFormContext, MappedEntityFormTemplate, Mapping, FormValidationResult, Synchronized, simpleUpdater, PrimitiveBuiltIn, GenericBuiltIn, TypeName, ListFieldState, ListForm, TypeDefinition } from "../../../../main";
2
+ import { BoolExpr, Unit, PromiseRepo, Guid, LeafPredicatesEvaluators, Predicate, FormsConfig, BuiltIns, FormDef, Sum, BasicFun, Template, unit, EditFormState, EditFormTemplate, ApiErrors, CreateFormTemplate, EntityFormTemplate, SharedFormState, CreateFormState, Entity, EditFormContext, CreateFormContext, MappedEntityFormTemplate, Mapping, FormValidationResult, Synchronized, simpleUpdater, PrimitiveType, GenericType, ApiConverter, TypeName, ListFieldState, ListForm, TypeDefinition, ApiConverters, defaultValue, fromAPIRawValue } from "../../../../main";
3
3
  import { Value } from "../../../value/state";
4
4
  import { CollectionReference } from "../collection/domains/reference/state";
5
5
  import { CollectionSelection } from "../collection/domains/selection/state";
@@ -26,43 +26,43 @@ const parseOptions = (leafPredicates: any, options: any) => {
26
26
  export const FieldView = //<Context, FieldViews extends DefaultFieldViews, EnumFieldConfigs extends {}, EnumSources extends {}>() => <ViewType extends keyof FieldViews, ViewName extends keyof FieldViews[ViewType]>
27
27
  (fieldViews: any, viewType: any, viewName: any, fieldName: string, label: string, enumFieldConfigs: any, enumSources: any, leafPredicates: any): any => // FieldView<Context, FieldViews, ViewType, ViewName> =>
28
28
  {
29
- if (viewType == "MaybeBooleanViews")
29
+ if (viewType == "maybeBoolean")
30
30
  return MaybeBooleanForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
31
31
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
32
32
  .mapContext<any & SharedFormState & Value<boolean>>(_ => ({ ..._, label: label })) as any
33
- if (viewType == "BooleanViews")
33
+ if (viewType == "boolean")
34
34
  return BooleanForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
35
35
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
36
36
  .mapContext<any & SharedFormState & Value<boolean>>(_ => ({ ..._, label: label })) as any
37
- if (viewType == "DateViews")
37
+ if (viewType == "date")
38
38
  return DateForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
39
39
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
40
40
  .mapContext<any & DateFormState & Value<Date>>(_ => ({ ..._, label: label })) as any
41
- if (viewType == "NumberViews")
41
+ if (viewType == "number")
42
42
  return NumberForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
43
43
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
44
44
  .mapContext<any & SharedFormState & Value<number>>(_ => ({ ..._, label: label })) as any
45
- if (viewType == "StringViews")
45
+ if (viewType == "string")
46
46
  return StringForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
47
47
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
48
48
  .mapContext<any & SharedFormState & Value<string>>(_ => ({ ..._, label: label })) as any
49
- if (viewType == "EnumViews")
49
+ if (viewType == "enumSingleSelection")
50
50
  return EnumForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>(_ => PromiseRepo.Default.mock(() => []))
51
51
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
52
52
  .mapContext<any & EnumFormState<any & BaseEnumContext<any, CollectionReference>, CollectionReference> & Value<CollectionSelection<CollectionReference>>>(_ => ({
53
53
  ..._, label: label, getOptions: () => ((enumFieldConfigs as any)((enumSources as any)[fieldName]) as Promise<any>).then(options => parseOptions(leafPredicates, options))
54
54
  })) as any
55
- if (viewType == "EnumMultiselectViews")
55
+ if (viewType == "enumMultiSelection")
56
56
  return EnumMultiselectForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>(_ => PromiseRepo.Default.mock(() => []))
57
57
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
58
58
  .mapContext<any & EnumFormState<any & BaseEnumContext<any, CollectionReference>, CollectionReference> & Value<OrderedMap<Guid, CollectionReference>>>(_ => ({
59
59
  ..._, label: label, getOptions: () => ((enumFieldConfigs as any)((enumSources as any)[fieldName]) as Promise<any>).then(options => parseOptions(leafPredicates, options))
60
60
  })) as any
61
- if (viewType == "InfiniteStreamViews")
61
+ if (viewType == "streamSingleSelection")
62
62
  return SearchableInfiniteStreamForm<CollectionReference, any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
63
63
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
64
64
  .mapContext<any & SearchableInfiniteStreamState<CollectionReference> & Value<CollectionSelection<CollectionReference>>>(_ => ({ ..._, label: label })) as any
65
- if (viewType == "InfiniteStreamMultiselectViews")
65
+ if (viewType == "streamMultiSelection")
66
66
  return InfiniteMultiselectDropdownForm<CollectionReference, any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
67
67
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
68
68
  .mapContext<any & FormLabel & SharedFormState & SearchableInfiniteStreamState<CollectionReference> & Value<OrderedMap<Guid, CollectionReference>>>(_ => ({ ..._, label: label })) as any
@@ -71,19 +71,19 @@ export const FieldView = //<Context, FieldViews extends DefaultFieldViews, EnumF
71
71
 
72
72
  export const FieldFormState = //<Context, FieldViews extends DefaultFieldViews, InfiniteStreamSources extends {}, InfiniteStreamConfigs extends {}>() => <ViewType extends keyof FieldViews, ViewName extends keyof FieldViews[ViewType]>
73
73
  (fieldViews: any, viewType: any, viewName: any, fieldName: string, InfiniteStreamSources: any, infiniteStreamConfigs: any): any => {
74
- if (viewType == "MaybeBooleanViews" || viewType == "BooleanViews" || viewType == "NumberViews" || viewType == "StringViews")
74
+ if (viewType == "maybeBoolean" || viewType == "boolean" || viewType == "number" || viewType == "string")
75
75
  return SharedFormState.Default();
76
- if (viewType == "DateViews")
76
+ if (viewType == "date")
77
77
  return DateFormState.Default("");
78
- if (viewType == "EnumViews" || viewType == "EnumMultiselectViews")
78
+ if (viewType == "enumSingleSelection" || viewType == "enumMultiSelection")
79
79
  return ({ ...EnumFormState<any, any>().Default(), ...SharedFormState.Default() });
80
- if (viewType == "InfiniteStreamViews" || viewType == "InfiniteStreamMultiselectViews") {
80
+ if (viewType == "streamSingleSelection" || viewType == "streamMultiSelection") {
81
81
  return ({
82
82
  ...SearchableInfiniteStreamState<any>().Default("", (InfiniteStreamSources as any)((infiniteStreamConfigs as any)[fieldName])
83
83
  ), ...SharedFormState.Default()
84
84
  });
85
85
  }
86
- if (viewType == "ListViews")
86
+ if (viewType == "list")
87
87
  return ListFieldState<any, any>().Default(Map())
88
88
  return `error: the view for ${viewType as string}::${viewName as string} cannot be found when creating the corresponding field form state`;
89
89
  };
@@ -97,6 +97,7 @@ export type ParsedForm = {
97
97
  export const ParseForm = (
98
98
  formDef: FormDef,
99
99
  containerFormView: any,
100
+ nestedContainerFormView: any,
100
101
  fieldViews: any,
101
102
  otherForms: ParsedForms,
102
103
  fieldsViewsConfig: any,
@@ -145,17 +146,15 @@ export const ParseForm = (
145
146
  }
146
147
  });
147
148
  const formConfig: any = {};
148
- console.log(fieldsViewsConfig)
149
- console.log(Object.keys(fieldsViewsConfig))
150
149
  Object.keys(fieldsViewsConfig).forEach(fieldName => {
151
150
  const label = formDef.fields.get(fieldName)!.label
152
151
  const viewName = (fieldsViewsConfig as any)[fieldName];
153
152
  const otherForm = otherForms.get(viewName)
154
153
  if (otherForm != undefined) {
155
- formConfig[fieldName] = otherForm.form.withView(containerFormView).mapContext<any>(_ => ({ ..._, label: label }))
154
+ formConfig[fieldName] = otherForm.form.withView(nestedContainerFormView).mapContext<any>(_ => ({ ..._, label: label }))
156
155
  } else {
157
156
  const viewType = fieldNameToViewCategory(fieldName) as any
158
- if (viewType == "ListViews") {
157
+ if (viewType == "list") {
159
158
  const elementRendererName = formFieldElementRenderers[fieldName]
160
159
  const field = type.fields.get(fieldName)!
161
160
  const initialElementValue = defaultValue(field.kind == "primitive" ? field.value : field.kind == "lookup" ? field.name : field.args[0])
@@ -166,7 +165,7 @@ export const ParseForm = (
166
165
  { Default: () => ({ ...initialFormState }) },
167
166
  { Default: () => ({ ...initialElementValue }) },
168
167
  _ => PromiseRepo.Default.mock(() => []),
169
- elementForm.form.withView(containerFormView)
168
+ elementForm.form.withView(nestedContainerFormView)
170
169
  ).withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
171
170
  .mapContext<any>(_ => ({ ..._, label: label }))
172
171
  } else { // the list argument is a primitive
@@ -187,7 +186,7 @@ export const ParseForm = (
187
186
  if (typeof formConfig[fieldName] == "string") {
188
187
  debugger
189
188
  const err = formConfig[fieldName]
190
- console.log(`error processing field ${fieldName}`, err)
189
+ console.error(`error processing field ${fieldName}`, err)
191
190
  formConfig[fieldName] = (props: any) => <>Error: field {fieldName} with {viewName} could not be instantiated</>
192
191
  throw err
193
192
  }
@@ -214,44 +213,6 @@ export const parseVisibleFields = (
214
213
  visibleFields.map(([fieldName, boolExpr]) => ([fieldName, boolExpr.eval<any>(leafPredicates)]) as any)
215
214
  );
216
215
 
217
- export const builtInsFromFieldViews = (fieldViews: any): BuiltIns => {
218
- let builtins: BuiltIns = {
219
- "primitives": Map([
220
- ["string", { renderers: Set(["StringViews"]), defaultValue: "" }] as [string, PrimitiveBuiltIn],
221
- ["number", { renderers: Set(["NumberViews"]), defaultValue: 0 }],
222
- ["boolean", { renderers: Set(["BooleanViews"]), defaultValue: false }],
223
- ["maybeBoolean", { renderers: Set(["MaybeBooleanViews"]), defaultValue: undefined }],
224
- ["Date", { renderers: Set(["DateViews"]), defaultValue: new Date(Date.now()) }],
225
- ["CollectionReference", { renderers: Set(["EnumViews"]), defaultValue: CollectionReference.Default("", "") }]]),
226
- "generics": Map([
227
- ["SingleSelection", { defaultValue: CollectionSelection().Default.right("no selection") }] as [string, GenericBuiltIn],
228
- ["Multiselection", { defaultValue: Map() }],
229
- ["List", { defaultValue: [] }]
230
- ]),
231
- "renderers": {
232
- "BooleanViews": Set(),
233
- "MaybeBooleanViews": Set(),
234
- "DateViews": Set(),
235
- "EnumMultiselectViews": Set(),
236
- "EnumViews": Set(),
237
- "InfiniteStreamMultiselectViews": Set(),
238
- "InfiniteStreamViews": Set(),
239
- "NumberViews": Set(),
240
- "StringViews": Set(),
241
- "ListViews": Set(),
242
- }
243
- }
244
- Object.keys(builtins.renderers).forEach((_categoryName) => {
245
- const categoryName = _categoryName as keyof BuiltIns["renderers"]
246
- if (categoryName in fieldViews) {
247
- Object.keys(fieldViews[categoryName]).forEach(viewName => {
248
- builtins.renderers[categoryName] = builtins.renderers[categoryName].add(viewName)
249
- })
250
- }
251
- })
252
- return builtins
253
- }
254
-
255
216
  export type EditLauncherContext<Entity, FormState, ExtraContext> =
256
217
  Omit<
257
218
  EditFormContext<Entity, FormState> &
@@ -306,11 +267,14 @@ export type EntityApis = {
306
267
  get: BasicFun<EntityName, BasicFun<Guid, Promise<any>>>
307
268
  }
308
269
  export type EnumName = string
270
+
271
+
309
272
  export type EnumOptionsSources = BasicFun<EnumName, Promise<Array<[CollectionReference, BoolExpr<Unit>]>>>
310
273
  export const parseForms =
311
274
  <LeafPredicates,>(
312
275
  builtIns: BuiltIns,
313
276
  containerFormView: any,
277
+ nestedContainerFormView: any,
314
278
  fieldViews: any,
315
279
  infiniteStreamSources: InfiniteStreamSources,
316
280
  enumOptionsSources: EnumOptionsSources,
@@ -322,31 +286,6 @@ export const parseForms =
322
286
  let seen = Set<string>()
323
287
  let formProcessingOrder = OrderedSet<string>()
324
288
 
325
- const defaultValue = (t: TypeName): any => {
326
- let primitive = builtIns.primitives.get(t)
327
- if (primitive != undefined) {
328
- return primitive.defaultValue
329
- } else {
330
- let generic = builtIns.generics.get(t)
331
- if (generic != undefined) {
332
- return generic.defaultValue
333
- } else {
334
- let custom = formsConfig.types.get(t)
335
- if (custom != undefined) {
336
- let res = {} as any
337
- custom.fields.forEach((field, fieldName) => {
338
- res[fieldName] = defaultValue(field.kind == "primitive" ? field.value : field.kind == "lookup" ? field.name : field.value)
339
- }
340
- )
341
- return res
342
- } else {
343
- errors.push(`cannot find type ${t} when resolving defaultValue`)
344
- return undefined
345
- }
346
- }
347
- }
348
- }
349
-
350
289
  let parsedLaunchers: ParsedLaunchers = {
351
290
  create: Map(),
352
291
  edit: Map(),
@@ -384,6 +323,7 @@ export const parseForms =
384
323
  const parsedForm = ParseForm(
385
324
  formConfig,
386
325
  containerFormView,
326
+ nestedContainerFormView,
387
327
  fieldViews,
388
328
  parsedForms,
389
329
  formFieldRenderers,
@@ -395,7 +335,7 @@ export const parseForms =
395
335
  leafPredicates,
396
336
  formFieldVisibilities,
397
337
  formFieldDisabled,
398
- defaultValue,
338
+ defaultValue(formsConfig.types, builtIns),
399
339
  formConfig.typeDef,
400
340
  )
401
341
  const formBuilder = Form<any, any, any, any>().Default<any>()
@@ -442,7 +382,12 @@ export const parseForms =
442
382
  const initialState = parsedForm.initialFormState
443
383
  const api = {
444
384
  create: entityApis.create(launcher.api),
445
- default: entityApis.default(launcher.api)
385
+ default: (_:Unit) => entityApis.default(launcher.api)(unit)
386
+ // .then((raw:undefined) => {
387
+ // alert(JSON.stringify(parsedForm.formConfig))
388
+ // const parsed = fromAPIRawValue({ kind:"lookup", name:"" }, null!, null!, null!)(raw)
389
+ // return parsed
390
+ // })
446
391
  }
447
392
  parsedLaunchers.create = parsedLaunchers.create.set(
448
393
  launcherName,
@@ -497,7 +442,9 @@ export const parseForms =
497
442
 
498
443
  export type FormsParserContext = {
499
444
  containerFormView: any,
445
+ nestedContainerFormView: any,
500
446
  fieldViews: any,
447
+ fieldTypeConverters: ApiConverters,
501
448
  infiniteStreamSources: InfiniteStreamSources,
502
449
  enumOptionsSources: EnumOptionsSources,
503
450
  entityApis: EntityApis,
@@ -35,10 +35,10 @@ const X = {
35
35
  }
36
36
  }
37
37
 
38
- const visitor =
39
- X.Updaters.y.l(LeftValue.Updaters.value(_ => _ + 1)).then(
40
- X.Updaters.y.r(RightValue.Updaters.value(_ => !_))
41
- )
38
+ // const visitor =
39
+ // X.Updaters.y.l(LeftValue.Updaters.value(_ => _ + 1)).then(
40
+ // X.Updaters.y.r(RightValue.Updaters.value(_ => !_))
41
+ // )
42
42
 
43
43
 
44
- console.log(visitor)
44
+ // console.log(visitor)