@voxgig/sdkgen 4.7.0 → 4.8.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.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/helpers/opShape.js +8 -11
- package/dist/helpers/opShape.js.map +1 -1
- package/dist/helpers/pointPath.d.ts +10 -0
- package/dist/helpers/pointPath.js +91 -0
- package/dist/helpers/pointPath.js.map +1 -0
- package/dist/sdkgen.d.ts +4 -2
- package/dist/sdkgen.js +8 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.js +26 -1
- package/dist/utility.js.map +1 -1
- package/package.json +2 -2
- package/project/.sdk/src/cmp/c/Config_c.ts +7 -8
- package/project/.sdk/src/cmp/c/TestDirect_c.ts +4 -3
- package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +4 -3
- package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +5 -4
- package/project/.sdk/src/cmp/dart/Config_dart.ts +7 -8
- package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +6 -5
- package/project/.sdk/src/cmp/elixir/Config_elixir.ts +9 -8
- package/project/.sdk/src/cmp/go/Config_go.ts +1 -7
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +5 -4
- package/project/.sdk/src/cmp/java/Config_java.ts +7 -7
- package/project/.sdk/src/cmp/java/TestDirect_java.ts +5 -4
- package/project/.sdk/src/cmp/js/Config_js.ts +7 -8
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +5 -4
- package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +7 -7
- package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +5 -4
- package/project/.sdk/src/cmp/lean/Config_lean.ts +9 -8
- package/project/.sdk/src/cmp/lua/Config_lua.ts +1 -7
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +5 -4
- package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +5 -4
- package/project/.sdk/src/cmp/php/Config_php.ts +1 -7
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +5 -4
- package/project/.sdk/src/cmp/py/Config_py.ts +1 -7
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +5 -4
- package/project/.sdk/src/cmp/rb/Config_rb.ts +1 -7
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +5 -4
- package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +5 -4
- package/project/.sdk/src/cmp/scala/Config_scala.ts +9 -7
- package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +4 -3
- package/project/.sdk/src/cmp/seneca-provider/Extras_seneca-provider.ts +3 -1
- package/project/.sdk/src/cmp/seneca-provider/Main_seneca-provider.ts +9 -5
- package/project/.sdk/src/cmp/ts/Config_ts.ts +7 -8
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +6 -5
- package/project/sdkgen-package.json +1 -1
- package/src/helpers/opShape.ts +9 -14
- package/src/helpers/pointPath.ts +118 -0
- package/src/sdkgen.ts +11 -0
- package/src/utility.ts +31 -1
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
snakify,
|
|
14
14
|
isAuthActive, envName, envToken,
|
|
15
15
|
serverVarEnv,
|
|
16
|
-
serverVariables
|
|
16
|
+
serverVariables,
|
|
17
|
+
pointParts,
|
|
17
18
|
} from '@voxgig/sdkgen'
|
|
18
19
|
|
|
19
20
|
import { formatLuaValue } from './utility_lua'
|
|
@@ -99,7 +100,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
99
100
|
const listOp = entity.op?.list
|
|
100
101
|
|
|
101
102
|
const loadPoint = loadOp?.points?.[0]
|
|
102
|
-
const loadPath = loadPoint ? normalizePathParams(loadPoint
|
|
103
|
+
const loadPath = loadPoint ? normalizePathParams(pointParts(loadPoint), loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
103
104
|
const allLoadParams = loadPoint?.args?.params || []
|
|
104
105
|
// Some upstream OpenAPI specs declare a parameter as `in: path` even when
|
|
105
106
|
// that path has no `{name}` placeholder for it. Only path params that
|
|
@@ -107,7 +108,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
107
108
|
// setup and URL-substitution asserts; otherwise the SDK silently drops
|
|
108
109
|
// them and the URL-includes assert fails.
|
|
109
110
|
const _pathPlaceholders = new Set<string>()
|
|
110
|
-
for (const part of (loadPoint
|
|
111
|
+
for (const part of pointParts(loadPoint)) {
|
|
111
112
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
112
113
|
_pathPlaceholders.add(part.slice(1, -1))
|
|
113
114
|
}
|
|
@@ -124,7 +125,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
124
125
|
_renamedPlaceholders.has(p.name) || _renamedPlaceholders.has(p.orig))
|
|
125
126
|
|
|
126
127
|
const listPoint = listOp?.points?.[0]
|
|
127
|
-
const listPath = listPoint ? normalizePathParams(listPoint
|
|
128
|
+
const listPath = listPoint ? normalizePathParams(pointParts(listPoint), listPoint?.args?.params || [], listPoint?.rename?.param) : ''
|
|
128
129
|
const listParams = listPoint?.args?.params || []
|
|
129
130
|
|
|
130
131
|
// Required query params with spec-provided examples — needed in live mode.
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
snakify,
|
|
14
14
|
isAuthActive, envName, envToken,
|
|
15
15
|
serverVarEnv,
|
|
16
|
-
serverVariables
|
|
16
|
+
serverVariables,
|
|
17
|
+
pointParts,
|
|
17
18
|
} from '@voxgig/sdkgen'
|
|
18
19
|
|
|
19
20
|
import { perlStringLiteral } from './utility_perl'
|
|
@@ -109,12 +110,12 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
109
110
|
const listOp = entity.op?.list
|
|
110
111
|
|
|
111
112
|
const loadPoint = loadOp?.points?.[0]
|
|
112
|
-
const loadPath = loadPoint ? normalizePathParams(loadPoint
|
|
113
|
+
const loadPath = loadPoint ? normalizePathParams(pointParts(loadPoint), loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
113
114
|
const allLoadParams = loadPoint?.args?.params || []
|
|
114
115
|
// Only path params that actually appear in the URL template drive direct-
|
|
115
116
|
// test path-param setup and URL-substitution asserts (see TestDirect_rb).
|
|
116
117
|
const _pathPlaceholders = new Set<string>()
|
|
117
|
-
for (const part of (loadPoint
|
|
118
|
+
for (const part of pointParts(loadPoint)) {
|
|
118
119
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
119
120
|
_pathPlaceholders.add(part.slice(1, -1))
|
|
120
121
|
}
|
|
@@ -131,7 +132,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
131
132
|
_renamedPlaceholders.has(p.name) || _renamedPlaceholders.has(p.orig))
|
|
132
133
|
|
|
133
134
|
const listPoint = listOp?.points?.[0]
|
|
134
|
-
const listPath = listPoint ? normalizePathParams(listPoint
|
|
135
|
+
const listPath = listPoint ? normalizePathParams(pointParts(listPoint), listPoint?.args?.params || [], listPoint?.rename?.param) : ''
|
|
135
136
|
const listParams = listPoint?.args?.params || []
|
|
136
137
|
|
|
137
138
|
// Required query params with spec-provided examples - needed in live mode.
|
|
@@ -29,7 +29,6 @@ import {
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
|
-
clean,
|
|
33
32
|
formatPhpArray,
|
|
34
33
|
} from './utility_php'
|
|
35
34
|
|
|
@@ -239,12 +238,7 @@ ${serverBlock}${authBlock} "headers" => ${formatPhpArray(headers,
|
|
|
239
238
|
Content(` ],
|
|
240
239
|
],
|
|
241
240
|
"entity" => ${formatPhpArray(
|
|
242
|
-
|
|
243
|
-
fields: n.fields,
|
|
244
|
-
name: n.name,
|
|
245
|
-
op: n.op,
|
|
246
|
-
relations: n.relations,
|
|
247
|
-
}, true), a), {}), 3)},
|
|
241
|
+
configDef.entity, 3)},
|
|
248
242
|
];
|
|
249
243
|
`)
|
|
250
244
|
}
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
snakify,
|
|
14
14
|
isAuthActive, envName, envToken,
|
|
15
15
|
serverVarEnv,
|
|
16
|
-
serverVariables
|
|
16
|
+
serverVariables,
|
|
17
|
+
pointParts,
|
|
17
18
|
} from '@voxgig/sdkgen'
|
|
18
19
|
|
|
19
20
|
import { formatPhpValue } from './utility_php'
|
|
@@ -99,7 +100,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
99
100
|
const listOp = entity.op?.list
|
|
100
101
|
|
|
101
102
|
const loadPoint = loadOp?.points?.[0]
|
|
102
|
-
const loadPath = loadPoint ? normalizePathParams(loadPoint
|
|
103
|
+
const loadPath = loadPoint ? normalizePathParams(pointParts(loadPoint), loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
103
104
|
const allLoadParams = loadPoint?.args?.params || []
|
|
104
105
|
// Some upstream OpenAPI specs declare a parameter as `in: path` even when
|
|
105
106
|
// that path has no `{name}` placeholder for it. Only path params that
|
|
@@ -107,7 +108,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
107
108
|
// setup and URL-substitution asserts; otherwise the SDK silently drops
|
|
108
109
|
// them and the URL-includes assert fails.
|
|
109
110
|
const _pathPlaceholders = new Set<string>()
|
|
110
|
-
for (const part of (loadPoint
|
|
111
|
+
for (const part of pointParts(loadPoint)) {
|
|
111
112
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
112
113
|
_pathPlaceholders.add(part.slice(1, -1))
|
|
113
114
|
}
|
|
@@ -124,7 +125,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
124
125
|
_renamedPlaceholders.has(p.name) || _renamedPlaceholders.has(p.orig))
|
|
125
126
|
|
|
126
127
|
const listPoint = listOp?.points?.[0]
|
|
127
|
-
const listPath = listPoint ? normalizePathParams(listPoint
|
|
128
|
+
const listPath = listPoint ? normalizePathParams(pointParts(listPoint), listPoint?.args?.params || [], listPoint?.rename?.param) : ''
|
|
128
129
|
const listParams = listPoint?.args?.params || []
|
|
129
130
|
|
|
130
131
|
// Required query params with spec-provided examples — needed in live mode.
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
import {
|
|
31
|
-
clean,
|
|
32
31
|
formatPyDict,
|
|
33
32
|
} from './utility_py'
|
|
34
33
|
|
|
@@ -180,12 +179,7 @@ ${serverBlock}${authBlock} "headers": ${formatPyDict(headers, 3)},
|
|
|
180
179
|
Content(` },
|
|
181
180
|
},
|
|
182
181
|
"entity": ${formatPyDict(
|
|
183
|
-
|
|
184
|
-
fields: n.fields,
|
|
185
|
-
name: n.name,
|
|
186
|
-
op: n.op,
|
|
187
|
-
relations: n.relations,
|
|
188
|
-
}, true), a), {}), 2)},
|
|
182
|
+
configDef.entity, 2)},
|
|
189
183
|
}
|
|
190
184
|
`)
|
|
191
185
|
})
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
snakify,
|
|
14
14
|
isAuthActive,
|
|
15
15
|
serverVarEnv,
|
|
16
|
-
serverVariables, envName, envToken
|
|
16
|
+
serverVariables, envName, envToken,
|
|
17
|
+
pointParts,
|
|
17
18
|
} from '@voxgig/sdkgen'
|
|
18
19
|
|
|
19
20
|
|
|
@@ -98,7 +99,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
98
99
|
const listOp = entity.op?.list
|
|
99
100
|
|
|
100
101
|
const loadPoint = loadOp?.points?.[0]
|
|
101
|
-
const loadPath = loadPoint ? normalizePathParams(loadPoint
|
|
102
|
+
const loadPath = loadPoint ? normalizePathParams(pointParts(loadPoint), loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
102
103
|
const allLoadParams = loadPoint?.args?.params || []
|
|
103
104
|
// Some upstream OpenAPI specs declare a parameter as `in: path` even when
|
|
104
105
|
// that path has no `{name}` placeholder for it. Only path params that
|
|
@@ -106,7 +107,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
106
107
|
// setup and URL-substitution asserts; otherwise the SDK silently drops
|
|
107
108
|
// them and the URL-includes assert fails.
|
|
108
109
|
const _pathPlaceholders = new Set<string>()
|
|
109
|
-
for (const part of (loadPoint
|
|
110
|
+
for (const part of pointParts(loadPoint)) {
|
|
110
111
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
111
112
|
_pathPlaceholders.add(part.slice(1, -1))
|
|
112
113
|
}
|
|
@@ -123,7 +124,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
123
124
|
_renamedPlaceholders.has(p.name) || _renamedPlaceholders.has(p.orig))
|
|
124
125
|
|
|
125
126
|
const listPoint = listOp?.points?.[0]
|
|
126
|
-
const listPath = listPoint ? normalizePathParams(listPoint
|
|
127
|
+
const listPath = listPoint ? normalizePathParams(pointParts(listPoint), listPoint?.args?.params || [], listPoint?.rename?.param) : ''
|
|
127
128
|
const listParams = listPoint?.args?.params || []
|
|
128
129
|
|
|
129
130
|
// Required query params with spec-provided examples — needed in live mode
|
|
@@ -29,7 +29,6 @@ import {
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
|
-
clean,
|
|
33
32
|
formatRubyHash,
|
|
34
33
|
} from './utility_rb'
|
|
35
34
|
|
|
@@ -165,12 +164,7 @@ ${serverBlock}${authBlock} "headers" => ${formatRubyHash(headers, 4)},
|
|
|
165
164
|
Content(` },
|
|
166
165
|
},
|
|
167
166
|
"entity" => ${formatRubyHash(
|
|
168
|
-
|
|
169
|
-
fields: n.fields,
|
|
170
|
-
name: n.name,
|
|
171
|
-
op: n.op,
|
|
172
|
-
relations: n.relations,
|
|
173
|
-
}, true), a), {}), 3)},
|
|
167
|
+
configDef.entity, 3)},
|
|
174
168
|
}
|
|
175
169
|
end
|
|
176
170
|
`)
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
snakify,
|
|
14
14
|
isAuthActive, envName, envToken,
|
|
15
15
|
serverVarEnv,
|
|
16
|
-
serverVariables
|
|
16
|
+
serverVariables,
|
|
17
|
+
pointParts,
|
|
17
18
|
} from '@voxgig/sdkgen'
|
|
18
19
|
|
|
19
20
|
import { formatRubyValue } from './utility_rb'
|
|
@@ -99,7 +100,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
99
100
|
const listOp = entity.op?.list
|
|
100
101
|
|
|
101
102
|
const loadPoint = loadOp?.points?.[0]
|
|
102
|
-
const loadPath = loadPoint ? normalizePathParams(loadPoint
|
|
103
|
+
const loadPath = loadPoint ? normalizePathParams(pointParts(loadPoint), loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
103
104
|
const allLoadParams = loadPoint?.args?.params || []
|
|
104
105
|
// Some upstream OpenAPI specs declare a parameter as `in: path` even when
|
|
105
106
|
// that path has no `{name}` placeholder for it. Only path params that
|
|
@@ -107,7 +108,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
107
108
|
// setup and URL-substitution asserts; otherwise the SDK silently drops
|
|
108
109
|
// them and the URL-includes assert fails.
|
|
109
110
|
const _pathPlaceholders = new Set<string>()
|
|
110
|
-
for (const part of (loadPoint
|
|
111
|
+
for (const part of pointParts(loadPoint)) {
|
|
111
112
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
112
113
|
_pathPlaceholders.add(part.slice(1, -1))
|
|
113
114
|
}
|
|
@@ -124,7 +125,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
124
125
|
_renamedPlaceholders.has(p.name) || _renamedPlaceholders.has(p.orig))
|
|
125
126
|
|
|
126
127
|
const listPoint = listOp?.points?.[0]
|
|
127
|
-
const listPath = listPoint ? normalizePathParams(listPoint
|
|
128
|
+
const listPath = listPoint ? normalizePathParams(pointParts(listPoint), listPoint?.args?.params || [], listPoint?.rename?.param) : ''
|
|
128
129
|
const listParams = listPoint?.args?.params || []
|
|
129
130
|
|
|
130
131
|
// Required query params with spec-provided examples — needed in live mode.
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
snakify,
|
|
14
14
|
isAuthActive, envName, envToken,
|
|
15
15
|
serverVarEnv,
|
|
16
|
-
serverVariables
|
|
16
|
+
serverVariables,
|
|
17
|
+
pointParts,
|
|
17
18
|
} from '@voxgig/sdkgen'
|
|
18
19
|
|
|
19
20
|
|
|
@@ -104,12 +105,12 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
104
105
|
|
|
105
106
|
// Load point info.
|
|
106
107
|
const loadPoint = loadOp?.points?.[0]
|
|
107
|
-
const loadPath = loadPoint ? normalizePathParams(loadPoint
|
|
108
|
+
const loadPath = loadPoint ? normalizePathParams(pointParts(loadPoint), loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
108
109
|
const allLoadParams = loadPoint?.args?.params || []
|
|
109
110
|
// Only path params that actually appear in the URL template drive the
|
|
110
111
|
// direct-test path-param setup and URL-substitution asserts.
|
|
111
112
|
const _pathPlaceholders = new Set<string>()
|
|
112
|
-
for (const part of (loadPoint
|
|
113
|
+
for (const part of pointParts(loadPoint)) {
|
|
113
114
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
114
115
|
_pathPlaceholders.add(part.slice(1, -1))
|
|
115
116
|
}
|
|
@@ -127,7 +128,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
127
128
|
|
|
128
129
|
// List point info.
|
|
129
130
|
const listPoint = listOp?.points?.[0]
|
|
130
|
-
const listPath = listPoint ? normalizePathParams(listPoint
|
|
131
|
+
const listPath = listPoint ? normalizePathParams(pointParts(listPoint), listPoint?.args?.params || [], listPoint?.rename?.param) : ''
|
|
131
132
|
const listParams = listPoint?.args?.params || []
|
|
132
133
|
|
|
133
134
|
const entidEnvVar = `${PROJECTNAME}_TEST_${envToken(entity.name)}_ENTID`
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
isAuthActive,
|
|
8
8
|
resolveAuthPrefix,
|
|
9
9
|
targetFeatures,
|
|
10
|
+
configDefinition,
|
|
10
11
|
} from '@voxgig/sdkgen'
|
|
11
12
|
|
|
12
13
|
|
|
@@ -36,6 +37,7 @@ const Config = cmp(async function Config(props: any) {
|
|
|
36
37
|
const scalapackage = scalaPackage(model)
|
|
37
38
|
|
|
38
39
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
40
|
+
const { def: configDef } = configDefinition(model, target.name)
|
|
39
41
|
// Gated by the applicability tags, so this target never imports or
|
|
40
42
|
// registers a feature it has no source for. One rule, one place:
|
|
41
43
|
// helpers/applicability.
|
|
@@ -68,13 +70,13 @@ const Config = cmp(async function Config(props: any) {
|
|
|
68
70
|
options.headers = headers
|
|
69
71
|
options.entity = optionsEntity
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
// configDefinition's `def.entity` verbatim, NOT rebuilt here. This reduce
|
|
74
|
+
// was one of fourteen copies of that function's entityDefs loop, and when
|
|
75
|
+
// configDefinition started reconstructing a point's `parts` from apidef's
|
|
76
|
+
// segment vector (its ADR-003), only the copies that read `configDef` got
|
|
77
|
+
// it — this target's literal config emitted paths with no parts at all
|
|
78
|
+
// while its data config had them. One rule, one place.
|
|
79
|
+
const entityConfig = configDef.entity
|
|
78
80
|
|
|
79
81
|
const config = {
|
|
80
82
|
main: { name: model.const.Name },
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
File,
|
|
12
12
|
cmp,
|
|
13
13
|
snakify,
|
|
14
|
+
pointParts,
|
|
14
15
|
} from '@voxgig/sdkgen'
|
|
15
16
|
|
|
16
17
|
|
|
@@ -79,13 +80,13 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
79
80
|
// Load point info.
|
|
80
81
|
const loadPoint = loadOp?.points?.[0]
|
|
81
82
|
const loadPath = loadPoint
|
|
82
|
-
? normalizePathParams(loadPoint
|
|
83
|
+
? normalizePathParams(pointParts(loadPoint), loadPoint?.args?.params || [], loadPoint?.rename?.param)
|
|
83
84
|
: ''
|
|
84
85
|
const allLoadParams = loadPoint?.args?.params || []
|
|
85
86
|
// Only path params that actually appear in the URL template drive the
|
|
86
87
|
// direct-test path-param setup and URL-substitution asserts.
|
|
87
88
|
const _pathPlaceholders = new Set<string>()
|
|
88
|
-
for (const part of (loadPoint
|
|
89
|
+
for (const part of pointParts(loadPoint)) {
|
|
89
90
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
90
91
|
_pathPlaceholders.add(part.slice(1, -1))
|
|
91
92
|
}
|
|
@@ -104,7 +105,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
104
105
|
// List point info.
|
|
105
106
|
const listPoint = listOp?.points?.[0]
|
|
106
107
|
const listPath = listPoint
|
|
107
|
-
? normalizePathParams(listPoint
|
|
108
|
+
? normalizePathParams(pointParts(listPoint), listPoint?.args?.params || [], listPoint?.rename?.param)
|
|
108
109
|
: ''
|
|
109
110
|
const listParams = listPoint?.args?.params || []
|
|
110
111
|
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
cmp, each,
|
|
3
3
|
File, Content, Folder,
|
|
4
4
|
jsKey, jsProp,
|
|
5
|
+
pointSegments,
|
|
5
6
|
} from '@voxgig/sdkgen'
|
|
6
7
|
|
|
7
8
|
|
|
@@ -22,7 +23,8 @@ import {
|
|
|
22
23
|
function loadHasKey(ent: any): boolean {
|
|
23
24
|
const point = (ent.op && ent.op.load && ent.op.load.points || [])[0]
|
|
24
25
|
if (null == point) return false
|
|
25
|
-
|
|
26
|
+
// apidef states which segments are variables (its ADR-003) — no brace test.
|
|
27
|
+
const hasPathParam = pointSegments(point).some((seg: any) => null != seg.var)
|
|
26
28
|
const hasQueryParam = (point.args && point.args.query || [])
|
|
27
29
|
.some((q: any) => false !== q.reqd)
|
|
28
30
|
return hasPathParam || hasQueryParam
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
authorInfo, contributorList, isAuthActive, isHttpBasicAuth, jsKey, jsProp,
|
|
8
8
|
SdkGenError,
|
|
9
9
|
PUBLISHER, PUBLISHER_URL,
|
|
10
|
+
pointSegments,
|
|
10
11
|
} from '@voxgig/sdkgen'
|
|
11
12
|
|
|
12
13
|
import {
|
|
@@ -102,11 +103,14 @@ function recordKey(ent: any): string {
|
|
|
102
103
|
const canonical = op.points.filter((pt: any) =>
|
|
103
104
|
null == (pt && pt.select && pt.select['$action']))
|
|
104
105
|
const point = ownPoint(0 < canonical.length ? canonical : op.points)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
// The LAST variable segment names the record's key. apidef states which
|
|
107
|
+
// segments are variables (its ADR-003), so this reads the name off the
|
|
108
|
+
// vector rather than finding a `{` and slicing the braces back off.
|
|
109
|
+
const vars = pointSegments(point)
|
|
110
|
+
.filter((seg: any) => null != seg.var)
|
|
111
|
+
|
|
112
|
+
if (0 < vars.length) {
|
|
113
|
+
return String(vars[vars.length - 1].var)
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
// No path param at all (e.g. GET /scan/async/result?trace_id=...): the
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
Fragment,
|
|
9
9
|
Line,
|
|
10
10
|
cmp,
|
|
11
|
-
clean,
|
|
12
11
|
configDefinition,
|
|
13
12
|
configReprSetting,
|
|
14
13
|
each,
|
|
@@ -170,13 +169,13 @@ const Config = cmp(async function Config(props: any) {
|
|
|
170
169
|
`)
|
|
171
170
|
}),
|
|
172
171
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
172
|
+
// configDefinition's `def.entity` verbatim, NOT rebuilt here. This
|
|
173
|
+
// reduce was a second copy of that function's entityDefs loop, and
|
|
174
|
+
// when configDefinition started reconstructing a point's `parts`
|
|
175
|
+
// from apidef's segment vector (its ADR-003), only the data
|
|
176
|
+
// representation got it — the literal one emitted empty paths. The
|
|
177
|
+
// config-repr equivalence test caught it, which is what it is for.
|
|
178
|
+
"'ENTITYMAP'": formatJson(configDef.entity, { margin: 2 }).trim(),
|
|
180
179
|
}
|
|
181
180
|
})
|
|
182
181
|
})
|
|
@@ -22,7 +22,8 @@ import {
|
|
|
22
22
|
isHttpBasicAuth,
|
|
23
23
|
jsProp,
|
|
24
24
|
jsOptProp, envName, envToken, liveStrict,
|
|
25
|
-
jsKey
|
|
25
|
+
jsKey,
|
|
26
|
+
pointParts,
|
|
26
27
|
} from '@voxgig/sdkgen'
|
|
27
28
|
|
|
28
29
|
|
|
@@ -295,7 +296,7 @@ function generateDirectLoad(model: Model, entity: ModelEntity, strict: boolean)
|
|
|
295
296
|
}
|
|
296
297
|
|
|
297
298
|
const allLoadParams = loadPoint.args?.params || []
|
|
298
|
-
const loadPath = normalizePathParams(loadPoint
|
|
299
|
+
const loadPath = normalizePathParams(pointParts(loadPoint), allLoadParams, loadPoint.rename?.param)
|
|
299
300
|
|
|
300
301
|
// Some upstream OpenAPI specs declare a parameter as `in: path` even when
|
|
301
302
|
// that path has no `{name}` placeholder for it. Only path params that
|
|
@@ -303,7 +304,7 @@ function generateDirectLoad(model: Model, entity: ModelEntity, strict: boolean)
|
|
|
303
304
|
// setup and URL-substitution asserts; otherwise the SDK silently drops
|
|
304
305
|
// them and the URL-includes assert fails.
|
|
305
306
|
const pathPlaceholders = new Set<string>()
|
|
306
|
-
for (const part of (loadPoint
|
|
307
|
+
for (const part of pointParts(loadPoint)) {
|
|
307
308
|
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
308
309
|
pathPlaceholders.add(part.slice(1, -1))
|
|
309
310
|
}
|
|
@@ -337,7 +338,7 @@ function generateDirectLoad(model: Model, entity: ModelEntity, strict: boolean)
|
|
|
337
338
|
const listOp = entity.op?.list
|
|
338
339
|
const listPoint = listOp?.points?.[0]
|
|
339
340
|
const listParams = listPoint?.args?.params || []
|
|
340
|
-
const listPath = listPoint ? normalizePathParams(listPoint
|
|
341
|
+
const listPath = listPoint ? normalizePathParams(pointParts(listPoint), listParams, listPoint.rename?.param) : ''
|
|
341
342
|
const hasList = null != listPoint
|
|
342
343
|
|
|
343
344
|
// Ancestor params (not 'id') for live mode
|
|
@@ -530,7 +531,7 @@ function generateDirectList(model: Model, entity: ModelEntity, strict: boolean)
|
|
|
530
531
|
}
|
|
531
532
|
|
|
532
533
|
const listParams = listPoint.args?.params || []
|
|
533
|
-
const listPath = normalizePathParams(listPoint
|
|
534
|
+
const listPath = normalizePathParams(pointParts(listPoint), listParams, listPoint.rename?.param)
|
|
534
535
|
|
|
535
536
|
// Required query params with spec-provided examples — needed to satisfy
|
|
536
537
|
// the API contract in live mode (see generateDirectLoad for rationale).
|
package/src/helpers/opShape.ts
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
import { each, names } from 'jostraca'
|
|
30
30
|
import { KIT, getModelPath } from '@voxgig/apidef'
|
|
31
31
|
|
|
32
|
+
import { pointSegments, pointTerminalParam, pointPathKey } from './pointPath'
|
|
33
|
+
|
|
32
34
|
|
|
33
35
|
// THE entity collection for a model — resolved once, with a stable identity.
|
|
34
36
|
//
|
|
@@ -217,25 +219,19 @@ function entityPath(entity: any): string {
|
|
|
217
219
|
// no point's `select.exist` matches. It cannot be shared with them — a
|
|
218
220
|
// template ships standalone, outside this package — so it is written twice on
|
|
219
221
|
// purpose, and both sides must move together.
|
|
220
|
-
function terminalParam(point: any): boolean {
|
|
221
|
-
const parts: any[] = (point && point.parts) || []
|
|
222
|
-
const last = 0 < parts.length ? parts[parts.length - 1] : ''
|
|
223
|
-
return 'string' === typeof last && last.startsWith('{')
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
222
|
function ownPoint(points: any[]): any {
|
|
228
223
|
let best = points[0]
|
|
229
224
|
|
|
230
225
|
for (const pt of points) {
|
|
231
|
-
if (null == pt || null == pt.
|
|
226
|
+
if (null == pt || null == pt.segments || null == best || null == best.segments) {
|
|
232
227
|
continue
|
|
233
228
|
}
|
|
234
229
|
|
|
235
|
-
const ptterm =
|
|
236
|
-
const bestterm =
|
|
230
|
+
const ptterm = pointTerminalParam(pt)
|
|
231
|
+
const bestterm = pointTerminalParam(best)
|
|
237
232
|
|
|
238
|
-
if (ptterm !== bestterm ?
|
|
233
|
+
if (ptterm !== bestterm ?
|
|
234
|
+
ptterm : pointSegments(pt).length < pointSegments(best).length) {
|
|
239
235
|
best = pt
|
|
240
236
|
}
|
|
241
237
|
}
|
|
@@ -248,10 +244,9 @@ function ownPoint(points: any[]): any {
|
|
|
248
244
|
// selectors on one endpoint (the same path, chosen by different query
|
|
249
245
|
// params), not cross-references to different resources.
|
|
250
246
|
function samePath(points: any[]): boolean {
|
|
251
|
-
const first = (
|
|
247
|
+
const first = pointPathKey(points[0])
|
|
252
248
|
|
|
253
|
-
return points.every((pt: any) =>
|
|
254
|
-
first === ((pt && pt.parts) || []).join('/'))
|
|
249
|
+
return points.every((pt: any) => first === pointPathKey(pt))
|
|
255
250
|
}
|
|
256
251
|
|
|
257
252
|
|