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.
- package/README.md +710 -3
- package/dist/bin/go-schema-gen +0 -0
- package/dist/builders/class-builder.d.ts +1 -0
- package/dist/builders/class-builder.d.ts.map +1 -1
- package/dist/builders/class-builder.js.map +1 -1
- package/dist/cli/commands/generate-crd.d.ts +1 -0
- package/dist/cli/commands/generate-crd.d.ts.map +1 -1
- package/dist/cli/commands/generate-crd.js +2 -0
- package/dist/cli/commands/generate-crd.js.map +1 -1
- package/dist/cli/commands/generate-go.d.ts +22 -0
- package/dist/cli/commands/generate-go.d.ts.map +1 -0
- package/dist/cli/commands/generate-go.js +130 -0
- package/dist/cli/commands/generate-go.js.map +1 -0
- package/dist/cli/commands/generate-jsonschema.d.ts +1 -0
- package/dist/cli/commands/generate-jsonschema.d.ts.map +1 -1
- package/dist/cli/commands/generate-jsonschema.js +2 -0
- package/dist/cli/commands/generate-jsonschema.js.map +1 -1
- package/dist/cli/commands/generate.d.ts +1 -0
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +2 -0
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/options.d.ts +4 -0
- package/dist/cli/utils/options.d.ts.map +1 -1
- package/dist/cli/utils/options.js +7 -0
- package/dist/cli/utils/options.js.map +1 -1
- package/dist/generator/generator.d.ts.map +1 -1
- package/dist/generator/generator.js +4 -0
- package/dist/generator/generator.js.map +1 -1
- package/dist/loaders/go-schema-loader.d.ts +60 -0
- package/dist/loaders/go-schema-loader.d.ts.map +1 -0
- package/dist/loaders/go-schema-loader.js +221 -0
- package/dist/loaders/go-schema-loader.js.map +1 -0
- package/dist/plugins/ajv-validator-plugin.d.ts +45 -0
- package/dist/plugins/ajv-validator-plugin.d.ts.map +1 -0
- package/dist/plugins/ajv-validator-plugin.js +320 -0
- package/dist/plugins/ajv-validator-plugin.js.map +1 -0
- package/package.json +5 -3
- package/tools/go-schema-gen/README.md +147 -0
- package/tools/go-schema-gen/build.sh +24 -0
- package/tools/go-schema-gen/comment_extractor.go +128 -0
- package/tools/go-schema-gen/go-schema-gen +0 -0
- package/tools/go-schema-gen/go.mod +36 -0
- package/tools/go-schema-gen/go.sum +112 -0
- package/tools/go-schema-gen/main.go +155 -0
- 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
|
|
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
|
+
}
|
|
Binary file
|
|
@@ -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
|
+
}
|