Skip to content

Use Hugo js.Build bundling #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
with:
node-version: 14
node-version: 20

- name: npm install
working-directory: assets
run: npm ci

- name: setup go
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: '1.16'
go-version: '1.22'

- name: go build
working-directory: assets/go
run: GOARCH=wasm GOOS=js go build -o ../../static/lib.wasm

- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
uses: peaceiris/actions-hugo@v3
with:
hugo-version: 'latest'
extended: true
Expand All @@ -38,7 +38,7 @@ jobs:
run: hugo --minify

- name: Deploy
uses: peaceiris/actions-gh-pages@v3
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/resources
/public
lib.wasm
lib.wasm
assets/jsconfig.json
.hugo_build.lock
.tmp
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,22 @@ declare interface user {
Those two tools approach this the same way. In fact, one is a fork of the other. Both use Go generation to generate your tagged stucts and convert them to typescript interfaces.

This tool, however, doesn't use Go generation. Instead, we use `go/parser` to parse the provided go into a syntax tree, and then we loop through the `StructType` nodes within the tree to generate our typescript. Doing it this way allows us to convert any struct to typescript via the browser, vs having to tag our structs and generate them all each time. I'm sure their libraries are extremely useful in their workflow, but personally, we like to be a little less coupled than that.

## Build WASM

Before running the site locally or building the project, compile the Go code to WebAssembly:

```bash
cd assets/go
GOOS=js GOARCH=wasm go build -o ../../static/lib.wasm
```

## Testing

Install front-end dependencies and verify the Hugo build:

```bash
npm test
```

This runs the `pretest` script to install dependencies in `assets`, and then runs `hugo build` to verify the site builds successfully.
2 changes: 1 addition & 1 deletion assets/go/go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/StirlingMarketingGroup/go2ts/assets/go

go 1.16
go 1.22

require github.com/fatih/structtag v1.2.0
14 changes: 11 additions & 3 deletions assets/js/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
'use strict';

import '../node_modules/bootstrap/dist/js/bootstrap.bundle.js';
import * as monaco from '../node_modules/monaco-editor/esm/vs/editor/editor.api.js';
import './wasm_exec.js';
const go = new Go();
WebAssembly.instantiateStreaming(fetch('lib.wasm'), go.importObject).then((result) => {
go.run(result.instance);
});
delete globalThis.process;

const example =
`type user struct {
ID xid.Xid \`json:"id"\`
Expand All @@ -26,8 +35,7 @@ var src, dst;
// https://stackoverflow.com/questions/67437284/how-to-throw-js-error-from-go-web-assembly
var err;

require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }});
require(['vs/editor/editor.main'], function() {
{
monaco.editor.defineTheme('error', {
base: 'vs-dark',
inherit: true,
Expand Down Expand Up @@ -81,4 +89,4 @@ require(['vs/editor/editor.main'], function() {
}
});
});
});
}
67 changes: 60 additions & 7 deletions assets/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {},
"devDependencies": {
"bootstrap": "^5.0.0"
"@fortawesome/fontawesome-free": "^6.7.2",
"bootstrap": "^5.3.6",
"monaco-editor": "^0.52.2"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
Expand Down
4 changes: 4 additions & 0 deletions assets/sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ $link-color: #8be9fd;

$pink: #ff79c6;

@import "../node_modules/@fortawesome/fontawesome-free/css/all.css";
@import "../node_modules/monaco-editor/min/vs/editor/editor.main.css";

@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";

Expand Down
4 changes: 2 additions & 2 deletions content/index.md → content/_index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: Golang Struct to TypeScript Interface
type: index
layout: index
---

This tool converts Go structs to TypeScript interfaces. Paste a Go struct on the left and the TypeScript interface will be generated on the right.
Custom types will be left alone for you to fix yourself. `time.Time` are converted to strings, because this makes sense for our use case.
The "json" struct tag will change the name of the property. Any pointers or "omitempty" fields will be optional.

This uses Go compiled to web assembly, so sorry IE users. But not really.
This uses Go compiled to web assembly, so sorry IE users. But not really.
18 changes: 18 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module github.com/StirlingMarketingGroup/go2ts

go 1.23.1

require (
github.com/chromedp/cdproto v0.0.0-20250403032234-65de8f5d025b
github.com/chromedp/chromedp v0.13.6
)

require (
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/chromedp/sysutil v1.1.0 // indirect
github.com/go-json-experiment/json v0.0.0-20250211171154-1ae217ad3535 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.4.0 // indirect
golang.org/x/sys v0.29.0 // indirect
)
23 changes: 23 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/chromedp/cdproto v0.0.0-20250403032234-65de8f5d025b h1:jJmiCljLNTaq/O1ju9Bzz2MPpFlmiTn0F7LwCoeDZVw=
github.com/chromedp/cdproto v0.0.0-20250403032234-65de8f5d025b/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k=
github.com/chromedp/chromedp v0.13.6 h1:xlNunMyzS5bu3r/QKrb3fzX6ow3WBQ6oao+J65PGZxk=
github.com/chromedp/chromedp v0.13.6/go.mod h1:h8GPP6ZtLMLsU8zFbTcb7ZDGCvCy8j/vRoFmRltQx9A=
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
github.com/go-json-experiment/json v0.0.0-20250211171154-1ae217ad3535 h1:yE7argOs92u+sSCRgqqe6eF+cDaVhSPlioy1UkA0p/w=
github.com/go-json-experiment/json v0.0.0-20250211171154-1ae217ad3535/go.mod h1:BWmvoE1Xia34f3l/ibJweyhrT+aROb/FQ6d+37F0e2s=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
2 changes: 2 additions & 0 deletions config.toml → hugo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
baseURL = "https://stirlingmarketinggroup.github.io/go2ts/"
languageCode = "en-us"
title = "Go Struct to TypeScript Interface"

[Taxonomies]
30 changes: 7 additions & 23 deletions layouts/_default/baseof.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.61.0/codemirror.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.61.0/theme/dracula.min.css" rel="stylesheet">
{{ range resources.Match `node_modules/**` }}
{{ .Publish }}
{{ end }}

{{ $style := resources.Get "sass/main.scss" | toCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $style.Permalink }}">
<link href=https://use.fontawesome.com/releases/v5.13.1/css/all.css rel=stylesheet>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css" integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ==" crossorigin="anonymous" />
<link rel="stylesheet" href="{{ $style.RelPermalink }}">

<title>{{ block "title" . }}{{ .Site.Title }}{{ end }}</title>
<meta name="description" content="{{ .Params.description }}">
Expand Down Expand Up @@ -64,24 +63,9 @@
</div>
</footer>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script>

{{ $js := resources.Get "js/wasm_exec.js" | fingerprint }}
<script src="{{ $js.Permalink }}"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
</script>

<script>
delete process; // yeet
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js" integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw==" crossorigin="anonymous"></script>
{{ $js := resources.Get "js/app.js" | fingerprint }}
<script src="{{ $js.Permalink }}"></script>
{{ $opts := dict "target" "es2017" "format" "iife" "minify" true "bundle" true "externals" (slice "fs" "crypto" "os" "util") "loader" (dict "ttf" "data") }}
{{ $js := resources.Get "js/app.js" | js.Build $opts | fingerprint }}
<script src="{{ $js.RelPermalink }}"></script>

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-DJQYD6K7L7"></script>
Expand Down
26 changes: 26 additions & 0 deletions layouts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{ define "title" }}{{ .Title }}{{ end }}

{{ define "main" }}
<div class="container">
<p>
{{ .Content }}
</p>
</div>

<div class="row bg-primary py-2 text-center g-0 fs-4">
<div class="col">
Go Struct
</div>
<div class="col">
TypeScript
</div>
</div>
<div class="row g-0 flex-grow-1">
<div class="col-6">
<div id="src" class="w-100 h-100"></div>
</div>
<div class="col-6">
<div id="dst" class="w-100 h-100"></div>
</div>
</div>
{{ end }}
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "go2ts",
"version": "0.1.0",
"private": true,
"scripts": {
"pretest": "npm install --prefix assets && mkdir -p .tmp && (cd assets/go && TMPDIR=$(pwd)/../../.tmp GOOS=js GOARCH=wasm go build -o ../../static/lib.wasm)",
"test": "mkdir -p .tmp && export TMPDIR=$(pwd)/.tmp && hugo build && go test -v ./..."
}
}
Loading