@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.
Files changed (56) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/cmp/Readme.js +10 -0
  3. package/dist/cmp/Readme.js.map +1 -1
  4. package/dist/cmp/ReadmeEntity.js +91 -8
  5. package/dist/cmp/ReadmeEntity.js.map +1 -1
  6. package/dist/cmp/ReadmeIntro.js +24 -2
  7. package/dist/cmp/ReadmeIntro.js.map +1 -1
  8. package/dist/cmp/ReadmeModel.js +93 -16
  9. package/dist/cmp/ReadmeModel.js.map +1 -1
  10. package/dist/cmp/ReadmeOptions.js +30 -5
  11. package/dist/cmp/ReadmeOptions.js.map +1 -1
  12. package/dist/cmp/ReadmeRef.d.ts +2 -0
  13. package/dist/cmp/ReadmeRef.js +334 -0
  14. package/dist/cmp/ReadmeRef.js.map +1 -0
  15. package/dist/sdkgen.d.ts +2 -1
  16. package/dist/sdkgen.js +3 -1
  17. package/dist/sdkgen.js.map +1 -1
  18. package/dist/tsconfig.tsbuildinfo +1 -1
  19. package/package.json +1 -1
  20. package/project/.sdk/src/cmp/go/TestDirect_go.ts +2 -2
  21. package/project/.sdk/src/cmp/go/TestEntity_go.ts +3 -3
  22. package/project/.sdk/src/cmp/js/Config_js.ts +62 -23
  23. package/project/.sdk/src/cmp/js/EntityOperation_js.ts +49 -0
  24. package/project/.sdk/src/cmp/js/Entity_js.ts +21 -50
  25. package/project/.sdk/src/cmp/js/MainEntity_js.ts +1 -1
  26. package/project/.sdk/src/cmp/js/Main_js.ts +53 -44
  27. package/project/.sdk/src/cmp/js/Package_js.ts +39 -12
  28. package/project/.sdk/src/cmp/js/Quick_js.ts +6 -10
  29. package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +101 -5
  30. package/project/.sdk/src/cmp/js/SdkError_js.ts +42 -0
  31. package/project/.sdk/src/cmp/js/TestDirect_js.ts +288 -0
  32. package/project/.sdk/src/cmp/js/TestEntity_js.ts +352 -2
  33. package/project/.sdk/src/cmp/js/TestMain_js.ts +0 -3
  34. package/project/.sdk/src/cmp/js/Test_js.ts +20 -8
  35. package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +55 -0
  36. package/project/.sdk/src/cmp/js/fragment/Direct.test.fragment.js +30 -0
  37. package/project/.sdk/src/cmp/js/fragment/Entity.fragment.js +119 -28
  38. package/project/.sdk/src/cmp/js/fragment/Entity.test.fragment.js +39 -0
  39. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +89 -45
  40. package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +92 -41
  41. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +95 -45
  42. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +95 -43
  43. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +95 -43
  44. package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +150 -65
  45. package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +22 -0
  46. package/project/.sdk/src/cmp/js/utility_js.ts +64 -0
  47. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +102 -5
  48. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +2 -2
  49. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +11 -8
  50. package/src/cmp/Readme.ts +12 -0
  51. package/src/cmp/ReadmeEntity.ts +105 -9
  52. package/src/cmp/ReadmeIntro.ts +30 -2
  53. package/src/cmp/ReadmeModel.ts +101 -18
  54. package/src/cmp/ReadmeOptions.ts +35 -6
  55. package/src/cmp/ReadmeRef.ts +369 -0
  56. package/src/sdkgen.ts +2 -0
@@ -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
- ### Entity: __${entity.Name}__
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(entity.field, (field: any) => {
30
- Content(`
31
- * __${field.name}__ (${field.type}): ${field.short}
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
 
@@ -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 { ctx$: { model } } = props
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
- ${model.main.def.desc}
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
 
@@ -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
- ## Entity Model
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
- The SDK itself allows you to create one or more client instances,
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
- ### SDK Methods
28
+ \`\`\`ts
29
+ // Production client
30
+ const client = new ${model.Name}SDK({ apikey: '...' })
22
31
 
23
- * \`make(options)\`: Create a new client instance.
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
- * \`[Entity]()\`: Create a new business entity instance.
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
- * \`data(data?)\`: Set the data properties of the entity, returning the current data.
34
- * \`load(query)\`: Load matching single entity data into the entity instance.
35
- * \`save(data?)\`: Save the current entity, optionally setting data.
36
- * \`list(query)\`: List matching entities, return an array of new entities.
37
- * \`remove(query)\`: Delete the matching single entity.
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
 
@@ -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
- each(target.options)
15
- .filter((option: any) => option.publish)
16
- .map((option: any) => {
17
- Content(`
18
- * __${option.name} (${option.kind})__: ${option.short}
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