@voxgig/sdkgen 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +135 -0
- package/dist/action/feature.d.ts +2 -0
- package/dist/action/feature.js +76 -0
- package/dist/action/feature.js.map +1 -0
- package/dist/action/lang.d.ts +2 -0
- package/dist/action/lang.js +68 -0
- package/dist/action/lang.js.map +1 -0
- package/dist/action/target.d.ts +2 -0
- package/dist/action/target.js +82 -0
- package/dist/action/target.js.map +1 -0
- package/dist/cmp/Entity.js +3 -3
- package/dist/cmp/Entity.js.map +1 -1
- package/dist/cmp/Feature.js +10 -3
- package/dist/cmp/Feature.js.map +1 -1
- package/dist/cmp/FeatureHook.d.ts +2 -0
- package/dist/cmp/FeatureHook.js +17 -0
- package/dist/cmp/FeatureHook.js.map +1 -0
- package/dist/cmp/Hook.d.ts +2 -0
- package/dist/cmp/Hook.js +10 -0
- package/dist/cmp/Hook.js.map +1 -0
- package/dist/cmp/Main.js +12 -5
- package/dist/cmp/Main.js.map +1 -1
- package/dist/cmp/Readme.js +8 -8
- package/dist/cmp/Readme.js.map +1 -1
- package/dist/cmp/ReadmeInstall.js +3 -3
- package/dist/cmp/ReadmeInstall.js.map +1 -1
- package/dist/cmp/ReadmeOptions.js +2 -2
- package/dist/cmp/ReadmeOptions.js.map +1 -1
- package/dist/cmp/ReadmeQuick.js +3 -3
- package/dist/cmp/ReadmeQuick.js.map +1 -1
- package/dist/sdkgen.d.ts +15 -4
- package/dist/sdkgen.js +106 -35
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.d.ts +4 -1
- package/dist/utility.js +11 -2
- package/dist/utility.js.map +1 -1
- package/model/sdkgen.jsonic +58 -6
- package/package.json +12 -12
- package/project/generate/model/feature/limit.jsonic +12 -0
- package/project/generate/model/feature/log.jsonic +28 -0
- package/project/generate/model/feature/page.jsonic +9 -0
- package/project/generate/model/feature/telemetry.jsonic +10 -0
- package/project/generate/model/target/go.jsonic +7 -0
- package/project/generate/model/target/js.jsonic +24 -0
- package/project/generate/src/cmp/js/Config_js.ts +34 -0
- package/project/generate/src/cmp/js/Entity_js.ts +91 -0
- package/project/generate/src/cmp/js/MainEntity_js.ts +22 -0
- package/project/generate/src/cmp/js/Main_js.ts +82 -0
- package/project/generate/src/cmp/js/Package_js.ts +57 -0
- package/project/generate/src/cmp/js/Quick_js.ts +82 -0
- package/project/generate/src/cmp/js/ReadmeInstall_js.ts +19 -0
- package/project/generate/src/cmp/js/ReadmeQuick_js.ts +25 -0
- package/project/generate/src/cmp/js/TestAcceptEntity_js.ts +101 -0
- package/project/generate/src/cmp/js/TestAccept_js.ts +60 -0
- package/project/generate/src/cmp/js/TestEntity_js.ts +24 -0
- package/project/generate/src/cmp/js/TestMain_js.ts +120 -0
- package/project/generate/src/cmp/js/Test_js.ts +24 -0
- package/project/generate/src/cmp/js/fragment/Entity.fragment.js +71 -0
- package/project/generate/src/cmp/js/fragment/EntityCreateOp.fragment.js +66 -0
- package/project/generate/src/cmp/js/fragment/EntityListOp.fragment.js +72 -0
- package/project/generate/src/cmp/js/fragment/EntityLoadOp.fragment.js +66 -0
- package/project/generate/src/cmp/js/fragment/EntityRemoveOp.fragment.js +66 -0
- package/project/generate/src/cmp/js/fragment/EntityUpdateOp.fragment.js +66 -0
- package/project/generate/src/cmp/js/fragment/Main.fragment.js +44 -0
- package/project/generate/tm/go/LICENSE +22 -0
- package/project/generate/tm/js/LICENSE +22 -0
- package/project/generate/tm/js/src/feature/log/LogFeature.js +104 -0
- package/project/generate/tm/js/src/utility/AuthUtility.js +16 -0
- package/project/generate/tm/js/src/utility/BodyUtility.js +27 -0
- package/project/generate/tm/js/src/utility/EmptyUtility.js +8 -0
- package/project/generate/tm/js/src/utility/ErrorUtility.js +15 -0
- package/project/generate/tm/js/src/utility/EscreUtility.js +8 -0
- package/project/generate/tm/js/src/utility/EscurlUtility.js +8 -0
- package/project/generate/tm/js/src/utility/FetchUtility.js +33 -0
- package/project/generate/tm/js/src/utility/FullurlUtility.js +41 -0
- package/project/generate/tm/js/src/utility/HeadersUtility.js +12 -0
- package/project/generate/tm/js/src/utility/InwardUtility.js +23 -0
- package/project/generate/tm/js/src/utility/JoinurlUtility.js +12 -0
- package/project/generate/tm/js/src/utility/MethodUtility.js +21 -0
- package/project/generate/tm/js/src/utility/OperatorUtility.js +36 -0
- package/project/generate/tm/js/src/utility/OptionsUtility.js +22 -0
- package/project/generate/tm/js/src/utility/OutwardUtility.js +23 -0
- package/project/generate/tm/js/src/utility/ParamsUtility.js +20 -0
- package/project/generate/tm/js/src/utility/QueryUtility.js +19 -0
- package/project/generate/tm/js/src/utility/ResbasicUtility.js +17 -0
- package/project/generate/tm/js/src/utility/ResbodyUtility.js +10 -0
- package/project/generate/tm/js/src/utility/ResheadersUtility.js +11 -0
- package/project/generate/tm/js/src/utility/ResponseUtility.js +36 -0
- package/project/generate/tm/js/src/utility/SpecUtility.js +41 -0
- package/project/generate/tm/js/src/utility/Utility.js +55 -0
- package/src/action/feature.ts +120 -0
- package/src/action/target.ts +127 -0
- package/src/cmp/Entity.ts +6 -4
- package/src/cmp/Feature.ts +11 -4
- package/src/cmp/FeatureHook.ts +23 -0
- package/src/cmp/Main.ts +14 -6
- package/src/cmp/Readme.ts +8 -8
- package/src/cmp/ReadmeInstall.ts +3 -3
- package/src/cmp/ReadmeOptions.ts +2 -2
- package/src/cmp/ReadmeQuick.ts +3 -3
- package/src/sdkgen.ts +116 -34
- package/src/utility.ts +11 -1
- package/src/prepare-openapi.ts +0 -59
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
const { fullurl } = require('./FullurlUtility')
|
|
3
|
+
|
|
4
|
+
// Make HTTP request.
|
|
5
|
+
async function fetch(ctx) {
|
|
6
|
+
const {op, spec} = ctx
|
|
7
|
+
let response = {}
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const url = spec.url = fullurl(ctx)
|
|
11
|
+
|
|
12
|
+
const fetchReq = {
|
|
13
|
+
method: spec.method,
|
|
14
|
+
headers: spec.headers,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if(null != spec.body) {
|
|
18
|
+
fetchReq.body =
|
|
19
|
+
'object' === typeof spec.body ? JSON.stringify(spec.body) : spec.body
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
response = global.fetch(url, fetchReq)
|
|
23
|
+
}
|
|
24
|
+
catch(err) {
|
|
25
|
+
response.err = err
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return response
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
fetch
|
|
33
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
const { joinurl } = require('./JoinurlUtility')
|
|
3
|
+
const { escurl } = require('./EscurlUtility')
|
|
4
|
+
const { escre } = require('./EscreUtility')
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
function fullurl(ctx) {
|
|
8
|
+
const { op, spec } = ctx
|
|
9
|
+
const { query, data } = op
|
|
10
|
+
|
|
11
|
+
let url = joinurl(spec.base, spec.prefix, spec.path, spec.suffix)
|
|
12
|
+
|
|
13
|
+
const params = spec.params
|
|
14
|
+
for(let key of op.params) {
|
|
15
|
+
if(null == params[key]) {
|
|
16
|
+
params[key] = 'res' === op.kind ? query[key] : data[key]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
for(let key in params) {
|
|
21
|
+
const val = spec.params[key]
|
|
22
|
+
if(null != val) {
|
|
23
|
+
url = url.replace(RegExp('{'+escre(key)+'}'), escurl(val))
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let qsep = '?'
|
|
28
|
+
for(let key in spec.query) {
|
|
29
|
+
const val = spec.query[key]
|
|
30
|
+
if(null != val) {
|
|
31
|
+
url += qsep + escurl(key) + '=' + escurl(val)
|
|
32
|
+
qsep = '&'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return url
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
fullurl
|
|
41
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
const { error } = require('./ErrorUtility')
|
|
3
|
+
|
|
4
|
+
function inward(ctx) {
|
|
5
|
+
if (!ctx.result.ok) {
|
|
6
|
+
return undefined
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
return ctx.op.inward(ctx)
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
// TDOD: need error codes and err msg text
|
|
14
|
+
ctx.result.ok = false
|
|
15
|
+
ctx.result.err = err
|
|
16
|
+
return error(ctx)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
inward
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
function method(ctx) {
|
|
3
|
+
const { op } = ctx
|
|
4
|
+
const opname = op.name
|
|
5
|
+
|
|
6
|
+
let key = opname
|
|
7
|
+
|
|
8
|
+
const mmap = {
|
|
9
|
+
create: 'POST',
|
|
10
|
+
save: 'PUT',
|
|
11
|
+
load: 'GET',
|
|
12
|
+
list: 'GET',
|
|
13
|
+
remove: 'DELETE',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return mmap[key]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
method
|
|
21
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
// NOTE: duplicated in @voxgig/apidef - dedup to @voxgig/util?
|
|
4
|
+
const OPKIND = {
|
|
5
|
+
create: 'req',
|
|
6
|
+
update: 'req',
|
|
7
|
+
remove: 'req',
|
|
8
|
+
load: 'res',
|
|
9
|
+
list: 'res',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// Ensure standard operation definition.
|
|
14
|
+
function operator(ctx) {
|
|
15
|
+
const { op } = ctx
|
|
16
|
+
|
|
17
|
+
let out = {
|
|
18
|
+
name: op.name,
|
|
19
|
+
kind: OPKIND[op.name],
|
|
20
|
+
entity: op.entity,
|
|
21
|
+
path: op.path,
|
|
22
|
+
params: op.params || [],
|
|
23
|
+
query: {...op.query} || {},
|
|
24
|
+
data: {...op.data} || {},
|
|
25
|
+
state: op.state,
|
|
26
|
+
inward: op.inward,
|
|
27
|
+
outward: op.outward,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return out
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
operator
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
const { empty } = require('./EmptyUtility')
|
|
3
|
+
|
|
4
|
+
function options(ctx) {
|
|
5
|
+
let config = ctx.config || {}
|
|
6
|
+
let copts = config.options || {}
|
|
7
|
+
|
|
8
|
+
let options = { ...(ctx.options||{}) }
|
|
9
|
+
|
|
10
|
+
options.base = empty(options.base) ?
|
|
11
|
+
empty(copts.base) ? 'http://localhost:8000' :
|
|
12
|
+
copts.base : options.base
|
|
13
|
+
|
|
14
|
+
options.prefix = empty(options.prefix) ? '' : options.prefix
|
|
15
|
+
options.suffix = empty(options.suffix) ? '' : options.suffix
|
|
16
|
+
|
|
17
|
+
return options
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
options
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
const { error } = require('./ErrorUtility')
|
|
3
|
+
|
|
4
|
+
function outward(ctx) {
|
|
5
|
+
if (!ctx.result.ok) {
|
|
6
|
+
return undefined
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
return ctx.op.outward(ctx)
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
// TDOD: need error codes and err msg text
|
|
14
|
+
ctx.result.ok = false
|
|
15
|
+
ctx.result.err = err
|
|
16
|
+
return error(ctx)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
outward
|
|
23
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
function params(ctx) {
|
|
3
|
+
const { op } = ctx
|
|
4
|
+
|
|
5
|
+
const { params, query } = op
|
|
6
|
+
|
|
7
|
+
const out = {}
|
|
8
|
+
for(let key of params) {
|
|
9
|
+
let val = query[key]
|
|
10
|
+
if(null!=val) {
|
|
11
|
+
out[key] = val
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return out
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
params
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
function query(ctx) {
|
|
3
|
+
const { op } = ctx
|
|
4
|
+
const { params, query } = op
|
|
5
|
+
|
|
6
|
+
const out = {}
|
|
7
|
+
for(let key of Object.keys(query)) {
|
|
8
|
+
let val = query[key]
|
|
9
|
+
if(null!=val && !params.includes(key)) {
|
|
10
|
+
out[key] = val
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return out
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
query
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
function resbasic(response, fetchResponse) {
|
|
3
|
+
response.status = fetchResponse.status
|
|
4
|
+
response.statusText = fetchResponse.statusText || 'no-status'
|
|
5
|
+
|
|
6
|
+
// TODO: use spec!
|
|
7
|
+
if(400 <= response.status) {
|
|
8
|
+
response.ok = false
|
|
9
|
+
response.err = new Error(response.status+': '+response.statusText)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return response
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
resbasic
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
const { resheaders } = require('./ResheadersUtility')
|
|
3
|
+
const { resbasic } = require('./ResbasicUtility')
|
|
4
|
+
const { resbody } = require('./ResbodyUtility')
|
|
5
|
+
|
|
6
|
+
async function response(ctx) {
|
|
7
|
+
let { response } = ctx
|
|
8
|
+
|
|
9
|
+
let result = {
|
|
10
|
+
ok: false,
|
|
11
|
+
status: -1,
|
|
12
|
+
statusText: '',
|
|
13
|
+
headers: {},
|
|
14
|
+
body: undefined,
|
|
15
|
+
err: response.err,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
result = resbasic(result, response)
|
|
20
|
+
result = resheaders(result, response)
|
|
21
|
+
result = await resbody(result, response)
|
|
22
|
+
|
|
23
|
+
if(null == result.err) {
|
|
24
|
+
result.ok = true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch(err) {
|
|
28
|
+
result.err = err
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return result
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
response
|
|
36
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
const { method } = require('./MethodUtility')
|
|
3
|
+
const { params } = require('./ParamsUtility')
|
|
4
|
+
const { query } = require('./QueryUtility')
|
|
5
|
+
const { headers } = require('./HeadersUtility')
|
|
6
|
+
const { body } = require('./BodyUtility')
|
|
7
|
+
const { auth } = require('./AuthUtility')
|
|
8
|
+
|
|
9
|
+
// Create request specificaton.
|
|
10
|
+
function spec(ctx) {
|
|
11
|
+
const {client, op} = ctx
|
|
12
|
+
|
|
13
|
+
let options = client.options()
|
|
14
|
+
|
|
15
|
+
const reqMethod = method(ctx)
|
|
16
|
+
const reqParams = params(ctx)
|
|
17
|
+
const reqQuery = query(ctx)
|
|
18
|
+
const reqHeaders = headers(ctx)
|
|
19
|
+
const reqBody = body(ctx)
|
|
20
|
+
|
|
21
|
+
let spec = {
|
|
22
|
+
base: options.base, // string, URL endpoint base prefix,
|
|
23
|
+
prefix: options.prefix,
|
|
24
|
+
path: op.path,
|
|
25
|
+
suffix: options.suffix,
|
|
26
|
+
method: reqMethod,
|
|
27
|
+
params: reqParams,
|
|
28
|
+
query: reqQuery,
|
|
29
|
+
headers: reqHeaders,
|
|
30
|
+
body: reqBody,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
spec = auth(ctx, spec)
|
|
34
|
+
|
|
35
|
+
return spec
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
spec
|
|
41
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
const { auth } = require('./AuthUtility')
|
|
3
|
+
const { body } = require('./BodyUtility')
|
|
4
|
+
const { empty } = require('./EmptyUtility')
|
|
5
|
+
const { error } = require('./ErrorUtility')
|
|
6
|
+
const { escre } = require('./EscreUtility')
|
|
7
|
+
const { escurl } = require('./EscurlUtility')
|
|
8
|
+
const { fetch } = require('./FetchUtility')
|
|
9
|
+
const { fullurl } = require('./FullurlUtility')
|
|
10
|
+
const { headers } = require('./HeadersUtility')
|
|
11
|
+
const { inward } = require('./InwardUtility')
|
|
12
|
+
const { joinurl } = require('./JoinurlUtility')
|
|
13
|
+
const { method } = require('./MethodUtility')
|
|
14
|
+
const { operator } = require('./OperatorUtility')
|
|
15
|
+
const { options } = require('./OptionsUtility')
|
|
16
|
+
const { outward } = require('./outwardUtility')
|
|
17
|
+
const { params } = require('./ParamsUtility')
|
|
18
|
+
const { query } = require('./QueryUtility')
|
|
19
|
+
const { resbasic } = require('./ResbasicUtility')
|
|
20
|
+
const { resbody } = require('./ResbodyUtility')
|
|
21
|
+
const { resheaders } = require('./ResheadersUtility')
|
|
22
|
+
const { response } = require('./ResponseUtility')
|
|
23
|
+
const { spec } = require('./SpecUtility')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const Utility = {
|
|
27
|
+
auth,
|
|
28
|
+
body,
|
|
29
|
+
empty,
|
|
30
|
+
error,
|
|
31
|
+
escre,
|
|
32
|
+
escurl,
|
|
33
|
+
fetch,
|
|
34
|
+
fullurl,
|
|
35
|
+
headers,
|
|
36
|
+
inward,
|
|
37
|
+
joinurl,
|
|
38
|
+
method,
|
|
39
|
+
operator,
|
|
40
|
+
options,
|
|
41
|
+
outward,
|
|
42
|
+
params,
|
|
43
|
+
query,
|
|
44
|
+
resbasic,
|
|
45
|
+
resbody,
|
|
46
|
+
resheaders,
|
|
47
|
+
response,
|
|
48
|
+
spec,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
Utility
|
|
54
|
+
}
|
|
55
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
Jostraca,
|
|
4
|
+
Project,
|
|
5
|
+
File,
|
|
6
|
+
Folder,
|
|
7
|
+
Content,
|
|
8
|
+
Copy,
|
|
9
|
+
cmp,
|
|
10
|
+
each,
|
|
11
|
+
} from 'jostraca'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { SdkGenError } from '../utility'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const CMD_MAP: any = {
|
|
18
|
+
add: cmd_feature_add
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const BASE = 'node_modules/@voxgig/sdkgen'
|
|
22
|
+
|
|
23
|
+
async function action_feature(args: any[], ctx: any) {
|
|
24
|
+
|
|
25
|
+
const cmdname = args[1]
|
|
26
|
+
|
|
27
|
+
const cmd = CMD_MAP[cmdname]
|
|
28
|
+
|
|
29
|
+
if (null == cmd) {
|
|
30
|
+
throw new SdkGenError('Unknown feature cmd: ' + cmdname)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await cmd(args, ctx)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async function cmd_feature_add(args: any[], ctx: any) {
|
|
38
|
+
|
|
39
|
+
let features = args[2]
|
|
40
|
+
features = 'string' === typeof features ? features.split(',') : features
|
|
41
|
+
|
|
42
|
+
const jostraca = Jostraca()
|
|
43
|
+
|
|
44
|
+
const opts = {
|
|
45
|
+
fs: ctx.fs,
|
|
46
|
+
folder: ctx.folder,
|
|
47
|
+
log: ctx.log.child({ cmp: 'jostraca' }),
|
|
48
|
+
meta: { model: ctx.model, tree: ctx.tree }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await jostraca.generate(opts, () => FeatureRoot({ features }))
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const FeatureRoot = cmp(function FeatureRoot(props: any) {
|
|
57
|
+
const { ctx$, features } = props
|
|
58
|
+
|
|
59
|
+
// TODO: model should be a top level ctx property
|
|
60
|
+
const model = ctx$.model = ctx$.meta.model
|
|
61
|
+
const target = model.main.sdk.target
|
|
62
|
+
|
|
63
|
+
Project({}, () => {
|
|
64
|
+
each(features, (n) => {
|
|
65
|
+
const name = n.val$
|
|
66
|
+
// TODO: validate feature is a-z0-9-_. only
|
|
67
|
+
|
|
68
|
+
Folder({ name: 'model/feature' }, () => {
|
|
69
|
+
Copy({
|
|
70
|
+
from: BASE + '/project/generate/model/feature/' + name + '.jsonic',
|
|
71
|
+
exclude: true
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
each(target, (target) =>
|
|
76
|
+
Folder({ name: 'tm/' + target.name + '/src/feature/' + name }, () => {
|
|
77
|
+
Copy({
|
|
78
|
+
from: BASE + '/project/generate/tm/' + target.name + '/src/feature/' + name,
|
|
79
|
+
exclude: true
|
|
80
|
+
})
|
|
81
|
+
}))
|
|
82
|
+
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
modifyModel({
|
|
87
|
+
features,
|
|
88
|
+
model: ctx$.meta.model,
|
|
89
|
+
tree: ctx$.meta.tree,
|
|
90
|
+
fs: ctx$.fs
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
async function modifyModel({ features, model, tree, fs }: any) {
|
|
97
|
+
// TODO: This is a kludge.
|
|
98
|
+
// Aontu should provide option for as-is AST so that can be used
|
|
99
|
+
// to find injection point more reliably
|
|
100
|
+
|
|
101
|
+
const path = tree.url
|
|
102
|
+
let src = fs().readFileSync(path, 'utf8')
|
|
103
|
+
|
|
104
|
+
// Inject feature file references into model
|
|
105
|
+
features.sort().map((feature: string) => {
|
|
106
|
+
const lineRE =
|
|
107
|
+
new RegExp(`@"feature/${feature}.jsonic"`)
|
|
108
|
+
if (!src.match(lineRE)) {
|
|
109
|
+
src = src.replace(/(main:\s+sdk:\s+feature:\s+\{\s*\}\n)/, '$1' +
|
|
110
|
+
`@"feature/${feature}.jsonic"\n`)
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
fs().writeFileSync(path, src)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
action_feature
|
|
120
|
+
}
|