ttsc 0.8.1 → 0.10.0

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 (88) hide show
  1. package/README.md +39 -68
  2. package/cmd/ttsc/api_compile.go +109 -115
  3. package/cmd/ttsc/api_transform.go +54 -51
  4. package/cmd/ttsc/main.go +103 -121
  5. package/driver/program.go +30 -2
  6. package/driver/rewrite.go +126 -9
  7. package/go.mod +2 -0
  8. package/lib/TtscCompiler.js +28 -46
  9. package/lib/TtscCompiler.js.map +1 -1
  10. package/lib/compiler/internal/buildNativeCompiler.js +8 -38
  11. package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
  12. package/lib/compiler/internal/compileProjectInMemory.js +36 -63
  13. package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
  14. package/lib/compiler/internal/project/readProjectConfig.js +108 -60
  15. package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
  16. package/lib/compiler/internal/project/resolveProjectConfig.js +15 -45
  17. package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
  18. package/lib/compiler/internal/resolveBinary.js +10 -40
  19. package/lib/compiler/internal/resolveBinary.js.map +1 -1
  20. package/lib/compiler/internal/resolveEmittedJavaScript.js +21 -48
  21. package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
  22. package/lib/compiler/internal/resolveTsgo.js +14 -44
  23. package/lib/compiler/internal/resolveTsgo.js.map +1 -1
  24. package/lib/compiler/internal/runBuild.d.ts +7 -0
  25. package/lib/compiler/internal/runBuild.js +47 -66
  26. package/lib/compiler/internal/runBuild.js.map +1 -1
  27. package/lib/compiler/internal/runSingleFileEmit.js +18 -48
  28. package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
  29. package/lib/compiler/internal/transformProjectInMemory.js +41 -75
  30. package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
  31. package/lib/launcher/internal/getCompilerVersionText.js +7 -37
  32. package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
  33. package/lib/launcher/internal/prepareExecution.js +48 -69
  34. package/lib/launcher/internal/prepareExecution.js.map +1 -1
  35. package/lib/launcher/internal/runTtsc.js +53 -64
  36. package/lib/launcher/internal/runTtsc.js.map +1 -1
  37. package/lib/launcher/internal/runTtsx.js +328 -57
  38. package/lib/launcher/internal/runTtsx.js.map +1 -1
  39. package/lib/plugin/internal/buildSourcePlugin.d.ts +8 -0
  40. package/lib/plugin/internal/buildSourcePlugin.js +287 -139
  41. package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
  42. package/lib/plugin/internal/loadProjectPlugins.d.ts +2 -0
  43. package/lib/plugin/internal/loadProjectPlugins.js +197 -9
  44. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
  45. package/lib/structures/ITtscCompilerContext.d.ts +16 -3
  46. package/lib/structures/ITtscCompilerResult.d.ts +4 -0
  47. package/lib/structures/ITtscCompilerTransformation.d.ts +2 -0
  48. package/lib/structures/ITtscPluginFactoryContext.d.ts +6 -3
  49. package/lib/structures/ITtscProjectPluginConfig.d.ts +8 -7
  50. package/lib/structures/internal/ITtscParsedProjectConfig.d.ts +2 -0
  51. package/lib/structures/internal/ITtscProjectLocatorOptions.d.ts +2 -0
  52. package/lib/structures/internal/TtscCommonOptions.d.ts +2 -0
  53. package/package.json +9 -14
  54. package/shim/diagnosticwriter/lint.go +8 -0
  55. package/shim/printer/go.mod +5 -0
  56. package/shim/printer/shim.go +23 -0
  57. package/src/TtscCompiler.ts +20 -5
  58. package/src/compiler/internal/buildNativeCompiler.ts +2 -2
  59. package/src/compiler/internal/compileProjectInMemory.ts +21 -16
  60. package/src/compiler/internal/project/readProjectConfig.ts +134 -35
  61. package/src/compiler/internal/project/resolveProjectConfig.ts +2 -2
  62. package/src/compiler/internal/resolveBinary.ts +2 -2
  63. package/src/compiler/internal/resolveEmittedJavaScript.ts +11 -7
  64. package/src/compiler/internal/resolveTsgo.ts +2 -2
  65. package/src/compiler/internal/runBuild.ts +34 -21
  66. package/src/compiler/internal/runSingleFileEmit.ts +3 -3
  67. package/src/compiler/internal/transformProjectInMemory.ts +37 -37
  68. package/src/launcher/internal/getCompilerVersionText.ts +2 -2
  69. package/src/launcher/internal/prepareExecution.ts +14 -4
  70. package/src/launcher/internal/runTtsc.ts +30 -4
  71. package/src/launcher/internal/runTtsx.ts +377 -26
  72. package/src/plugin/internal/buildSourcePlugin.ts +321 -50
  73. package/src/plugin/internal/loadProjectPlugins.ts +266 -10
  74. package/src/structures/ITtscCompilerContext.ts +17 -3
  75. package/src/structures/ITtscCompilerResult.ts +5 -0
  76. package/src/structures/ITtscCompilerTransformation.ts +3 -0
  77. package/src/structures/ITtscPluginFactoryContext.ts +6 -3
  78. package/src/structures/ITtscProjectPluginConfig.ts +8 -7
  79. package/src/structures/internal/ITtscParsedProjectConfig.ts +2 -0
  80. package/src/structures/internal/ITtscProjectLocatorOptions.ts +2 -0
  81. package/src/structures/internal/TtscCommonOptions.ts +2 -0
  82. package/utility/host.go +622 -20
  83. package/cmd/ttsc/main_test.go +0 -288
  84. package/test/compiler.test.ts +0 -422
  85. package/test/platform.test.ts +0 -12
  86. package/test/project.test.ts +0 -197
  87. package/test/source-build.test.ts +0 -45
  88. package/test/tsgo.test.ts +0 -69
package/README.md CHANGED
@@ -9,13 +9,13 @@
9
9
  [![Guide Documents](https://img.shields.io/badge/Guide-Documents-forestgreen)](https://github.com/samchon/ttsc/tree/master/docs)
10
10
  [![Discord Badge](https://img.shields.io/badge/discord-samchon-d91965?style=flat&labelColor=5866f2&logo=discord&logoColor=white&link=https://discord.gg/E94XhzrUCZ)](https://discord.gg/E94XhzrUCZ)
11
11
 
12
- A `typescript-go` toolchain for compiler-powered transforms and type-safe execution.
12
+ A `typescript-go` toolchain for compiler-powered plugins and type-safe execution.
13
13
 
14
14
  - **`ttsc`**: build, check, and transform.
15
15
  - **`ttsx`**: execute TypeScript with type checking.
16
- - 10x faster than `ts-node`.
16
+ - native TypeScript-Go execution instead of transpile-only runners.
17
17
  - type checking that `tsx` does not provide.
18
- - **transformer support**: compiler-powered libraries, such as `typia`.
18
+ - **plugin support**: compiler-powered libraries, such as `typia`.
19
19
  - `@ttsc/lint`: lint violations as TS compile errors.
20
20
 
21
21
  ## Setup
@@ -25,7 +25,7 @@ A `typescript-go` toolchain for compiler-powered transforms and type-safe execut
25
25
  Install the native TypeScript preview package with `ttsc`:
26
26
 
27
27
  ```bash
28
- npm i -D ttsc @typescript/native-preview
28
+ npm install -D ttsc @typescript/native-preview
29
29
  ```
30
30
 
31
31
  ### Commands
@@ -48,11 +48,11 @@ npx ttsc --watch
48
48
 
49
49
  Use `@ttsc/unplugin` when a bundler owns your build.
50
50
 
51
- It runs the same `compilerOptions.plugins` that `ttsc` and `ttsx` use.
51
+ It runs `ttsc` plugins inside supported bundlers.
52
52
 
53
53
  ```bash
54
- npm i -D ttsc @typescript/native-preview
55
- npm i -D @ttsc/unplugin
54
+ npm install -D ttsc @typescript/native-preview
55
+ npm install -D @ttsc/unplugin
56
56
  ```
57
57
 
58
58
  Minimal Vite setup:
@@ -83,30 +83,7 @@ See [`@ttsc/unplugin`](https://github.com/samchon/ttsc/tree/master/packages/unpl
83
83
 
84
84
  ## Plugins
85
85
 
86
- ### Configuration
87
-
88
- Add plugin entries under `compilerOptions.plugins` in your `tsconfig.json`.
89
-
90
- ```json
91
- {
92
- "compilerOptions": {
93
- "plugins": [
94
- {
95
- "transform": "@ttsc/lint",
96
- "config": {
97
- "no-var": "error",
98
- "no-explicit-any": "warning",
99
- "no-non-null-assertion": "off"
100
- }
101
- },
102
- { "transform": "@ttsc/paths" },
103
- { "transform": "typia/lib/transform" }
104
- ]
105
- }
106
- }
107
- ```
108
-
109
- The same configuration is used by both `ttsc` and `ttsx` commands.
86
+ Plugins let libraries add compile-time checks, transforms, and type-driven code generation to normal `ttsc` and `ttsx` runs.
110
87
 
111
88
  ```bash
112
89
  # compile
@@ -116,9 +93,7 @@ npx ttsc
116
93
  npx ttsx src/index.ts
117
94
  ```
118
95
 
119
- This gives compiler-powered libraries one transform path for both build-time and runtime execution.
120
-
121
- ### What Is a Transform?
96
+ ### Transform Example
122
97
 
123
98
  A transform uses TypeScript types to generate JavaScript before runtime.
124
99
 
@@ -143,52 +118,48 @@ interface IMember {
143
118
  }
144
119
  ```
145
120
 
146
- It is transformed into dedicated JavaScript:
147
-
148
- > ```js
149
- > import typia from "typia";
150
- > import * as __typia_transform__isFormatEmail from "typia/lib/internal/_isFormatEmail";
151
- > import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid";
152
- > import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32";
153
- > import { v4 } from "uuid";
154
- >
155
- > const matched = (() => {
156
- > const _io0 = (input) =>
157
- > "string" === typeof input.id &&
158
- > __typia_transform__isFormatUuid._isFormatUuid(input.id) &&
159
- > "string" === typeof input.email &&
160
- > __typia_transform__isFormatEmail._isFormatEmail(input.email) &&
161
- > "number" === typeof input.age &&
162
- > __typia_transform__isTypeUint32._isTypeUint32(input.age) &&
163
- > 19 < input.age &&
164
- > input.age <= 100;
165
- > return (input) =>
166
- > "object" === typeof input && null !== input && _io0(input);
167
- > })()({
168
- > id: v4(),
169
- > email: "samchon.github@gmail.com",
170
- > age: 30,
171
- > });
172
- > console.log(matched); // true
173
- > ```
174
-
175
- `ttsc` applies this transform at build time; `ttsx` applies the same transform when running the file.
121
+ The transform replaces `typia.is<IMember>()` with dedicated JavaScript checks at build time:
122
+
123
+ ```js
124
+ import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid";
125
+ import * as __typia_transform__isFormatEmail from "typia/lib/internal/_isFormatEmail";
126
+ import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32";
127
+ import typia from "typia";
128
+ import { v4 } from "uuid";
129
+ const matched = (() => {
130
+ const _io0 = (input) =>
131
+ "string" === typeof input.id &&
132
+ __typia_transform__isFormatUuid._isFormatUuid(input.id) &&
133
+ "string" === typeof input.email &&
134
+ __typia_transform__isFormatEmail._isFormatEmail(input.email) &&
135
+ "number" === typeof input.age &&
136
+ __typia_transform__isTypeUint32._isTypeUint32(input.age) &&
137
+ 19 < input.age &&
138
+ input.age <= 100;
139
+ return (input) => "object" === typeof input && null !== input && _io0(input);
140
+ })()({
141
+ id: v4(),
142
+ email: "samchon.github@gmail.com",
143
+ age: 30,
144
+ });
145
+ console.log(matched); // true
146
+ ```
176
147
 
177
148
  ### List of Plugins
178
149
 
179
150
  `ttsc` ships a few small utility plugins in this repository.
180
151
 
181
- - [`@ttsc/banner`](https://github.com/samchon/ttsc/tree/master/packages/banner): adds `@packageDocumentation` JSDoc banners through source preamble insertion.
182
- - [`@ttsc/lint`](https://github.com/samchon/ttsc/tree/master/packages/lint): type-check + lint in one compile pass, ~20x faster than `eslint` in theory.
152
+ - [`@ttsc/banner`](https://github.com/samchon/ttsc/tree/master/packages/banner): adds `@packageDocumentation` JSDoc banners.
153
+ - [`@ttsc/lint`](https://github.com/samchon/ttsc/tree/master/packages/lint): reports lint violations as TypeScript compile errors.
183
154
  - [`@ttsc/paths`](https://github.com/samchon/ttsc/tree/master/packages/paths): rewrites source path aliases so JS and declaration emit receive relative imports.
184
155
  - [`@ttsc/strip`](https://github.com/samchon/ttsc/tree/master/packages/strip): removes configured calls and `debugger` statements.
185
- - [`@ttsc/unplugin`](https://github.com/samchon/ttsc/tree/master/packages/unplugin): runs configured `ttsc` source transforms inside bundlers supported by `unplugin`.
156
+ - [`@ttsc/unplugin`](https://github.com/samchon/ttsc/tree/master/packages/unplugin): runs `ttsc` plugins inside bundlers supported by `unplugin`.
186
157
 
187
158
  Plugin authors should start from the [`Guide Documents`](https://github.com/samchon/ttsc/tree/master/docs).
188
159
 
189
160
  Ecosystem plugins are listed below; PRs adding `ttsc` plugins are welcome.
190
161
 
191
- - [`@nestia/core`](https://github.com/samchon/nestia): generates NestJS routes, OpenAPI, and SDKs.
162
+ - [`nestia`](https://github.com/samchon/nestia): generates NestJS routes, OpenAPI, and SDKs.
192
163
  - [`typia`](https://github.com/samchon/typia): generates validators, serializers, and type-driven runtime code.
193
164
 
194
165
  ## References
@@ -7,24 +7,25 @@
7
7
  package main
8
8
 
9
9
  import (
10
- "encoding/json"
11
- "flag"
12
- "fmt"
13
- "os"
14
- "path/filepath"
15
- "strings"
10
+ "encoding/json"
11
+ "flag"
12
+ "fmt"
13
+ "os"
14
+ "path/filepath"
15
+ "strings"
16
16
 
17
- shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
17
+ shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
18
18
 
19
- "github.com/samchon/ttsc/packages/ttsc/driver"
19
+ "github.com/samchon/ttsc/packages/ttsc/driver"
20
+ cwdutil "github.com/samchon/ttsc/packages/ttsc/internal/cwd"
20
21
  )
21
22
 
22
23
  type apiCompileResult struct {
23
- // Diagnostics is omitted only when the compiler produced no diagnostics.
24
- // Output is still returned in diagnostic cases because TypeScript-Go may
25
- // produce partial emit text before a build-failing error is reported.
26
- Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
27
- Output map[string]string `json:"output"`
24
+ // Diagnostics is omitted only when the compiler produced no diagnostics.
25
+ // Output is still returned in diagnostic cases because TypeScript-Go may
26
+ // produce partial emit text before a build-failing error is reported.
27
+ Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
28
+ Output map[string]string `json:"output"`
28
29
  }
29
30
 
30
31
  // apiCompileDiagnostic mirrors the public TypeScript-side diagnostic DTO.
@@ -32,120 +33,113 @@ type apiCompileResult struct {
32
33
  // `character`) instead of Go naming so callers can pass the data through
33
34
  // without remapping.
34
35
  type apiCompileDiagnostic struct {
35
- File *string `json:"file"`
36
- Category string `json:"category"`
37
- Code int32 `json:"code"`
38
- Start *int `json:"start,omitempty"`
39
- Length *int `json:"length,omitempty"`
40
- Line int `json:"line,omitempty"`
41
- Character int `json:"character,omitempty"`
42
- MessageText string `json:"messageText"`
36
+ File *string `json:"file"`
37
+ Category string `json:"category"`
38
+ Code int32 `json:"code"`
39
+ Start *int `json:"start,omitempty"`
40
+ Length *int `json:"length,omitempty"`
41
+ Line int `json:"line,omitempty"`
42
+ Character int `json:"character,omitempty"`
43
+ MessageText string `json:"messageText"`
43
44
  }
44
45
 
45
46
  func runAPICompile(args []string) int {
46
- fs := flag.NewFlagSet("api-compile", flag.ContinueOnError)
47
- fs.SetOutput(stderr)
48
- tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
49
- cwdOverride := fs.String("cwd", "", "override the working directory")
50
- if err := fs.Parse(args); err != nil {
51
- return 2
52
- }
47
+ fs := flag.NewFlagSet("api-compile", flag.ContinueOnError)
48
+ fs.SetOutput(stderr)
49
+ tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
50
+ cwdOverride := fs.String("cwd", "", "override the working directory")
51
+ if err := fs.Parse(args); err != nil {
52
+ return 2
53
+ }
53
54
 
54
- cwd, ok := resolveBuildCwd(*cwdOverride)
55
- if !ok {
56
- return 2
57
- }
55
+ cwd, err := cwdutil.Resolve(*cwdOverride, os.Getwd)
56
+ if err != nil {
57
+ fmt.Fprintf(stderr, "ttsc: %v\n", err)
58
+ return 2
59
+ }
58
60
 
59
- prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
60
- ForceEmit: true,
61
- })
62
- if err != nil {
63
- fmt.Fprintf(stderr, "ttsc api-compile: %v\n", err)
64
- return 2
65
- }
66
- if prog != nil {
67
- defer prog.Close()
68
- diags = append(diags, prog.Diagnostics()...)
69
- }
61
+ prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
62
+ ForceEmit: true,
63
+ })
64
+ if err != nil {
65
+ fmt.Fprintf(stderr, "ttsc api-compile: %v\n", err)
66
+ return 2
67
+ }
68
+ if prog != nil {
69
+ defer prog.Close()
70
+ diags = append(diags, prog.Diagnostics()...)
71
+ }
70
72
 
71
- output := map[string]string{}
72
- if prog != nil {
73
- rewrites := driver.NewRewriteSet()
74
- // Capture WriteFile output in a map keyed by project-relative paths. This
75
- // gives the JS API a deterministic object and avoids touching outDir.
76
- writeFile := shimcompiler.WriteFile(
77
- func(fileName, text string, _ *shimcompiler.WriteFileData) error {
78
- output[apiOutputKey(cwd, fileName)] = text
79
- return nil
80
- },
81
- )
82
- _, emitDiags, err := prog.EmitAll(rewrites, writeFile)
83
- if err != nil {
84
- fmt.Fprintf(stderr, "ttsc api-compile: emit failed: %v\n", err)
85
- return 3
86
- }
87
- diags = append(diags, emitDiags...)
88
- }
73
+ output := map[string]string{}
74
+ if prog != nil {
75
+ rewrites := driver.NewRewriteSet()
76
+ // Capture WriteFile output in a map keyed by project-relative paths. This
77
+ // gives the JS API a deterministic object and avoids touching outDir.
78
+ writeFile := shimcompiler.WriteFile(
79
+ func(fileName, text string, _ *shimcompiler.WriteFileData) error {
80
+ output[apiOutputKey(cwd, fileName)] = text
81
+ return nil
82
+ },
83
+ )
84
+ _, emitDiags, err := prog.EmitAll(rewrites, writeFile)
85
+ if err != nil {
86
+ fmt.Fprintf(stderr, "ttsc api-compile: emit failed: %v\n", err)
87
+ return 3
88
+ }
89
+ diags = append(diags, emitDiags...)
90
+ }
89
91
 
90
- result := apiCompileResult{
91
- Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
92
- Output: output,
93
- }
94
- for _, diag := range diags {
95
- result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
96
- }
92
+ result := apiCompileResult{
93
+ Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
94
+ Output: output,
95
+ }
96
+ for _, diag := range diags {
97
+ result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
98
+ }
97
99
 
98
- data, err := json.Marshal(result)
99
- if err != nil {
100
- fmt.Fprintf(stderr, "ttsc api-compile: result marshal failed: %v\n", err)
101
- return 3
102
- }
103
- fmt.Fprintln(stdout, string(data))
104
- if driver.CountErrors(diags) > 0 {
105
- return 2
106
- }
107
- return 0
108
- }
109
-
110
- func resolveBuildCwd(cwdOverride string) (string, bool) {
111
- if cwdOverride != "" {
112
- return cwdOverride, true
113
- }
114
- cwd, err := os.Getwd()
115
- if err != nil {
116
- fmt.Fprintf(stderr, "ttsc: could not get working directory: %v\n", err)
117
- return "", false
118
- }
119
- return cwd, true
100
+ data, err := json.Marshal(result)
101
+ if err != nil {
102
+ fmt.Fprintf(stderr, "ttsc api-compile: result marshal failed: %v\n", err)
103
+ return 3
104
+ }
105
+ fmt.Fprintln(stdout, string(data))
106
+ if driver.CountErrors(diags) > 0 {
107
+ return 2
108
+ }
109
+ return 0
120
110
  }
121
111
 
122
112
  func toAPICompileDiagnostic(diag driver.Diagnostic) apiCompileDiagnostic {
123
- var file *string
124
- if diag.File != "" {
125
- value := diag.File
126
- file = &value
127
- }
128
- category := "error"
129
- if diag.Severity == driver.SeverityWarning {
130
- category = "warning"
131
- }
132
- return apiCompileDiagnostic{
133
- File: file,
134
- Category: category,
135
- Code: diag.Code,
136
- Start: diag.Start,
137
- Length: diag.Length,
138
- Line: diag.Line,
139
- Character: diag.Column,
140
- MessageText: diag.Message,
141
- }
113
+ var file *string
114
+ if diag.File != "" {
115
+ value := diag.File
116
+ file = &value
117
+ }
118
+ category := "error"
119
+ if diag.Severity == driver.SeverityWarning {
120
+ category = "warning"
121
+ }
122
+ return apiCompileDiagnostic{
123
+ File: file,
124
+ Category: category,
125
+ Code: diag.Code,
126
+ Start: diag.Start,
127
+ Length: diag.Length,
128
+ Line: diag.Line,
129
+ Character: diag.Column,
130
+ MessageText: diag.Message,
131
+ }
142
132
  }
143
133
 
144
134
  func apiOutputKey(cwd, fileName string) string {
145
- // Relative keys are the API contract for files inside the project. Absolute
146
- // keys are preserved for uncommon compiler outputs outside cwd.
147
- if rel, err := filepath.Rel(cwd, fileName); err == nil && !strings.HasPrefix(rel, "..") {
148
- return filepath.ToSlash(rel)
149
- }
150
- return filepath.ToSlash(fileName)
135
+ // Relative keys are the API contract for files inside the project. Absolute
136
+ // keys are preserved for uncommon compiler outputs outside cwd.
137
+ if rel, err := filepath.Rel(cwd, fileName); err == nil && !isOutsideRelativePath(rel) {
138
+ return filepath.ToSlash(rel)
139
+ }
140
+ return filepath.ToSlash(fileName)
141
+ }
142
+
143
+ func isOutsideRelativePath(rel string) bool {
144
+ return rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator))
151
145
  }
@@ -7,66 +7,69 @@
7
7
  package main
8
8
 
9
9
  import (
10
- "encoding/json"
11
- "flag"
12
- "fmt"
10
+ "encoding/json"
11
+ "flag"
12
+ "fmt"
13
+ "os"
13
14
 
14
- "github.com/samchon/ttsc/packages/ttsc/driver"
15
+ "github.com/samchon/ttsc/packages/ttsc/driver"
16
+ cwdutil "github.com/samchon/ttsc/packages/ttsc/internal/cwd"
15
17
  )
16
18
 
17
19
  type apiTransformResult struct {
18
- // TypeScript contains every non-library source file visible through the
19
- // Program facade, keyed the same way api-compile keys emitted files.
20
- Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
21
- TypeScript map[string]string `json:"typescript"`
20
+ // TypeScript contains every non-library source file visible through the
21
+ // Program facade, keyed the same way api-compile keys emitted files.
22
+ Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
23
+ TypeScript map[string]string `json:"typescript"`
22
24
  }
23
25
 
24
26
  func runAPITransform(args []string) int {
25
- fs := flag.NewFlagSet("api-transform", flag.ContinueOnError)
26
- fs.SetOutput(stderr)
27
- tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
28
- cwdOverride := fs.String("cwd", "", "override the working directory")
29
- if err := fs.Parse(args); err != nil {
30
- return 2
31
- }
27
+ fs := flag.NewFlagSet("api-transform", flag.ContinueOnError)
28
+ fs.SetOutput(stderr)
29
+ tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
30
+ cwdOverride := fs.String("cwd", "", "override the working directory")
31
+ if err := fs.Parse(args); err != nil {
32
+ return 2
33
+ }
32
34
 
33
- cwd, ok := resolveBuildCwd(*cwdOverride)
34
- if !ok {
35
- return 2
36
- }
35
+ cwd, err := cwdutil.Resolve(*cwdOverride, os.Getwd)
36
+ if err != nil {
37
+ fmt.Fprintf(stderr, "ttsc: %v\n", err)
38
+ return 2
39
+ }
37
40
 
38
- prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
39
- ForceNoEmit: true,
40
- })
41
- if err != nil {
42
- fmt.Fprintf(stderr, "ttsc api-transform: %v\n", err)
43
- return 2
44
- }
45
- typescript := map[string]string{}
46
- if prog != nil {
47
- defer prog.Close()
48
- for _, file := range prog.SourceFiles() {
49
- typescript[apiOutputKey(cwd, file.FileName())] = file.Text()
50
- }
51
- diags = append(diags, prog.Diagnostics()...)
52
- }
41
+ prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
42
+ ForceNoEmit: true,
43
+ })
44
+ if err != nil {
45
+ fmt.Fprintf(stderr, "ttsc api-transform: %v\n", err)
46
+ return 2
47
+ }
48
+ typescript := map[string]string{}
49
+ if prog != nil {
50
+ defer prog.Close()
51
+ for _, file := range prog.SourceFiles() {
52
+ typescript[apiOutputKey(cwd, file.FileName())] = file.Text()
53
+ }
54
+ diags = append(diags, prog.Diagnostics()...)
55
+ }
53
56
 
54
- result := apiTransformResult{
55
- Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
56
- TypeScript: typescript,
57
- }
58
- for _, diag := range diags {
59
- result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
60
- }
57
+ result := apiTransformResult{
58
+ Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
59
+ TypeScript: typescript,
60
+ }
61
+ for _, diag := range diags {
62
+ result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
63
+ }
61
64
 
62
- data, err := json.Marshal(result)
63
- if err != nil {
64
- fmt.Fprintf(stderr, "ttsc api-transform: result marshal failed: %v\n", err)
65
- return 3
66
- }
67
- fmt.Fprintln(stdout, string(data))
68
- if driver.CountErrors(diags) > 0 {
69
- return 2
70
- }
71
- return 0
65
+ data, err := json.Marshal(result)
66
+ if err != nil {
67
+ fmt.Fprintf(stderr, "ttsc api-transform: result marshal failed: %v\n", err)
68
+ return 3
69
+ }
70
+ fmt.Fprintln(stdout, string(data))
71
+ if driver.CountErrors(diags) > 0 {
72
+ return 2
73
+ }
74
+ return 0
72
75
  }