Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
32cf6b4
Make resolver swappable
nathanwhit Sep 2, 2025
e397aae
refactor out session / project host
nathanwhit Sep 17, 2025
6b5759e
init wrapper host
nathanwhit Sep 18, 2025
32f623d
actually use custom host
nathanwhit Sep 18, 2025
e738efc
more wiring for api
nathanwhit Sep 18, 2025
6785a0d
resolver callbacks
nathanwhit Sep 22, 2025
8ba82e8
deno lib files + some fixes
nathanwhit Sep 24, 2025
8702c88
return both line/char and byte pos
nathanwhit Sep 25, 2025
4b340a1
implied node format on resolver
nathanwhit Sep 25, 2025
4a3dc8b
add isNodeSourceFile hook
nathanwhit Sep 25, 2025
f1a32c5
wip
nathanwhit Sep 25, 2025
7ee6616
massive symbol table refactor
nathanwhit Sep 26, 2025
f533d2e
ughhh
nathanwhit Sep 26, 2025
a54d5e9
debugging
nathanwhit Sep 29, 2025
a11c0f7
callback for isNodesourceFile
nathanwhit Sep 29, 2025
d40d5e1
merge symbol fix
nathanwhit Sep 29, 2025
baeee73
fixes
nathanwhit Sep 29, 2025
9fd0b89
cleanup
nathanwhit Sep 30, 2025
cc0dd12
Merge main into deno-tsgo
nathanwhit Sep 30, 2025
452ce2e
merge fixup
nathanwhit Sep 30, 2025
4201de8
release workflow
nathanwhit Sep 30, 2025
88fb8d0
fix workflow
nathanwhit Sep 30, 2025
c94e8d9
fix workflow
nathanwhit Sep 30, 2025
522aedd
pass source line in diagnostic
nathanwhit Sep 30, 2025
1ea2d83
upload source to release
nathanwhit Oct 1, 2025
21cddec
always treat case sensitive
nathanwhit Oct 2, 2025
d97e1b9
do not include lib files
nathanwhit Oct 2, 2025
225c766
put binary at root of release zip
nathanwhit Oct 3, 2025
39dc89c
Merge main into deno-tsgo
nathanwhit Oct 3, 2025
ee2cdf8
asset libpath
nathanwhit Oct 3, 2025
6e65dec
Merge main into deno-tsgo
nathanwhit Oct 3, 2025
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
154 changes: 154 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: Release

on:
push:
tags:
- 'v*'

permissions:
contents: write

defaults:
run:
shell: bash

jobs:
build:
name: Build ${{ matrix.archive_suffix }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
archive_suffix: linux-x64
binary_name: tsgo
- goos: linux
goarch: arm64
archive_suffix: linux-arm64
binary_name: tsgo
- goos: darwin
goarch: amd64
archive_suffix: macos-x64
binary_name: tsgo
- goos: darwin
goarch: arm64
archive_suffix: macos-arm64
binary_name: tsgo
- goos: windows
goarch: amd64
archive_suffix: windows-x64
binary_name: tsgo.exe

steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- uses: ./.github/actions/setup-go

- name: Determine version
id: version
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "VERSION=$VERSION" >> $GITHUB_ENV

- name: Build release archive
id: package
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: 0
run: |
set -euo pipefail

VERSION="${VERSION:?}"
TARGET="typescript-go-${VERSION}-${{ matrix.archive_suffix }}"
OUT_DIR="dist/${TARGET}"
BIN_NAME="${{ matrix.binary_name }}"

mkdir -p "$OUT_DIR"

go build \
-trimpath \
-tags "noembed,release" \
-ldflags "-s -w -X github.com/microsoft/typescript-go/internal/core.version=${VERSION}" \
-o "$OUT_DIR/$BIN_NAME" \
./cmd/tsgo

cp LICENSE "$OUT_DIR/"
cp NOTICE.txt "$OUT_DIR/"

ARCHIVE_NAME="${TARGET}.zip"
mkdir -p artifacts
zip -9 -j "artifacts/${ARCHIVE_NAME}" "$OUT_DIR"/*

echo "archive-path=artifacts/${ARCHIVE_NAME}" >> "$GITHUB_OUTPUT"

- name: Upload release artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: tsgo-${{ matrix.archive_suffix }}-${{ steps.version.outputs.version }}
path: ${{ steps.package.outputs.archive-path }}

publish:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Download build artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
path: release
merge-multiple: true

- name: Create source archive
run: |
set -euo pipefail

RAW_TAG="${GITHUB_REF_NAME}"
VERSION="${RAW_TAG#v}"
ARCHIVE_FOLDER="typescript-go-${VERSION}"
ARCHIVE_NAME="${ARCHIVE_FOLDER}-source.zip"
TMP_DIR="$(mktemp -d)"
SOURCE_DIR="${TMP_DIR}/${ARCHIVE_FOLDER}"

mkdir -p "${SOURCE_DIR}"

rsync -a \
--exclude='.git/' \
--exclude='release/' \
--exclude='node_modules/' \
--exclude='testdata/' \
./ "${SOURCE_DIR}/"

mkdir -p release
(cd "${TMP_DIR}" && zip -9 -r "${GITHUB_WORKSPACE}/release/${ARCHIVE_NAME}" "${ARCHIVE_FOLDER}")

- name: Create or update GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail

RAW_TAG="${GITHUB_REF_NAME}"
VERSION="${RAW_TAG#v}"
TITLE="TypeScript Go ${VERSION}"
NOTES="Release ${VERSION}"
REPO="${GITHUB_REPOSITORY}"

shopt -s nullglob
ASSETS=(release/*.zip)
if [ ${#ASSETS[@]} -eq 0 ]; then
echo "No release assets found" >&2
exit 1
fi

if gh release view "$RAW_TAG" --repo "$REPO" >/dev/null 2>&1; then
gh release edit "$RAW_TAG" --repo "$REPO" --title "$TITLE" --notes "$NOTES"
gh release upload "$RAW_TAG" "${ASSETS[@]}" --repo "$REPO" --clobber
else
gh release create "$RAW_TAG" "${ASSETS[@]}" --repo "$REPO" --title "$TITLE" --notes "$NOTES" --latest --verify-tag
fi
3 changes: 3 additions & 0 deletions cmd/tsgo/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ func runAPI(args []string) int {

defaultLibraryPath := bundled.LibPath()

logEnabled := os.Getenv("TSGO_LOG_ENABLED") == "1"

s := api.NewServer(&api.ServerOptions{
In: os.Stdin,
Out: os.Stdout,
Err: os.Stderr,
Cwd: *cwd,
DefaultLibraryPath: defaultLibraryPath,
LogEnabled: logEnabled,
})

if err := s.Run(); err != nil && !errors.Is(err, io.EOF) {
Expand Down
7 changes: 1 addition & 6 deletions cmd/tsgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package main

import (
"os"

"github.com/microsoft/typescript-go/internal/execute"
)

func main() {
Expand All @@ -14,12 +12,9 @@ func runMain() int {
args := os.Args[1:]
if len(args) > 0 {
switch args[0] {
case "--lsp":
return runLSP(args[1:])
case "--api":
return runAPI(args[1:])
}
}
result := execute.CommandLine(newSystem(), args, nil)
return int(result.Status)
return 1
}
29 changes: 28 additions & 1 deletion internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ func (api *API) HandleRequest(ctx context.Context, method string, payload []byte
return encodeJSON(core.TryMap(params.Symbols, func(symbol Handle[ast.Symbol]) (any, error) {
return api.GetTypeOfSymbol(ctx, params.Project, symbol)
}))
case MethodGetDiagnostics:
params := params.(*GetDiagnosticsParams)
return encodeJSON((api.GetDiagnostics(ctx, params.Project)))
default:
return nil, fmt.Errorf("unhandled API method %q", method)
}
Expand Down Expand Up @@ -262,6 +265,26 @@ func (api *API) GetSourceFile(projectId Handle[project.Project], fileName string
return sourceFile, nil
}

func (api *API) GetDiagnostics(ctx context.Context, projectId Handle[project.Project]) ([]ls.Diagnostic, error) {
projectPath, ok := api.projects[projectId]
if !ok {
return nil, errors.New("project ID not found")
}
snapshot, release := api.session.Snapshot()
defer release()
project := snapshot.ProjectCollection.GetProjectByPath(projectPath)
if project == nil {
return nil, errors.New("project not found")
}

languageService := ls.NewLanguageService(project, snapshot.Converters())
diagnostics := languageService.GetDiagnostics(ctx)

api.symbolsMu.Lock()
defer api.symbolsMu.Unlock()
return diagnostics, nil
}

func (api *API) releaseHandle(handle string) error {
switch handle[0] {
case handlePrefixProject:
Expand Down Expand Up @@ -316,5 +339,9 @@ func encodeJSON(v any, err error) ([]byte, error) {
if err != nil {
return nil, err
}
return json.Marshal(v)
b, err := json.Marshal(v)
if err != nil {
return nil, err
}
return b, nil
}
23 changes: 23 additions & 0 deletions internal/api/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package api

import "github.com/microsoft/typescript-go/internal/project/logging"

type NoLogger struct{}

// SetVerbose implements logging.Logger.
func (n NoLogger) SetVerbose(verbose bool) {
panic("unimplemented")
}

var _ logging.Logger = (*NoLogger)(nil)

func (n NoLogger) Log(msg ...any) {}
func (n NoLogger) Logf(format string, args ...any) {}
func (n NoLogger) Write(msg string) {}
func (n NoLogger) Verbose() logging.Logger {
return n
}

func (n NoLogger) IsVerbose() bool {
return false
}
6 changes: 6 additions & 0 deletions internal/api/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const (
MethodGetTypeOfSymbol Method = "getTypeOfSymbol"
MethodGetTypesOfSymbols Method = "getTypesOfSymbols"
MethodGetSourceFile Method = "getSourceFile"
MethodGetDiagnostics Method = "getDiagnostics"
)

var unmarshalers = map[Method]func([]byte) (any, error){
Expand All @@ -100,6 +101,7 @@ var unmarshalers = map[Method]func([]byte) (any, error){
MethodGetSymbolsAtLocations: unmarshallerFor[GetSymbolsAtLocationsParams],
MethodGetTypeOfSymbol: unmarshallerFor[GetTypeOfSymbolParams],
MethodGetTypesOfSymbols: unmarshallerFor[GetTypesOfSymbolsParams],
MethodGetDiagnostics: unmarshallerFor[GetDiagnosticsParams],
}

type ConfigureParams struct {
Expand Down Expand Up @@ -174,6 +176,10 @@ func NewSymbolResponse(symbol *ast.Symbol) *SymbolResponse {
}
}

type GetDiagnosticsParams struct {
Project Handle[project.Project] `json:"project"`
}

type GetTypeOfSymbolParams struct {
Project Handle[project.Project] `json:"project"`
Symbol Handle[ast.Symbol] `json:"symbol"`
Expand Down
Loading