added jsvm typings and docs generation
This commit is contained in:
parent
c0a6a21b9e
commit
ed4304dc30
|
@ -1,8 +1,11 @@
|
||||||
package jsvm
|
package jsvm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
|
@ -12,8 +15,16 @@ import (
|
||||||
"github.com/dop251/goja_nodejs/require"
|
"github.com/dop251/goja_nodejs/require"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/pocketbase/dbx"
|
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
"github.com/pocketbase/pocketbase/plugins/jsvm/internal/docs/generated"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
hooksExtension = ".pb.js"
|
||||||
|
|
||||||
|
typesFileName = ".types.d.ts"
|
||||||
|
|
||||||
|
typesReferenceDirective = `/// <reference path="./` + typesFileName + `" />`
|
||||||
)
|
)
|
||||||
|
|
||||||
// HooksConfig defines the config options of the JS app hooks plugin.
|
// HooksConfig defines the config options of the JS app hooks plugin.
|
||||||
|
@ -51,12 +62,21 @@ func RegisterHooks(app core.App, config HooksConfig) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch all js hooks sorted by their filename
|
// fetch all js hooks sorted by their filename
|
||||||
files, err := filesContent(p.config.Dir, `^.*\.pb\.js$`)
|
files, err := filesContent(p.config.Dir, `^.*`+regexp.QuoteMeta(hooksExtension)+`$`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbx.HashExp{}.Build(app.DB(), nil)
|
// prepend the types reference directive to empty files
|
||||||
|
for name, content := range files {
|
||||||
|
if len(content) != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
path := filepath.Join(p.config.Dir, name)
|
||||||
|
if err := prependToEmptyFile(path, typesReferenceDirective+"\n\n"); err != nil {
|
||||||
|
color.Yellow("Unable to prepend the types reference: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
registry := new(require.Registry) // this can be shared by multiple runtimes
|
registry := new(require.Registry) // this can be shared by multiple runtimes
|
||||||
|
|
||||||
|
@ -82,7 +102,7 @@ func RegisterHooks(app core.App, config HooksConfig) error {
|
||||||
if p.config.Watch {
|
if p.config.Watch {
|
||||||
color.Red("Failed to execute %s: %v", file, err)
|
color.Red("Failed to execute %s: %v", file, err)
|
||||||
} else {
|
} else {
|
||||||
// return err
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +110,18 @@ func RegisterHooks(app core.App, config HooksConfig) error {
|
||||||
|
|
||||||
loop.Start()
|
loop.Start()
|
||||||
|
|
||||||
|
app.OnAfterBootstrap().Add(func(e *core.BootstrapEvent) error {
|
||||||
|
// always update the app types on start to ensure that
|
||||||
|
// the user has the latest generated declarations
|
||||||
|
if len(files) > 0 {
|
||||||
|
if err := p.saveTypesFile(); err != nil {
|
||||||
|
color.Yellow("Unable to save app types file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
app.OnTerminate().Add(func(e *core.TerminateEvent) error {
|
app.OnTerminate().Add(func(e *core.TerminateEvent) error {
|
||||||
loop.StopNoWait()
|
loop.StopNoWait()
|
||||||
|
|
||||||
|
@ -108,45 +140,58 @@ type hooks struct {
|
||||||
config HooksConfig
|
config HooksConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hooks) watchFiles() error {
|
func (p *hooks) watchFiles() error {
|
||||||
watcher, err := fsnotify.NewWatcher()
|
watcher, err := fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
h.app.OnTerminate().Add(func(e *core.TerminateEvent) error {
|
var debounceTimer *time.Timer
|
||||||
|
|
||||||
|
stopDebounceTimer := func() {
|
||||||
|
if debounceTimer != nil {
|
||||||
|
debounceTimer.Stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.app.OnTerminate().Add(func(e *core.TerminateEvent) error {
|
||||||
watcher.Close()
|
watcher.Close()
|
||||||
|
|
||||||
|
stopDebounceTimer()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
var debounceTimer *time.Timer
|
|
||||||
|
|
||||||
// start listening for events.
|
// start listening for events.
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case event, ok := <-watcher.Events:
|
case event, ok := <-watcher.Events:
|
||||||
if !ok {
|
if !ok {
|
||||||
|
stopDebounceTimer()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if debounceTimer != nil {
|
// skip TS declaration files change
|
||||||
debounceTimer.Stop()
|
if strings.HasSuffix(event.Name, ".d.ts") {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
debounceTimer = time.AfterFunc(100*time.Millisecond, func() {
|
|
||||||
|
stopDebounceTimer()
|
||||||
|
debounceTimer = time.AfterFunc(50*time.Millisecond, func() {
|
||||||
// app restart is currently not supported on Windows
|
// app restart is currently not supported on Windows
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
color.Yellow("File %s changed, please restart the app", event.Name)
|
color.Yellow("File %s changed, please restart the app", event.Name)
|
||||||
} else {
|
} else {
|
||||||
color.Yellow("File %s changed, restarting...", event.Name)
|
color.Yellow("File %s changed, restarting...", event.Name)
|
||||||
if err := h.app.Restart(); err != nil {
|
if err := p.app.Restart(); err != nil {
|
||||||
color.Red("Failed to restart the app:", err)
|
color.Red("Failed to restart the app:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
case err, ok := <-watcher.Errors:
|
case err, ok := <-watcher.Errors:
|
||||||
if !ok {
|
if !ok {
|
||||||
|
stopDebounceTimer()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
color.Red("Watch error:", err)
|
color.Red("Watch error:", err)
|
||||||
|
@ -155,7 +200,7 @@ func (h *hooks) watchFiles() error {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// add the directory to watch
|
// add the directory to watch
|
||||||
err = watcher.Add(h.config.Dir)
|
err = watcher.Add(p.config.Dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
watcher.Close()
|
watcher.Close()
|
||||||
return err
|
return err
|
||||||
|
@ -163,3 +208,26 @@ func (h *hooks) watchFiles() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *hooks) saveTypesFile() error {
|
||||||
|
data, _ := generated.Types.ReadFile("types.d.ts")
|
||||||
|
|
||||||
|
if err := os.WriteFile(filepath.Join(p.config.Dir, typesFileName), data, 0644); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// prependToEmptyFile prepends the specified text to an empty file.
|
||||||
|
//
|
||||||
|
// If the file is not empty this method does nothing.
|
||||||
|
func prependToEmptyFile(path, text string) error {
|
||||||
|
info, err := os.Stat(path)
|
||||||
|
|
||||||
|
if err == nil && info.Size() == 0 {
|
||||||
|
return os.WriteFile(path, []byte(text), 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,294 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/pocketbase/pocketbase/plugins/jsvm"
|
||||||
|
"github.com/pocketbase/tygoja"
|
||||||
|
)
|
||||||
|
|
||||||
|
const heading = `
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// baseBinds
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
declare var $app: core.App
|
||||||
|
|
||||||
|
interface Record extends models.Record{} // merge
|
||||||
|
declare class Record implements models.Record {
|
||||||
|
constructor(collection?: models.Collection, data?: { [key:string]: any })
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Collection extends models.Collection{} // merge
|
||||||
|
declare class Collection implements models.Collection {
|
||||||
|
constructor(data?: Partial<models.Collection>)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Admin extends models.Admin{} // merge
|
||||||
|
declare class Admin implements models.Admin {
|
||||||
|
constructor(data?: Partial<models.Admin>)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Schema extends schema.Schema{} // merge
|
||||||
|
declare class Schema implements schema.Schema {
|
||||||
|
constructor(data?: Partial<schema.Schema>)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SchemaField extends schema.SchemaField{} // merge
|
||||||
|
declare class SchemaField implements schema.SchemaField {
|
||||||
|
constructor(data?: Partial<schema.SchemaField>)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Mail extends mailer.Message{} // merge
|
||||||
|
declare class Mail implements mailer.Message {
|
||||||
|
constructor(message?: Partial<mailer.Message>)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ValidationError extends ozzo_validation.Error{} // merge
|
||||||
|
declare class ValidationError implements ozzo_validation.Error {
|
||||||
|
constructor(code?: number, message?: string)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Dao extends daos.Dao{} // merge
|
||||||
|
declare class Dao implements daos.Dao {
|
||||||
|
constructor(concurrentDB?: dbx.Builder, nonconcurrentDB?: dbx.Builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// dbxBinds
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
declare namespace $dbx {
|
||||||
|
/**
|
||||||
|
* {@inheritDoc dbx.HashExp}
|
||||||
|
*/
|
||||||
|
export function hashExp(pairs: { [key:string]: any }): dbx.Expression
|
||||||
|
|
||||||
|
let _in: dbx._in
|
||||||
|
export { _in as in }
|
||||||
|
|
||||||
|
export let exp: dbx.newExp
|
||||||
|
export let not: dbx.not
|
||||||
|
export let and: dbx.and
|
||||||
|
export let or: dbx.or
|
||||||
|
export let notIn: dbx.notIn
|
||||||
|
export let like: dbx.like
|
||||||
|
export let orLike: dbx.orLike
|
||||||
|
export let notLike: dbx.notLike
|
||||||
|
export let orNotLike: dbx.orNotLike
|
||||||
|
export let exists: dbx.exists
|
||||||
|
export let notExists: dbx.notExists
|
||||||
|
export let between: dbx.between
|
||||||
|
export let notBetween: dbx.notBetween
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// tokensBinds
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
declare namespace $tokens {
|
||||||
|
let adminAuthToken: tokens.newAdminAuthToken
|
||||||
|
let adminResetPasswordToken: tokens.newAdminResetPasswordToken
|
||||||
|
let adminFileToken: tokens.newAdminFileToken
|
||||||
|
let recordAuthToken: tokens.newRecordAuthToken
|
||||||
|
let recordVerifyToken: tokens.newRecordVerifyToken
|
||||||
|
let recordResetPasswordToken: tokens.newRecordResetPasswordToken
|
||||||
|
let recordChangeEmailToken: tokens.newRecordChangeEmailToken
|
||||||
|
let recordFileToken: tokens.newRecordFileToken
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// securityBinds
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
declare namespace $security {
|
||||||
|
let randomString: security.randomString
|
||||||
|
let randomStringWithAlphabet: security.randomStringWithAlphabet
|
||||||
|
let pseudorandomString: security.pseudorandomString
|
||||||
|
let pseudorandomStringWithAlphabet: security.pseudorandomStringWithAlphabet
|
||||||
|
let parseUnverifiedToken: security.parseUnverifiedJWT
|
||||||
|
let parseToken: security.parseJWT
|
||||||
|
let createToken: security.newToken
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// filesystemBinds
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
declare namespace $filesystem {
|
||||||
|
let fileFromPath: filesystem.newFileFromPath
|
||||||
|
let fileFromBytes: filesystem.newFileFromBytes
|
||||||
|
let fileFromMultipart: filesystem.newFileFromMultipart
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// formsBinds
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
interface AdminLoginForm extends forms.AdminLogin{} // merge
|
||||||
|
declare class AdminLoginForm implements forms.AdminLogin {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AdminPasswordResetConfirmForm extends forms.AdminPasswordResetConfirm{} // merge
|
||||||
|
declare class AdminPasswordResetConfirmForm implements forms.AdminPasswordResetConfirm {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AdminPasswordResetRequestForm extends forms.AdminPasswordResetRequest{} // merge
|
||||||
|
declare class AdminPasswordResetRequestForm implements forms.AdminPasswordResetRequest {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AdminUpsertForm extends forms.AdminUpsert{} // merge
|
||||||
|
declare class AdminUpsertForm implements forms.AdminUpsert {
|
||||||
|
constructor(app: core.App, admin: models.Admin)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AppleClientSecretCreateForm extends forms.AppleClientSecretCreate{} // merge
|
||||||
|
declare class AppleClientSecretCreateForm implements forms.AppleClientSecretCreate {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CollectionUpsertForm extends forms.CollectionUpsert{} // merge
|
||||||
|
declare class CollectionUpsertForm implements forms.CollectionUpsert {
|
||||||
|
constructor(app: core.App, collection: models.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CollectionsImportForm extends forms.CollectionsImport{} // merge
|
||||||
|
declare class CollectionsImportForm implements forms.CollectionsImport {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RealtimeSubscribeForm extends forms.RealtimeSubscribe{} // merge
|
||||||
|
declare class RealtimeSubscribeForm implements forms.RealtimeSubscribe {}
|
||||||
|
|
||||||
|
interface RecordEmailChangeConfirmForm extends forms.RecordEmailChangeConfirm{} // merge
|
||||||
|
declare class RecordEmailChangeConfirmForm implements forms.RecordEmailChangeConfirm {
|
||||||
|
constructor(app: core.App, collection: models.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordEmailChangeRequestForm extends forms.RecordEmailChangeRequest{} // merge
|
||||||
|
declare class RecordEmailChangeRequestForm implements forms.RecordEmailChangeRequest {
|
||||||
|
constructor(app: core.App, record: models.Record)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordOAuth2LoginForm extends forms.RecordOAuth2Login{} // merge
|
||||||
|
declare class RecordOAuth2LoginForm implements forms.RecordOAuth2Login {
|
||||||
|
constructor(app: core.App, collection: models.Collection, optAuthRecord?: models.Record)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordPasswordLoginForm extends forms.RecordPasswordLogin{} // merge
|
||||||
|
declare class RecordPasswordLoginForm implements forms.RecordPasswordLogin {
|
||||||
|
constructor(app: core.App, collection: models.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordPasswordResetConfirmForm extends forms.RecordPasswordResetConfirm{} // merge
|
||||||
|
declare class RecordPasswordResetConfirmForm implements forms.RecordPasswordResetConfirm {
|
||||||
|
constructor(app: core.App, collection: models.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordPasswordResetRequestForm extends forms.RecordPasswordResetRequest{} // merge
|
||||||
|
declare class RecordPasswordResetRequestForm implements forms.RecordPasswordResetRequest {
|
||||||
|
constructor(app: core.App, collection: models.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordUpsertForm extends forms.RecordUpsert{} // merge
|
||||||
|
declare class RecordUpsertForm implements forms.RecordUpsert {
|
||||||
|
constructor(app: core.App, record: models.Record)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordVerificationConfirmForm extends forms.RecordVerificationConfirm{} // merge
|
||||||
|
declare class RecordVerificationConfirmForm implements forms.RecordVerificationConfirm {
|
||||||
|
constructor(app: core.App, collection: models.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecordVerificationRequestForm extends forms.RecordVerificationRequest{} // merge
|
||||||
|
declare class RecordVerificationRequestForm implements forms.RecordVerificationRequest {
|
||||||
|
constructor(app: core.App, collection: models.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SettingsUpsertForm extends forms.SettingsUpsert{} // merge
|
||||||
|
declare class SettingsUpsertForm implements forms.SettingsUpsert {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestEmailSendForm extends forms.TestEmailSend{} // merge
|
||||||
|
declare class TestEmailSendForm implements forms.TestEmailSend {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestS3FilesystemForm extends forms.TestS3Filesystem{} // merge
|
||||||
|
declare class TestS3FilesystemForm implements forms.TestS3Filesystem {
|
||||||
|
constructor(app: core.App)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// apisBinds
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
interface Route extends echo.Route{} // merge
|
||||||
|
declare class Route implements echo.Route {
|
||||||
|
constructor(data?: Partial<echo.Route>)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ApiError extends apis.ApiError{} // merge
|
||||||
|
declare class ApiError implements apis.ApiError {
|
||||||
|
constructor(status?: number, message?: string, data?: any)
|
||||||
|
}
|
||||||
|
|
||||||
|
declare namespace $apis {
|
||||||
|
let requireRecordAuth: apis.requireRecordAuth
|
||||||
|
let requireSameContextRecordAuth: apis.requireSameContextRecordAuth
|
||||||
|
let requireAdminAuth: apis.requireAdminAuth
|
||||||
|
let requireAdminAuthOnlyIfAny: apis.requireAdminAuthOnlyIfAny
|
||||||
|
let requireAdminOrRecordAuth: apis.requireAdminOrRecordAuth
|
||||||
|
let requireAdminOrOwnerAuth: apis.requireAdminOrOwnerAuth
|
||||||
|
let activityLogger: apis.activityLogger
|
||||||
|
let requestData: apis.requestData
|
||||||
|
let recordAuthResponse: apis.recordAuthResponse
|
||||||
|
let enrichRecord: apis.enrichRecord
|
||||||
|
let enrichRecords: apis.enrichRecords
|
||||||
|
let notFoundError: apis.newNotFoundError
|
||||||
|
let badRequestError: apis.newBadRequestError
|
||||||
|
let forbiddenError: apis.newForbiddenError
|
||||||
|
let unauthorizedError: apis.newUnauthorizedError
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mapper := &jsvm.FieldMapper{}
|
||||||
|
|
||||||
|
gen := tygoja.New(tygoja.Config{
|
||||||
|
Packages: map[string][]string{
|
||||||
|
"github.com/go-ozzo/ozzo-validation/v4": {"Error"},
|
||||||
|
"github.com/pocketbase/dbx": {"*"},
|
||||||
|
"github.com/pocketbase/pocketbase/tools/security": {"*"},
|
||||||
|
"github.com/pocketbase/pocketbase/tools/filesystem": {"*"},
|
||||||
|
"github.com/pocketbase/pocketbase/tokens": {"*"},
|
||||||
|
"github.com/pocketbase/pocketbase/apis": {"*"},
|
||||||
|
"github.com/pocketbase/pocketbase/forms": {"*"},
|
||||||
|
"github.com/pocketbase/pocketbase/core": {"*"},
|
||||||
|
},
|
||||||
|
FieldNameFormatter: func(s string) string {
|
||||||
|
return mapper.FieldName(nil, reflect.StructField{Name: s})
|
||||||
|
},
|
||||||
|
MethodNameFormatter: func(s string) string {
|
||||||
|
return mapper.MethodName(nil, reflect.Method{Name: s})
|
||||||
|
},
|
||||||
|
Indent: " ", // use only a single space to reduce slight the size
|
||||||
|
WithPackageFunctions: true,
|
||||||
|
Heading: heading,
|
||||||
|
})
|
||||||
|
|
||||||
|
result, err := gen.Generate()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile("./generated/types.d.ts", []byte(result), 0644); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package generated
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed types.d.ts
|
||||||
|
var Types embed.FS
|
File diff suppressed because it is too large
Load Diff
|
@ -41,6 +41,29 @@ import (
|
||||||
func baseBinds(vm *goja.Runtime) {
|
func baseBinds(vm *goja.Runtime) {
|
||||||
vm.SetFieldNameMapper(FieldMapper{})
|
vm.SetFieldNameMapper(FieldMapper{})
|
||||||
|
|
||||||
|
// override primitive class constructors to return pointers
|
||||||
|
// (this is useful when unmarshaling or scaning a db result)
|
||||||
|
vm.Set("_numberPointer", func(arg float64) *float64 {
|
||||||
|
return &arg
|
||||||
|
})
|
||||||
|
vm.Set("_stringPointer", func(arg string) *string {
|
||||||
|
return &arg
|
||||||
|
})
|
||||||
|
vm.Set("_boolPointer", func(arg bool) *bool {
|
||||||
|
return &arg
|
||||||
|
})
|
||||||
|
vm.RunString(`
|
||||||
|
this.Number = function(arg) {
|
||||||
|
return _numberPointer(arg)
|
||||||
|
}
|
||||||
|
this.String = function(arg) {
|
||||||
|
return _stringPointer(arg)
|
||||||
|
}
|
||||||
|
this.Boolean = function(arg) {
|
||||||
|
return _boolPointer(arg)
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
vm.Set("unmarshal", func(src map[string]any, dest any) (any, error) {
|
vm.Set("unmarshal", func(src map[string]any, dest any) (any, error) {
|
||||||
raw, err := json.Marshal(src)
|
raw, err := json.Marshal(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -221,17 +244,10 @@ func formsBinds(vm *goja.Runtime) {
|
||||||
|
|
||||||
func apisBinds(vm *goja.Runtime) {
|
func apisBinds(vm *goja.Runtime) {
|
||||||
obj := vm.NewObject()
|
obj := vm.NewObject()
|
||||||
|
|
||||||
vm.Set("Route", func(call goja.ConstructorCall) *goja.Object {
|
|
||||||
instance := echo.Route{}
|
|
||||||
return structConstructor(vm, call, &instance)
|
|
||||||
})
|
|
||||||
|
|
||||||
vm.Set("$apis", obj)
|
vm.Set("$apis", obj)
|
||||||
|
|
||||||
// middlewares
|
// middlewares
|
||||||
obj.Set("requireRecordAuth", apis.RequireRecordAuth)
|
obj.Set("requireRecordAuth", apis.RequireRecordAuth)
|
||||||
obj.Set("requireRecordAuth", apis.RequireRecordAuth)
|
|
||||||
obj.Set("requireSameContextRecordAuth", apis.RequireSameContextRecordAuth)
|
obj.Set("requireSameContextRecordAuth", apis.RequireSameContextRecordAuth)
|
||||||
obj.Set("requireAdminAuth", apis.RequireAdminAuth)
|
obj.Set("requireAdminAuth", apis.RequireAdminAuth)
|
||||||
obj.Set("requireAdminAuthOnlyIfAny", apis.RequireAdminAuthOnlyIfAny)
|
obj.Set("requireAdminAuthOnlyIfAny", apis.RequireAdminAuthOnlyIfAny)
|
||||||
|
@ -261,6 +277,11 @@ func apisBinds(vm *goja.Runtime) {
|
||||||
obj.Set("badRequestError", apis.NewBadRequestError)
|
obj.Set("badRequestError", apis.NewBadRequestError)
|
||||||
obj.Set("forbiddenError", apis.NewForbiddenError)
|
obj.Set("forbiddenError", apis.NewForbiddenError)
|
||||||
obj.Set("unauthorizedError", apis.NewUnauthorizedError)
|
obj.Set("unauthorizedError", apis.NewUnauthorizedError)
|
||||||
|
|
||||||
|
vm.Set("Route", func(call goja.ConstructorCall) *goja.Object {
|
||||||
|
instance := echo.Route{}
|
||||||
|
return structConstructor(vm, call, &instance)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -24,7 +24,7 @@ func TestBaseBindsCount(t *testing.T) {
|
||||||
vm := goja.New()
|
vm := goja.New()
|
||||||
baseBinds(vm)
|
baseBinds(vm)
|
||||||
|
|
||||||
testBindsCount(vm, "this", 9, t)
|
testBindsCount(vm, "this", 12, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBaseBindsUnmarshal(t *testing.T) {
|
func TestBaseBindsUnmarshal(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue