@voxgig/sdkgen 0.32.2 → 0.32.3
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 +1 -1
- package/dist/cmp/Readme.js +10 -0
- package/dist/cmp/Readme.js.map +1 -1
- package/dist/cmp/ReadmeEntity.js +91 -8
- package/dist/cmp/ReadmeEntity.js.map +1 -1
- package/dist/cmp/ReadmeIntro.js +24 -2
- package/dist/cmp/ReadmeIntro.js.map +1 -1
- package/dist/cmp/ReadmeModel.js +93 -16
- package/dist/cmp/ReadmeModel.js.map +1 -1
- package/dist/cmp/ReadmeOptions.js +30 -5
- package/dist/cmp/ReadmeOptions.js.map +1 -1
- package/dist/cmp/ReadmeRef.d.ts +2 -0
- package/dist/cmp/ReadmeRef.js +334 -0
- package/dist/cmp/ReadmeRef.js.map +1 -0
- package/dist/sdkgen.d.ts +2 -1
- package/dist/sdkgen.js +3 -1
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +2 -2
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +3 -3
- package/project/.sdk/src/cmp/js/Config_js.ts +62 -23
- package/project/.sdk/src/cmp/js/EntityOperation_js.ts +49 -0
- package/project/.sdk/src/cmp/js/Entity_js.ts +21 -50
- package/project/.sdk/src/cmp/js/MainEntity_js.ts +1 -1
- package/project/.sdk/src/cmp/js/Main_js.ts +53 -44
- package/project/.sdk/src/cmp/js/Package_js.ts +39 -12
- package/project/.sdk/src/cmp/js/Quick_js.ts +6 -10
- package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +101 -5
- package/project/.sdk/src/cmp/js/SdkError_js.ts +42 -0
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +288 -0
- package/project/.sdk/src/cmp/js/TestEntity_js.ts +352 -2
- package/project/.sdk/src/cmp/js/TestMain_js.ts +0 -3
- package/project/.sdk/src/cmp/js/Test_js.ts +20 -8
- package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +55 -0
- package/project/.sdk/src/cmp/js/fragment/Direct.test.fragment.js +30 -0
- package/project/.sdk/src/cmp/js/fragment/Entity.fragment.js +119 -28
- package/project/.sdk/src/cmp/js/fragment/Entity.test.fragment.js +39 -0
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +89 -45
- package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +92 -41
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +95 -45
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +95 -43
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +95 -43
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +150 -65
- package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +22 -0
- package/project/.sdk/src/cmp/js/utility_js.ts +64 -0
- package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +102 -5
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +2 -2
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +11 -8
- package/src/cmp/Readme.ts +12 -0
- package/src/cmp/ReadmeEntity.ts +105 -9
- package/src/cmp/ReadmeIntro.ts +30 -2
- package/src/cmp/ReadmeModel.ts +101 -18
- package/src/cmp/ReadmeOptions.ts +35 -6
- package/src/cmp/ReadmeRef.ts +369 -0
- package/src/sdkgen.ts +2 -0
package/src/cmp/ReadmeEntity.ts
CHANGED
|
@@ -7,33 +7,129 @@ import {
|
|
|
7
7
|
} from '../types'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
const OP_DESC: Record<string, { method: string, desc: string }> = {
|
|
11
|
+
load: { method: 'load(match)', desc: 'Load a single entity by match criteria.' },
|
|
12
|
+
list: { method: 'list(match)', desc: 'List entities matching the criteria.' },
|
|
13
|
+
create: { method: 'create(data)', desc: 'Create a new entity with the given data.' },
|
|
14
|
+
update: { method: 'update(data)', desc: 'Update an existing entity.' },
|
|
15
|
+
remove: { method: 'remove(match)', desc: 'Remove the matching entity.' },
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
10
19
|
const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
|
|
11
20
|
const { ctx$: { model } } = props
|
|
12
21
|
|
|
13
22
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
14
23
|
|
|
24
|
+
const publishedEntities = each(entity)
|
|
25
|
+
.filter((entity: any) => entity.publish)
|
|
26
|
+
|
|
27
|
+
if (0 === publishedEntities.length) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
15
31
|
Content(`
|
|
16
32
|
|
|
17
33
|
## Entities
|
|
34
|
+
|
|
18
35
|
`)
|
|
19
36
|
|
|
37
|
+
publishedEntities.map((entity: any) => {
|
|
38
|
+
const opnames = Object.keys(entity.op || {})
|
|
39
|
+
const fields = entity.field || []
|
|
40
|
+
|
|
41
|
+
Content(`
|
|
42
|
+
### ${entity.Name}
|
|
43
|
+
|
|
44
|
+
`)
|
|
45
|
+
|
|
46
|
+
if (entity.short) {
|
|
47
|
+
Content(`${entity.short}
|
|
48
|
+
|
|
49
|
+
`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Content(`Create an instance: \`const ${entity.name} = client.${entity.Name}()\`
|
|
53
|
+
|
|
54
|
+
`)
|
|
55
|
+
|
|
56
|
+
// Operations table
|
|
57
|
+
if (opnames.length > 0) {
|
|
58
|
+
Content(`#### Operations
|
|
59
|
+
|
|
60
|
+
| Method | Description |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
`)
|
|
63
|
+
opnames.map((opname: string) => {
|
|
64
|
+
const info = OP_DESC[opname]
|
|
65
|
+
if (info) {
|
|
66
|
+
Content(`| \`${info.method}\` | ${info.desc} |
|
|
67
|
+
`)
|
|
68
|
+
}
|
|
69
|
+
})
|
|
20
70
|
|
|
21
|
-
each(entity)
|
|
22
|
-
.filter((entity: any) => entity.publish)
|
|
23
|
-
.map((entity: any) => {
|
|
24
71
|
Content(`
|
|
25
|
-
|
|
72
|
+
`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Fields table
|
|
76
|
+
if (fields.length > 0) {
|
|
77
|
+
Content(`#### Fields
|
|
26
78
|
|
|
79
|
+
| Field | Type | Description |
|
|
80
|
+
| --- | --- | --- |
|
|
27
81
|
`)
|
|
28
82
|
|
|
29
|
-
each(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
83
|
+
each(fields, (field: any) => {
|
|
84
|
+
const desc = field.short || ''
|
|
85
|
+
Content(`| \`${field.name}\` | \`${field.type || 'any'}\` | ${desc} |
|
|
33
86
|
`)
|
|
34
87
|
})
|
|
35
|
-
})
|
|
36
88
|
|
|
89
|
+
Content(`
|
|
90
|
+
`)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Example usage
|
|
94
|
+
if (opnames.includes('load')) {
|
|
95
|
+
Content(`#### Example: Load
|
|
96
|
+
|
|
97
|
+
\`\`\`ts
|
|
98
|
+
const ${entity.name} = await client.${entity.Name}().load({ id: '${entity.name}_id' })
|
|
99
|
+
\`\`\`
|
|
100
|
+
|
|
101
|
+
`)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (opnames.includes('list')) {
|
|
105
|
+
Content(`#### Example: List
|
|
106
|
+
|
|
107
|
+
\`\`\`ts
|
|
108
|
+
const ${entity.name}s = await client.${entity.Name}().list()
|
|
109
|
+
\`\`\`
|
|
110
|
+
|
|
111
|
+
`)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (opnames.includes('create')) {
|
|
115
|
+
Content(`#### Example: Create
|
|
116
|
+
|
|
117
|
+
\`\`\`ts
|
|
118
|
+
const ${entity.name} = await client.${entity.Name}().create({
|
|
119
|
+
`)
|
|
120
|
+
each(fields, (field: any) => {
|
|
121
|
+
if ('id' !== field.name && field.req) {
|
|
122
|
+
Content(` ${field.name}: /* ${field.type || 'value'} */,
|
|
123
|
+
`)
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
Content(`})
|
|
127
|
+
\`\`\`
|
|
128
|
+
|
|
129
|
+
`)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
})
|
|
37
133
|
|
|
38
134
|
})
|
|
39
135
|
|
package/src/cmp/ReadmeIntro.ts
CHANGED
|
@@ -1,18 +1,46 @@
|
|
|
1
1
|
|
|
2
2
|
import { cmp, Content } from 'jostraca'
|
|
3
3
|
|
|
4
|
+
import {
|
|
5
|
+
KIT,
|
|
6
|
+
getModelPath
|
|
7
|
+
} from '../types'
|
|
8
|
+
|
|
4
9
|
|
|
5
10
|
const ReadmeIntro = cmp(function ReadmeIntro(props: any) {
|
|
6
|
-
const {
|
|
11
|
+
const { target } = props
|
|
12
|
+
const { model } = props.ctx$
|
|
13
|
+
|
|
14
|
+
const desc = model.main.def.desc || ''
|
|
15
|
+
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
16
|
+
|
|
17
|
+
const entityNames = Object.values(entity)
|
|
18
|
+
.filter((e: any) => e.publish)
|
|
19
|
+
.map((e: any) => `\`${e.Name}\``)
|
|
7
20
|
|
|
8
21
|
Content(`
|
|
9
22
|
## Introduction
|
|
10
23
|
|
|
11
|
-
${
|
|
24
|
+
${desc}
|
|
25
|
+
`)
|
|
26
|
+
|
|
27
|
+
if (entityNames.length > 0) {
|
|
28
|
+
Content(`
|
|
29
|
+
This SDK provides an entity-oriented interface for the ${model.Name} API.
|
|
30
|
+
The following entities are available: ${entityNames.join(', ')}.
|
|
12
31
|
|
|
13
32
|
`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Content(`
|
|
36
|
+
### Features
|
|
14
37
|
|
|
38
|
+
- Entity-based API: work with business objects directly.
|
|
39
|
+
- Type safe: full TypeScript definitions included.
|
|
40
|
+
- Direct HTTP access: call any API endpoint using \`client.direct()\`.
|
|
41
|
+
- Testable: built-in test mode with mock support.
|
|
15
42
|
|
|
43
|
+
`)
|
|
16
44
|
|
|
17
45
|
})
|
|
18
46
|
|
package/src/cmp/ReadmeModel.ts
CHANGED
|
@@ -1,44 +1,127 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, Content } from 'jostraca'
|
|
2
|
+
import { cmp, each, Content } from 'jostraca'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
KIT,
|
|
6
|
+
getModelPath
|
|
7
|
+
} from '../types'
|
|
3
8
|
|
|
4
9
|
|
|
5
10
|
const ReadmeModel = cmp(function ReadmeModel(props: any) {
|
|
6
11
|
const { ctx$: { model } } = props
|
|
7
12
|
|
|
13
|
+
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
14
|
+
const entityList = Object.values(entity).filter((e: any) => e.publish)
|
|
15
|
+
|
|
8
16
|
Content(`
|
|
9
|
-
##
|
|
17
|
+
## SDK Structure
|
|
18
|
+
|
|
19
|
+
This SDK uses an entity-oriented interface rather than exposing API
|
|
20
|
+
endpoint paths directly. Business logic maps directly to business
|
|
21
|
+
entities in your code.
|
|
10
22
|
|
|
11
|
-
This SDK uses an entity-oriented interface, rather than exposing
|
|
12
|
-
endpoint paths directly. Business logic can be mapped directly to
|
|
13
|
-
business entities in your code.
|
|
14
23
|
|
|
15
|
-
|
|
16
|
-
which can be used concurrently in the same thread. Each client
|
|
17
|
-
instance provides a set of entity methods to create entity
|
|
18
|
-
instances. Each entity instance can likewise operate independently.
|
|
24
|
+
### Client
|
|
19
25
|
|
|
26
|
+
Create a client instance using the constructor or the static \`test\` method:
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
\`\`\`ts
|
|
29
|
+
// Production client
|
|
30
|
+
const client = new ${model.Name}SDK({ apikey: '...' })
|
|
22
31
|
|
|
23
|
-
|
|
32
|
+
// Test client with mock features
|
|
33
|
+
const testClient = ${model.Name}SDK.test()
|
|
34
|
+
\`\`\`
|
|
24
35
|
|
|
25
36
|
|
|
26
37
|
### Client Methods
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
| Method | Description |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
`)
|
|
42
|
+
|
|
43
|
+
each(entityList, (entity: any) => {
|
|
44
|
+
Content(`| \`${entity.Name}(data?)\` | Create a new \`${entity.Name}\` entity instance. |
|
|
45
|
+
`)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
Content(`| \`options()\` | Return a copy of the current SDK options. |
|
|
49
|
+
| \`utility()\` | Return a copy of the SDK utility object. |
|
|
50
|
+
| \`direct(fetchargs)\` | Make a direct HTTP request to any API endpoint. |
|
|
51
|
+
| \`prepare(fetchargs)\` | Prepare a fetch definition without sending the request. |
|
|
52
|
+
| \`tester(testopts?, sdkopts?)\` | Create a test client instance. |
|
|
29
53
|
|
|
30
54
|
|
|
31
55
|
### Entity Methods
|
|
32
56
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
Each entity instance provides the following methods, where available:
|
|
58
|
+
|
|
59
|
+
| Method | Description |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| \`data(data?)\` | Get or set the entity data. Returns the current data. |
|
|
62
|
+
| \`match(match?)\` | Get or set the entity match criteria. Returns the current match. |
|
|
63
|
+
| \`load(match)\` | Load a single entity by match criteria. |
|
|
64
|
+
| \`list(match)\` | List entities matching the criteria. Returns an array. |
|
|
65
|
+
| \`create(data)\` | Create a new entity with the given data. |
|
|
66
|
+
| \`update(data)\` | Update an existing entity with the given data. |
|
|
67
|
+
| \`remove(match)\` | Remove the entity matching the criteria. |
|
|
68
|
+
| \`make()\` | Create a new entity instance with the same options. |
|
|
69
|
+
| \`client()\` | Return the parent client instance. |
|
|
70
|
+
| \`entopts()\` | Return a copy of the entity options. |
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Direct API Access
|
|
74
|
+
|
|
75
|
+
The \`direct\` method allows you to call any API endpoint without
|
|
76
|
+
using the entity interface:
|
|
77
|
+
|
|
78
|
+
\`\`\`ts
|
|
79
|
+
const result = await client.direct({
|
|
80
|
+
path: '/api/v1/resource/{id}',
|
|
81
|
+
method: 'GET',
|
|
82
|
+
params: { id: 'abc123' },
|
|
83
|
+
query: { fields: 'name,status' },
|
|
84
|
+
headers: { 'X-Custom': 'value' },
|
|
85
|
+
body: { key: 'value' },
|
|
86
|
+
})
|
|
87
|
+
\`\`\`
|
|
38
88
|
|
|
39
|
-
|
|
89
|
+
The result object has the following shape:
|
|
90
|
+
|
|
91
|
+
\`\`\`ts
|
|
92
|
+
{
|
|
93
|
+
ok: boolean, // true if status is 2xx
|
|
94
|
+
status: number, // HTTP status code
|
|
95
|
+
headers: object, // Response headers
|
|
96
|
+
data: any, // Parsed JSON response body
|
|
97
|
+
}
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
Use the \`prepare\` method to build the fetch definition without
|
|
101
|
+
sending the request:
|
|
102
|
+
|
|
103
|
+
\`\`\`ts
|
|
104
|
+
const fetchdef = await client.prepare({
|
|
105
|
+
path: '/api/v1/resource',
|
|
106
|
+
method: 'POST',
|
|
107
|
+
body: { name: 'example' },
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// fetchdef contains: { url, method, headers, body }
|
|
111
|
+
\`\`\`
|
|
40
112
|
|
|
41
113
|
|
|
114
|
+
### Testing
|
|
115
|
+
|
|
116
|
+
Create a test client using the static \`test\` method. The test
|
|
117
|
+
client activates the test feature, which provides mock responses:
|
|
118
|
+
|
|
119
|
+
\`\`\`ts
|
|
120
|
+
const client = ${model.Name}SDK.test()
|
|
121
|
+
\`\`\`
|
|
122
|
+
|
|
123
|
+
`)
|
|
124
|
+
|
|
42
125
|
|
|
43
126
|
})
|
|
44
127
|
|
package/src/cmp/ReadmeOptions.ts
CHANGED
|
@@ -4,21 +4,50 @@ import { cmp, each, Content } from 'jostraca'
|
|
|
4
4
|
|
|
5
5
|
const ReadmeOptions = cmp(function ReadmeOptions(props: any) {
|
|
6
6
|
const { target } = props
|
|
7
|
+
const { model } = props.ctx$
|
|
8
|
+
|
|
9
|
+
const publishedOptions = each(target.options)
|
|
10
|
+
.filter((option: any) => option.publish)
|
|
11
|
+
|
|
12
|
+
if (0 === publishedOptions.length) {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
7
15
|
|
|
8
16
|
Content(`
|
|
9
17
|
|
|
10
18
|
## Options
|
|
11
19
|
|
|
20
|
+
Pass options when creating a client instance:
|
|
21
|
+
|
|
22
|
+
\`\`\`ts
|
|
23
|
+
const client = new ${model.Name}SDK({
|
|
12
24
|
`)
|
|
13
25
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
publishedOptions.map((option: any) => {
|
|
27
|
+
if ('apikey' === option.name) {
|
|
28
|
+
Content(` ${option.name}: process.env.${model.NAME}_APIKEY,
|
|
29
|
+
`)
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
Content(` // ${option.name}: ${option.kind === 'string' ? "'...'" : '...'},
|
|
19
33
|
`)
|
|
20
|
-
}
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
Content(`})
|
|
38
|
+
\`\`\`
|
|
21
39
|
|
|
40
|
+
| Option | Type | Description |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
`)
|
|
43
|
+
|
|
44
|
+
publishedOptions.map((option: any) => {
|
|
45
|
+
Content(`| \`${option.name}\` | \`${option.kind}\` | ${option.short} |
|
|
46
|
+
`)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
Content(`
|
|
50
|
+
`)
|
|
22
51
|
|
|
23
52
|
})
|
|
24
53
|
|