@live-change/framework 0.9.73 → 0.9.75
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 +39 -0
- package/lib/App.js +21 -0
- package/lib/definition/{ActionDefinition.js → ActionDefinition.ts} +19 -3
- package/lib/definition/{EventDefinition.js → EventDefinition.ts} +14 -3
- package/lib/definition/{ForeignIndexDefinition.js → ForeignIndexDefinition.ts} +3 -2
- package/lib/definition/{ForeignModelDefinition.js → ForeignModelDefinition.ts} +3 -1
- package/lib/definition/{IndexDefinition.js → IndexDefinition.ts} +14 -3
- package/lib/definition/{ModelDefinition.js → ModelDefinition.ts} +24 -2
- package/lib/definition/{PropertyDefinition.js → PropertyDefinition.ts} +21 -4
- package/lib/definition/{ServiceDefinition.js → ServiceDefinition.ts} +19 -10
- package/lib/definition/{TriggerDefinition.js → TriggerDefinition.ts} +11 -3
- package/lib/definition/ViewDefinition.ts +71 -0
- package/lib/definition/types.ts +21 -0
- package/lib/processors/{accessMethod.js → accessMethod.ts} +7 -1
- package/lib/processors/autoValidation.js +21 -7
- package/package.json +7 -4
- package/tsconfig.json +29 -0
- package/typedoc.json +14 -0
- package/index.js +0 -46
- package/lib/definition/ViewDefinition.js +0 -39
package/index.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import App from './lib/App.js'
|
|
2
|
+
|
|
3
|
+
export default App
|
|
4
|
+
|
|
5
|
+
import ActionDefinition from './lib/definition/ActionDefinition.js'
|
|
6
|
+
import EventDefinition from './lib/definition/EventDefinition.js'
|
|
7
|
+
import ForeignIndexDefinition from './lib/definition/ForeignIndexDefinition.js'
|
|
8
|
+
import ForeignModelDefinition from './lib/definition/ForeignModelDefinition.js'
|
|
9
|
+
import IndexDefinition from './lib/definition/IndexDefinition.js'
|
|
10
|
+
import ModelDefinition from './lib/definition/ModelDefinition.js'
|
|
11
|
+
import PropertyDefinition from './lib/definition/PropertyDefinition.js'
|
|
12
|
+
import ServiceDefinition from './lib/definition/ServiceDefinition.js'
|
|
13
|
+
import TriggerDefinition from './lib/definition/TriggerDefinition.js'
|
|
14
|
+
import ViewDefinition from './lib/definition/ViewDefinition.js'
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
ActionDefinition,
|
|
18
|
+
EventDefinition,
|
|
19
|
+
ForeignIndexDefinition,
|
|
20
|
+
ForeignModelDefinition,
|
|
21
|
+
IndexDefinition,
|
|
22
|
+
ModelDefinition,
|
|
23
|
+
PropertyDefinition,
|
|
24
|
+
ServiceDefinition,
|
|
25
|
+
TriggerDefinition,
|
|
26
|
+
ViewDefinition
|
|
27
|
+
}
|
|
28
|
+
|
|
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'
|
|
32
|
+
export type { IndexDefinitionSpecification } from './lib/definition/IndexDefinition.js'
|
|
33
|
+
export type { ModelDefinitionSpecification, ModelIndexDefinitionSpecification, ModelPropertyDefinitionSpecification } from './lib/definition/ModelDefinition.js'
|
|
34
|
+
export type { PropertyDefinitionSpecification, ValidationSpecification, ValidationSpecificationObject } from './lib/definition/PropertyDefinition.js'
|
|
35
|
+
export type { ViewDefinitionSpecification, ViewDefinitionSpecificationBase, ViewDefinitionSpecificationObservable, ViewDefinitionSpecificationDaoPath, ViewDefinitionSpecificationFetch } from './lib/definition/ViewDefinition.js'
|
|
36
|
+
export type { TriggerDefinitionSpecification } from './lib/definition/TriggerDefinition.js'
|
|
37
|
+
export type { ClientContext, ContextBase, ViewContext, ActionContext } from './lib/definition/types.js'
|
|
38
|
+
export type { ServiceDefinitionSpecification } from './lib/definition/ServiceDefinition.js'
|
|
39
|
+
export type { AccessSpecification, AccessFunction } from './lib/processors/accessMethod.js'
|
package/lib/App.js
CHANGED
|
@@ -36,6 +36,10 @@ import Debug from 'debug'
|
|
|
36
36
|
|
|
37
37
|
const debug = Debug('framework')
|
|
38
38
|
|
|
39
|
+
|
|
40
|
+
import * as utils from './utils.js'
|
|
41
|
+
import * as validation from './utils/validation.js'
|
|
42
|
+
|
|
39
43
|
class App {
|
|
40
44
|
|
|
41
45
|
constructor(config = {}) {
|
|
@@ -82,8 +86,25 @@ class App {
|
|
|
82
86
|
this.startedServices = {}
|
|
83
87
|
this.triggerRoutes = {}
|
|
84
88
|
this.globalViews = {}
|
|
89
|
+
|
|
85
90
|
}
|
|
86
91
|
|
|
92
|
+
static app() {
|
|
93
|
+
if(!globalThis.liveChangeFrameworkApp) {
|
|
94
|
+
globalThis.liveChangeFrameworkApp = new App()
|
|
95
|
+
}
|
|
96
|
+
return globalThis.liveChangeFrameworkApp
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static utils = utils
|
|
100
|
+
static validation = validation
|
|
101
|
+
static rangeProperties = utils.rangeProperties
|
|
102
|
+
static encodeIdentifier = utils.encodeIdentifier
|
|
103
|
+
static extractRange = utils.extractRange
|
|
104
|
+
static isomorphic = utils.isomorphic
|
|
105
|
+
static computeDefaults = utils.computeDefaults
|
|
106
|
+
static computeUpdates = utils.computeUpdates
|
|
107
|
+
|
|
87
108
|
createServiceDefinition( definition ) {
|
|
88
109
|
const sourceConfig = this.config && this.config.services && this.config.services.find
|
|
89
110
|
&& this.config.services.find(c => c.name === definition.name)
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AccessSpecification } from "../processors/accessMethod.js"
|
|
2
|
+
import PropertyDefinition, { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
|
|
3
|
+
import type { ActionContext } from "./types.js"
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
export type ActionParameters = Record<string, any>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
export interface ActionDefinitionSpecification {
|
|
8
|
+
name: string
|
|
9
|
+
properties: Record<string, PropertyDefinitionSpecification>
|
|
10
|
+
returns: PropertyDefinitionSpecification,
|
|
11
|
+
execute: (parameters: ActionParameters, context: ActionContext, emit: (event: any) => void) => any,
|
|
12
|
+
access: AccessSpecification,
|
|
13
|
+
skipValidation: boolean,
|
|
14
|
+
validation: (parameters: ActionParameters, context: ActionContext) => Promise<any>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class ActionDefinition<T extends ActionDefinitionSpecification> {
|
|
18
|
+
[key: string]: any
|
|
19
|
+
|
|
20
|
+
constructor(definition: T) {
|
|
6
21
|
this.properties = {}
|
|
22
|
+
// @ts-ignore
|
|
7
23
|
for(let key in definition) this[key] = definition[key]
|
|
8
24
|
if(definition.properties) {
|
|
9
25
|
for (let propName in definition.properties) {
|
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import PropertyDefinition from "./PropertyDefinition.js"
|
|
1
|
+
import PropertyDefinition, { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export type EventParameters = Record<string, any>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
export interface EventDefinitionSpecification {
|
|
6
|
+
name: string
|
|
7
|
+
properties: Record<string, PropertyDefinitionSpecification>
|
|
8
|
+
returns: PropertyDefinitionSpecification,
|
|
9
|
+
execute: (parameters: EventParameters) => any
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class EventDefinition<T extends EventDefinitionSpecification> {
|
|
13
|
+
[key: string]: any
|
|
14
|
+
|
|
15
|
+
constructor(definition: T) {
|
|
6
16
|
this.properties = {}
|
|
17
|
+
// @ts-ignore
|
|
7
18
|
for(let key in definition) this[key] = definition[key]
|
|
8
19
|
if(definition.properties) {
|
|
9
20
|
for (let propName in definition.properties) {
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
export interface IndexDefinitionSpecification {
|
|
3
|
+
name: string
|
|
4
|
+
property: string | string[]
|
|
5
|
+
function: (...args: any[]) => any
|
|
6
|
+
parameters: Record<string, any>
|
|
7
|
+
storage: any
|
|
8
|
+
multi: boolean,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class IndexDefinition<T extends IndexDefinitionSpecification> {
|
|
12
|
+
[key: string]: any
|
|
3
13
|
|
|
4
|
-
constructor(definition) {
|
|
14
|
+
constructor(definition: T) {
|
|
5
15
|
this.properties = {}
|
|
16
|
+
// @ts-ignore
|
|
6
17
|
for(let key in definition) this[key] = definition[key]
|
|
7
18
|
}
|
|
8
19
|
|
|
@@ -16,7 +27,7 @@ class IndexDefinition {
|
|
|
16
27
|
computeChanges( oldIndexParam ) {
|
|
17
28
|
let oldIndex = JSON.parse(JSON.stringify(oldIndexParam))
|
|
18
29
|
oldIndex.indexes = oldIndex.indexes || {}
|
|
19
|
-
let changes = []
|
|
30
|
+
let changes: Record<string, any>[] = []
|
|
20
31
|
if(oldIndex.function !== `${this.function}`) {
|
|
21
32
|
changes.push({ operation: "deleteIndex", name: this.name })
|
|
22
33
|
changes.push({ operation: "createIndex", name: this.name, index: this.toJSON() })
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import PropertyDefinition from "./PropertyDefinition.js"
|
|
2
|
+
import type { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
|
|
2
3
|
import { crudChanges, definitionToJSON } from "../utils.js"
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
export interface ModelIndexDefinitionSpecification {
|
|
6
|
+
property?: string | string[]
|
|
7
|
+
function?: (...args: any[]) => any
|
|
8
|
+
parameters?: Record<string, any>
|
|
9
|
+
storage?: any
|
|
10
|
+
multi?: boolean,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ModelPropertyDefinitionSpecification {
|
|
14
|
+
type: string,
|
|
15
|
+
index: ModelIndexDefinitionSpecification
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ModelDefinitionSpecification {
|
|
19
|
+
name: string
|
|
20
|
+
properties: Record<string, ModelPropertyDefinitionSpecification>
|
|
21
|
+
indexes: Record<string, ModelIndexDefinitionSpecification>
|
|
22
|
+
onChange: (() => void)[]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class ModelDefinition<T extends ModelDefinitionSpecification> {
|
|
26
|
+
[key: string]: any
|
|
5
27
|
|
|
6
28
|
constructor(definition, serviceName) {
|
|
7
29
|
this.serviceName = serviceName
|
|
@@ -55,7 +77,7 @@ class ModelDefinition {
|
|
|
55
77
|
computeChanges( oldModelParam ) {
|
|
56
78
|
let oldModel = JSON.parse(JSON.stringify(oldModelParam))
|
|
57
79
|
oldModel.indexes = oldModel.indexes || {}
|
|
58
|
-
let changes = []
|
|
80
|
+
let changes: Record<string, any>[] = []
|
|
59
81
|
const json = this.toJSON()
|
|
60
82
|
changes.push(...crudChanges(oldModel.properties || {}, json.properties || {},
|
|
61
83
|
"Property", "property", { model: this.name }))
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import { typeName, definitionToJSON } from "../utils.js"
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export interface ValidationSpecificationObject {
|
|
4
|
+
name: string
|
|
5
|
+
[key: string]: any
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type ValidationSpecification = ValidationSpecificationObject | string
|
|
9
|
+
|
|
10
|
+
export interface PropertyDefinitionSpecification {
|
|
11
|
+
type: string
|
|
12
|
+
of?: PropertyDefinitionSpecification
|
|
13
|
+
items?: PropertyDefinitionSpecification
|
|
14
|
+
properties?: Record<string, PropertyDefinitionSpecification>,
|
|
15
|
+
validation: ValidationSpecification[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class PropertyDefinition<T extends PropertyDefinitionSpecification> {
|
|
19
|
+
[key: string]: any
|
|
4
20
|
|
|
5
|
-
constructor(definition) {
|
|
21
|
+
constructor(definition: T) {
|
|
22
|
+
// @ts-ignore
|
|
6
23
|
for(let key in definition) this[key] = definition[key]
|
|
7
24
|
if(definition.properties) {
|
|
8
25
|
for (let propName in definition.properties) {
|
|
@@ -24,7 +41,7 @@ class PropertyDefinition {
|
|
|
24
41
|
}
|
|
25
42
|
|
|
26
43
|
toJSON() {
|
|
27
|
-
let properties = undefined
|
|
44
|
+
let properties: Record<string, any> | undefined = undefined
|
|
28
45
|
if(this.properties) {
|
|
29
46
|
properties = {}
|
|
30
47
|
for (let propName in this.properties) {
|
|
@@ -47,7 +64,7 @@ class PropertyDefinition {
|
|
|
47
64
|
}
|
|
48
65
|
|
|
49
66
|
computeChanges( oldProperty, params, name) {
|
|
50
|
-
let changes = []
|
|
67
|
+
let changes: Record<string, any>[] = []
|
|
51
68
|
let typeChanged = false
|
|
52
69
|
if(typeName(this.type) !== typeName(oldProperty.type)) typeChanged = true
|
|
53
70
|
if((this.of && typeName(this.of.type)) !== (oldProperty.of && typeName(oldProperty.of.type)))
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import ModelDefinition from "./ModelDefinition.js"
|
|
1
|
+
import ModelDefinition, { ModelDefinitionSpecification } from "./ModelDefinition.js"
|
|
2
2
|
import ForeignModelDefinition from "./ForeignModelDefinition.js"
|
|
3
|
-
import IndexDefinition from "./IndexDefinition.js"
|
|
3
|
+
import IndexDefinition, { IndexDefinitionSpecification } from "./IndexDefinition.js"
|
|
4
4
|
import ForeignIndexDefinition from "./ForeignIndexDefinition.js"
|
|
5
5
|
import ActionDefinition from "./ActionDefinition.js"
|
|
6
|
-
import TriggerDefinition from "./TriggerDefinition.js"
|
|
7
|
-
import ViewDefinition from "./ViewDefinition.js"
|
|
6
|
+
import TriggerDefinition, { TriggerDefinitionSpecification } from "./TriggerDefinition.js"
|
|
7
|
+
import ViewDefinition, { ViewDefinitionSpecification } from "./ViewDefinition.js"
|
|
8
8
|
import EventDefinition from "./EventDefinition.js"
|
|
9
9
|
import defaultValidators from '../utils/validators.js'
|
|
10
10
|
import { crudChanges } from "../utils.js"
|
|
@@ -70,8 +70,16 @@ function createForeignIndexProxy(definition, model) {
|
|
|
70
70
|
})
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
export interface ServiceDefinitionSpecification {
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class ServiceDefinition<T extends ServiceDefinitionSpecification> {
|
|
80
|
+
[key: string]: any
|
|
81
|
+
|
|
82
|
+
constructor(definition: T) {
|
|
75
83
|
this.models = {}
|
|
76
84
|
this.foreignModels = {}
|
|
77
85
|
this.indexes = {}
|
|
@@ -89,10 +97,11 @@ class ServiceDefinition {
|
|
|
89
97
|
this.endpoints = []
|
|
90
98
|
this.validators = { ...defaultValidators }
|
|
91
99
|
this.clientSideFilters = []
|
|
100
|
+
// @ts-ignore
|
|
92
101
|
for(let key in definition) this[key] = definition[key]
|
|
93
102
|
}
|
|
94
103
|
|
|
95
|
-
model(definition) {
|
|
104
|
+
model<T extends ModelDefinitionSpecification>(definition: T) {
|
|
96
105
|
if(this.models[definition.name]) throw new Error('model ' + definition.name + ' already exists')
|
|
97
106
|
const model = new ModelDefinition(definition, this.name)
|
|
98
107
|
this.models[model.name] = model
|
|
@@ -132,14 +141,14 @@ class ServiceDefinition {
|
|
|
132
141
|
return event
|
|
133
142
|
}
|
|
134
143
|
|
|
135
|
-
view(definition) {
|
|
144
|
+
view<T extends ViewDefinitionSpecification>(definition: T) {
|
|
136
145
|
if(this.views[definition.name]) throw new Error('view ' + definition.name + ' already exists')
|
|
137
146
|
const view = new ViewDefinition(definition)
|
|
138
147
|
this.views[view.name] = view
|
|
139
148
|
return view
|
|
140
149
|
}
|
|
141
150
|
|
|
142
|
-
trigger(definition) {
|
|
151
|
+
trigger<T extends TriggerDefinitionSpecification>(definition: T) {
|
|
143
152
|
const trigger = new TriggerDefinition(definition)
|
|
144
153
|
//if(this.triggers[trigger.name]) throw new Error('trigger ' + trigger.name + ' already exists')
|
|
145
154
|
this.triggers[trigger.name] = [ ...(this.triggers[trigger.name] || []) , trigger ]
|
|
@@ -220,7 +229,7 @@ class ServiceDefinition {
|
|
|
220
229
|
|
|
221
230
|
computeChanges( oldModuleParam ) {
|
|
222
231
|
let oldModule = JSON.parse(JSON.stringify(oldModuleParam))
|
|
223
|
-
let changes = []
|
|
232
|
+
let changes: Record<string, any>[] = []
|
|
224
233
|
changes.push(...crudChanges(oldModule.models || {}, this.models || {},
|
|
225
234
|
"Model", "model", { }))
|
|
226
235
|
changes.push(...crudChanges(oldModule.indexes || {}, this.indexes || {},
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import PropertyDefinition from "./PropertyDefinition.js"
|
|
1
|
+
import PropertyDefinition, { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export interface TriggerDefinitionSpecification {
|
|
4
|
+
name: string
|
|
5
|
+
properties: Record<string, PropertyDefinitionSpecification>
|
|
6
|
+
returns: PropertyDefinitionSpecification
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class TriggerDefinition<T extends TriggerDefinitionSpecification> {
|
|
10
|
+
[key: string]: any
|
|
4
11
|
|
|
5
|
-
constructor(definition) {
|
|
12
|
+
constructor(definition: T) {
|
|
6
13
|
this.properties = {}
|
|
14
|
+
// @ts-ignore
|
|
7
15
|
for(let key in definition) this[key] = definition[key]
|
|
8
16
|
if(definition.properties) {
|
|
9
17
|
for (let propName in definition.properties) {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import PropertyDefinition, { PropertyDefinitionSpecification } from "./PropertyDefinition.js"
|
|
2
|
+
|
|
3
|
+
import type { ViewContext } from "./types.js"
|
|
4
|
+
|
|
5
|
+
import type { AccessSpecification } from "../processors/accessMethod.js"
|
|
6
|
+
|
|
7
|
+
export interface ViewDefinitionSpecificationBase {
|
|
8
|
+
name: string
|
|
9
|
+
properties: Record<string, PropertyDefinitionSpecification>
|
|
10
|
+
returns: PropertyDefinitionSpecification
|
|
11
|
+
internal: boolean,
|
|
12
|
+
access: AccessSpecification,
|
|
13
|
+
skipValidation: boolean,
|
|
14
|
+
validation: (parameters: Record<string, any>, context: ViewContext) => Promise<any>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ViewDefinitionSpecificationObservable extends ViewDefinitionSpecificationBase {
|
|
18
|
+
observable: (parameters: Record<string, any>, context: ViewContext) => any
|
|
19
|
+
get: (parameters: Record<string, any>, context: ViewContext) => Promise<any>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ViewDefinitionSpecificationDaoPath extends ViewDefinitionSpecificationBase {
|
|
23
|
+
daoPath: (parameters: Record<string, any>, context: ViewContext) => any[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ViewDefinitionSpecificationFetch extends ViewDefinitionSpecificationBase {
|
|
27
|
+
fetch: (parameters: Record<string, any>, context: ViewContext) => Promise<any>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type ViewDefinitionSpecification =
|
|
31
|
+
ViewDefinitionSpecificationObservable | ViewDefinitionSpecificationDaoPath | ViewDefinitionSpecificationFetch
|
|
32
|
+
|
|
33
|
+
class ViewDefinition<T extends ViewDefinitionSpecification> {
|
|
34
|
+
[key: string]: any
|
|
35
|
+
|
|
36
|
+
constructor(definition: T) {
|
|
37
|
+
this.properties = {}
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
for(let key in definition) this[key] = definition[key]
|
|
40
|
+
if(definition.properties) {
|
|
41
|
+
for (let propName in definition.properties) {
|
|
42
|
+
const propDefn = definition.properties[propName]
|
|
43
|
+
this.createAndAddProperty(propName, propDefn)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if(definition.returns) {
|
|
47
|
+
this.returns = new PropertyDefinition(definition.returns)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
createAndAddProperty(name, definition) {
|
|
52
|
+
const property = new PropertyDefinition(definition)
|
|
53
|
+
this.properties[name] = property
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
toJSON() {
|
|
57
|
+
let properties = {}
|
|
58
|
+
for(let propName in this.properties) {
|
|
59
|
+
properties[propName] = this.properties[propName].toJSON()
|
|
60
|
+
}
|
|
61
|
+
let returns = this.returns ? this.returns.toJSON() : null
|
|
62
|
+
return {
|
|
63
|
+
... this,
|
|
64
|
+
properties,
|
|
65
|
+
returns
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default ViewDefinition
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
export interface ClientContext {
|
|
3
|
+
session: string
|
|
4
|
+
user: string
|
|
5
|
+
ip: string
|
|
6
|
+
roles: string[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ContextBase {
|
|
10
|
+
client: ClientContext
|
|
11
|
+
service: any,
|
|
12
|
+
visibilityTest: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ViewContext extends ContextBase {
|
|
16
|
+
view: any,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ActionContext extends ContextBase {
|
|
20
|
+
action: any
|
|
21
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { ActionContext, ViewContext } from "../definition/types.js"
|
|
2
|
+
|
|
3
|
+
export type AccessFunction = (params: Record<string, any>, context: ViewContext | ActionContext) => boolean
|
|
4
|
+
|
|
5
|
+
export type AccessSpecification = AccessFunction | string[] | 'internal'
|
|
6
|
+
|
|
7
|
+
export default function getAccessMethod(access: AccessSpecification) {
|
|
2
8
|
if(typeof access == 'function') {
|
|
3
9
|
return access
|
|
4
10
|
} else if(Array.isArray(access)) {
|
|
@@ -24,6 +24,10 @@ export default function(service, app) {
|
|
|
24
24
|
if(!action.skipValidation) {
|
|
25
25
|
await validate(args[0], validators, { source: action, action, service, app, ...context })
|
|
26
26
|
}
|
|
27
|
+
if(typeof action.validation === 'function') {
|
|
28
|
+
const result = await action.validation(args[0], { source: action, action, service, app, ...context })
|
|
29
|
+
if(result) throw result
|
|
30
|
+
}
|
|
27
31
|
return oldExec.apply(action, args)
|
|
28
32
|
}
|
|
29
33
|
}
|
|
@@ -31,25 +35,35 @@ export default function(service, app) {
|
|
|
31
35
|
}
|
|
32
36
|
for(let viewName in service.views) {
|
|
33
37
|
const view = service.views[viewName]
|
|
34
|
-
if(view.skipValidation) continue
|
|
38
|
+
if(view.skipValidation && !view.validation) continue
|
|
35
39
|
const validators = getValidators(view, service, view)
|
|
36
40
|
if(Object.keys(validators).length > 0) {
|
|
37
41
|
if (view.observable) {
|
|
38
42
|
const oldObservable = view.observable
|
|
39
43
|
view.observable = async (...args) => {
|
|
40
44
|
const context = args[1]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
if(!view.skipValidation) {
|
|
46
|
+
await validate(args[0], validators, { source: view, view, service, app, ...context })
|
|
47
|
+
}
|
|
48
|
+
if(typeof view.validation === 'function') {
|
|
49
|
+
const result = await view.validation(args[0], { source: view, view, service, app, ...context })
|
|
50
|
+
if(result) throw result
|
|
51
|
+
}
|
|
52
|
+
return oldObservable.apply(view, args)
|
|
44
53
|
}
|
|
45
54
|
}
|
|
46
55
|
if(view.get) {
|
|
47
56
|
const oldGet = view.get
|
|
48
57
|
view.get = async (...args) => {
|
|
49
58
|
const context = args[1]
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
if(!view.skipValidation) {
|
|
60
|
+
await validate(args[0], validators, { source: view, view, service, app, ...context })
|
|
61
|
+
}
|
|
62
|
+
if(typeof view.validation === 'function') {
|
|
63
|
+
const result = await view.validation(args[0], { source: view, view, service, app, ...context })
|
|
64
|
+
if(result) throw result
|
|
65
|
+
}
|
|
66
|
+
return oldGet.apply(view, args)
|
|
53
67
|
}
|
|
54
68
|
}
|
|
55
69
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/framework",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.75",
|
|
4
4
|
"description": "Live Change Framework - ultimate solution for real time mobile/web apps",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,8 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/live-change/live-change-stack",
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@live-change/dao": "^0.9.
|
|
26
|
-
"@live-change/uid": "^0.9.
|
|
25
|
+
"@live-change/dao": "^0.9.75",
|
|
26
|
+
"@live-change/uid": "^0.9.75",
|
|
27
|
+
"typedoc": "0.28.3",
|
|
28
|
+
"typedoc-plugin-markdown": "^4.6.3",
|
|
29
|
+
"typedoc-plugin-rename-defaults": "^0.7.3"
|
|
27
30
|
},
|
|
28
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "07528a11201aa968ce48bf48bd2eea5e030842f6"
|
|
29
32
|
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"composite": true,
|
|
4
|
+
"module": "nodenext",
|
|
5
|
+
"moduleResolution": "nodenext",
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
|
|
8
|
+
"target": "ES2020",
|
|
9
|
+
"useDefineForClassFields": true,
|
|
10
|
+
"lib": ["ES2020", "DOM"],
|
|
11
|
+
|
|
12
|
+
/* Linting */
|
|
13
|
+
"strict": false,
|
|
14
|
+
"noUnusedLocals": false,
|
|
15
|
+
"noUnusedParameters": false,
|
|
16
|
+
"noFallthroughCasesInSwitch": true,
|
|
17
|
+
"outDir": "dist",
|
|
18
|
+
"checkJs": false,
|
|
19
|
+
"esModuleInterop": true, // Enable interop for ES modules
|
|
20
|
+
"resolveJsonModule": true, // Allow importing JSON files
|
|
21
|
+
"skipLibCheck": true,
|
|
22
|
+
"noImplicitAny": false
|
|
23
|
+
},
|
|
24
|
+
"files": ["index.ts"],
|
|
25
|
+
"include": [
|
|
26
|
+
"lib/**/*.ts", "lib/**/*.js", "index.ts"],
|
|
27
|
+
"exclude": ["node_modules/@types", "node_modules/**/*.d.ts", "**/*.test.js", "**/CMakeFiles/**"]
|
|
28
|
+
}
|
|
29
|
+
|
package/typedoc.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"entryPoints": ["index.ts"],
|
|
3
|
+
"out": "docs",
|
|
4
|
+
"includeVersion": true,
|
|
5
|
+
"excludePrivate": true,
|
|
6
|
+
"excludeInternal": true,
|
|
7
|
+
"excludeProtected": true,
|
|
8
|
+
"tsconfig": "./tsconfig.json",
|
|
9
|
+
"plugin": [
|
|
10
|
+
"typedoc-plugin-markdown",
|
|
11
|
+
"typedoc-plugin-rename-defaults"
|
|
12
|
+
],
|
|
13
|
+
"sourceLinkTemplate": "https://github.com/live-change/live-change-stack/blob/master/framework/framework/{path}#L{line}"
|
|
14
|
+
}
|
package/index.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import App from './lib/App.js'
|
|
2
|
-
|
|
3
|
-
App.app = () => {
|
|
4
|
-
if(!globalThis.liveChangeFrameworkApp) {
|
|
5
|
-
globalThis.liveChangeFrameworkApp = new App()
|
|
6
|
-
}
|
|
7
|
-
return globalThis.liveChangeFrameworkApp
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
import * as utils from './lib/utils.js'
|
|
11
|
-
import * as validation from './lib/utils/validation.js'
|
|
12
|
-
|
|
13
|
-
App.utils = utils
|
|
14
|
-
App.validation = validation
|
|
15
|
-
App.rangeProperties = utils.rangeProperties
|
|
16
|
-
App.encodeIdentifier = utils.encodeIdentifier
|
|
17
|
-
App.extractRange = utils.extractRange
|
|
18
|
-
App.isomorphic = utils.isomorphic
|
|
19
|
-
App.computeDefaults = utils.computeDefaults
|
|
20
|
-
App.computeUpdates = utils.computeUpdates
|
|
21
|
-
|
|
22
|
-
export default App
|
|
23
|
-
|
|
24
|
-
import ActionDefinition from './lib/definition/ActionDefinition.js'
|
|
25
|
-
import EventDefinition from './lib/definition/EventDefinition.js'
|
|
26
|
-
import ForeignIndexDefinition from './lib/definition/ForeignIndexDefinition.js'
|
|
27
|
-
import ForeignModelDefinition from './lib/definition/ForeignModelDefinition.js'
|
|
28
|
-
import IndexDefinition from './lib/definition/IndexDefinition.js'
|
|
29
|
-
import ModelDefinition from './lib/definition/ModelDefinition.js'
|
|
30
|
-
import PropertyDefinition from './lib/definition/PropertyDefinition.js'
|
|
31
|
-
import ServiceDefinition from './lib/definition/ServiceDefinition.js'
|
|
32
|
-
import TriggerDefinition from './lib/definition/TriggerDefinition.js'
|
|
33
|
-
import ViewDefinition from './lib/definition/ViewDefinition.js'
|
|
34
|
-
|
|
35
|
-
export {
|
|
36
|
-
ActionDefinition,
|
|
37
|
-
EventDefinition,
|
|
38
|
-
ForeignIndexDefinition,
|
|
39
|
-
ForeignModelDefinition,
|
|
40
|
-
IndexDefinition,
|
|
41
|
-
ModelDefinition,
|
|
42
|
-
PropertyDefinition,
|
|
43
|
-
ServiceDefinition,
|
|
44
|
-
TriggerDefinition,
|
|
45
|
-
ViewDefinition
|
|
46
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import PropertyDefinition from "./PropertyDefinition.js"
|
|
2
|
-
|
|
3
|
-
class ViewDefinition {
|
|
4
|
-
|
|
5
|
-
constructor(definition) {
|
|
6
|
-
this.properties = {}
|
|
7
|
-
for(let key in definition) this[key] = definition[key]
|
|
8
|
-
if(definition.properties) {
|
|
9
|
-
for (let propName in definition.properties) {
|
|
10
|
-
const propDefn = definition.properties[propName]
|
|
11
|
-
this.createAndAddProperty(propName, propDefn)
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
if(definition.returns) {
|
|
15
|
-
this.returns = new PropertyDefinition(definition.returns)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
createAndAddProperty(name, definition) {
|
|
20
|
-
const property = new PropertyDefinition(definition)
|
|
21
|
-
this.properties[name] = property
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
toJSON() {
|
|
25
|
-
let properties = {}
|
|
26
|
-
for(let propName in this.properties) {
|
|
27
|
-
properties[propName] = this.properties[propName].toJSON()
|
|
28
|
-
}
|
|
29
|
-
let returns = this.returns ? this.returns.toJSON() : null
|
|
30
|
-
return {
|
|
31
|
-
... this,
|
|
32
|
-
properties,
|
|
33
|
-
returns
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default ViewDefinition
|