@ttsc/banner 0.7.3 → 0.8.0-dev.20260506

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/README.md CHANGED
@@ -9,7 +9,7 @@
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
- `@ttsc/banner` prepends a fixed comment to emitted JavaScript and declaration files.
12
+ `@ttsc/banner` adds a fixed `@packageDocumentation` JSDoc banner by inserting a source preamble before TypeScript-Go parses the project.
13
13
 
14
14
  ## Setup
15
15
 
@@ -27,10 +27,10 @@ Open your project's `tsconfig.json`, then add this entry under `compilerOptions.
27
27
  "plugins": [
28
28
  {
29
29
  "transform": "@ttsc/banner",
30
- "banner": "/*! @license MIT (c) 2026 Acme */"
31
- }
32
- ]
33
- }
30
+ "banner": "License MIT (c) 2026 Acme",
31
+ },
32
+ ],
33
+ },
34
34
  }
35
35
  ```
36
36
 
@@ -40,7 +40,7 @@ Run your normal `ttsc` command:
40
40
  npx ttsc
41
41
  ```
42
42
 
43
- The banner is written to emitted `.js`, `.mjs`, `.cjs`, `.d.ts`, `.d.mts`, and `.d.cts` files. Source maps and build-info files are left unchanged.
43
+ The plugin formats every banner line inside a JSDoc block and adds `@packageDocumentation`. The banner follows TypeScript's normal comment emit policy, so `removeComments: true` removes it.
44
44
 
45
45
  ## Notes
46
46
 
@@ -53,11 +53,11 @@ The banner is written to emitted `.js`, `.mjs`, `.cjs`, `.d.ts`, `.d.mts`, and `
53
53
  // Keep lint first.
54
54
  { "transform": "@ttsc/lint", "config": { "no-var": "error" } },
55
55
 
56
- // Output plugins run after emit, in order.
57
- { "transform": "@ttsc/banner", "banner": "/*! @license MIT */" },
56
+ // First-party utilities use their documented transform order.
57
+ { "transform": "@ttsc/banner", "banner": "License MIT" },
58
58
  { "transform": "@ttsc/paths" },
59
- { "transform": "@ttsc/strip", "calls": ["console.log"] }
60
- ]
61
- }
59
+ { "transform": "@ttsc/strip", "calls": ["console.log"] },
60
+ ],
61
+ },
62
62
  }
63
63
  ```
package/go.mod CHANGED
@@ -1,3 +1,5 @@
1
1
  module github.com/samchon/ttsc/packages/banner
2
2
 
3
3
  go 1.26
4
+
5
+ require github.com/samchon/ttsc/packages/ttsc v0.0.0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ttsc/banner",
3
- "version": "0.7.3",
4
- "description": "First-party ttsc plugin that prepends a banner comment to emitted files.",
3
+ "version": "0.8.0-dev.20260506",
4
+ "description": "First-party ttsc plugin that adds package-documentation JSDoc banners during emit.",
5
5
  "main": "src/index.cjs",
6
6
  "exports": {
7
7
  ".": "./src/index.cjs",
package/plugin/banner.go CHANGED
@@ -1,148 +1,3 @@
1
- // Output transformer for `@ttsc/banner`.
2
- //
3
- // The transformer prepends a configured banner to JavaScript and declaration
4
- // outputs. Source maps and tsbuildinfo files are excluded because prepending
5
- // human-readable text would corrupt their structured content.
6
1
  package main
7
2
 
8
- import (
9
- "encoding/json"
10
- "flag"
11
- "fmt"
12
- "os"
13
- "path/filepath"
14
- "strings"
15
- )
16
-
17
- type pluginEntry struct {
18
- // Config carries the original compilerOptions.plugins[] config object. The
19
- // sidecar scans the ordered descriptor list and consumes only its own entry.
20
- Config map[string]any `json:"config"`
21
- Name string `json:"name"`
22
- Stage string `json:"stage"`
23
- }
24
-
25
- // RunOutput implements the output-stage sidecar command. The host passes an
26
- // emitted file path, the serialized plugin manifest, and an optional alternate
27
- // output path.
28
- func RunOutput(args []string) int {
29
- fs := flag.NewFlagSet("output", flag.ContinueOnError)
30
- fs.SetOutput(os.Stderr)
31
- file := fs.String("file", "", "emitted file to transform")
32
- out := fs.String("out", "", "write transformed text to this file instead of updating --file")
33
- _ = fs.String("cwd", "", "project directory")
34
- _ = fs.String("outDir", "", "emit directory override")
35
- pluginsJSON := fs.String("plugins-json", "", "ttsc plugin manifest JSON")
36
- _ = fs.String("tsconfig", "tsconfig.json", "project tsconfig")
37
- if err := fs.Parse(args); err != nil {
38
- return 2
39
- }
40
- if *file == "" {
41
- fmt.Fprintln(os.Stderr, "@ttsc/banner: output requires --file")
42
- return 2
43
- }
44
- config, err := findConfig(*pluginsJSON)
45
- if err != nil {
46
- fmt.Fprintln(os.Stderr, err)
47
- return 2
48
- }
49
- text, err := os.ReadFile(*file)
50
- if err != nil {
51
- fmt.Fprintf(os.Stderr, "@ttsc/banner: read %s: %v\n", *file, err)
52
- return 2
53
- }
54
- patched, err := Apply(*file, string(text), config)
55
- if err != nil {
56
- fmt.Fprintln(os.Stderr, err)
57
- return 2
58
- }
59
- target := *file
60
- if *out != "" {
61
- target = *out
62
- }
63
- if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
64
- fmt.Fprintf(os.Stderr, "@ttsc/banner: mkdir: %v\n", err)
65
- return 2
66
- }
67
- if err := os.WriteFile(target, []byte(patched), 0o644); err != nil {
68
- fmt.Fprintf(os.Stderr, "@ttsc/banner: write %s: %v\n", target, err)
69
- return 2
70
- }
71
- return 0
72
- }
73
-
74
- func Apply(fileName string, text string, config map[string]any) (string, error) {
75
- if !isBannerableOutput(fileName) {
76
- return text, nil
77
- }
78
- banner, err := parseBanner(config)
79
- if err != nil {
80
- return "", err
81
- }
82
- // The operation is idempotent so watch builds do not duplicate banners when
83
- // the same output file is seen more than once.
84
- if strings.HasPrefix(text, banner) {
85
- return text, nil
86
- }
87
- return banner + text, nil
88
- }
89
-
90
- func parseBanner(config map[string]any) (string, error) {
91
- raw, ok := config["banner"]
92
- if !ok {
93
- return "", fmt.Errorf("@ttsc/banner: \"banner\" must be a non-empty string")
94
- }
95
- text, ok := raw.(string)
96
- if !ok || strings.TrimSpace(text) == "" {
97
- return "", fmt.Errorf("@ttsc/banner: \"banner\" must be a non-empty string")
98
- }
99
- if !strings.HasSuffix(text, "\n") {
100
- // The banner is line-oriented; forcing a trailing newline keeps the first
101
- // emitted statement on its own line.
102
- text += "\n"
103
- }
104
- return text, nil
105
- }
106
-
107
- func findConfig(pluginsJSON string) (map[string]any, error) {
108
- if strings.TrimSpace(pluginsJSON) == "" {
109
- return nil, fmt.Errorf("@ttsc/banner: missing --plugins-json")
110
- }
111
- var entries []pluginEntry
112
- if err := json.Unmarshal([]byte(pluginsJSON), &entries); err != nil {
113
- return nil, fmt.Errorf("@ttsc/banner: invalid --plugins-json: %w", err)
114
- }
115
- for _, entry := range entries {
116
- if entry.Name == "@ttsc/banner" {
117
- if entry.Config == nil {
118
- return map[string]any{}, nil
119
- }
120
- return entry.Config, nil
121
- }
122
- }
123
- return nil, fmt.Errorf("@ttsc/banner: plugin entry not found")
124
- }
125
-
126
- func isBannerableOutput(fileName string) bool {
127
- lower := strings.ToLower(fileName)
128
- if strings.HasSuffix(lower, ".map") || strings.HasSuffix(lower, ".tsbuildinfo") {
129
- return false
130
- }
131
- return isJavaScriptOutput(fileName) || isDeclarationOutput(fileName)
132
- }
133
-
134
- func isJavaScriptOutput(fileName string) bool {
135
- switch strings.ToLower(filepath.Ext(fileName)) {
136
- case ".js", ".mjs", ".cjs":
137
- return true
138
- default:
139
- return false
140
- }
141
- }
142
-
143
- func isDeclarationOutput(fileName string) bool {
144
- lower := strings.ToLower(fileName)
145
- return strings.HasSuffix(lower, ".d.ts") ||
146
- strings.HasSuffix(lower, ".d.mts") ||
147
- strings.HasSuffix(lower, ".d.cts")
148
- }
3
+ // Banner transform logic lives in github.com/samchon/ttsc/packages/ttsc/utility.
package/plugin/main.go CHANGED
@@ -1,14 +1,11 @@
1
1
  // Native sidecar entrypoint for `@ttsc/banner`.
2
- //
3
- // The command follows the ttsc plugin sidecar protocol: `check` validates the
4
- // plugin can run, `output` receives one emitted file and may rewrite it, and
5
- // `version` reports the sidecar version. All project semantics stay in the
6
- // host; this binary only prepends configured banner text.
7
2
  package main
8
3
 
9
4
  import (
10
5
  "fmt"
11
6
  "os"
7
+
8
+ "github.com/samchon/ttsc/packages/ttsc/utility"
12
9
  )
13
10
 
14
11
  const version = "0.0.1"
@@ -19,18 +16,19 @@ func main() {
19
16
 
20
17
  func run(args []string) int {
21
18
  if len(args) == 0 {
22
- fmt.Fprintln(os.Stderr, "@ttsc/banner: command required (expected output|version)")
19
+ fmt.Fprintln(os.Stderr, "@ttsc/banner: command required (expected build|transform|check|version)")
23
20
  return 2
24
21
  }
25
22
  switch args[0] {
26
23
  case "-v", "--version", "version":
27
24
  fmt.Fprintf(os.Stdout, "@ttsc/banner %s\n", version)
28
25
  return 0
26
+ case "build":
27
+ return utility.RunBuild(args[1:])
28
+ case "transform":
29
+ return utility.RunTransform(args[1:])
29
30
  case "check":
30
- // Banner rewriting is output-only; there is no program-wide analysis.
31
31
  return 0
32
- case "output":
33
- return RunOutput(args[1:])
34
32
  default:
35
33
  fmt.Fprintf(os.Stderr, "@ttsc/banner: unknown command %q\n", args[0])
36
34
  return 2
package/src/index.cjs CHANGED
@@ -7,6 +7,6 @@ module.exports = function createTtscBanner() {
7
7
  return {
8
8
  name: "@ttsc/banner",
9
9
  source: path.resolve(__dirname, "..", "plugin"),
10
- stage: "output",
10
+ stage: "transform",
11
11
  };
12
12
  };