@voxgig/sdkgen 0.45.0 → 1.1.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.
Files changed (65) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/package.json +3 -3
  3. package/project/.sdk/src/cmp/go/Entity_go.ts +2 -2
  4. package/project/.sdk/src/cmp/go/Main_go.ts +8 -4
  5. package/project/.sdk/src/cmp/go/Package_go.ts +2 -2
  6. package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +2 -2
  7. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +2 -2
  8. package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +2 -2
  9. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +2 -2
  10. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +2 -2
  11. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +2 -2
  12. package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +2 -2
  13. package/project/.sdk/src/cmp/go/TestDirect_go.ts +204 -33
  14. package/project/.sdk/src/cmp/go/TestEntity_go.ts +37 -6
  15. package/project/.sdk/src/cmp/go/Test_go.ts +2 -2
  16. package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +21 -4
  17. package/project/.sdk/src/cmp/lua/Package_lua.ts +9 -2
  18. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +154 -21
  19. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +25 -1
  20. package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +20 -4
  21. package/project/.sdk/src/cmp/php/Package_php.ts +7 -1
  22. package/project/.sdk/src/cmp/php/TestDirect_php.ts +153 -20
  23. package/project/.sdk/src/cmp/php/TestEntity_php.ts +25 -1
  24. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +17 -3
  25. package/project/.sdk/src/cmp/py/Package_py.ts +8 -1
  26. package/project/.sdk/src/cmp/py/TestDirect_py.ts +146 -19
  27. package/project/.sdk/src/cmp/py/TestEntity_py.ts +25 -1
  28. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -4
  29. package/project/.sdk/src/cmp/rb/Package_rb.ts +9 -2
  30. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +154 -21
  31. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +25 -1
  32. package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +19 -3
  33. package/project/.sdk/src/cmp/ts/Package_ts.ts +1 -1
  34. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +145 -22
  35. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +59 -1
  36. package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +8 -1
  37. package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +8 -2
  38. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +21 -1
  39. package/project/.sdk/tm/go/feature/test_feature.go +56 -3
  40. package/project/.sdk/tm/go/test/runner_test.go +106 -6
  41. package/project/.sdk/tm/go/test/sdk-test-control.json +19 -0
  42. package/project/.sdk/tm/go/utility/fetcher.go +10 -0
  43. package/project/.sdk/tm/go/utility/make_url.go +12 -0
  44. package/project/.sdk/tm/lua/feature/test_feature.lua +46 -3
  45. package/project/.sdk/tm/lua/test/runner.lua +74 -0
  46. package/project/.sdk/tm/lua/test/sdk-test-control.json +19 -0
  47. package/project/.sdk/tm/lua/utility/fetcher.lua +13 -0
  48. package/project/.sdk/tm/lua/utility/make_url.lua +16 -0
  49. package/project/.sdk/tm/php/feature/TestFeature.php +192 -43
  50. package/project/.sdk/tm/php/test/Runner.php +62 -0
  51. package/project/.sdk/tm/php/test/sdk-test-control.json +19 -0
  52. package/project/.sdk/tm/php/utility/Fetcher.php +132 -9
  53. package/project/.sdk/tm/php/utility/MakeUrl.php +16 -0
  54. package/project/.sdk/tm/py/feature/test_feature.py +39 -3
  55. package/project/.sdk/tm/py/test/runner.py +60 -0
  56. package/project/.sdk/tm/py/test/sdk-test-control.json +19 -0
  57. package/project/.sdk/tm/py/utility/fetcher.py +13 -0
  58. package/project/.sdk/tm/py/utility/make_url.py +13 -0
  59. package/project/.sdk/tm/rb/feature/test_feature.rb +37 -3
  60. package/project/.sdk/tm/rb/test/runner.rb +46 -0
  61. package/project/.sdk/tm/rb/test/sdk-test-control.json +19 -0
  62. package/project/.sdk/tm/rb/utility/fetcher.rb +49 -28
  63. package/project/.sdk/tm/rb/utility/make_url.rb +16 -0
  64. package/project/.sdk/tm/ts/test/sdk-test-control.json +19 -0
  65. package/project/.sdk/tm/ts/test/utility.ts +120 -2
@@ -71,12 +71,112 @@ func envOverride(m map[string]any) map[string]any {
71
71
  }
72
72
 
73
73
  type entityTestSetup struct {
74
- client *sdk.ProjectNameSDK
75
- data map[string]any
76
- idmap map[string]any
77
- env map[string]any
78
- explain bool
79
- now int64
74
+ client *sdk.ProjectNameSDK
75
+ data map[string]any
76
+ idmap map[string]any
77
+ env map[string]any
78
+ explain bool
79
+ live bool
80
+ syntheticOnly bool
81
+ now int64
82
+ }
83
+
84
+ var (
85
+ cachedTestControl map[string]any
86
+ cachedTestControlOnce sync.Once
87
+ )
88
+
89
+ // loadTestControl reads sdk-test-control.json from this test dir; caches
90
+ // after first read. Returns an empty-skip default if the file is missing
91
+ // or invalid so tests never crash on a bad config.
92
+ func loadTestControl() map[string]any {
93
+ cachedTestControlOnce.Do(func() {
94
+ _, filename, _, _ := runtime.Caller(0)
95
+ dir := filepath.Dir(filename)
96
+ ctrlPath := filepath.Join(dir, "sdk-test-control.json")
97
+ def := map[string]any{
98
+ "version": 1,
99
+ "test": map[string]any{"skip": map[string]any{
100
+ "live": map[string]any{"direct": []any{}, "entityOp": []any{}},
101
+ "unit": map[string]any{"direct": []any{}, "entityOp": []any{}},
102
+ }},
103
+ }
104
+ data, err := os.ReadFile(ctrlPath)
105
+ if err != nil {
106
+ cachedTestControl = def
107
+ return
108
+ }
109
+ var parsed map[string]any
110
+ if err := json.Unmarshal(data, &parsed); err != nil {
111
+ cachedTestControl = def
112
+ return
113
+ }
114
+ cachedTestControl = parsed
115
+ })
116
+ return cachedTestControl
117
+ }
118
+
119
+ // isControlSkipped checks sdk-test-control.json for a skip entry.
120
+ // Returns (skip, reason).
121
+ func isControlSkipped(kind, name, mode string) (bool, string) {
122
+ ctrl := loadTestControl()
123
+ test, _ := ctrl["test"].(map[string]any)
124
+ if test == nil {
125
+ return false, ""
126
+ }
127
+ skip, _ := test["skip"].(map[string]any)
128
+ if skip == nil {
129
+ return false, ""
130
+ }
131
+ modeMap, _ := skip[mode].(map[string]any)
132
+ if modeMap == nil {
133
+ return false, ""
134
+ }
135
+ items, _ := modeMap[kind].([]any)
136
+ for _, raw := range items {
137
+ item, _ := raw.(map[string]any)
138
+ if item == nil {
139
+ continue
140
+ }
141
+ reason, _ := item["reason"].(string)
142
+ if kind == "direct" {
143
+ if t, _ := item["test"].(string); t == name {
144
+ return true, reason
145
+ }
146
+ }
147
+ if kind == "entityOp" {
148
+ ent, _ := item["entity"].(string)
149
+ op, _ := item["op"].(string)
150
+ if ent+"."+op == name {
151
+ return true, reason
152
+ }
153
+ }
154
+ }
155
+ return false, ""
156
+ }
157
+
158
+ // liveDelayMs returns the configured per-test live delay in ms; default 500.
159
+ func liveDelayMs() int {
160
+ ctrl := loadTestControl()
161
+ test, _ := ctrl["test"].(map[string]any)
162
+ if test == nil {
163
+ return 500
164
+ }
165
+ live, _ := test["live"].(map[string]any)
166
+ if live == nil {
167
+ return 500
168
+ }
169
+ switch v := live["delayMs"].(type) {
170
+ case float64:
171
+ if v >= 0 {
172
+ return int(v)
173
+ }
174
+ case int:
175
+ if v >= 0 {
176
+ return v
177
+ }
178
+ }
179
+ return 500
80
180
  }
81
181
 
82
182
  var cachedTestSpec map[string]any
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": 1,
3
+ "_doc": "Per-SDK test control. Lists tests/operations to skip in unit and live modes; tunes per-test pacing. Edit by hand. Loaded by go test runner.",
4
+ "test": {
5
+ "skip": {
6
+ "live": {
7
+ "direct": [],
8
+ "entityOp": []
9
+ },
10
+ "unit": {
11
+ "direct": [],
12
+ "entityOp": []
13
+ }
14
+ },
15
+ "live": {
16
+ "delayMs": 500
17
+ }
18
+ }
19
+ }
@@ -27,13 +27,23 @@ func defaultHTTPFetch(fullurl string, fetchdef map[string]any) (map[string]any,
27
27
  return nil, err
28
28
  }
29
29
 
30
+ hasUA := false
30
31
  if headers, ok := fetchdef["headers"].(map[string]any); ok {
31
32
  for k, v := range headers {
32
33
  if sv, ok := v.(string); ok {
34
+ if strings.EqualFold(k, "user-agent") {
35
+ hasUA = true
36
+ }
33
37
  req.Header.Set(k, sv)
34
38
  }
35
39
  }
36
40
  }
41
+ // Default User-Agent — Go's net/http defaults to "Go-http-client/1.1"
42
+ // which some CDNs block. Use a Mozilla-shaped UA unless the caller
43
+ // already set one.
44
+ if !hasUA {
45
+ req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; ProjectNameSDK/1.0)")
46
+ }
37
47
 
38
48
  resp, err := http.DefaultClient.Do(req)
39
49
  if err != nil {
@@ -35,6 +35,18 @@ func makeUrlUtil(ctx *core.Context) (string, error) {
35
35
  }
36
36
  }
37
37
 
38
+ // Append query string from spec.Query.
39
+ qsep := "?"
40
+ for _, item := range vs.Items(spec.Query) {
41
+ key, _ := item[0].(string)
42
+ val := item[1]
43
+ if val != nil {
44
+ url += qsep + vs.EscUrl(key) + "=" + vs.EscUrl(vs.Stringify(val))
45
+ qsep = "&"
46
+ resmatch[key] = val
47
+ }
48
+ }
49
+
38
50
  result.Resmatch = resmatch
39
51
 
40
52
  return url, nil
@@ -62,8 +62,27 @@ function TestFeature:init(ctx, options)
62
62
  entmap = {}
63
63
  end
64
64
 
65
+ -- For single-entity ops (load, remove) with an empty explicit match, fall
66
+ -- back to the id the entity client already knows from a prior create/load
67
+ -- (in fctx.match / fctx.data). Mirrors the TS mock where param() resolves
68
+ -- the id from that accumulated state.
69
+ local function resolve_match(explicit)
70
+ if type(explicit) == "table" and next(explicit) ~= nil then
71
+ return explicit
72
+ end
73
+ local function id_of(src)
74
+ if src == nil then return nil end
75
+ local v = vs.getprop(src, "id")
76
+ if v ~= nil and v ~= "__UNDEFINED__" then return v end
77
+ return nil
78
+ end
79
+ local v = id_of(fctx.match) or id_of(fctx.data)
80
+ if v ~= nil then return { id = v } end
81
+ return {}
82
+ end
83
+
65
84
  if op.name == "load" then
66
- local args = test_self:build_args(fctx, op, fctx.reqmatch)
85
+ local args = test_self:build_args(fctx, op, resolve_match(fctx.reqmatch))
67
86
  local found = vs.select(entmap, args)
68
87
  local ent = vs.getelem(found, 0)
69
88
  if ent == nil then
@@ -88,9 +107,33 @@ function TestFeature:init(ctx, options)
88
107
  return respond(200, out, nil)
89
108
 
90
109
  elseif op.name == "update" then
91
- local args = test_self:build_args(fctx, op, fctx.reqdata)
110
+ -- Match the existing entity by id only (or its alias). reqdata also
111
+ -- contains the new field values, which would otherwise cause select
112
+ -- to filter out the entity we want to update. When reqdata has no id,
113
+ -- fall back to the id the entity client carries from a prior
114
+ -- create/load (in fctx.match / fctx.data), mirroring the TS mock
115
+ -- where param(ctx,'id') resolves from accumulated state.
116
+ local update_match = {}
117
+ if type(fctx.reqdata) == "table" then
118
+ if fctx.reqdata["id"] ~= nil then update_match["id"] = fctx.reqdata["id"] end
119
+ if op.alias_map ~= nil then
120
+ local alias_id = vs.getprop(op.alias_map, "id")
121
+ if alias_id ~= nil and fctx.reqdata[alias_id] ~= nil then
122
+ update_match[alias_id] = fctx.reqdata[alias_id]
123
+ end
124
+ end
125
+ end
126
+ if next(update_match) == nil then
127
+ update_match = resolve_match({})
128
+ end
129
+ local args = test_self:build_args(fctx, op, update_match)
92
130
  local found = vs.select(entmap, args)
93
131
  local ent = vs.getelem(found, 0)
132
+ if ent == nil and type(entmap) == "table" then
133
+ for _, e in pairs(entmap) do
134
+ if type(e) == "table" then ent = e; break end
135
+ end
136
+ end
94
137
  if ent == nil then
95
138
  return respond(404, nil, { statusText = "Not found" })
96
139
  end
@@ -107,7 +150,7 @@ function TestFeature:init(ctx, options)
107
150
  return respond(200, out, nil)
108
151
 
109
152
  elseif op.name == "remove" then
110
- local args = test_self:build_args(fctx, op, fctx.reqmatch)
153
+ local args = test_self:build_args(fctx, op, resolve_match(fctx.reqmatch))
111
154
  local found = vs.select(entmap, args)
112
155
  local ent = vs.getelem(found, 0)
113
156
  if ent == nil then
@@ -83,4 +83,78 @@ function runner.entity_list_to_data(list)
83
83
  end
84
84
 
85
85
 
86
+ -- Load sdk-test-control.json from this test dir; cache. Returns an
87
+ -- empty-skip default if the file is missing or invalid.
88
+ runner._test_control = nil
89
+
90
+ function runner.load_test_control()
91
+ if runner._test_control ~= nil then
92
+ return runner._test_control
93
+ end
94
+ local this_dir = debug.getinfo(1, "S").source:match("^@(.+/)") or "./"
95
+ local ctrl_path = this_dir .. "sdk-test-control.json"
96
+ local f = io.open(ctrl_path, "r")
97
+ if f == nil then
98
+ runner._test_control = {
99
+ version = 1,
100
+ test = {
101
+ skip = {
102
+ live = { direct = {}, entityOp = {} },
103
+ unit = { direct = {}, entityOp = {} },
104
+ },
105
+ },
106
+ }
107
+ return runner._test_control
108
+ end
109
+ local content = f:read("*a")
110
+ f:close()
111
+ local parsed = json.decode(content)
112
+ if parsed == nil then
113
+ runner._test_control = {
114
+ version = 1,
115
+ test = {
116
+ skip = {
117
+ live = { direct = {}, entityOp = {} },
118
+ unit = { direct = {}, entityOp = {} },
119
+ },
120
+ },
121
+ }
122
+ else
123
+ runner._test_control = parsed
124
+ end
125
+ return runner._test_control
126
+ end
127
+
128
+
129
+ -- Check sdk-test-control.json for a skip entry. Returns (skip, reason).
130
+ function runner.is_control_skipped(kind, name, mode)
131
+ local ctrl = runner.load_test_control()
132
+ local skip = (((ctrl.test or {}).skip or {})[mode] or {})
133
+ local items = skip[kind] or {}
134
+ for _, item in ipairs(items) do
135
+ if kind == "direct" and item.test == name then
136
+ return true, item.reason
137
+ end
138
+ if kind == "entityOp" then
139
+ local key = (item.entity or "") .. "." .. (item.op or "")
140
+ if key == name then
141
+ return true, item.reason
142
+ end
143
+ end
144
+ end
145
+ return false, nil
146
+ end
147
+
148
+
149
+ -- Per-test live pacing delay (ms); default 500.
150
+ function runner.live_delay_ms()
151
+ local ctrl = runner.load_test_control()
152
+ local v = ((ctrl.test or {}).live or {}).delayMs
153
+ if type(v) == "number" and v >= 0 then
154
+ return v
155
+ end
156
+ return 500
157
+ end
158
+
159
+
86
160
  return runner
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": 1,
3
+ "_doc": "Per-SDK test control. Lists tests/operations to skip in unit and live modes; tunes per-test pacing. Edit by hand. Loaded by lua test runner.",
4
+ "test": {
5
+ "skip": {
6
+ "live": {
7
+ "direct": [],
8
+ "entityOp": []
9
+ },
10
+ "unit": {
11
+ "direct": [],
12
+ "entityOp": []
13
+ }
14
+ },
15
+ "live": {
16
+ "delayMs": 500
17
+ }
18
+ }
19
+ }
@@ -25,6 +25,19 @@ local function default_http_fetch(fullurl, fetchdef)
25
25
  headers["content-length"] = tostring(#body_str)
26
26
  end
27
27
 
28
+ -- Default User-Agent — many CDNs reject requests with no UA. Set a
29
+ -- Mozilla-shaped UA unless the caller already set one.
30
+ local has_ua = false
31
+ for k, _ in pairs(headers) do
32
+ if string.lower(k) == "user-agent" then
33
+ has_ua = true
34
+ break
35
+ end
36
+ end
37
+ if not has_ua then
38
+ headers["User-Agent"] = "Mozilla/5.0 (compatible; ProjectNameSDK/1.0)"
39
+ end
40
+
28
41
  local response_body = {}
29
42
  local res, code, response_headers = http.request({
30
43
  url = fullurl,
@@ -38,6 +38,22 @@ local function make_url_util(ctx)
38
38
  end
39
39
  end
40
40
 
41
+ -- Append query string from spec.query.
42
+ local qsep = "?"
43
+ local query_items = vs.items(spec.query)
44
+ if query_items ~= nil then
45
+ for _, item in ipairs(query_items) do
46
+ local key = item[1]
47
+ local val = item[2]
48
+ if val ~= nil and type(key) == "string" then
49
+ local val_str = type(val) == "string" and val or tostring(val)
50
+ url = url .. qsep .. vs.escurl(key) .. "=" .. vs.escurl(val_str)
51
+ qsep = "&"
52
+ resmatch[key] = val
53
+ end
54
+ end
55
+ end
56
+
41
57
  result.resmatch = resmatch
42
58
 
43
59
  return url, nil