@di-framework/tsc 4.2.1 → 4.2.2

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 (2) hide show
  1. package/package.json +1 -1
  2. package/plugin/main.go +49 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@di-framework/tsc",
3
- "version": "4.2.1",
3
+ "version": "4.2.2",
4
4
  "description": "ttsc transform that injects runtime parameter checks from TypeScript types (assertAll)",
5
5
  "author": "@di-framework Contributors",
6
6
  "license": "(MIT OR Apache-2.0)",
package/plugin/main.go CHANGED
@@ -31,6 +31,12 @@ type transformResult struct {
31
31
  TypeScript map[string]string `json:"typescript"`
32
32
  }
33
33
 
34
+ type tsconfigFile struct {
35
+ CompilerOptions struct {
36
+ RootDir string `json:"rootDir"`
37
+ } `json:"compilerOptions"`
38
+ }
39
+
34
40
  func main() {
35
41
  os.Exit(run(os.Args[1:]))
36
42
  }
@@ -67,7 +73,7 @@ func runTransform(args []string) int {
67
73
  }
68
74
  defer prog.Close()
69
75
 
70
- injectProgram(prog)
76
+ injectProgram(prog, projectRoot(opts))
71
77
 
72
78
  // Host treats typescript[path] as opaque text — print the mutated AST.
73
79
  printer := shimprinter.NewPrinter(
@@ -102,7 +108,7 @@ func runBuild(args []string) int {
102
108
  }
103
109
  defer prog.Close()
104
110
 
105
- injectProgram(prog)
111
+ injectProgram(prog, projectRoot(opts))
106
112
  if opts.noEmit {
107
113
  return 0
108
114
  }
@@ -143,10 +149,28 @@ func loadProgram(opts options) (*driver.Program, bool) {
143
149
  return prog, true
144
150
  }
145
151
 
146
- func injectProgram(prog *driver.Program) {
152
+ func projectRoot(opts options) string {
153
+ root := opts.cwd
154
+ data, err := os.ReadFile(opts.tsconfig)
155
+ if err != nil {
156
+ return root
157
+ }
158
+ var config tsconfigFile
159
+ if json.Unmarshal(data, &config) != nil || config.CompilerOptions.RootDir == "" {
160
+ return root
161
+ }
162
+ return filepath.Clean(filepath.Join(filepath.Dir(opts.tsconfig), config.CompilerOptions.RootDir))
163
+ }
164
+
165
+ func isWithinRoot(fileName string, root string) bool {
166
+ rel, err := filepath.Rel(root, fileName)
167
+ return err == nil && rel != ".." && !strings.HasPrefix(rel, ".."+string(filepath.Separator))
168
+ }
169
+
170
+ func injectProgram(prog *driver.Program, root string) {
147
171
  factory := shimast.NewNodeFactory(shimast.NodeFactoryHooks{})
148
172
  for _, file := range prog.SourceFiles() {
149
- if file == nil || file.IsDeclarationFile {
173
+ if file == nil || file.IsDeclarationFile || !isWithinRoot(file.FileName(), root) {
150
174
  continue
151
175
  }
152
176
  injectFile(factory, file, prog.Checker)
@@ -262,6 +286,22 @@ func stmtsFromCheckerType(
262
286
  path string,
263
287
  t *shimchecker.Type,
264
288
  ) []*shimast.Node {
289
+ return stmtsFromCheckerTypeSeen(factory, checker, path, t, make(map[*shimchecker.Type]bool), 0)
290
+ }
291
+
292
+ func stmtsFromCheckerTypeSeen(
293
+ factory *shimast.NodeFactory,
294
+ checker *shimchecker.Checker,
295
+ path string,
296
+ t *shimchecker.Type,
297
+ seen map[*shimchecker.Type]bool,
298
+ depth int,
299
+ ) []*shimast.Node {
300
+ // Platform and application interfaces can be recursive. Runtime guards are
301
+ // deliberately bounded so a cyclic type graph cannot make compilation hang.
302
+ if depth > 8 || seen[t] {
303
+ return nil
304
+ }
265
305
  flags := t.Flags()
266
306
  switch {
267
307
  case flags&shimchecker.TypeFlagsString != 0:
@@ -273,6 +313,8 @@ func stmtsFromCheckerType(
273
313
  case flags&shimchecker.TypeFlagsBigInt != 0:
274
314
  return []*shimast.Node{typeofCheck(factory, path, "bigint")}
275
315
  case flags&shimchecker.TypeFlagsObject != 0:
316
+ seen[t] = true
317
+ defer delete(seen, t)
276
318
  props := shimchecker.Checker_getApparentProperties(checker, t)
277
319
  if len(props) == 0 {
278
320
  return nil
@@ -293,11 +335,13 @@ func stmtsFromCheckerType(
293
335
  if propType == nil {
294
336
  continue
295
337
  }
296
- out = append(out, stmtsFromCheckerType(
338
+ out = append(out, stmtsFromCheckerTypeSeen(
297
339
  factory,
298
340
  checker,
299
341
  path+"."+propName,
300
342
  propType,
343
+ seen,
344
+ depth+1,
301
345
  )...)
302
346
  }
303
347
  return out