klasik 2.0.8 → 2.2.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 (47) hide show
  1. package/README.md +710 -3
  2. package/dist/bin/go-schema-gen +0 -0
  3. package/dist/builders/class-builder.d.ts +1 -0
  4. package/dist/builders/class-builder.d.ts.map +1 -1
  5. package/dist/builders/class-builder.js.map +1 -1
  6. package/dist/cli/commands/generate-crd.d.ts +1 -0
  7. package/dist/cli/commands/generate-crd.d.ts.map +1 -1
  8. package/dist/cli/commands/generate-crd.js +2 -0
  9. package/dist/cli/commands/generate-crd.js.map +1 -1
  10. package/dist/cli/commands/generate-go.d.ts +22 -0
  11. package/dist/cli/commands/generate-go.d.ts.map +1 -0
  12. package/dist/cli/commands/generate-go.js +130 -0
  13. package/dist/cli/commands/generate-go.js.map +1 -0
  14. package/dist/cli/commands/generate-jsonschema.d.ts +1 -0
  15. package/dist/cli/commands/generate-jsonschema.d.ts.map +1 -1
  16. package/dist/cli/commands/generate-jsonschema.js +2 -0
  17. package/dist/cli/commands/generate-jsonschema.js.map +1 -1
  18. package/dist/cli/commands/generate.d.ts +1 -0
  19. package/dist/cli/commands/generate.d.ts.map +1 -1
  20. package/dist/cli/commands/generate.js +2 -0
  21. package/dist/cli/commands/generate.js.map +1 -1
  22. package/dist/cli/index.js +3 -1
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/cli/utils/options.d.ts +4 -0
  25. package/dist/cli/utils/options.d.ts.map +1 -1
  26. package/dist/cli/utils/options.js +7 -0
  27. package/dist/cli/utils/options.js.map +1 -1
  28. package/dist/generator/generator.d.ts.map +1 -1
  29. package/dist/generator/generator.js +4 -0
  30. package/dist/generator/generator.js.map +1 -1
  31. package/dist/loaders/go-schema-loader.d.ts +60 -0
  32. package/dist/loaders/go-schema-loader.d.ts.map +1 -0
  33. package/dist/loaders/go-schema-loader.js +221 -0
  34. package/dist/loaders/go-schema-loader.js.map +1 -0
  35. package/dist/plugins/ajv-validator-plugin.d.ts +45 -0
  36. package/dist/plugins/ajv-validator-plugin.d.ts.map +1 -0
  37. package/dist/plugins/ajv-validator-plugin.js +320 -0
  38. package/dist/plugins/ajv-validator-plugin.js.map +1 -0
  39. package/package.json +5 -3
  40. package/tools/go-schema-gen/README.md +147 -0
  41. package/tools/go-schema-gen/build.sh +24 -0
  42. package/tools/go-schema-gen/comment_extractor.go +128 -0
  43. package/tools/go-schema-gen/go-schema-gen +0 -0
  44. package/tools/go-schema-gen/go.mod +36 -0
  45. package/tools/go-schema-gen/go.sum +112 -0
  46. package/tools/go-schema-gen/main.go +155 -0
  47. package/tools/go-schema-gen/registry.go +35 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ajv-validator-plugin.js","sourceRoot":"","sources":["../../src/plugins/ajv-validator-plugin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "klasik",
3
- "version": "2.0.8",
4
- "description": "TypeScript code generator from OpenAPI/CRD/JSON Schema - rebuilt from ground up with AST-based generation",
3
+ "version": "2.2.0",
4
+ "description": "TypeScript code generator from OpenAPI/CRD/JSON Schema/Go structs - rebuilt from ground up with AST-based generation",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
@@ -10,12 +10,14 @@
10
10
  "files": [
11
11
  "dist/",
12
12
  "templates/",
13
+ "tools/go-schema-gen/",
13
14
  "docs/",
14
15
  "demo-output/",
15
16
  "README.md"
16
17
  ],
17
18
  "scripts": {
18
- "build": "tsc",
19
+ "build": "npm run build:go && tsc",
20
+ "build:go": "cd tools/go-schema-gen && ./build.sh || echo 'Warning: Go tool build failed. Go generation will not be available.'",
19
21
  "test": "jest",
20
22
  "test:watch": "jest --watch",
21
23
  "test:coverage": "jest --coverage",
@@ -0,0 +1,147 @@
1
+ # go-schema-gen
2
+
3
+ Go tool that generates JSON Schema from Go structs using runtime reflection.
4
+
5
+ ## Overview
6
+
7
+ This tool uses Go's reflection API and the `invopop/jsonschema` library to generate JSON Schema Draft 2020-12 from registered Go types. It's used by Klasik to enable TypeScript code generation from Go structs.
8
+
9
+ ## Automatic Installation
10
+
11
+ **You don't need to build this manually!** When you run `klasik generate-go` for the first time, it will automatically:
12
+
13
+ 1. Check if Go is installed
14
+ 2. Run `go mod tidy` to download dependencies
15
+ 3. Build the binary to `../../dist/bin/go-schema-gen`
16
+
17
+ This only happens once - subsequent runs use the cached binary.
18
+
19
+ ## Manual Build (Optional)
20
+
21
+ If you want to build manually:
22
+
23
+ ```bash
24
+ # From this directory:
25
+ ./build.sh
26
+
27
+ # Or step by step:
28
+ go mod tidy
29
+ go build -o ../../dist/bin/go-schema-gen .
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```bash
35
+ # Generate JSON Schema for a registered type:
36
+ go-schema-gen --type "helm.sh/helm/v3/pkg/chart.Metadata"
37
+
38
+ # With options:
39
+ go-schema-gen --type "helm.sh/helm/v3/pkg/chart.Chart" --allow-additional
40
+ ```
41
+
42
+ ## Adding New Types
43
+
44
+ To add new Go packages/structs:
45
+
46
+ 1. **Edit `registry.go`:**
47
+ ```go
48
+ import (
49
+ chart "helm.sh/helm/v3/pkg/chart"
50
+ mypackage "github.com/org/package" // Add your import
51
+ )
52
+
53
+ var typeRegistry = map[string]interface{}{
54
+ // Existing types
55
+ "helm.sh/helm/v3/pkg/chart.Metadata": chart.Metadata{},
56
+
57
+ // Add your types
58
+ "github.com/org/package.MyStruct": mypackage.MyStruct{},
59
+ }
60
+ ```
61
+
62
+ 2. **Update dependencies:**
63
+ ```bash
64
+ go mod tidy
65
+ ```
66
+
67
+ 3. **Rebuild:**
68
+ ```bash
69
+ ./build.sh
70
+ ```
71
+
72
+ 4. **Use in Klasik:**
73
+ ```bash
74
+ klasik generate-go \
75
+ --type "github.com/org/package.MyStruct" \
76
+ --output ./src/types
77
+ ```
78
+
79
+ ## Dependencies
80
+
81
+ - **Go 1.21+**
82
+ - `github.com/invopop/jsonschema` v0.12.0 - JSON Schema generation
83
+ - `helm.sh/helm/v3` v3.14.0 - Example package (Helm chart types)
84
+
85
+ ## How It Works
86
+
87
+ 1. User specifies a type path (e.g., `"helm.sh/helm/v3/pkg/chart.Metadata"`)
88
+ 2. Tool looks up the type in `typeRegistry`
89
+ 3. Uses `invopop/jsonschema.Reflector` to generate JSON Schema
90
+ 4. Outputs JSON to stdout
91
+
92
+ **Architecture:**
93
+ ```
94
+ Go Struct → reflect.TypeOf() → jsonschema.Reflector → JSON Schema → stdout
95
+ ```
96
+
97
+ ## Struct Tag Support
98
+
99
+ The `invopop/jsonschema` library respects these struct tags:
100
+
101
+ | Tag | Effect | Example |
102
+ |-----|--------|---------|
103
+ | `json:"fieldName"` | Property name | `json:"metadata"` |
104
+ | `json:",omitempty"` | Optional field | `json:"description,omitempty"` |
105
+ | `jsonschema:"required"` | Force required | `jsonschema:"required"` |
106
+ | `jsonschema:"minLength=5"` | Min length | `jsonschema:"minLength=5"` |
107
+ | `jsonschema:"pattern=^[A-Z]"` | Regex pattern | `jsonschema:"pattern=^[A-Z]"` |
108
+ | `jsonschema_description:"..."` | Field description | `jsonschema_description:"Chart name"` |
109
+
110
+ **Example:**
111
+ ```go
112
+ type Chart struct {
113
+ Name string `json:"name" jsonschema:"required,minLength=1"`
114
+ Version string `json:"version" jsonschema:"pattern=^v[0-9]"`
115
+ Values map[string]interface{} `json:"values,omitempty"`
116
+ }
117
+ ```
118
+
119
+ ## Troubleshooting
120
+
121
+ **"Type not registered" error:**
122
+ - Add the type to `registry.go` (see "Adding New Types" above)
123
+ - Make sure to import the package
124
+ - Run `go mod tidy`
125
+ - Rebuild with `./build.sh`
126
+
127
+ **Build errors:**
128
+ - Ensure Go 1.21+ is installed: `go version`
129
+ - Clear module cache: `go clean -modcache`
130
+ - Try: `rm -f go.sum && go mod tidy`
131
+
132
+ **Import errors:**
133
+ - Check that the package version matches `go.mod`
134
+ - Run `go get <package>@<version>` to update
135
+
136
+ ## Limitations
137
+
138
+ - **No dynamic loading**: Types must be registered at compile time
139
+ - **Requires recompilation**: Adding new packages needs rebuild
140
+ - **Go installation required**: Cannot run without Go toolchain
141
+
142
+ ## Future Enhancements
143
+
144
+ - Go plugin support for dynamic type loading
145
+ - Auto-discovery of types in packages
146
+ - Support for `validate` struct tags
147
+ - Pre-built binaries for multiple platforms
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "Building go-schema-gen..."
5
+
6
+ # Download dependencies
7
+ echo "Downloading Go dependencies..."
8
+ go mod tidy
9
+
10
+ # Build binary
11
+ echo "Compiling binary..."
12
+ go build -o ../../dist/bin/go-schema-gen .
13
+
14
+ echo "✓ Build complete: dist/bin/go-schema-gen"
15
+
16
+ # Test the binary
17
+ echo ""
18
+ echo "Testing binary..."
19
+ if ../../dist/bin/go-schema-gen --type "helm.sh/helm/v3/pkg/chart.Metadata" > /dev/null 2>&1; then
20
+ echo "✓ Binary test successful"
21
+ else
22
+ echo "✗ Binary test failed"
23
+ exit 1
24
+ fi
@@ -0,0 +1,128 @@
1
+ package main
2
+
3
+ import (
4
+ "go/ast"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
8
+
9
+ "golang.org/x/tools/go/packages"
10
+ )
11
+
12
+ // CommentMap holds field comments for structs
13
+ type CommentMap map[string]map[string]string // packagePath.TypeName -> fieldName -> description
14
+
15
+ // ExtractComments extracts struct field comments from Go source code
16
+ func ExtractComments(packagePath string) (CommentMap, error) {
17
+ // Load the package with full type info and syntax
18
+ // Set Dir to the directory containing go.mod (tools/go-schema-gen)
19
+ // This ensures packages.Load can find dependencies regardless of where the binary is run from
20
+ cfg := &packages.Config{
21
+ Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo,
22
+ Dir: getModuleDir(),
23
+ }
24
+
25
+ pkgs, err := packages.Load(cfg, packagePath)
26
+ if err != nil {
27
+ return nil, err
28
+ }
29
+
30
+ if len(pkgs) == 0 {
31
+ return nil, nil
32
+ }
33
+
34
+ pkg := pkgs[0]
35
+ commentMap := make(CommentMap)
36
+
37
+ // Process each file in the package
38
+ for _, file := range pkg.Syntax {
39
+ // Traverse AST to find struct types and their field comments
40
+ ast.Inspect(file, func(n ast.Node) bool {
41
+ typeSpec, ok := n.(*ast.TypeSpec)
42
+ if !ok {
43
+ return true
44
+ }
45
+
46
+ structType, ok := typeSpec.Type.(*ast.StructType)
47
+ if !ok {
48
+ return true
49
+ }
50
+
51
+ // This is a struct type
52
+ structKey := pkg.PkgPath + "." + typeSpec.Name.Name
53
+ fieldComments := make(map[string]string)
54
+
55
+ // Extract field comments
56
+ for _, field := range structType.Fields.List {
57
+ if field.Doc != nil && len(field.Names) > 0 {
58
+ fieldName := field.Names[0].Name
59
+ comment := strings.TrimSpace(field.Doc.Text())
60
+ if comment != "" {
61
+ fieldComments[fieldName] = comment
62
+ }
63
+ }
64
+ }
65
+
66
+ if len(fieldComments) > 0 {
67
+ commentMap[structKey] = fieldComments
68
+ }
69
+
70
+ return true
71
+ })
72
+ }
73
+
74
+ return commentMap, nil
75
+ }
76
+
77
+ // GetFieldDescription retrieves the description for a specific struct field
78
+ func (cm CommentMap) GetFieldDescription(packagePath, typeName, fieldName string) string {
79
+ structKey := packagePath + "." + typeName
80
+ if fields, ok := cm[structKey]; ok {
81
+ return fields[fieldName]
82
+ }
83
+ return ""
84
+ }
85
+
86
+ // getModuleDir returns the directory containing go.mod
87
+ // This function searches for go.mod starting from the executable's directory
88
+ func getModuleDir() string {
89
+ // Get the executable path
90
+ exePath, err := os.Executable()
91
+ if err != nil {
92
+ return "."
93
+ }
94
+
95
+ // Resolve symlinks
96
+ exePath, err = filepath.EvalSymlinks(exePath)
97
+ if err != nil {
98
+ return "."
99
+ }
100
+
101
+ // Start from the directory containing the executable
102
+ dir := filepath.Dir(exePath)
103
+
104
+ // Check specific known locations first (for dist/bin/go-schema-gen)
105
+ // Try ../../tools/go-schema-gen (when binary is in dist/bin/)
106
+ toolsDir := filepath.Join(dir, "..", "..", "tools", "go-schema-gen")
107
+ if _, err := os.Stat(filepath.Join(toolsDir, "go.mod")); err == nil {
108
+ return toolsDir
109
+ }
110
+
111
+ // Search up the directory tree for go.mod
112
+ for {
113
+ goModPath := filepath.Join(dir, "go.mod")
114
+ if _, err := os.Stat(goModPath); err == nil {
115
+ return dir
116
+ }
117
+
118
+ parent := filepath.Dir(dir)
119
+ if parent == dir {
120
+ // Reached the root without finding go.mod
121
+ break
122
+ }
123
+ dir = parent
124
+ }
125
+
126
+ // Fallback to current directory
127
+ return "."
128
+ }
@@ -0,0 +1,36 @@
1
+ module github.com/koalaops/klasik/tools/go-schema-gen
2
+
3
+ go 1.22.0
4
+
5
+ require (
6
+ github.com/invopop/jsonschema v0.12.0
7
+ golang.org/x/tools v0.26.0
8
+ helm.sh/helm/v3 v3.14.0
9
+ k8s.io/api v0.29.0
10
+ )
11
+
12
+ require (
13
+ github.com/Masterminds/semver/v3 v3.2.1 // indirect
14
+ github.com/bahlo/generic-list-go v0.2.0 // indirect
15
+ github.com/buger/jsonparser v1.1.1 // indirect
16
+ github.com/go-logr/logr v1.3.0 // indirect
17
+ github.com/gogo/protobuf v1.3.2 // indirect
18
+ github.com/google/gofuzz v1.2.0 // indirect
19
+ github.com/json-iterator/go v1.1.12 // indirect
20
+ github.com/mailru/easyjson v0.7.7 // indirect
21
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
22
+ github.com/modern-go/reflect2 v1.0.2 // indirect
23
+ github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
24
+ golang.org/x/mod v0.21.0 // indirect
25
+ golang.org/x/net v0.30.0 // indirect
26
+ golang.org/x/sync v0.8.0 // indirect
27
+ golang.org/x/text v0.19.0 // indirect
28
+ gopkg.in/inf.v0 v0.9.1 // indirect
29
+ gopkg.in/yaml.v2 v2.4.0 // indirect
30
+ gopkg.in/yaml.v3 v3.0.1 // indirect
31
+ k8s.io/apimachinery v0.29.0 // indirect
32
+ k8s.io/klog/v2 v2.110.1 // indirect
33
+ k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
34
+ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
35
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
36
+ )
@@ -0,0 +1,112 @@
1
+ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
2
+ github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
3
+ github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
4
+ github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
5
+ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
6
+ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
7
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8
+ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
9
+ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10
+ github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
11
+ github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
12
+ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
13
+ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
14
+ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
15
+ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
16
+ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
17
+ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
18
+ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
19
+ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
20
+ github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI=
21
+ github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
22
+ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
23
+ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
24
+ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
25
+ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
26
+ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
27
+ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
28
+ github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
29
+ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
30
+ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
31
+ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
32
+ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
33
+ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
34
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
35
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
36
+ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
37
+ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
38
+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
39
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
40
+ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
41
+ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
42
+ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
43
+ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
44
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
45
+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
46
+ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
47
+ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
48
+ github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
49
+ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
50
+ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
51
+ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
52
+ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
53
+ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
54
+ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
55
+ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
56
+ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
57
+ golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
58
+ golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
59
+ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
60
+ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
61
+ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
62
+ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
63
+ golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
64
+ golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
65
+ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
66
+ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
67
+ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
68
+ golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
69
+ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
70
+ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
71
+ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
72
+ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
73
+ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
74
+ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
75
+ golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
76
+ golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
77
+ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
78
+ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
79
+ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
80
+ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
81
+ golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
82
+ golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
83
+ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
84
+ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
85
+ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
86
+ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
87
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
88
+ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
89
+ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
90
+ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
91
+ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
92
+ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
93
+ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
94
+ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
95
+ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
96
+ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
97
+ helm.sh/helm/v3 v3.14.0 h1:TaZIH6uOchn7L27ptwnnuHJiFrT/BsD4dFdp/HLT2nM=
98
+ helm.sh/helm/v3 v3.14.0/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424=
99
+ k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A=
100
+ k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA=
101
+ k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o=
102
+ k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis=
103
+ k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
104
+ k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
105
+ k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
106
+ k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
107
+ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
108
+ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
109
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
110
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
111
+ sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
112
+ sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
@@ -0,0 +1,155 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/json"
5
+ "flag"
6
+ "fmt"
7
+ "os"
8
+ "strings"
9
+
10
+ "github.com/invopop/jsonschema"
11
+ )
12
+
13
+ // Config holds the CLI configuration
14
+ type Config struct {
15
+ TypePath string
16
+ AllowAdditional bool
17
+ Expanded bool
18
+ }
19
+
20
+ func main() {
21
+ config := parseFlags()
22
+
23
+ // Get type value from registry
24
+ typeValue, err := getType(config.TypePath)
25
+ if err != nil {
26
+ fmt.Fprintf(os.Stderr, "Error: %v\n", err)
27
+ os.Exit(1)
28
+ }
29
+
30
+ // Extract package path from type path
31
+ packagePath := extractPackagePath(config.TypePath)
32
+
33
+ // Extract comments from Go source (AST parsing)
34
+ comments, err := ExtractComments(packagePath)
35
+ if err != nil {
36
+ // Non-fatal: just warn and continue without comments
37
+ fmt.Fprintf(os.Stderr, "Warning: Could not extract comments: %v\n", err)
38
+ comments = make(CommentMap)
39
+ }
40
+
41
+ // Generate schema
42
+ schema, err := generateSchema(typeValue, config)
43
+ if err != nil {
44
+ fmt.Fprintf(os.Stderr, "Error generating schema: %v\n", err)
45
+ os.Exit(1)
46
+ }
47
+
48
+ // Enrich schema with comments
49
+ enrichSchemaWithComments(schema, comments, config.TypePath)
50
+
51
+ // Output JSON
52
+ output, err := json.MarshalIndent(schema, "", " ")
53
+ if err != nil {
54
+ fmt.Fprintf(os.Stderr, "Error marshaling JSON: %v\n", err)
55
+ os.Exit(1)
56
+ }
57
+
58
+ fmt.Println(string(output))
59
+ }
60
+
61
+ // extractPackagePath extracts package path from type path
62
+ // Example: "helm.sh/helm/v3/pkg/chart.Metadata" -> "helm.sh/helm/v3/pkg/chart"
63
+ func extractPackagePath(typePath string) string {
64
+ lastDot := strings.LastIndex(typePath, ".")
65
+ if lastDot == -1 {
66
+ return typePath
67
+ }
68
+ return typePath[:lastDot]
69
+ }
70
+
71
+ // enrichSchemaWithComments adds field descriptions from Go comments to JSON Schema
72
+ func enrichSchemaWithComments(schema *jsonschema.Schema, comments CommentMap, typePath string) {
73
+ if schema.Definitions == nil {
74
+ return
75
+ }
76
+
77
+ // Get package path and type name
78
+ packagePath := extractPackagePath(typePath)
79
+ lastDot := strings.LastIndex(typePath, ".")
80
+ if lastDot == -1 {
81
+ return
82
+ }
83
+ rootTypeName := typePath[lastDot+1:]
84
+
85
+ // Enrich each definition
86
+ for defName, defSchema := range schema.Definitions {
87
+ // Try to match this definition to comments
88
+ fullTypeName := packagePath + "." + defName
89
+ fieldComments, ok := comments[fullTypeName]
90
+ if !ok {
91
+ // Also try with root type name
92
+ fullTypeName = packagePath + "." + rootTypeName
93
+ fieldComments, ok = comments[fullTypeName]
94
+ if !ok {
95
+ continue
96
+ }
97
+ }
98
+
99
+ // Add descriptions to properties
100
+ if defSchema.Properties != nil {
101
+ for pair := defSchema.Properties.Oldest(); pair != nil; pair = pair.Next() {
102
+ fieldName := pair.Key
103
+ propSchema := pair.Value
104
+
105
+ // Convert JSON field name to Go field name (capitalize first letter)
106
+ goFieldName := strings.ToUpper(fieldName[:1]) + fieldName[1:]
107
+ if desc, ok := fieldComments[goFieldName]; ok && desc != "" {
108
+ propSchema.Description = desc
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ func parseFlags() Config {
116
+ var config Config
117
+ flag.StringVar(&config.TypePath, "type", "", "Go type path (package.Type)")
118
+ flag.BoolVar(&config.AllowAdditional, "allow-additional", false, "Allow additional properties")
119
+ flag.BoolVar(&config.Expanded, "expanded", false, "Generate expanded definitions")
120
+ flag.Parse()
121
+
122
+ if config.TypePath == "" {
123
+ fmt.Fprintf(os.Stderr, "Error: --type is required\n\n")
124
+ flag.Usage()
125
+ os.Exit(1)
126
+ }
127
+
128
+ return config
129
+ }
130
+
131
+ func generateSchema(typeValue interface{}, config Config) (*jsonschema.Schema, error) {
132
+ reflector := jsonschema.Reflector{
133
+ AllowAdditionalProperties: config.AllowAdditional,
134
+ ExpandedStruct: config.Expanded,
135
+ DoNotReference: false,
136
+ }
137
+
138
+ return reflector.Reflect(typeValue), nil
139
+ }
140
+
141
+ func getType(typePath string) (interface{}, error) {
142
+ typeValue, ok := typeRegistry[typePath]
143
+ if !ok {
144
+ return nil, fmt.Errorf("type %s not registered.\n\nAvailable types:\n%s", typePath, listAvailableTypes())
145
+ }
146
+ return typeValue, nil
147
+ }
148
+
149
+ func listAvailableTypes() string {
150
+ var types []string
151
+ for k := range typeRegistry {
152
+ types = append(types, " - "+k)
153
+ }
154
+ return strings.Join(types, "\n")
155
+ }