@voxgig/sdkgen 0.24.0 → 0.26.1

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.
Files changed (98) hide show
  1. package/bin/voxgig-sdkgen +6 -6
  2. package/dist/action/action.js +1 -2
  3. package/dist/action/action.js.map +1 -1
  4. package/dist/action/feature.js +4 -2
  5. package/dist/action/feature.js.map +1 -1
  6. package/dist/action/target.js +4 -2
  7. package/dist/action/target.js.map +1 -1
  8. package/dist/cmp/Entity.js +2 -1
  9. package/dist/cmp/Entity.js.map +1 -1
  10. package/dist/cmp/FeatureHook.js +2 -1
  11. package/dist/cmp/FeatureHook.js.map +1 -1
  12. package/dist/cmp/Main.js.map +1 -1
  13. package/dist/cmp/ReadmeEntity.js +2 -1
  14. package/dist/cmp/ReadmeEntity.js.map +1 -1
  15. package/dist/cmp/Test.d.ts +2 -0
  16. package/dist/cmp/Test.js +17 -0
  17. package/dist/cmp/Test.js.map +1 -0
  18. package/dist/sdkgen.d.ts +2 -1
  19. package/dist/sdkgen.js +17 -28
  20. package/dist/sdkgen.js.map +1 -1
  21. package/dist/tsconfig.tsbuildinfo +1 -1
  22. package/dist/types.d.ts +3 -1
  23. package/dist/types.js +4 -0
  24. package/dist/types.js.map +1 -1
  25. package/model/sdkgen.jsonic +8 -8
  26. package/package.json +8 -6
  27. package/project/.sdk/model/feature/log.jsonic +2 -2
  28. package/project/.sdk/model/feature/test.jsonic +7 -2
  29. package/project/.sdk/model/target/js.jsonic +2 -2
  30. package/project/.sdk/model/target/ts.jsonic +2 -2
  31. package/project/.sdk/src/cmp/js/Main_js.ts +3 -3
  32. package/project/.sdk/src/cmp/js/Quick_js.ts +1 -1
  33. package/project/.sdk/src/cmp/ts/Config_ts.ts +53 -6
  34. package/project/.sdk/src/cmp/ts/EntityOperation_ts.ts +3 -21
  35. package/project/.sdk/src/cmp/ts/Entity_ts.ts +3 -5
  36. package/project/.sdk/src/cmp/ts/Main_ts.ts +22 -12
  37. package/project/.sdk/src/cmp/ts/Package_ts.ts +32 -12
  38. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +341 -2
  39. package/project/.sdk/src/cmp/ts/TestMain_ts.ts +0 -3
  40. package/project/.sdk/src/cmp/ts/Test_ts.ts +21 -3
  41. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +38 -5
  42. package/project/.sdk/src/cmp/ts/fragment/Entity.fragment.ts +50 -38
  43. package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +9 -7
  44. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +47 -31
  45. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +49 -31
  46. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +50 -33
  47. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +50 -31
  48. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +51 -31
  49. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +70 -34
  50. package/project/.sdk/src/cmp/ts/tsconfig.json +15 -0
  51. package/project/.sdk/src/cmp/ts/utility_ts.ts +55 -1
  52. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +158 -104
  53. package/project/.sdk/tm/ts/src/types.ts +164 -34
  54. package/project/.sdk/tm/ts/src/utility/AuthUtility.ts +8 -2
  55. package/project/.sdk/tm/ts/src/utility/BodyUtility.ts +9 -6
  56. package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +17 -31
  57. package/project/.sdk/tm/ts/src/utility/ContextUtility.ts +14 -54
  58. package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +1 -1
  59. package/project/.sdk/tm/ts/src/utility/ErrorUtility.ts +7 -3
  60. package/project/.sdk/tm/ts/src/utility/FeaturehookUtility.ts +8 -5
  61. package/project/.sdk/tm/ts/src/utility/FetcherUtility.ts +18 -2
  62. package/project/.sdk/tm/ts/src/utility/FindparamUtility.ts +12 -5
  63. package/project/.sdk/tm/ts/src/utility/FullurlUtility.ts +21 -5
  64. package/project/.sdk/tm/ts/src/utility/InitfeatureUtility.ts +3 -1
  65. package/project/.sdk/tm/ts/src/utility/OperationUtility.ts +23 -0
  66. package/project/.sdk/tm/ts/src/utility/OptionsUtility.ts +25 -3
  67. package/project/.sdk/tm/ts/src/utility/ParamsUtility.ts +10 -10
  68. package/project/.sdk/tm/ts/src/utility/PreparePathUtility.ts +18 -0
  69. package/project/.sdk/tm/ts/src/utility/QueryUtility.ts +2 -2
  70. package/project/.sdk/tm/ts/src/utility/ReqformUtility.ts +2 -2
  71. package/project/.sdk/tm/ts/src/utility/RequestUtility.ts +20 -3
  72. package/project/.sdk/tm/ts/src/utility/ResbasicUtility.ts +1 -1
  73. package/project/.sdk/tm/ts/src/utility/ResbodyUtility.ts +5 -3
  74. package/project/.sdk/tm/ts/src/utility/ResformUtility.ts +3 -3
  75. package/project/.sdk/tm/ts/src/utility/ResheadersUtility.ts +9 -7
  76. package/project/.sdk/tm/ts/src/utility/ResponseUtility.ts +35 -4
  77. package/project/.sdk/tm/ts/src/utility/ResultUtility.ts +24 -4
  78. package/project/.sdk/tm/ts/src/utility/SelectionUtility.ts +78 -0
  79. package/project/.sdk/tm/ts/src/utility/SpecUtility.ts +34 -27
  80. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +1117 -509
  81. package/project/.sdk/tm/ts/src/utility/Utility.ts +10 -8
  82. package/project/.sdk/tm/ts/test/exists.test.ts +0 -1
  83. package/project/.sdk/tm/ts/test/runner.ts +12 -10
  84. package/project/.sdk/tm/ts/test/utility/Custom.test.ts +30 -29
  85. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +53 -47
  86. package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +433 -189
  87. package/src/action/action.ts +1 -2
  88. package/src/action/feature.ts +7 -2
  89. package/src/action/target.ts +7 -7
  90. package/src/cmp/Entity.ts +7 -1
  91. package/src/cmp/FeatureHook.ts +6 -1
  92. package/src/cmp/Main.ts +4 -0
  93. package/src/cmp/ReadmeEntity.ts +6 -1
  94. package/src/cmp/Test.ts +31 -0
  95. package/src/sdkgen.ts +19 -34
  96. package/src/types.ts +10 -1
  97. package/project/.sdk/src/cmp/ts/EntityTest_ts.ts +0 -180
  98. package/project/.sdk/tm/ts/src/utility/OperatorUtility.ts +0 -90
@@ -1,47 +1,44 @@
1
1
 
2
+ import { inspect } from 'node:util'
3
+
2
4
  import { ProjectNameSDK } from './ProjectNameSDK'
3
5
 
4
6
  import { Utility } from './utility/Utility'
7
+ import { getprop, setprop, getpath } from './utility/StructUtility'
5
8
 
6
- type Context = {
7
- ctrl: any
8
- client: ProjectNameSDK
9
- op: Operation
10
- spec: Spec
11
- result: Result
12
- utility: Utility
13
- entopts: any
14
- options: any
15
- config: any
16
- response: any
17
- entity: any
18
- data: any
19
- match: any
20
- reqdata: any
21
- reqmatch: any
22
- work: any
23
- }
9
+
10
+
11
+
12
+ // TODO: convert to classes
24
13
 
25
14
 
26
15
  type Operation = {
27
- kind: string
28
16
  entity: string
29
17
  name: string
30
- path: string
31
- pathalt: ({ path: string } & Record<string, boolean>)[],
32
- params: string[],
33
- alias: Record<string, string>
34
- state: Record<string, any>
35
- reqform: any
36
- resform: any
37
- validate: {
38
- params: Record<string, any>
18
+ select: string
19
+ alts: Alt[]
20
+ }
21
+
22
+
23
+ type Alt = {
24
+ args: {
25
+ param: any[]
26
+ }
27
+ rename: {
28
+ param: Record<string, string>
39
29
  }
40
- check: Record<string, any>
30
+ method: string
31
+ orig: string
32
+ parts: string[]
33
+ select: any
34
+ active: boolean
35
+ relations: any[]
41
36
  }
42
37
 
43
38
 
44
39
  type Spec = {
40
+ parts: string[]
41
+
45
42
  headers: Record<string, string>
46
43
  alias: any
47
44
  base: string
@@ -52,8 +49,20 @@ type Spec = {
52
49
  step: string
53
50
  method: string
54
51
  body: any
55
- path: string
56
52
  url?: string
53
+
54
+ path?: string
55
+
56
+ }
57
+
58
+
59
+ type Response = {
60
+ status: number,
61
+ statusText: string,
62
+ headers: any,
63
+ json: Function,
64
+ err?: Error,
65
+ body?: any,
57
66
  }
58
67
 
59
68
 
@@ -76,6 +85,121 @@ type Control = {
76
85
  }
77
86
 
78
87
 
88
+ // TODO: move to own file
89
+ class Context {
90
+
91
+ id = 'C' + ('' + Math.random()).substring(2, 10)
92
+
93
+ // Store the output of each operation step.
94
+ out: Record<string, any> = {}
95
+
96
+ // Store for the current operation.
97
+ current: WeakMap<String, any> = new WeakMap()
98
+
99
+
100
+ ctrl: Record<string, any> = {}
101
+ meta: Record<string, any> = {}
102
+
103
+ client: ProjectNameSDK
104
+ utility: Utility
105
+
106
+ op: Operation
107
+ alt: any
108
+
109
+ config: Record<string, any>
110
+ entopts: Record<string, any>
111
+ options: Record<string, any>
112
+
113
+ opmap: Record<string, Operation>
114
+
115
+ response?: Response
116
+ result?: Result
117
+ spec?: Spec
118
+
119
+ data?: any
120
+ reqdata?: any
121
+ match?: any
122
+ reqmatch?: any
123
+
124
+ entity?: any
125
+
126
+ // Shared persistent store.
127
+ shared: WeakMap<String, any>
128
+
129
+
130
+ constructor(ctxmap: Record<string, any>, basectx?: Context) {
131
+ this.client = getprop(ctxmap, 'client', getprop(basectx, 'client'))
132
+ this.utility = getprop(ctxmap, 'utility', getprop(basectx, 'utility'))
133
+
134
+ this.ctrl = getprop(ctxmap, 'ctrl', getprop(basectx, 'ctrl', this.ctrl))
135
+ this.meta = getprop(ctxmap, 'meta', getprop(basectx, 'meta', this.meta))
136
+
137
+ this.config = getprop(ctxmap, 'config', getprop(basectx, 'config'))
138
+ this.entopts = getprop(ctxmap, 'entopts', getprop(basectx, 'entopts'))
139
+ this.options = getprop(ctxmap, 'options', getprop(basectx, 'options'))
140
+
141
+ this.entity = getprop(ctxmap, 'entity', getprop(basectx, 'entity'))
142
+ this.shared = getprop(ctxmap, 'shared', getprop(basectx, 'shared'))
143
+ this.opmap = getprop(ctxmap, 'opmap', getprop(basectx, 'opmap'))
144
+
145
+ this.data = getprop(ctxmap, 'data', {})
146
+ this.reqdata = getprop(ctxmap, 'reqdata', {})
147
+ this.match = getprop(ctxmap, 'match', {})
148
+ this.reqmatch = getprop(ctxmap, 'reqmatch', {})
149
+
150
+ const opname = getprop(ctxmap, 'opname')
151
+ this.op = this.resolveOp(opname)
152
+ }
153
+
154
+
155
+ resolveOp(opname: string): Operation {
156
+ let op: Operation = getprop(this.opmap, opname)
157
+
158
+ if (null == op && null != opname) {
159
+ const entname = getprop(this.entity, 'name', '')
160
+ const opcfg = getpath(this.config, ['entity', entname, 'op', opname])
161
+ let select = 'match'
162
+
163
+ if ('update' === opname || 'create' === opname) {
164
+ select = 'data'
165
+ }
166
+
167
+ op = {
168
+ entity: entname,
169
+ name: opname,
170
+ select,
171
+ alts: getprop(opcfg, 'alts', [])
172
+ }
173
+
174
+ setprop(this.opmap, opname, op)
175
+ }
176
+
177
+ return op
178
+ }
179
+
180
+
181
+ toJSON() {
182
+ return {
183
+ id: this.id,
184
+ op: this.op,
185
+ spec: this.spec,
186
+ entity: this.entity,
187
+ result: this.result,
188
+ meta: this.meta,
189
+ }
190
+ }
191
+
192
+ toString() {
193
+ return 'Context ' + (this as any).utility?.struct.jsonify(this.toJSON())
194
+ }
195
+
196
+ [inspect.custom]() {
197
+ return this.toString()
198
+ }
199
+
200
+ }
201
+
202
+
79
203
  type FeatureOptions = Record<string, any> | {
80
204
  active: boolean
81
205
  }
@@ -103,12 +227,18 @@ interface Feature {
103
227
  }
104
228
 
105
229
 
230
+ export {
231
+ Context
232
+ }
233
+
106
234
 
107
235
  export type {
108
- Context,
109
- Operation,
110
- Spec,
236
+ Alt,
111
237
  Control,
112
- FeatureOptions,
113
238
  Feature,
239
+ FeatureOptions,
240
+ Operation,
241
+ Response,
242
+ Result,
243
+ Spec,
114
244
  }
@@ -1,5 +1,5 @@
1
1
 
2
- import { Context } from '../types'
2
+ import { Context, Spec } from '../types'
3
3
 
4
4
 
5
5
  const HEADER_auth = 'authorization'
@@ -9,7 +9,7 @@ const OPTION_apikey = 'apikey'
9
9
  const NOTFOUND = ''
10
10
 
11
11
 
12
- function auth(ctx: Context) {
12
+ function auth(ctx: Context): Spec | Error {
13
13
  const utility = ctx.utility
14
14
 
15
15
  const struct = utility.struct
@@ -20,6 +20,12 @@ function auth(ctx: Context) {
20
20
  const client = ctx.client
21
21
  const spec = ctx.spec
22
22
 
23
+ if (null == spec) {
24
+ return new Error('Expected context spec property to be defined.')
25
+ }
26
+
27
+
28
+
23
29
  const headers = spec.headers
24
30
 
25
31
  const options = client.options()
@@ -2,18 +2,21 @@
2
2
  import { Context } from '../types'
3
3
 
4
4
  function body(ctx: Context) {
5
- const { op, utility } = ctx
6
- const { error, reqform } = utility
5
+ const op = ctx.op
6
+
7
+ const utility = ctx.utility
8
+ const error = utility.error
9
+ const reqform = utility.reqform
7
10
 
8
11
  let body = undefined
9
12
 
10
- if ('req' === op.kind) {
13
+ if ('data' === op.select) {
11
14
  try {
12
15
  body = reqform(ctx)
13
16
 
14
- if (op.check.nobody && null == body) {
15
- return error(ctx, new Error('Request body is empty.'))
16
- }
17
+ // if (alt.check.nobody && null == body) {
18
+ // return error(ctx, new Error('Request body is empty.'))
19
+ // }
17
20
  }
18
21
  catch (err) {
19
22
  return error(ctx, err)
@@ -3,45 +3,31 @@ import { Context } from '../types'
3
3
 
4
4
 
5
5
  import {
6
- walk, getpath, escre, getprop, size, pad, slice, setprop, clone
6
+ walk, size, pad, slice, clone
7
7
  } from './StructUtility'
8
8
 
9
9
 
10
10
  // Clean request data by partially hiding sensitive values.
11
11
  function clean(ctx: Context, val: any) {
12
12
  const options = ctx.options
13
- const work = ctx.work
14
-
15
- let cleaners = getprop(work, 'cleaners')
16
-
17
- if (null == cleaners) {
18
- cleaners =
19
- [
20
- { p: 'apikey', s: 4 }
21
- ]
22
- .map((p: any) => (p.v = getpath(options, p.p), p))
23
- .filter(p => null != p.v && 'string' === typeof p.v)
24
- .map(
25
- p => (
26
- p.re = new RegExp(escre(p.v)),
27
- p.v = pad(slice(p.v, 0, p.s), size(p.v), '*'),
28
- p
29
- )
30
- )
31
- }
32
-
33
- setprop(work, 'cleaners', cleaners)
34
13
 
35
- const out = walk(clone(val), (_k: any, v: any) => {
36
- if ('string' === typeof v) {
37
- cleaners.map((p: any) => {
38
- v = v.replace(p.re, p.v)
39
- })
40
- }
41
- return v
42
- })
14
+ const cleankeyre = options.__derived__.clean.keyre
15
+ const hintsize = 4
16
+
17
+ /*
18
+ if (null != cleankeyre) {
19
+ val = walk(clone(val), (key: any, subval: any) => {
20
+ if (cleankeyre.exec(key) && 'string' === typeof subval) {
21
+ const len = size(subval)
22
+ const hint = (hintsize * 4) < len ? slice(subval, 0, hintsize) : ''
23
+ subval = pad(hint, len, '*')
24
+ }
25
+ return subval
26
+ })
27
+ }
28
+ */
43
29
 
44
- return out
30
+ return val
45
31
  }
46
32
 
47
33
 
@@ -1,67 +1,27 @@
1
1
 
2
- import { getprop } from './StructUtility'
2
+ import { ProjectNameSDK } from '../ProjectNameSDK'
3
3
 
4
+ import { Utility } from './Utility'
4
5
 
5
- function contextify(ctxmap: Record<string, any>, basectx?: Context): any {
6
- const ctx = new Context()
6
+ import type {
7
+ Operation,
8
+ Spec,
9
+ Response,
10
+ Result,
11
+ } from '../types'
7
12
 
8
- ctx.ctrl = getprop(ctxmap, 'ctrl', getprop(basectx, 'ctrl', {}))
9
- ctx.meta = getprop(ctxmap, 'meta', getprop(basectx, 'meta', {}))
10
- ctx.work = getprop(ctxmap, 'work', getprop(basectx, 'work', {}))
13
+ import {
14
+ Context
15
+ } from '../types'
11
16
 
12
- ctx.client = getprop(ctxmap, 'client', getprop(basectx, 'client'))
13
- ctx.config = getprop(ctxmap, 'config', getprop(basectx, 'config'))
14
- ctx.entity = getprop(ctxmap, 'entity', getprop(basectx, 'entity'))
15
- ctx.op = getprop(ctxmap, 'op', getprop(basectx, 'op'))
16
- ctx.entopts = getprop(ctxmap, 'entopts', getprop(basectx, 'entopts'))
17
- ctx.options = getprop(ctxmap, 'options', getprop(basectx, 'options'))
18
- ctx.response = getprop(ctxmap, 'response', getprop(basectx, 'response'))
19
- ctx.result = getprop(ctxmap, 'result', getprop(basectx, 'result'))
20
- ctx.spec = getprop(ctxmap, 'spec', getprop(basectx, 'spec'))
21
- ctx.utility = getprop(ctxmap, 'utility', getprop(basectx, 'utility'))
22
- ctx.data = getprop(ctxmap, 'data', getprop(basectx, 'data'))
23
- ctx.reqdata = getprop(ctxmap, 'reqdata', getprop(basectx, 'reqdata'))
24
- ctx.match = getprop(ctxmap, 'match', getprop(basectx, 'match'))
25
- ctx.reqmatch = getprop(ctxmap, 'reqmatch', getprop(basectx, 'reqmatch'))
26
17
 
18
+ function makeContext(ctxmap: Record<string, any>, basectx?: Context): any {
19
+ const ctx = new Context(ctxmap, basectx)
27
20
  return ctx
28
21
  }
29
22
 
30
23
 
31
- class Context {
32
-
33
- ctrl = {}
34
- meta = {}
35
- work = {}
36
-
37
- client = undefined
38
- config = undefined
39
- entity = undefined
40
- op = undefined
41
- entopts = undefined
42
- options = undefined
43
- response = undefined
44
- result = undefined
45
- spec = undefined
46
- utility = undefined
47
- data = undefined
48
- reqdata = undefined
49
- match = undefined
50
- reqmatch = undefined
51
-
52
- toJSON() {
53
- return {
54
- op: this.op,
55
- spec: this.spec,
56
- entity: this.entity,
57
- result: this.result,
58
- meta: this.meta,
59
- }
60
- }
61
- }
62
-
63
24
 
64
25
  export {
65
- contextify,
66
- Context
26
+ makeContext,
67
27
  }
@@ -15,7 +15,7 @@ function done(ctx: Context) {
15
15
  delprop(ctx.ctrl.explain.result, 'err')
16
16
  }
17
17
 
18
- if (ctx.result.ok) {
18
+ if (ctx.result && ctx.result.ok) {
19
19
  return ctx.result.resdata
20
20
  }
21
21
 
@@ -1,5 +1,5 @@
1
1
 
2
- import { Context } from '../types'
2
+ import { Result, Context } from '../types'
3
3
 
4
4
 
5
5
  import { clean } from './CleanUtility'
@@ -13,7 +13,8 @@ function error(ctx: Context, err?: any) {
13
13
  const op = ctx.op || {}
14
14
  op.name = op.name || 'unknown operation'
15
15
 
16
- const result = ctx.result = ctx.result || {}
16
+
17
+ const result = ctx.result || ({} as Result)
17
18
  result.ok = false
18
19
 
19
20
  const reserr = result.err
@@ -22,6 +23,9 @@ function error(ctx: Context, err?: any) {
22
23
  err = err || new Error('unknown error')
23
24
 
24
25
  const errmsg = err.message || 'unknown error'
26
+ // TODO: project name should come from config
27
+ // avoids spurious changes between template and generated utility
28
+ // applies for all utility files
25
29
  const msg = 'ProjectNameSDK: ' + op.name + ': ' + errmsg
26
30
  err.message = clean(ctx, msg)
27
31
 
@@ -46,7 +50,7 @@ function error(ctx: Context, err?: any) {
46
50
 
47
51
  // TODO: model option to return instead
48
52
  if (false === ctx.ctrl.throw) {
49
- return ctx.result.resdata
53
+ return result.resdata
50
54
  }
51
55
  else {
52
56
  throw err
@@ -2,16 +2,19 @@
2
2
  import { Context, Feature } from '../types'
3
3
 
4
4
 
5
- function featurehook(ctx: Context, name: string) {
5
+ function featureHook(ctx: Context, name: string) {
6
6
  const client = ctx.client
7
7
 
8
8
  let resp: Promise<any>[] = []
9
9
  const features: Feature[] = client._features || []
10
10
 
11
11
  for (let f of features) {
12
- let fres = (f as any)[name](ctx)
13
- if (fres instanceof Promise) {
14
- resp.push(fres)
12
+ const fh = (f as any)[name]
13
+ if (null != fh) {
14
+ const fres = fh(ctx)
15
+ if (fres instanceof Promise) {
16
+ resp.push(fres)
17
+ }
15
18
  }
16
19
  }
17
20
 
@@ -22,5 +25,5 @@ function featurehook(ctx: Context, name: string) {
22
25
 
23
26
 
24
27
  export {
25
- featurehook
28
+ featureHook
26
29
  }
@@ -1,9 +1,25 @@
1
1
 
2
- import { Context } from '../types'
2
+ import { Context, Response } from '../types'
3
3
 
4
4
  // Make HTTP call using library. Replace this utility for mocking etc.
5
- async function fetcher(ctx: Context, fullurl: string, fetchdef: Record<string, any>) {
5
+ async function fetcher(
6
+ ctx: Context,
7
+ fullurl: string,
8
+ fetchdef: Record<string, any>
9
+ ): Promise<Response | Error> {
10
+
11
+ if ('live' !== ctx.client._mode) {
12
+ return Error('Request blocked by mode: "' + ctx.client._mode +
13
+ '" (URL was: "' + fullurl + '")')
14
+ }
15
+
6
16
  const options = ctx.client.options()
17
+
18
+ if (true === ctx.utility.struct.getpath(options, 'feature.test.active')) {
19
+ return Error('Request blocked as test feature is active' +
20
+ ' (URL was: "' + fullurl + '")')
21
+ }
22
+
7
23
  const fetch = options.system.fetch
8
24
 
9
25
  const response = await fetch(fullurl, fetchdef)
@@ -1,7 +1,7 @@
1
1
 
2
2
  import { Context } from '../types'
3
3
 
4
- import { getprop } from './StructUtility'
4
+ import { setprop, getprop } from './StructUtility'
5
5
 
6
6
 
7
7
  /* Find value of a match parameter, possibly using an alias.
@@ -11,10 +11,14 @@ import { getprop } from './StructUtility'
11
11
  *
12
12
  * This function returns `undefined` rather than failing.
13
13
  */
14
- function findparam(ctx: Context, key: string) {
15
- let { op, spec, match, reqmatch, data, reqdata } = ctx
14
+ function findparam(ctx: Context, param: any) {
15
+ let { alt, spec, match, reqmatch, data, reqdata } = ctx
16
16
 
17
- let akey = op.alias[key]
17
+ // TODO: review this search algorithm
18
+
19
+ const key = param.name
20
+
21
+ let akey = getprop(alt.alias, key)
18
22
 
19
23
  let val = getprop(reqmatch, key)
20
24
 
@@ -23,7 +27,10 @@ function findparam(ctx: Context, key: string) {
23
27
  }
24
28
 
25
29
  if (null == val && null != akey) {
26
- spec.alias[akey] = key
30
+
31
+ if (null != spec) {
32
+ setprop(spec.alias, akey, key)
33
+ }
27
34
 
28
35
  val = getprop(reqmatch, akey)
29
36
  }
@@ -1,16 +1,29 @@
1
1
 
2
2
  import { Context } from '../types'
3
3
 
4
- function fullurl(ctx: Context) {
4
+
5
+ function fullurl(ctx: Context): Error | string {
5
6
  const utility = ctx.utility
6
- // const findparam = utility.findparam
7
+ const spec = ctx.spec
8
+ const result = ctx.result
7
9
 
8
10
  const struct = utility.struct
9
- const { escurl, escre, joinurl } = struct
11
+ const escurl = struct.escurl
12
+ const escre = struct.escre
13
+ const join = struct.join
14
+
10
15
 
11
- const { spec, result } = ctx
16
+ if (null == spec) {
17
+ return new Error('Expected context spec property to be defined.')
18
+ }
12
19
 
13
- let url = joinurl([spec.base, spec.prefix, spec.path, spec.suffix])
20
+ if (null == result) {
21
+ return new Error('Expected context result property to be defined.')
22
+ }
23
+
24
+
25
+ // TODO: use parts to avoid regexp?
26
+ let url = join([spec.base, spec.prefix, spec.path, spec.suffix], '/', true)
14
27
  let resmatch: Record<string, any> = {}
15
28
 
16
29
  const params = spec.params
@@ -23,6 +36,8 @@ function fullurl(ctx: Context) {
23
36
  }
24
37
  }
25
38
 
39
+
40
+ /* TODO: fix
26
41
  let qsep = '?'
27
42
  for (let key in spec.query) {
28
43
  if (null == spec.alias[key]) {
@@ -34,6 +49,7 @@ function fullurl(ctx: Context) {
34
49
  }
35
50
  }
36
51
  }
52
+ */
37
53
 
38
54
  result.resmatch = resmatch
39
55
 
@@ -4,7 +4,9 @@ import { Context, Feature } from '../types'
4
4
 
5
5
  function initfeature(ctx: Context, f: Feature) {
6
6
  const fopts = ctx.options.feature[f.name] || {}
7
- f.init(ctx, fopts)
7
+ if (true === fopts.active) {
8
+ f.init(ctx, fopts)
9
+ }
8
10
  }
9
11
 
10
12
 
@@ -0,0 +1,23 @@
1
+
2
+ import { Operation } from '../types'
3
+
4
+ import { getprop } from './StructUtility'
5
+
6
+
7
+ function makeOperation(opmap: Record<string, any>) {
8
+
9
+ const op: Operation = {
10
+ name: getprop(opmap, 'name', '_'),
11
+ entity: getprop(opmap, 'entity', '_'),
12
+ select: getprop(opmap, 'select', '_'),
13
+ alts: getprop(opmap, 'alts', []),
14
+ }
15
+
16
+ return op
17
+ }
18
+
19
+
20
+
21
+ export {
22
+ makeOperation,
23
+ }