@live-change/framework 0.9.76 → 0.9.78

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/index.ts CHANGED
@@ -27,8 +27,8 @@ export {
27
27
  }
28
28
 
29
29
  // Export all types from definition files
30
- export type { ActionDefinitionSpecification, ActionParameters } from './lib/definition/ActionDefinition.js'
31
- export type { EventDefinitionSpecification, EventParameters } from './lib/definition/EventDefinition.js'
30
+ export type { ActionDefinitionSpecification } from './lib/definition/ActionDefinition.js'
31
+ export type { EventDefinitionSpecification } from './lib/definition/EventDefinition.js'
32
32
  export type { IndexDefinitionSpecification } from './lib/definition/IndexDefinition.js'
33
33
  export type { ModelDefinitionSpecification, ModelIndexDefinitionSpecification, ModelPropertyDefinitionSpecification } from './lib/definition/ModelDefinition.js'
34
34
  export type { PropertyDefinitionSpecification, ValidationSpecification, ValidationSpecificationObject } from './lib/definition/PropertyDefinition.js'
@@ -37,3 +37,5 @@ export type { TriggerDefinitionSpecification } from './lib/definition/TriggerDef
37
37
  export type { ClientContext, ContextBase, ViewContext, ActionContext } from './lib/definition/types.js'
38
38
  export type { ServiceDefinitionSpecification } from './lib/definition/ServiceDefinition.js'
39
39
  export type { AccessSpecification, AccessFunction } from './lib/processors/accessMethod.js'
40
+ export type { EventDefinitionSpecification as EventDefinitionSpecificationAC } from './lib/definition/EventDefinition.js'
41
+ export type * from './lib/definition/types.js'
@@ -1,17 +1,16 @@
1
1
  import { AccessSpecification } from "../processors/accessMethod.js"
2
2
  import PropertyDefinition, { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
3
- import type { ActionContext } from "./types.js"
4
-
5
- export type ActionParameters = Record<string, any>
3
+ import type { ActionContext, ActionParameters } from "./types.js"
6
4
 
7
5
  export interface ActionDefinitionSpecification {
8
6
  name: string
9
7
  properties: Record<string, PropertyDefinitionSpecification>
10
- returns: PropertyDefinitionSpecification,
8
+ returns?: PropertyDefinitionSpecification,
11
9
  execute: (parameters: ActionParameters, context: ActionContext, emit: (event: any) => void) => any,
12
- access: AccessSpecification,
13
- skipValidation: boolean,
14
- validation: (parameters: ActionParameters, context: ActionContext) => Promise<any>
10
+ access?: AccessSpecification,
11
+ skipValidation?: boolean,
12
+ validation?: (parameters: ActionParameters, context: ActionContext) => Promise<any>
13
+ waitForEvents?: boolean
15
14
  }
16
15
 
17
16
  class ActionDefinition<T extends ActionDefinitionSpecification> {
@@ -1,11 +1,10 @@
1
1
  import PropertyDefinition, { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
2
2
 
3
- export type EventParameters = Record<string, any>
3
+ import type { EventParameters } from "./types.js"
4
4
 
5
5
  export interface EventDefinitionSpecification {
6
6
  name: string
7
7
  properties: Record<string, PropertyDefinitionSpecification>
8
- returns: PropertyDefinitionSpecification,
9
8
  execute: (parameters: EventParameters) => any
10
9
  }
11
10
 
@@ -22,9 +21,6 @@ class EventDefinition<T extends EventDefinitionSpecification> {
22
21
  this.createAndAddProperty(propName, propDefn)
23
22
  }
24
23
  }
25
- if(definition.returns) {
26
- this.returns = new PropertyDefinition(definition.returns)
27
- }
28
24
  }
29
25
 
30
26
  createAndAddProperty(name, definition) {
@@ -7,12 +7,15 @@ export interface ValidationSpecificationObject {
7
7
 
8
8
  export type ValidationSpecification = ValidationSpecificationObject | string
9
9
 
10
+ type PropertyDefinitionSpecificationType = string | StringConstructor | NumberConstructor | BooleanConstructor
11
+ | DateConstructor | ObjectConstructor | ArrayConstructor
12
+
10
13
  export interface PropertyDefinitionSpecification {
11
- type: string
14
+ type: PropertyDefinitionSpecificationType
12
15
  of?: PropertyDefinitionSpecification
13
16
  items?: PropertyDefinitionSpecification
14
17
  properties?: Record<string, PropertyDefinitionSpecification>,
15
- validation: ValidationSpecification[]
18
+ validation?: ValidationSpecification[]
16
19
  }
17
20
 
18
21
  class PropertyDefinition<T extends PropertyDefinitionSpecification> {
@@ -2,7 +2,7 @@ import ModelDefinition, { ModelDefinitionSpecification } from "./ModelDefinition
2
2
  import ForeignModelDefinition from "./ForeignModelDefinition.js"
3
3
  import IndexDefinition, { IndexDefinitionSpecification } from "./IndexDefinition.js"
4
4
  import ForeignIndexDefinition from "./ForeignIndexDefinition.js"
5
- import ActionDefinition from "./ActionDefinition.js"
5
+ import ActionDefinition, { ActionDefinitionSpecification } from "./ActionDefinition.js"
6
6
  import TriggerDefinition, { TriggerDefinitionSpecification } from "./TriggerDefinition.js"
7
7
  import ViewDefinition, { ViewDefinitionSpecification } from "./ViewDefinition.js"
8
8
  import EventDefinition from "./EventDefinition.js"
@@ -127,9 +127,9 @@ class ServiceDefinition<T extends ServiceDefinitionSpecification> {
127
127
  return createForeignIndexProxy(this, index)
128
128
  }
129
129
 
130
- action(definition) {
130
+ action<T extends ActionDefinitionSpecification>(definition: T) {
131
131
  if(this.actions[definition.name]) throw new Error('action ' + definition.name + ' already exists')
132
- const action = new ActionDefinition(definition)
132
+ const action = new ActionDefinition<T>(definition)
133
133
  this.actions[action.name] = action
134
134
  return action
135
135
  }
@@ -143,7 +143,7 @@ class ServiceDefinition<T extends ServiceDefinitionSpecification> {
143
143
 
144
144
  view<T extends ViewDefinitionSpecification>(definition: T) {
145
145
  if(this.views[definition.name]) throw new Error('view ' + definition.name + ' already exists')
146
- const view = new ViewDefinition(definition)
146
+ const view = new ViewDefinition<T>(definition)
147
147
  this.views[view.name] = view
148
148
  return view
149
149
  }
@@ -1,9 +1,15 @@
1
1
  import PropertyDefinition, { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
2
2
 
3
+ import { TriggerParameters, TriggerContext } from "./types.js"
4
+
3
5
  export interface TriggerDefinitionSpecification {
4
6
  name: string
5
7
  properties: Record<string, PropertyDefinitionSpecification>
6
- returns: PropertyDefinitionSpecification
8
+ returns?: PropertyDefinitionSpecification,
9
+ waitForEvents?: boolean
10
+ skipValidation?: boolean
11
+ validation?: (parameters: TriggerParameters, context: TriggerContext) => Promise<any>
12
+ execute: (parameters: TriggerParameters, context: TriggerContext, emit: (event: any) => void) => any,
7
13
  }
8
14
 
9
15
  class TriggerDefinition<T extends TriggerDefinitionSpecification> {
@@ -16,6 +16,30 @@ export interface ViewContext extends ContextBase {
16
16
  view: any,
17
17
  }
18
18
 
19
+ export type ActionParameters = Record<string, any>
20
+ export type TriggerParameters = Record<string, any>
21
+ export type EventParameters = Record<string, any>
22
+
23
+ export interface TriggerSettings {
24
+ service?: string,
25
+ type: string,
26
+ }
27
+
28
+ export interface TriggerServiceSettings {
29
+ service: string,
30
+ type: string,
31
+ }
32
+
33
+ type ContextTriggerFunction = (triggerSettings: TriggerSettings, parameters: ActionParameters) => void
34
+ type ContextTriggerServiceFunction = (triggerSettings: TriggerServiceSettings, parameters: ActionParameters) => void
19
35
  export interface ActionContext extends ContextBase {
20
- action: any
36
+ action: any,
37
+ trigger: ContextTriggerFunction,
38
+ triggerService: ContextTriggerServiceFunction,
39
+ }
40
+
41
+ export interface TriggerContext extends ContextBase {
42
+ reaction: any,
43
+ trigger: ContextTriggerFunction,
44
+ triggerService: ContextTriggerServiceFunction,
21
45
  }
@@ -23,6 +23,33 @@ function getValidators(source, service) {
23
23
  else validators[propName] = [validator]
24
24
  }
25
25
  }
26
+ if(prop.type === Object) {
27
+ validators = {
28
+ ...validators,
29
+ ...Object.fromEntries(
30
+ Object.entries(getValidators(prop, service))
31
+ .map(([key, value]) => [propName + '.' + key, value])
32
+ )
33
+ }
34
+ }
35
+ if(prop.type === Array) {
36
+ const elementType = prop.of ?? prop.items
37
+ if(elementType?.type === Object) {
38
+ validators = {
39
+ ...validators,
40
+ ...Object.fromEntries(
41
+ Object.entries(getValidators(prop, service))
42
+ .map(([key, value]) => [propName + '.' + key, value])
43
+ )
44
+ }
45
+ }
46
+ if(elementType?.validation) {
47
+ validators[propName + '.#'] = validators[propName + '.#'] || []
48
+ for(let validation of elementType.validation) {
49
+ validators[propName + '.#'].push(getValidator(validation, context))
50
+ }
51
+ }
52
+ }
26
53
  }
27
54
  return validators
28
55
  }
@@ -32,23 +59,39 @@ async function validate(props, validators, context) {
32
59
  let propPromises = {}
33
60
  for(let propName in validators) {
34
61
  let propValidators = validators[propName]
35
- let promises = []
36
- for(let validator of propValidators) {
37
- //console.log("PROPS",props, propName)
38
- promises.push(validator(props[propName], { ...context, props, propName }))
62
+ const path = propName.split('.')
63
+ function validateProperty(data, pathIndex, propNameAccumulator = '') {
64
+ //console.log(' '.repeat(pathIndex), "VALIDATE PROPERTY", pathIndex, propNameAccumulator)
65
+ if(pathIndex === path.length) {
66
+ const promises = (propPromises[propNameAccumulator] || [])
67
+ for(let validator of propValidators) {
68
+ promises.push(validator(data, { ...context, props, propName: propNameAccumulator }))
69
+ }
70
+ propPromises[propNameAccumulator] = promises
71
+ } else {
72
+ if(path[pathIndex] === '#') {
73
+ for(let i = 0; i < data.length; i++) {
74
+ validateProperty(data[i], pathIndex + 1,
75
+ propNameAccumulator + (propNameAccumulator ? '.' : '') + i)
76
+ }
77
+ } else {
78
+ const deeper = data?.[path[pathIndex]] ?? null
79
+ if(deeper === null) return
80
+ validateProperty(deeper, pathIndex + 1,
81
+ propNameAccumulator + (propNameAccumulator ? '.' : '') + path[pathIndex])
82
+ }
83
+ }
39
84
  }
40
- propPromises[propName] = Promise.all(promises)
85
+ validateProperty(props, 0)
41
86
  }
42
87
  let propErrors = {}
43
- for(let propName in validators) {
44
- let errors = (await propPromises[propName]).filter(e=>!!e)
45
- //console.log("EERRS",propName, errors)
88
+ for(const [propName, promises] of Object.entries(propPromises)) {
89
+ let errors = (await Promise.all(promises)).filter(x=> !!x)
46
90
  if(errors.length > 0) {
47
- //console.log("ERRS", propName)
48
91
  propErrors[propName] = errors[0]
49
92
  }
50
93
  }
51
- //console.log("PROP ERRORS", propErrors)
94
+ console.log("PROP ERRORS", propErrors)
52
95
  if(Object.keys(propErrors).length > 0) throw { properties: propErrors }
53
96
  }
54
97
 
@@ -1,6 +1,6 @@
1
1
  import { mergeDeep } from "../utils.js"
2
2
 
3
- function nonEmpty(value) {
3
+ export function nonEmpty(value) {
4
4
  if(!value) return 'empty'
5
5
  if(typeof value == 'string') {
6
6
  if(!value.trim()) return 'empty'
@@ -14,7 +14,7 @@ function nonEmpty(value) {
14
14
  }
15
15
  }
16
16
 
17
- function getField(context, fieldName) {
17
+ export function getField(context, fieldName) {
18
18
  const propPath = context.propName ? context.propName.split('.') : []
19
19
  propPath.pop()
20
20
  let path
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/framework",
3
- "version": "0.9.76",
3
+ "version": "0.9.78",
4
4
  "description": "Live Change Framework - ultimate solution for real time mobile/web apps",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "homepage": "https://github.com/live-change/live-change-stack",
24
24
  "devDependencies": {
25
- "@live-change/dao": "^0.9.76",
26
- "@live-change/uid": "^0.9.76",
25
+ "@live-change/dao": "^0.9.78",
26
+ "@live-change/uid": "^0.9.78",
27
27
  "typedoc": "0.28.3",
28
28
  "typedoc-plugin-markdown": "^4.6.3",
29
29
  "typedoc-plugin-rename-defaults": "^0.7.3"
30
30
  },
31
- "gitHead": "7b28068b9dca33af82e94db52b8a778c289edfbc"
31
+ "gitHead": "747a9cb02377d924583925508f082c8dd5031d43"
32
32
  }