@voxgig/sdkgen 0.22.0 → 0.23.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.
Files changed (119) hide show
  1. package/bin/voxgig-sdkgen +12 -4
  2. package/dist/action/action.d.ts +4 -0
  3. package/dist/action/action.js +35 -0
  4. package/dist/action/action.js.map +1 -0
  5. package/dist/action/feature.d.ts +4 -2
  6. package/dist/action/feature.js +57 -38
  7. package/dist/action/feature.js.map +1 -1
  8. package/dist/action/target.d.ts +4 -2
  9. package/dist/action/target.js +136 -45
  10. package/dist/action/target.js.map +1 -1
  11. package/dist/cmp/Entity.js +5 -0
  12. package/dist/cmp/Entity.js.map +1 -1
  13. package/dist/cmp/Feature.js +5 -0
  14. package/dist/cmp/Feature.js.map +1 -1
  15. package/dist/cmp/Main.js +4 -1
  16. package/dist/cmp/Main.js.map +1 -1
  17. package/dist/cmp/Top.d.ts +2 -0
  18. package/dist/cmp/Top.js +23 -0
  19. package/dist/cmp/Top.js.map +1 -0
  20. package/dist/sdkgen.d.ts +10 -3
  21. package/dist/sdkgen.js +53 -8
  22. package/dist/sdkgen.js.map +1 -1
  23. package/dist/tsconfig.tsbuildinfo +1 -1
  24. package/dist/types.d.ts +16 -0
  25. package/dist/types.js +3 -0
  26. package/dist/types.js.map +1 -0
  27. package/dist/utility.d.ts +3 -3
  28. package/dist/utility.js +7 -8
  29. package/dist/utility.js.map +1 -1
  30. package/package.json +6 -10
  31. package/project/.sdk/model/feature/README.md +2 -0
  32. package/project/.sdk/model/feature/log.jsonic +7 -4
  33. package/project/.sdk/model/feature/test.jsonic +26 -0
  34. package/project/.sdk/model/target/ts.jsonic +1 -0
  35. package/project/.sdk/src/cmp/ts/Config_ts.ts +7 -2
  36. package/project/.sdk/src/cmp/ts/EntityOperation_ts.ts +67 -0
  37. package/project/.sdk/src/cmp/ts/EntityTest_ts.ts +180 -0
  38. package/project/.sdk/src/cmp/ts/Entity_ts.ts +41 -66
  39. package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +22 -0
  40. package/project/.sdk/src/cmp/ts/Main_ts.ts +52 -53
  41. package/project/.sdk/src/cmp/ts/Package_ts.ts +12 -7
  42. package/project/.sdk/src/cmp/ts/ReadmeInstall_ts.ts +19 -0
  43. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +24 -0
  44. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +13 -0
  45. package/project/.sdk/src/cmp/ts/TestMain_ts.ts +19 -0
  46. package/project/.sdk/src/cmp/ts/Test_ts.ts +20 -0
  47. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +8 -1
  48. package/project/.sdk/src/cmp/ts/fragment/Entity.fragment.ts +164 -0
  49. package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +37 -0
  50. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +91 -0
  51. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +92 -0
  52. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +96 -0
  53. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +96 -0
  54. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +95 -0
  55. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +107 -0
  56. package/project/.sdk/src/cmp/ts/utility_ts.ts +10 -0
  57. package/project/.sdk/tm/ts/src/feature/base/BaseFeature.ts +43 -0
  58. package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +109 -0
  59. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +159 -0
  60. package/project/.sdk/tm/ts/src/tsconfig.json +1 -1
  61. package/project/.sdk/tm/ts/src/types.ts +114 -0
  62. package/project/.sdk/tm/ts/src/utility/AddfeatureUtility.ts +47 -0
  63. package/project/.sdk/tm/ts/src/utility/AuthUtility.ts +42 -0
  64. package/project/.sdk/tm/ts/src/utility/BodyUtility.ts +29 -0
  65. package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +50 -0
  66. package/project/.sdk/tm/ts/src/utility/ContextUtility.ts +67 -0
  67. package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +28 -0
  68. package/project/.sdk/tm/ts/src/utility/ErrorUtility.ts +59 -0
  69. package/project/.sdk/tm/ts/src/utility/FeaturehookUtility.ts +26 -0
  70. package/project/.sdk/tm/ts/src/utility/FetcherUtility.ts +17 -0
  71. package/project/.sdk/tm/ts/src/utility/FindparamUtility.ts +54 -0
  72. package/project/.sdk/tm/ts/src/utility/FullurlUtility.ts +46 -0
  73. package/project/.sdk/tm/ts/src/utility/HeadersUtility.ts +24 -0
  74. package/project/.sdk/tm/ts/src/utility/InitfeatureUtility.ts +13 -0
  75. package/project/.sdk/tm/ts/src/utility/JoinurlUtility.ts +15 -0
  76. package/project/.sdk/tm/ts/src/utility/MethodUtility.ts +25 -0
  77. package/project/.sdk/tm/ts/src/utility/OperatorUtility.ts +90 -0
  78. package/project/.sdk/tm/ts/src/utility/OptionsUtility.ts +72 -0
  79. package/project/.sdk/tm/ts/src/utility/ParamsUtility.ts +37 -0
  80. package/project/.sdk/tm/ts/src/utility/QueryUtility.ts +27 -0
  81. package/project/.sdk/tm/ts/src/utility/ReqformUtility.ts +33 -0
  82. package/project/.sdk/tm/ts/src/utility/RequestUtility.ts +66 -0
  83. package/project/.sdk/tm/ts/src/utility/ResbasicUtility.ts +34 -0
  84. package/project/.sdk/tm/ts/src/utility/ResbodyUtility.ts +19 -0
  85. package/project/.sdk/tm/ts/src/utility/ResformUtility.ts +36 -0
  86. package/project/.sdk/tm/ts/src/utility/ResheadersUtility.ts +23 -0
  87. package/project/.sdk/tm/ts/src/utility/ResponseUtility.ts +30 -0
  88. package/project/.sdk/tm/ts/src/utility/ResultUtility.ts +36 -0
  89. package/project/.sdk/tm/ts/src/utility/SpecUtility.ts +61 -0
  90. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +2499 -0
  91. package/project/.sdk/tm/ts/src/utility/Utility.ts +88 -0
  92. package/project/.sdk/tm/ts/test/exists.test.ts +17 -0
  93. package/project/.sdk/tm/ts/test/runner.ts +402 -0
  94. package/project/.sdk/tm/ts/test/tsconfig.json +1 -1
  95. package/project/.sdk/tm/ts/test/utility/Custom.test.ts +62 -0
  96. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +244 -0
  97. package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +678 -0
  98. package/project/.sdk/tm/ts/test/utility/index.ts +9 -0
  99. package/project/.sdk/tm/ts/test/utility.ts +86 -0
  100. package/src/action/action.ts +54 -0
  101. package/src/action/feature.ts +83 -47
  102. package/src/action/target.ts +173 -53
  103. package/src/cmp/Entity.ts +6 -0
  104. package/src/cmp/Feature.ts +6 -3
  105. package/src/cmp/Main.ts +4 -1
  106. package/src/sdkgen.ts +86 -11
  107. package/src/types.ts +33 -0
  108. package/src/utility.ts +5 -3
  109. package/project/.sdk/model/feature/limit.jsonic +0 -12
  110. package/project/.sdk/model/feature/page.jsonic +0 -9
  111. package/project/.sdk/model/feature/telemetry.jsonic +0 -10
  112. package/project/.sdk/src/cmp/ts/fragment/Entity.fragment.js +0 -79
  113. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.js +0 -61
  114. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.js +0 -57
  115. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.js +0 -61
  116. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.js +0 -61
  117. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.js +0 -61
  118. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.js +0 -67
  119. package/project/.sdk/tm/ts/test/README.md~ +0 -2
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Shared utility functions for unit tests
3
+ *
4
+ * This module provides common helper functions used across unit tests
5
+ * for creating test data, transformations, validations, and environment overrides.
6
+ */
7
+
8
+ // Creates a new step data structure within the data model
9
+ function makeStepData(dm: Record<string, any>, stepname: string): Record<string, any> {
10
+ dm.s[stepname] = {
11
+ entity: undefined,
12
+ match: undefined,
13
+ reqdata: undefined,
14
+ resdata: undefined,
15
+ }
16
+ return dm.s[stepname]
17
+ }
18
+
19
+
20
+ // Transforms and creates a match object using the provided transform function
21
+ function makeMatch(
22
+ dm: Record<string, any>,
23
+ transform: Function,
24
+ match: any
25
+ ): Record<string, any> {
26
+ return transform({}, match, { meta: { dm } })
27
+ }
28
+
29
+
30
+ // Transforms and creates request data using the provided transform function
31
+ function makeReqdata(
32
+ dm: Record<string, any>,
33
+ transform: Function,
34
+ data: any
35
+ ): Record<string, any> {
36
+ return transform({}, data, { meta: { dm } })
37
+ }
38
+
39
+
40
+ // Validates data against validation rules and returns the result
41
+ function makeValid(
42
+ dm: Record<string, any>,
43
+ validate: Function,
44
+ data: any,
45
+ valid: any
46
+ ): Record<string, any> {
47
+ valid["`$OPEN`"] = true
48
+ return validate(data, valid, { meta: { '`$EXISTS`': true, dm } })
49
+ }
50
+
51
+
52
+ // Creates a control object for test explanations when enabled
53
+ function makeCtrl(explain: boolean) {
54
+ return explain ? { explain: {} } : undefined
55
+ }
56
+ // CLAUDE: add a full stop to each function comment
57
+
58
+ // Overrides configuration values with environment variables if available
59
+ function envOverride(m: Record<string, any>) {
60
+ if (
61
+ 'TRUE' === process.env.PROJECTNAME_TEST_LIVE ||
62
+ 'TRUE' === process.env.PROJECTNAME_TEST_OVERRIDE
63
+ ) {
64
+ Object.entries(m).map(n => {
65
+ let envval = process.env[n[0]]
66
+ if (null != envval) {
67
+ envval = envval.trim()
68
+ m[n[0]] = envval.startsWith('{') ? JSON.parse(envval) : envval
69
+ }
70
+ })
71
+ }
72
+
73
+ m.PROJECTNAME_TEST_EXPLAIN = process.env.PROJECTNAME_TEST_EXPLAIN || m.PROJECTNAME_TEST_EXPLAIN
74
+
75
+ return m
76
+ }
77
+
78
+
79
+ export {
80
+ makeStepData,
81
+ makeMatch,
82
+ makeReqdata,
83
+ makeValid,
84
+ makeCtrl,
85
+ envOverride
86
+ }
@@ -0,0 +1,54 @@
1
+
2
+ import Path from 'node:path'
3
+
4
+ import {
5
+ Content,
6
+ cmp,
7
+ } from 'jostraca'
8
+
9
+
10
+ import type {
11
+ ActionContext,
12
+ } from '../types'
13
+
14
+
15
+ const UpdateIndex = cmp(function UpdateIndex(props: any) {
16
+ const names = props.names
17
+
18
+ let oldcontent = props.content
19
+ let newcontent = oldcontent
20
+
21
+ names.map((n: string) => {
22
+ if (!oldcontent.includes(`@"${n}.jsonic"`)) {
23
+ newcontent += `\n@"${n}.jsonic"`
24
+ }
25
+ })
26
+
27
+ Content(newcontent)
28
+ })
29
+
30
+
31
+ function loadContent(actx: ActionContext, which: string | string[]) {
32
+ which = Array.isArray(which) ? which : [which]
33
+
34
+ const content: any = {}
35
+
36
+ const fs = actx.fs()
37
+ const tree = actx.tree
38
+ const modelfolder = Path.dirname(tree.url)
39
+
40
+ which.map((w: string) => {
41
+ const indexfile = Path.join(modelfolder, w, w + '-index.jsonic')
42
+ const indexcontent = fs.readFileSync(indexfile, 'utf8')
43
+ content[`${w}_index`] = indexcontent
44
+ })
45
+
46
+ return content
47
+ }
48
+
49
+
50
+
51
+ export {
52
+ UpdateIndex,
53
+ loadContent
54
+ }
@@ -1,19 +1,32 @@
1
1
 
2
+ import Path from 'node:path'
3
+
2
4
  import {
3
5
  Jostraca,
4
6
  Project,
5
7
  File,
6
8
  Folder,
7
- Content,
8
9
  Copy,
9
10
  cmp,
10
11
  each,
11
12
  } from 'jostraca'
12
13
 
14
+ import { showChanges } from '@voxgig/util'
15
+
16
+ import type {
17
+ ActionContext,
18
+ ActionResult,
19
+ } from '../types'
13
20
 
14
21
  import { SdkGenError } from '../utility'
15
22
 
16
23
 
24
+ import {
25
+ UpdateIndex,
26
+ loadContent,
27
+ } from './action'
28
+
29
+
17
30
  const CMD_MAP: any = {
18
31
  add: cmd_feature_add
19
32
  }
@@ -21,7 +34,7 @@ const CMD_MAP: any = {
21
34
  const BASE = 'node_modules/@voxgig/sdkgen'
22
35
 
23
36
 
24
- async function action_feature(args: any[], ctx: any) {
37
+ async function action_feature(args: string[], actx: ActionContext): Promise<ActionResult> {
25
38
 
26
39
  const cmdname = args[1]
27
40
 
@@ -31,91 +44,114 @@ async function action_feature(args: any[], ctx: any) {
31
44
  throw new SdkGenError('Unknown feature cmd: ' + cmdname)
32
45
  }
33
46
 
34
- await cmd(args, ctx)
47
+ return await cmd(args, actx)
35
48
  }
36
49
 
37
50
 
38
- async function cmd_feature_add(args: any[], ctx: any) {
51
+ async function cmd_feature_add(args: string[], actx: ActionContext): Promise<ActionResult> {
52
+
53
+ const features_arg = args[2]
54
+ const features: string[] =
55
+ 'string' === typeof features_arg ? features_arg.split(',') : features_arg
56
+
57
+ return feature_add(features, actx)
58
+ }
59
+
39
60
 
40
- let features = args[2]
41
- features = 'string' === typeof features ? features.split(',') : features
61
+ async function feature_add(features: string[], actx: ActionContext): Promise<ActionResult> {
42
62
 
43
63
  const jostraca = Jostraca()
44
64
 
45
65
  const opts = {
46
- fs: ctx.fs,
47
- folder: ctx.folder,
48
- log: ctx.log.child({ cmp: 'jostraca' }),
49
- meta: { model: ctx.model, tree: ctx.tree }
66
+ fs: actx.fs,
67
+ folder: actx.folder,
68
+ log: actx.log.child({ cmp: 'jostraca' }),
69
+ meta: {
70
+ // model: actx.model,
71
+ tree: actx.tree,
72
+ content: loadContent(actx, 'feature')
73
+ },
74
+ model: actx.model
50
75
  }
51
76
 
52
- await jostraca.generate(opts, () => FeatureRoot({ features }))
77
+ opts.log.info({
78
+ point: 'feature-start',
79
+ note: (actx.opts.dryrun ? '** DRY RUN **' : '')
80
+ })
81
+
82
+ const jres = await jostraca.generate(opts, () => FeatureRoot({ features }))
83
+
84
+ showChanges(opts.log, 'feature-result', jres)
85
+
86
+ opts.log.info({
87
+ point: 'feature-end',
88
+ note: (actx.opts.dryrun ? '** DRY RUN **' : '')
89
+ })
90
+
91
+ return {
92
+ jres
93
+ }
53
94
  }
54
95
 
55
96
 
56
97
  const FeatureRoot = cmp(function FeatureRoot(props: any) {
57
98
  const { ctx$, features } = props
99
+ const { model, log } = ctx$
58
100
 
59
- // TODO: model should be a top level ctx property
60
- const model = ctx$.model = ctx$.meta.model
61
101
  const target = model.main.sdk.target
62
102
 
63
103
  Project({}, () => {
64
104
  each(features, (n) => {
65
- const name = n.val$
105
+ const fname = n.val$
66
106
  // TODO: validate feature is a-z0-9-_. only
67
107
 
108
+ log.info({
109
+ point: 'feature-build',
110
+ feature: fname,
111
+ note: fname
112
+ })
113
+
114
+
68
115
  Folder({ name: 'model/feature' }, () => {
69
116
  Copy({
70
117
  // TODO: these paths needs to be parameterised
71
- from: BASE + '/project/.sdk/model/feature/' + name + '.jsonic',
118
+ from: BASE + '/project/.sdk/model/feature/' + fname + '.jsonic',
72
119
  exclude: true
73
120
  })
121
+ File({ name: 'feature-index.jsonic' }, () => UpdateIndex({
122
+ content: ctx$.meta.content.feature_index,
123
+ names: features,
124
+ }))
74
125
  })
75
126
 
76
127
  each(target, (target) =>
77
- Folder({ name: 'tm/' + target.name + '/src/feature/' + name }, () => {
128
+ Folder({ name: 'tm/' + target.name + '/src/feature/' + fname }, () => {
129
+ const from = Path.join(
130
+ (target.base || Path.join(BASE, '/project/.sdk')),
131
+ 'tm',
132
+ target.name,
133
+ '/src/feature/',
134
+ fname
135
+ )
136
+
78
137
  Copy({
79
- from: BASE + '/project/.sdk/tm/' + target.name + '/src/feature/' + name,
138
+ // from: BASE + '/project/.sdk/tm/' + target.name + '/src/feature/' + name,
139
+ from,
80
140
  exclude: true
81
141
  })
82
142
  }))
83
143
 
144
+ log.info({
145
+ point: 'feature-done', feature: fname,
146
+ note: fname
147
+ })
84
148
  })
85
149
  })
86
150
 
87
- modifyModel({
88
- features,
89
- model: ctx$.meta.model,
90
- tree: ctx$.meta.tree,
91
- fs: ctx$.fs
92
- })
93
-
94
151
  })
95
152
 
96
153
 
97
- async function modifyModel({ features, model, tree, fs }: any) {
98
- // TODO: This is a kludge.
99
- // Aontu should provide option for as-is AST so that can be used
100
- // to find injection point more reliably
101
-
102
- const path = tree.url
103
- let src = fs().readFileSync(path, 'utf8')
104
-
105
- // Inject feature file references into model
106
- features.sort().map((feature: string) => {
107
- const lineRE =
108
- new RegExp(`@"feature/${feature}.jsonic"`)
109
- if (!src.match(lineRE)) {
110
- src = src.replace(/(main:\s+sdk:\s+feature:\s+\{\s*\}\n)/, '$1' +
111
- `@"feature/${feature}.jsonic"\n`)
112
- }
113
- })
114
-
115
- fs().writeFileSync(path, src)
116
- }
117
-
118
-
119
154
  export {
120
- action_feature
155
+ feature_add,
156
+ action_feature,
121
157
  }
@@ -1,25 +1,48 @@
1
1
 
2
+ import Path from 'node:path'
3
+
2
4
  import {
3
- Jostraca,
4
5
  Project,
5
- File,
6
6
  Folder,
7
- Content,
8
7
  Copy,
8
+ File,
9
9
  cmp,
10
10
  each,
11
11
  } from 'jostraca'
12
12
 
13
+ import { showChanges } from '@voxgig/util'
14
+
15
+ import { getelem } from '@voxgig/struct'
16
+
17
+ import type {
18
+ ActionContext,
19
+ ActionResult,
20
+ } from '../types'
13
21
 
14
22
  import { SdkGenError } from '../utility'
15
23
 
24
+ import {
25
+ feature_add
26
+ } from './feature'
27
+
28
+ import {
29
+ UpdateIndex,
30
+ loadContent,
31
+ } from './action'
32
+
16
33
 
17
34
  const CMD_MAP: any = {
18
35
  add: cmd_target_add
19
36
  }
20
37
 
21
- async function action_target(args: any[], ctx: any) {
22
38
 
39
+ type Target = {
40
+ origin: string
41
+ name: string
42
+ }
43
+
44
+
45
+ async function action_target(args: string[], actx: ActionContext): Promise<ActionResult> {
23
46
  const cmdname = args[1]
24
47
 
25
48
  const cmd = CMD_MAP[cmdname]
@@ -28,106 +51,203 @@ async function action_target(args: any[], ctx: any) {
28
51
  throw new SdkGenError('Unknown target cmd: ' + cmdname)
29
52
  }
30
53
 
31
- await cmd(args, ctx)
54
+ return await cmd(args, actx)
32
55
  }
33
56
 
34
57
 
35
- async function cmd_target_add(args: any[], ctx: any) {
58
+ async function cmd_target_add(args: string[], actx: ActionContext): Promise<ActionResult> {
59
+ const targets_arg = args[2]
60
+ const targets: string[] =
61
+ 'string' === typeof targets_arg ? targets_arg.split(',') : targets_arg
62
+
63
+ return target_add(targets, actx)
64
+ }
36
65
 
37
- let targets = args[2]
38
- targets = 'string' === typeof targets ? targets.split(',') : targets
39
66
 
40
- const jostraca = Jostraca()
67
+ // Code API
68
+ async function target_add(targets: string[], actx: ActionContext): Promise<ActionResult> {
69
+ // const jostraca = Jostraca()
70
+ const jostraca = actx.jostraca
41
71
 
42
72
  const opts = {
43
- fs: ctx.fs,
44
- folder: ctx.folder,
45
- log: ctx.log.child({ cmp: 'jostraca' }),
46
- meta: { model: ctx.model, tree: ctx.tree },
47
- model: ctx.model
73
+ fs: actx.fs,
74
+ folder: actx.folder,
75
+ log: actx.log.child({ cmp: 'jostraca' }),
76
+ meta: {
77
+ // model: actx.model,
78
+ tree: actx.tree,
79
+ content: loadContent(actx, 'target')
80
+ },
81
+ model: actx.model,
48
82
  }
49
83
 
50
- await jostraca.generate(opts, () => TargetRoot({ targets }))
84
+ opts.log.info({
85
+ point: 'target-start',
86
+ note: (actx.opts.dryrun ? '** DRY RUN **' : '')
87
+ })
88
+
89
+
90
+ const jres = await jostraca.generate(opts, () => TargetRoot({ targets, actx }))
91
+
92
+ showChanges(opts.log, 'target-result', jres)
51
93
 
94
+ const features = Object.keys(actx.model.main.sdk.feature)
95
+ await feature_add(features, actx)
96
+
97
+ opts.log.info({
98
+ point: 'target-end',
99
+ note: (actx.opts.dryrun ? '** DRY RUN **' : '')
100
+ })
101
+
102
+ return {
103
+ jres
104
+ }
52
105
  }
53
106
 
54
107
 
55
108
  const TargetRoot = cmp(function TargetRoot(props: any) {
56
109
  const { ctx$, targets } = props
110
+ const { model, log } = ctx$
57
111
 
58
- // TODO: model should be a top level ctx property
59
- // ctx$.model = ctx$.meta.model
60
-
61
- // console.log('MODEL')
62
- // console.dir(ctx$.model, { depth: null })
63
-
64
- const { model } = ctx$
112
+ // TODO: jostraca - make from value easier to specify
113
+ // const tfolder = 'node_modules/@voxgig/sdkgen/project/.sdk'
65
114
 
66
115
  Project({}, () => {
67
116
  each(targets, (n) => {
68
- // TODO: validate target is a-z0-9-_. only
69
- const name = n.val$
117
+ const tref = n.val$
118
+
119
+ log.info({
120
+ point: 'target-build',
121
+ target: tref,
122
+ note: tref
123
+ })
124
+
125
+ const { tname, tfolder, torigname, base } = resolveTarget(tref, ctx$)
126
+ const targetNote = tname + (tname != tref ? ' ref:' + tref : '')
127
+
128
+ log.info({
129
+ point: 'target-name', name: tname, folder: tfolder,
130
+ target: tref,
131
+ tname,
132
+ note: tname + (tname != torigname ? 'original' + torigname : '') + ' from:' + tfolder
133
+ })
70
134
 
71
135
  Folder({ name: 'model/target' }, () => {
72
136
  Copy({
73
- from: 'node_modules/@voxgig/sdkgen/project/.sdk/model/target/' + name + '.jsonic',
137
+ from: tfolder + '/model/target/' + torigname + '.jsonic',
74
138
  // exclude: true
139
+ replace: {
140
+ "'BASE'": "'" + base + "'"
141
+ }
75
142
  })
143
+ File({ name: 'target-index.jsonic' }, () => UpdateIndex({
144
+ content: ctx$.meta.content.target_index,
145
+ // names: targets,
146
+ names: [tname]
147
+ }))
76
148
  })
77
149
 
78
- Folder({ name: 'src/cmp/' + name }, () => {
150
+ Folder({ name: 'src/cmp/' + tname }, () => {
79
151
  Copy({
80
- from: 'node_modules/@voxgig/sdkgen/project/.sdk/src/cmp/' + name,
152
+ from: tfolder + '/src/cmp/' + torigname,
81
153
  // exclude: true
82
154
  })
83
155
  })
84
156
 
85
- Folder({ name: 'tm/' + name }, () => {
157
+ Folder({ name: 'tm/' + tname }, () => {
86
158
  Copy({
87
- from: 'node_modules/@voxgig/sdkgen/project/.sdk/tm/' + name,
159
+ from: tfolder + '/tm/' + torigname,
88
160
  exclude: [/src\/feature/],
89
161
  replace: {
90
- Name: model.const.Name,
162
+
163
+ // TODO: standard replacements
164
+ ProjectName: model.const.Name,
91
165
  }
92
166
  })
167
+
168
+ Folder({ name: 'src/feature' }, () => {
169
+ Copy({ from: tfolder + '/tm/' + torigname + '/src/feature/README.md' })
170
+
171
+ Folder({ name: 'base' }, () => {
172
+ Copy({ from: tfolder + '/tm/' + torigname + '/src/feature/base' })
173
+ })
174
+ })
93
175
  })
94
176
 
177
+ log.info({
178
+ point: 'target-done', target: tref, note: targetNote
179
+ })
95
180
 
96
181
  })
97
182
  })
183
+ })
98
184
 
99
- modifyModel({
100
- targets,
101
- model: ctx$.meta.model,
102
- tree: ctx$.meta.tree,
103
- fs: ctx$.fs
104
- })
105
185
 
106
- })
186
+ function resolveTarget(tref: string, ctx$: any) {
187
+ let tname = tref
188
+ let torigname = tref
189
+ let tfolder = 'node_modules/@voxgig/sdkgen/project/.sdk'
107
190
 
191
+ const root = ctx$.folder
192
+ const fs = ctx$.fs()
108
193
 
109
- async function modifyModel({ targets, model, tree, fs }: any) {
110
- // TODO: This is a kludge.
111
- // Aontu should provide option for as-is AST so that can be used
112
- // to find injection point more reliably
194
+ let fulltfolder = Path.normalize(Path.join(root, tfolder))
195
+ tname = getelem(tref.split('/'), -1)
113
196
 
114
- const path = tree.url
115
- let src = fs().readFileSync(path, 'utf8')
197
+ let aliasref = tref
198
+ torigname = getelem(aliasref.split('/'), -1)
199
+ const aliasing = tref.split('~')
200
+ if (1 < aliasing.length) {
201
+ aliasref = aliasing[0]
202
+ tname = aliasing.slice(1).join('~')
203
+ torigname = getelem(aliasref.split('/'), -1)
204
+ }
116
205
 
117
- // Inject target file references into model
118
- targets.sort().map((target: string) => {
119
- const lineRE =
120
- new RegExp(`@"target/${target}.jsonic"`)
121
- if (!src.match(lineRE)) {
122
- src = src.replace(/(main:\s+sdk:\s+target:\s+\{\s*\}\n)/, '$1' +
123
- `@"target/${target}.jsonic"\n`)
206
+ const search: string[] = []
207
+ let found = false
208
+ if (aliasref.includes('/')) {
209
+ // NOTE: the last path element of the ref is the target name, not a folder.
210
+ const aliasbase = Path.dirname(aliasref)
211
+
212
+ if (!aliasref.startsWith('/')) {
213
+ fulltfolder = Path.normalize(Path.join(root, 'node_modules', aliasbase, '.sdk'))
214
+ search.push(fulltfolder)
215
+ found = fs.existsSync(fulltfolder)
216
+
217
+ if (!found) {
218
+ fulltfolder = Path.normalize(Path.join(root, aliasbase, '.sdk'))
219
+ search.push(fulltfolder)
220
+ found = fs.existsSync(fulltfolder)
221
+ }
124
222
  }
125
- })
223
+ else {
224
+ fulltfolder = Path.normalize(Path.join(aliasbase, '.sdk'))
225
+ search.push(fulltfolder)
226
+ found = fs.existsSync(fulltfolder)
227
+ }
228
+ }
229
+ else {
230
+ search.push(fulltfolder)
231
+ found = fs.existsSync(fulltfolder)
232
+ }
233
+
234
+ if (!found) {
235
+ throw new Error('Target folder not found in:\n' + search.join('\n '))
236
+ }
237
+
238
+ const rootslash = root.endsWith('/') ? root : root + '/'
239
+ const out = {
240
+ tname,
241
+ tfolder: fulltfolder,
242
+ torigname,
243
+ base: fulltfolder.replace(rootslash, '')
244
+ }
126
245
 
127
- fs().writeFileSync(path, src)
246
+ return out
128
247
  }
129
248
 
130
249
 
131
250
  export {
132
- action_target
251
+ action_target,
252
+ target_add,
133
253
  }
package/src/cmp/Entity.ts CHANGED
@@ -8,11 +8,17 @@ import { requirePath } from '../utility'
8
8
 
9
9
  const Entity = cmp(function Entity(props: any) {
10
10
  const { target, entity, ctx$ } = props
11
+ const { log } = ctx$
11
12
 
12
13
  const entitySDK = ctx$.model.main.sdk.entity[entity.name]
13
14
 
14
15
  const Entity_sdk = requirePath(ctx$, `./cmp/${target.name}/Entity_${target.name}`)
15
16
  Entity_sdk['Entity']({ target, entity, entitySDK })
17
+
18
+ log.info({
19
+ point: 'generate-entity', target, entity,
20
+ note: 'target:' + target.name + ', ' + 'entity: ' + entity.name
21
+ })
16
22
  })
17
23
 
18
24
 
@@ -1,11 +1,9 @@
1
1
 
2
2
  import { cmp, Copy, Folder } from 'jostraca'
3
3
 
4
- import { resolvePath } from '../utility'
5
-
6
-
7
4
  const Feature = cmp(function Feature(props: any) {
8
5
  const { target, feature, ctx$ } = props
6
+ const { log } = ctx$
9
7
 
10
8
  Folder({ name: 'src/feature/' + feature.name }, () => {
11
9
  // TODO: Copy should just warn if from not found
@@ -18,6 +16,11 @@ const Feature = cmp(function Feature(props: any) {
18
16
  })
19
17
  })
20
18
 
19
+ log.info({
20
+ point: 'generate-feature', target, feature,
21
+ note: 'target:' + target.name + ', ' + 'feature: ' + feature.name
22
+ })
23
+
21
24
  })
22
25
 
23
26