remove unused packages
This commit is contained in:
parent
4712bb4e56
commit
d14eb0a9b7
@ -1,148 +0,0 @@
|
|||||||
package packagejson
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnostics"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/semver"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
|
|
||||||
)
|
|
||||||
|
|
||||||
var typeScriptVersion = semver.MustParse(core.Version())
|
|
||||||
|
|
||||||
type PackageJson struct {
|
|
||||||
Fields
|
|
||||||
versionPaths VersionPaths
|
|
||||||
versionTraces []string
|
|
||||||
once sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageJson) GetVersionPaths(trace func(string)) VersionPaths {
|
|
||||||
p.once.Do(func() {
|
|
||||||
if p.Fields.TypesVersions.Type == JSONValueTypeNotPresent {
|
|
||||||
p.versionTraces = append(p.versionTraces, diagnostics.X_package_json_does_not_have_a_0_field.Format("typesVersions"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if p.Fields.TypesVersions.Type != JSONValueTypeObject {
|
|
||||||
p.versionTraces = append(p.versionTraces, diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2.Format("typesVersions", "object", p.Fields.TypesVersions.Type.String()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
p.versionTraces = append(p.versionTraces, diagnostics.X_package_json_has_a_typesVersions_field_with_version_specific_path_mappings.Format("typesVersions"))
|
|
||||||
|
|
||||||
for key, value := range p.Fields.TypesVersions.AsObject().Entries() {
|
|
||||||
keyRange, ok := semver.TryParseVersionRange(key)
|
|
||||||
if !ok {
|
|
||||||
p.versionTraces = append(p.versionTraces, diagnostics.X_package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range.Format(key))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if keyRange.Test(&typeScriptVersion) {
|
|
||||||
if value.Type != JSONValueTypeObject {
|
|
||||||
p.versionTraces = append(p.versionTraces, diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2.Format("typesVersions['"+key+"']", "object", value.Type.String()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.versionPaths = VersionPaths{
|
|
||||||
Version: key,
|
|
||||||
pathsJSON: value.AsObject(),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.versionTraces = append(p.versionTraces, diagnostics.X_package_json_does_not_have_a_typesVersions_entry_that_matches_version_0.Format(core.VersionMajorMinor()))
|
|
||||||
})
|
|
||||||
if trace != nil {
|
|
||||||
for _, msg := range p.versionTraces {
|
|
||||||
trace(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return p.versionPaths
|
|
||||||
}
|
|
||||||
|
|
||||||
type VersionPaths struct {
|
|
||||||
Version string
|
|
||||||
pathsJSON *collections.OrderedMap[string, JSONValue]
|
|
||||||
paths *collections.OrderedMap[string, []string]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VersionPaths) Exists() bool {
|
|
||||||
return v != nil && v.Version != "" && v.pathsJSON != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VersionPaths) GetPaths() *collections.OrderedMap[string, []string] {
|
|
||||||
if !v.Exists() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if v.paths != nil {
|
|
||||||
return v.paths
|
|
||||||
}
|
|
||||||
paths := collections.NewOrderedMapWithSizeHint[string, []string](v.pathsJSON.Size())
|
|
||||||
for key, value := range v.pathsJSON.Entries() {
|
|
||||||
if value.Type != JSONValueTypeArray {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
slice := make([]string, len(value.AsArray()))
|
|
||||||
for i, path := range value.AsArray() {
|
|
||||||
if path.Type != JSONValueTypeString {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
slice[i] = path.Value.(string)
|
|
||||||
}
|
|
||||||
paths.Set(key, slice)
|
|
||||||
}
|
|
||||||
v.paths = paths
|
|
||||||
return v.paths
|
|
||||||
}
|
|
||||||
|
|
||||||
type InfoCacheEntry struct {
|
|
||||||
PackageDirectory string
|
|
||||||
DirectoryExists bool
|
|
||||||
Contents *PackageJson
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *InfoCacheEntry) Exists() bool {
|
|
||||||
return p != nil && p.Contents != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *InfoCacheEntry) GetContents() *PackageJson {
|
|
||||||
if p == nil || p.Contents == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return p.Contents
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *InfoCacheEntry) GetDirectory() string {
|
|
||||||
if p == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return p.PackageDirectory
|
|
||||||
}
|
|
||||||
|
|
||||||
type InfoCache struct {
|
|
||||||
cache collections.SyncMap[tspath.Path, *InfoCacheEntry]
|
|
||||||
currentDirectory string
|
|
||||||
useCaseSensitiveFileNames bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInfoCache(currentDirectory string, useCaseSensitiveFileNames bool) *InfoCache {
|
|
||||||
return &InfoCache{
|
|
||||||
currentDirectory: currentDirectory,
|
|
||||||
useCaseSensitiveFileNames: useCaseSensitiveFileNames,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *InfoCache) Get(packageJsonPath string) *InfoCacheEntry {
|
|
||||||
key := tspath.ToPath(packageJsonPath, p.currentDirectory, p.useCaseSensitiveFileNames)
|
|
||||||
if value, ok := p.cache.Load(key); ok {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *InfoCache) Set(packageJsonPath string, info *InfoCacheEntry) *InfoCacheEntry {
|
|
||||||
key := tspath.ToPath(packageJsonPath, p.currentDirectory, p.useCaseSensitiveFileNames)
|
|
||||||
actual, _ := p.cache.LoadOrStore(key, info)
|
|
||||||
return actual
|
|
||||||
}
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
package packagejson
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/go-json-experiment/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Expected[T any] struct {
|
|
||||||
actualJSONType string
|
|
||||||
Null bool
|
|
||||||
Valid bool
|
|
||||||
Value T
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Expected[T]) UnmarshalJSON(data []byte) error {
|
|
||||||
if string(data) == "null" {
|
|
||||||
*e = Expected[T]{Null: true, actualJSONType: "null"}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if json.Unmarshal(data, &e.Value) == nil {
|
|
||||||
e.Valid = true
|
|
||||||
}
|
|
||||||
switch data[0] {
|
|
||||||
case '"':
|
|
||||||
e.actualJSONType = "string"
|
|
||||||
case 't', 'f':
|
|
||||||
e.actualJSONType = "boolean"
|
|
||||||
case '[':
|
|
||||||
e.actualJSONType = "array"
|
|
||||||
case '{':
|
|
||||||
e.actualJSONType = "object"
|
|
||||||
default:
|
|
||||||
e.actualJSONType = "number"
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Expected[T]) IsPresent() bool {
|
|
||||||
return e.actualJSONType != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Expected[T]) GetValue() (value T, ok bool) {
|
|
||||||
return e.Value, e.Valid
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Expected[T]) IsValid() bool {
|
|
||||||
return e.Valid
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Expected[T]) ExpectedJSONType() string {
|
|
||||||
switch reflect.TypeFor[T]().Kind() {
|
|
||||||
case reflect.String:
|
|
||||||
return "string"
|
|
||||||
case reflect.Bool:
|
|
||||||
return "boolean"
|
|
||||||
case reflect.Slice, reflect.Array:
|
|
||||||
return "array"
|
|
||||||
case reflect.Map:
|
|
||||||
return "object"
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
|
||||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return "number"
|
|
||||||
default:
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Expected[T]) ActualJSONType() string {
|
|
||||||
return e.actualJSONType
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExpectedOf[T any](value T) Expected[T] {
|
|
||||||
return Expected[T]{Value: value, Valid: true, actualJSONType: (*Expected[T])(nil).ExpectedJSONType()}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package packagejson_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/packagejson"
|
|
||||||
"github.com/go-json-experiment/json"
|
|
||||||
"gotest.tools/v3/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestExpected(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
type packageJson struct {
|
|
||||||
Name packagejson.Expected[string] `json:"name"`
|
|
||||||
Version packagejson.Expected[string] `json:"version"`
|
|
||||||
Exports packagejson.Expected[any] `json:"exports"`
|
|
||||||
Main packagejson.Expected[string] `json:"main"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var p packageJson
|
|
||||||
|
|
||||||
jsonString := `{
|
|
||||||
"name": "test",
|
|
||||||
"version": 2,
|
|
||||||
"exports": null
|
|
||||||
}`
|
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(jsonString), &p)
|
|
||||||
assert.NilError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, p.Name.Valid, true)
|
|
||||||
assert.Equal(t, p.Name.Value, "test")
|
|
||||||
|
|
||||||
assert.Equal(t, p.Version.Valid, false)
|
|
||||||
assert.Equal(t, p.Version.Value, "")
|
|
||||||
|
|
||||||
assert.Assert(t, p.Exports.Null)
|
|
||||||
assert.Equal(t, p.Exports.Valid, false)
|
|
||||||
|
|
||||||
assert.Equal(t, p.Main.Valid, false)
|
|
||||||
assert.Equal(t, p.Main.Null, false)
|
|
||||||
assert.Equal(t, p.Main.Value, "")
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
package packagejson
|
|
||||||
|
|
||||||
import (
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections"
|
|
||||||
"github.com/go-json-experiment/json"
|
|
||||||
"github.com/go-json-experiment/json/jsontext"
|
|
||||||
)
|
|
||||||
|
|
||||||
type objectKind int8
|
|
||||||
|
|
||||||
const (
|
|
||||||
objectKindUnknown objectKind = iota
|
|
||||||
objectKindSubpaths
|
|
||||||
objectKindConditions
|
|
||||||
objectKindImports
|
|
||||||
objectKindInvalid
|
|
||||||
)
|
|
||||||
|
|
||||||
type ExportsOrImports struct {
|
|
||||||
JSONValue
|
|
||||||
objectKind objectKind
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ json.UnmarshalerFrom = (*ExportsOrImports)(nil)
|
|
||||||
|
|
||||||
func (e *ExportsOrImports) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
|
||||||
return unmarshalJSONValueV2[ExportsOrImports](&e.JSONValue, dec)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ExportsOrImports) AsObject() *collections.OrderedMap[string, ExportsOrImports] {
|
|
||||||
if e.Type != JSONValueTypeObject {
|
|
||||||
panic("expected object")
|
|
||||||
}
|
|
||||||
return e.Value.(*collections.OrderedMap[string, ExportsOrImports])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ExportsOrImports) AsArray() []ExportsOrImports {
|
|
||||||
if e.Type != JSONValueTypeArray {
|
|
||||||
panic("expected array")
|
|
||||||
}
|
|
||||||
return e.Value.([]ExportsOrImports)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ExportsOrImports) IsSubpaths() bool {
|
|
||||||
e.initObjectKind()
|
|
||||||
return e.objectKind == objectKindSubpaths
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ExportsOrImports) IsImports() bool {
|
|
||||||
e.initObjectKind()
|
|
||||||
return e.objectKind == objectKindImports
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ExportsOrImports) IsConditions() bool {
|
|
||||||
e.initObjectKind()
|
|
||||||
return e.objectKind == objectKindConditions
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *ExportsOrImports) initObjectKind() {
|
|
||||||
if e.objectKind == objectKindUnknown && e.Type == JSONValueTypeObject {
|
|
||||||
if obj := e.AsObject(); obj.Size() > 0 {
|
|
||||||
seenDot, seenHash, seenOther := false, false, false
|
|
||||||
for k := range obj.Keys() {
|
|
||||||
if len(k) > 0 {
|
|
||||||
seenDot = seenDot || k[0] == '.'
|
|
||||||
seenHash = seenHash || k[0] == '#'
|
|
||||||
seenOther = seenOther || (k[0] != '.' && k[0] != '#')
|
|
||||||
if seenOther && (seenDot || seenHash) {
|
|
||||||
e.objectKind = objectKindInvalid
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if seenDot {
|
|
||||||
e.objectKind = objectKindSubpaths
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if seenHash {
|
|
||||||
e.objectKind = objectKindImports
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.objectKind = objectKindConditions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
package packagejson_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/packagejson"
|
|
||||||
"github.com/go-json-experiment/json"
|
|
||||||
"gotest.tools/v3/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestExports(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
t.Run("UnmarshalJSONV2", func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
testExports(t, func(in []byte, out any) error { return json.Unmarshal(in, out) })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testExports(t *testing.T, unmarshal func([]byte, any) error) {
|
|
||||||
type Exports struct {
|
|
||||||
Imports packagejson.ExportsOrImports `json:"imports"`
|
|
||||||
Exports packagejson.ExportsOrImports `json:"exports"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var e Exports
|
|
||||||
|
|
||||||
jsonString := `{
|
|
||||||
"imports": {
|
|
||||||
"#foo": {
|
|
||||||
"import": "./foo.ts"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": "./test.ts",
|
|
||||||
"default": "./test.ts"
|
|
||||||
},
|
|
||||||
"./test": [
|
|
||||||
"./test1.ts",
|
|
||||||
"./test2.ts",
|
|
||||||
null
|
|
||||||
],
|
|
||||||
"./null": null
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
|
|
||||||
err := unmarshal([]byte(jsonString), &e)
|
|
||||||
assert.NilError(t, err)
|
|
||||||
|
|
||||||
assert.Assert(t, e.Exports.IsSubpaths())
|
|
||||||
assert.Equal(t, e.Exports.AsObject().Size(), 3)
|
|
||||||
assert.Assert(t, e.Exports.AsObject().GetOrZero(".").IsConditions())
|
|
||||||
assert.Assert(t, e.Exports.AsObject().GetOrZero(".").AsObject().GetOrZero("import").Type == packagejson.JSONValueTypeString)
|
|
||||||
assert.Equal(t, e.Exports.AsObject().GetOrZero("./test").AsArray()[2].Type, packagejson.JSONValueTypeNull)
|
|
||||||
assert.Assert(t, e.Exports.AsObject().GetOrZero("./null").Type == packagejson.JSONValueTypeNull)
|
|
||||||
|
|
||||||
assert.Assert(t, e.Imports.IsImports())
|
|
||||||
assert.Equal(t, e.Imports.AsObject().Size(), 1)
|
|
||||||
assert.Assert(t, e.Imports.AsObject().GetOrZero("#foo").IsConditions())
|
|
||||||
assert.Assert(t, e.Imports.AsObject().GetOrZero("#foo").AsObject().GetOrZero("import").Type == packagejson.JSONValueTypeString)
|
|
||||||
}
|
|
||||||
@ -1,165 +0,0 @@
|
|||||||
package packagejson
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections"
|
|
||||||
"github.com/go-json-experiment/json"
|
|
||||||
"github.com/go-json-experiment/json/jsontext"
|
|
||||||
)
|
|
||||||
|
|
||||||
type JSONValueType int8
|
|
||||||
|
|
||||||
const (
|
|
||||||
JSONValueTypeNotPresent JSONValueType = iota
|
|
||||||
JSONValueTypeNull
|
|
||||||
JSONValueTypeString
|
|
||||||
JSONValueTypeNumber
|
|
||||||
JSONValueTypeBoolean
|
|
||||||
JSONValueTypeArray
|
|
||||||
JSONValueTypeObject
|
|
||||||
)
|
|
||||||
|
|
||||||
func (t JSONValueType) String() string {
|
|
||||||
switch t {
|
|
||||||
case JSONValueTypeNull:
|
|
||||||
return "null"
|
|
||||||
case JSONValueTypeString:
|
|
||||||
return "string"
|
|
||||||
case JSONValueTypeNumber:
|
|
||||||
return "number"
|
|
||||||
case JSONValueTypeBoolean:
|
|
||||||
return "boolean"
|
|
||||||
case JSONValueTypeArray:
|
|
||||||
return "array"
|
|
||||||
case JSONValueTypeObject:
|
|
||||||
return "object"
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown(%d)", t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type JSONValue struct {
|
|
||||||
Type JSONValueType
|
|
||||||
Value any
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *JSONValue) IsFalsy() bool {
|
|
||||||
switch v.Type {
|
|
||||||
case JSONValueTypeNotPresent, JSONValueTypeNull:
|
|
||||||
return true
|
|
||||||
case JSONValueTypeString:
|
|
||||||
return v.Value == ""
|
|
||||||
case JSONValueTypeNumber:
|
|
||||||
return v.Value == 0
|
|
||||||
case JSONValueTypeBoolean:
|
|
||||||
return !v.Value.(bool)
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v JSONValue) AsObject() *collections.OrderedMap[string, JSONValue] {
|
|
||||||
if v.Type != JSONValueTypeObject {
|
|
||||||
panic(fmt.Sprintf("expected object, got %v", v.Type))
|
|
||||||
}
|
|
||||||
return v.Value.(*collections.OrderedMap[string, JSONValue])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v JSONValue) AsArray() []JSONValue {
|
|
||||||
if v.Type != JSONValueTypeArray {
|
|
||||||
panic(fmt.Sprintf("expected array, got %v", v.Type))
|
|
||||||
}
|
|
||||||
return v.Value.([]JSONValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ json.UnmarshalerFrom = (*JSONValue)(nil)
|
|
||||||
|
|
||||||
func (v *JSONValue) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
|
||||||
return unmarshalJSONValueV2[JSONValue](v, dec)
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalJSONValue[T any](v *JSONValue, data []byte) error {
|
|
||||||
if string(data) == "null" {
|
|
||||||
*v = JSONValue{Type: JSONValueTypeNull}
|
|
||||||
} else if data[0] == '"' {
|
|
||||||
v.Type = JSONValueTypeString
|
|
||||||
return json.Unmarshal(data, &v.Value)
|
|
||||||
} else if data[0] == '[' {
|
|
||||||
var elements []T
|
|
||||||
if err := json.Unmarshal(data, &elements); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.Type = JSONValueTypeArray
|
|
||||||
v.Value = elements
|
|
||||||
} else if data[0] == '{' {
|
|
||||||
var object collections.OrderedMap[string, T]
|
|
||||||
if err := json.Unmarshal(data, &object); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.Type = JSONValueTypeObject
|
|
||||||
v.Value = &object
|
|
||||||
} else if string(data) == "true" {
|
|
||||||
v.Type = JSONValueTypeBoolean
|
|
||||||
v.Value = true
|
|
||||||
} else if string(data) == "false" {
|
|
||||||
v.Type = JSONValueTypeBoolean
|
|
||||||
v.Value = false
|
|
||||||
} else {
|
|
||||||
v.Type = JSONValueTypeNumber
|
|
||||||
return json.Unmarshal(data, &v.Value)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalJSONValueV2[T any](v *JSONValue, dec *jsontext.Decoder) error {
|
|
||||||
switch dec.PeekKind() {
|
|
||||||
case 'n': // jsontext.Null.Kind()
|
|
||||||
if _, err := dec.ReadToken(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.Value = nil
|
|
||||||
v.Type = JSONValueTypeNull
|
|
||||||
return nil
|
|
||||||
case '"':
|
|
||||||
v.Type = JSONValueTypeString
|
|
||||||
if err := json.UnmarshalDecode(dec, &v.Value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case '[':
|
|
||||||
if _, err := dec.ReadToken(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var elements []T
|
|
||||||
for dec.PeekKind() != jsontext.EndArray.Kind() {
|
|
||||||
var element T
|
|
||||||
if err := json.UnmarshalDecode(dec, &element); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
elements = append(elements, element)
|
|
||||||
}
|
|
||||||
if _, err := dec.ReadToken(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.Type = JSONValueTypeArray
|
|
||||||
v.Value = elements
|
|
||||||
case '{':
|
|
||||||
var object collections.OrderedMap[string, T]
|
|
||||||
if err := json.UnmarshalDecode(dec, &object); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.Type = JSONValueTypeObject
|
|
||||||
v.Value = &object
|
|
||||||
case 't', 'f': // jsontext.True.Kind(), jsontext.False.Kind()
|
|
||||||
v.Type = JSONValueTypeBoolean
|
|
||||||
if err := json.UnmarshalDecode(dec, &v.Value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
v.Type = JSONValueTypeNumber
|
|
||||||
if err := json.UnmarshalDecode(dec, &v.Value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
package packagejson_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/packagejson"
|
|
||||||
"github.com/go-json-experiment/json"
|
|
||||||
"gotest.tools/v3/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestJSONValue(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
t.Run("UnmarshalJSONV2", func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
testJSONValue(t, func(in []byte, out any) error { return json.Unmarshal(in, out) })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testJSONValue(t *testing.T, unmarshal func([]byte, any) error) {
|
|
||||||
type packageJson struct {
|
|
||||||
Private packagejson.JSONValue `json:"private"`
|
|
||||||
False packagejson.JSONValue `json:"false"`
|
|
||||||
Name packagejson.JSONValue `json:"name"`
|
|
||||||
Version packagejson.JSONValue `json:"version"`
|
|
||||||
Exports packagejson.JSONValue `json:"exports"`
|
|
||||||
Imports packagejson.JSONValue `json:"imports"`
|
|
||||||
NotPresent packagejson.JSONValue `json:"notPresent"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var p packageJson
|
|
||||||
|
|
||||||
jsonString := `{
|
|
||||||
"private": true,
|
|
||||||
"false": false,
|
|
||||||
"name": "test",
|
|
||||||
"version": 2,
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": "./test.ts",
|
|
||||||
"default": "./test.ts"
|
|
||||||
},
|
|
||||||
"./test": [
|
|
||||||
"./test1.ts",
|
|
||||||
"./test2.ts",
|
|
||||||
null
|
|
||||||
],
|
|
||||||
"./null": null
|
|
||||||
},
|
|
||||||
"imports": null
|
|
||||||
}`
|
|
||||||
|
|
||||||
err := unmarshal([]byte(jsonString), &p)
|
|
||||||
assert.NilError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, p.Private.Type, packagejson.JSONValueTypeBoolean)
|
|
||||||
assert.Equal(t, p.Private.Value, true)
|
|
||||||
|
|
||||||
assert.Equal(t, p.Name.Type, packagejson.JSONValueTypeString)
|
|
||||||
assert.Equal(t, p.Name.Value, "test")
|
|
||||||
|
|
||||||
assert.Equal(t, p.Version.Type, packagejson.JSONValueTypeNumber)
|
|
||||||
assert.Equal(t, p.Version.Value, float64(2))
|
|
||||||
|
|
||||||
assert.Equal(t, p.Exports.Type, packagejson.JSONValueTypeObject)
|
|
||||||
assert.Equal(t, p.Exports.AsObject().Size(), 3)
|
|
||||||
assert.Equal(t, p.Exports.AsObject().GetOrZero(".").Type, packagejson.JSONValueTypeObject)
|
|
||||||
assert.Equal(t, p.Exports.AsObject().GetOrZero(".").AsObject().GetOrZero("import").Value, "./test.ts")
|
|
||||||
|
|
||||||
assert.Equal(t, p.Exports.AsObject().GetOrZero("./test").Type, packagejson.JSONValueTypeArray)
|
|
||||||
assert.Equal(t, len(p.Exports.AsObject().GetOrZero("./test").AsArray()), 3)
|
|
||||||
assert.Equal(t, p.Exports.AsObject().GetOrZero("./test").AsArray()[0].Value, "./test1.ts")
|
|
||||||
assert.Equal(t, p.Exports.AsObject().GetOrZero("./test").AsArray()[1].Value, "./test2.ts")
|
|
||||||
assert.Equal(t, p.Exports.AsObject().GetOrZero("./test").AsArray()[2].Type, packagejson.JSONValueTypeNull)
|
|
||||||
|
|
||||||
assert.Equal(t, p.Exports.AsObject().GetOrZero("./null").Type, packagejson.JSONValueTypeNull)
|
|
||||||
|
|
||||||
assert.Equal(t, p.Imports.Type, packagejson.JSONValueTypeNull)
|
|
||||||
assert.Equal(t, p.Imports.Value, nil)
|
|
||||||
|
|
||||||
assert.Equal(t, p.NotPresent.Type, packagejson.JSONValueTypeNotPresent)
|
|
||||||
assert.Equal(t, p.NotPresent.Value, nil)
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package packagejson
|
|
||||||
|
|
||||||
import (
|
|
||||||
json "github.com/go-json-experiment/json"
|
|
||||||
"github.com/go-json-experiment/json/jsontext"
|
|
||||||
)
|
|
||||||
|
|
||||||
type HeaderFields struct {
|
|
||||||
Name Expected[string] `json:"name"`
|
|
||||||
Version Expected[string] `json:"version"`
|
|
||||||
Type Expected[string] `json:"type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathFields struct {
|
|
||||||
TSConfig Expected[string] `json:"tsconfig"`
|
|
||||||
Main Expected[string] `json:"main"`
|
|
||||||
Types Expected[string] `json:"types"`
|
|
||||||
Typings Expected[string] `json:"typings"`
|
|
||||||
TypesVersions JSONValue `json:"typesVersions"`
|
|
||||||
Imports ExportsOrImports `json:"imports"`
|
|
||||||
Exports ExportsOrImports `json:"exports"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DependencyFields struct {
|
|
||||||
Dependencies Expected[map[string]string] `json:"dependencies"`
|
|
||||||
DevDependencies Expected[map[string]string] `json:"devDependencies"`
|
|
||||||
PeerDependencies Expected[map[string]string] `json:"peerDependencies"`
|
|
||||||
OptionalDependencies Expected[map[string]string] `json:"optionalDependencies"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Fields struct {
|
|
||||||
HeaderFields
|
|
||||||
PathFields
|
|
||||||
DependencyFields
|
|
||||||
}
|
|
||||||
|
|
||||||
func Parse(data []byte) (Fields, error) {
|
|
||||||
var f Fields
|
|
||||||
if err := json.Unmarshal(data, &f, jsontext.AllowDuplicateNames(true)); err != nil {
|
|
||||||
return Fields{}, err
|
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
@ -1,103 +0,0 @@
|
|||||||
package packagejson_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/packagejson"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/parser"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/repo"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/testutil/filefixture"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
|
|
||||||
"github.com/go-json-experiment/json"
|
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
|
||||||
"gotest.tools/v3/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
var packageJsonFixtures = []filefixture.Fixture{
|
|
||||||
filefixture.FromFile("package.json", filepath.Join(repo.RootPath, "package.json")),
|
|
||||||
filefixture.FromFile("date-fns.json", filepath.Join(repo.TestDataPath, "fixtures", "packagejson", "date-fns.json")),
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkPackageJSON(b *testing.B) {
|
|
||||||
for _, f := range packageJsonFixtures {
|
|
||||||
f.SkipIfNotExist(b)
|
|
||||||
content := []byte(f.ReadFile(b))
|
|
||||||
b.Run("UnmarshalJSON", func(b *testing.B) {
|
|
||||||
b.Run(f.Name(), func(b *testing.B) {
|
|
||||||
for b.Loop() {
|
|
||||||
var p packagejson.Fields
|
|
||||||
if err := json.Unmarshal(content, &p); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
b.Run("UnmarshalJSONV2", func(b *testing.B) {
|
|
||||||
b.Run(f.Name(), func(b *testing.B) {
|
|
||||||
for b.Loop() {
|
|
||||||
var p packagejson.Fields
|
|
||||||
if err := json.Unmarshal(content, &p); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
b.Run("ParseJSONText", func(b *testing.B) {
|
|
||||||
b.Run(f.Name(), func(b *testing.B) {
|
|
||||||
fileName := "/" + f.Name()
|
|
||||||
for b.Loop() {
|
|
||||||
parser.ParseSourceFile(ast.SourceFileParseOptions{
|
|
||||||
FileName: fileName,
|
|
||||||
Path: tspath.Path(fileName),
|
|
||||||
}, string(content), core.ScriptKindJSON)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
content string
|
|
||||||
want packagejson.Fields
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "duplicate names",
|
|
||||||
content: `{
|
|
||||||
"name": "test-package",
|
|
||||||
"name": "test-package",
|
|
||||||
"version": "1.0.0"
|
|
||||||
}`,
|
|
||||||
want: packagejson.Fields{
|
|
||||||
HeaderFields: packagejson.HeaderFields{
|
|
||||||
Name: packagejson.ExpectedOf("test-package"),
|
|
||||||
Version: packagejson.ExpectedOf("1.0.0"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
got, err := packagejson.Parse([]byte(tt.content))
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.DeepEqual(t, got, tt.want, cmpopts.IgnoreUnexported(
|
|
||||||
packagejson.Fields{},
|
|
||||||
packagejson.HeaderFields{},
|
|
||||||
packagejson.Expected[string]{},
|
|
||||||
packagejson.Expected[map[string]string]{},
|
|
||||||
packagejson.ExportsOrImports{},
|
|
||||||
))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
package packagejson
|
|
||||||
|
|
||||||
type TypeValidatedField interface {
|
|
||||||
IsPresent() bool
|
|
||||||
IsValid() bool
|
|
||||||
ExpectedJSONType() string
|
|
||||||
ActualJSONType() string
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user