Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
9b209dfe63 |
18
.idea/copilotDiffState.xml
generated
18
.idea/copilotDiffState.xml
generated
File diff suppressed because one or more lines are too long
33
examples/langV2/debug.go
Normal file
33
examples/langV2/debug.go
Normal file
@ -0,0 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"masonry/langV2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Read the example.masonry file
|
||||
content, err := ioutil.ReadFile("example.masonry2")
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading example.masonry: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
input := string(content)
|
||||
|
||||
ast, err := langV2.ParseInput(input)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
} else {
|
||||
fmt.Printf("🎉 Successfully parsed complete DSL with pages!\n\n")
|
||||
|
||||
out, err := json.MarshalIndent(ast, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
println(string(out))
|
||||
|
||||
}
|
||||
}
|
39
examples/langV2/example.masonry2
Normal file
39
examples/langV2/example.masonry2
Normal file
@ -0,0 +1,39 @@
|
||||
entity User {
|
||||
id: string required unique
|
||||
email: string required unique validate email
|
||||
name: string required
|
||||
age: int validate min "18"
|
||||
created_at: datetime
|
||||
}
|
||||
|
||||
entity Post {
|
||||
id: string required unique
|
||||
title: string required validate maxlen "100"
|
||||
content: string required
|
||||
author_id: string required relates to User as one via "user_id"
|
||||
published: bool default "false"
|
||||
}
|
||||
|
||||
server UserService {
|
||||
GET "/users" entity User
|
||||
POST "/users" entity User
|
||||
GET "/users/{id}" entity User
|
||||
PUT "/users/{id}" entity User
|
||||
}
|
||||
|
||||
server BlogService {
|
||||
GET "/posts" entity Post
|
||||
POST "/posts" entity Post
|
||||
GET "/posts/{id}" entity Post
|
||||
DELETE "/posts/{id}" entity Post
|
||||
}
|
||||
|
||||
page UserProfile {
|
||||
User from UserService
|
||||
Post from BlogService
|
||||
}
|
||||
|
||||
page Dashboard {
|
||||
User from UserService
|
||||
Post from BlogService
|
||||
}
|
136
examples/sdk/debug_sdk.go
Normal file
136
examples/sdk/debug_sdk.go
Normal file
@ -0,0 +1,136 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"masonry/sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
userEntity := sdk.Entity{
|
||||
Name: "User",
|
||||
Description: nil,
|
||||
Fields: []sdk.Field{
|
||||
{
|
||||
Name: "id",
|
||||
Type: "int",
|
||||
Required: true,
|
||||
Unique: true,
|
||||
Default: nil,
|
||||
Validations: []sdk.Validation{
|
||||
{
|
||||
Type: "validate",
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
Relationship: nil,
|
||||
},
|
||||
{
|
||||
Name: "username",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Unique: true,
|
||||
Default: nil,
|
||||
Validations: []sdk.Validation{
|
||||
{
|
||||
Type: "validate",
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
Relationship: nil,
|
||||
},
|
||||
{
|
||||
Name: "email",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Unique: true,
|
||||
Default: nil,
|
||||
Validations: []sdk.Validation{
|
||||
{
|
||||
Type: "validate",
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
Relationship: nil,
|
||||
},
|
||||
{
|
||||
Name: "password",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Unique: false,
|
||||
Default: nil,
|
||||
Validations: []sdk.Validation{
|
||||
{
|
||||
Type: "validate",
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
Relationship: nil,
|
||||
},
|
||||
{
|
||||
Name: "created_at",
|
||||
Type: "datetime",
|
||||
Required: true,
|
||||
Unique: false,
|
||||
Default: nil,
|
||||
Validations: []sdk.Validation{
|
||||
{
|
||||
Type: "validate",
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
Relationship: nil,
|
||||
},
|
||||
{
|
||||
Name: "updated_at",
|
||||
Type: "datetime",
|
||||
Required: true,
|
||||
Unique: false,
|
||||
Default: nil,
|
||||
Validations: []sdk.Validation{
|
||||
{
|
||||
Type: "validate",
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
Relationship: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
createUserDesc := "Create a new user with username, email, and password. Returns the created user object."
|
||||
createUser := sdk.Endpoint{
|
||||
Method: "POST",
|
||||
Path: "/user",
|
||||
Entity: userEntity,
|
||||
Description: &createUserDesc,
|
||||
Auth: true,
|
||||
Permissions: nil,
|
||||
}
|
||||
|
||||
server := sdk.Server{
|
||||
Name: "TestServer",
|
||||
Settings: []sdk.ServerSetting{
|
||||
{
|
||||
Host: "localhost",
|
||||
Port: 8000,
|
||||
},
|
||||
},
|
||||
Endpoints: []sdk.Endpoint{
|
||||
createUser,
|
||||
},
|
||||
}
|
||||
|
||||
def := sdk.Definition{
|
||||
Server: []sdk.Server{
|
||||
server,
|
||||
},
|
||||
}
|
||||
|
||||
out, err := json.MarshalIndent(def, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
println(string(out))
|
||||
println("🎉 Successfully built SDK definition!")
|
||||
println("You can now use this SDK definition in your application.")
|
||||
}
|
79
langV2/lang.go
Normal file
79
langV2/lang.go
Normal file
@ -0,0 +1,79 @@
|
||||
package langV2
|
||||
|
||||
import (
|
||||
participle "github.com/alecthomas/participle/v2"
|
||||
)
|
||||
|
||||
// Root AST node containing all definitions
|
||||
type AST struct {
|
||||
Definitions []Definition `parser:"@@*"`
|
||||
}
|
||||
|
||||
type Definition struct {
|
||||
Entity *EntityDef `parser:"@@"`
|
||||
Server *ServerDef `parser:"| @@"`
|
||||
Page *PageDef `parser:"| @@"`
|
||||
Component *ComponentDef `parser:"| @@"`
|
||||
}
|
||||
|
||||
type EntityDef struct {
|
||||
Name string `parser:"'entity' @Ident"`
|
||||
Fields []Field `parser:"'{' @@* '}'"`
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
Name string `parser:"@Ident ':'"`
|
||||
Type string `parser:"@Ident"`
|
||||
Required bool `parser:"@'required'?"`
|
||||
Unique bool `parser:"@'unique'?"`
|
||||
Index bool `parser:"@'indexed'?"`
|
||||
Default *string `parser:"('default' @String)?"`
|
||||
Validations []Validation `parser:"@@*"`
|
||||
Relationship *Relationship `parser:"@@?"`
|
||||
}
|
||||
|
||||
type Validation struct {
|
||||
Type string `parser:"'validate' @Ident"`
|
||||
Value *string `parser:"@String?"`
|
||||
}
|
||||
|
||||
type Relationship struct {
|
||||
Type string `parser:"'relates' 'to' @Ident"`
|
||||
Cardinality string `parser:"'as' @('one' | 'many')"`
|
||||
ForeignKey *string `parser:"('via' @String)?"`
|
||||
}
|
||||
|
||||
type ServerDef struct {
|
||||
Name string `parser:"'server' @Ident"`
|
||||
Endpoints []EndpointDef `parser:"'{' @@* '}'"`
|
||||
}
|
||||
|
||||
type EndpointDef struct {
|
||||
Method string `parser:"@('GET'|'POST'|'PUT'|'DELETE')"`
|
||||
Path string `parser:"@String"`
|
||||
EntityRef string `parser:"'entity' @Ident"`
|
||||
}
|
||||
|
||||
type ComponentDef struct {
|
||||
EntityRef string `parser:"@Ident"`
|
||||
ServerRef string `parser:"('from' @Ident)?"`
|
||||
}
|
||||
|
||||
type PageDef struct {
|
||||
Name string `parser:"'page' @Ident"`
|
||||
Components []ComponentDef `parser:"'{' @@* '}'"`
|
||||
}
|
||||
|
||||
func ParseInput(input string) (AST, error) {
|
||||
parser, err := participle.Build[AST](
|
||||
participle.Unquote("String"),
|
||||
)
|
||||
if err != nil {
|
||||
return AST{}, err
|
||||
}
|
||||
ast, err := parser.ParseString("", input)
|
||||
if err != nil {
|
||||
return AST{}, err
|
||||
}
|
||||
return *ast, nil
|
||||
}
|
91
sdk/sdk.go
Normal file
91
sdk/sdk.go
Normal file
@ -0,0 +1,91 @@
|
||||
package sdk
|
||||
|
||||
type Definition struct {
|
||||
Server []Server `json:"server,omitempty"`
|
||||
Entity []Entity `json:"entity,omitempty"`
|
||||
Endpoint []Endpoint `json:"endpoint,omitempty"`
|
||||
Page []Page `json:"page,omitempty"`
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Name string `json:"name"`
|
||||
Settings []ServerSetting `json:"settings,omitempty"`
|
||||
Endpoints []Endpoint `json:"endpoints,omitempty"` // Optional endpoints for the server
|
||||
}
|
||||
|
||||
type ServerSetting struct {
|
||||
Host string `json:"host,omitempty"`
|
||||
Port int `json:"port,omitempty"`
|
||||
// TODO: Add more settings as needed e.g. TLS, CORS, etc.
|
||||
}
|
||||
|
||||
type Entity struct {
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Fields []Field `json:"fields,omitempty"`
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Required bool `json:"required,omitempty"`
|
||||
Unique bool `json:"unique,omitempty"`
|
||||
Index bool `json:"index,omitempty"`
|
||||
Default *string `json:"default,omitempty"`
|
||||
Validations []Validation `json:"validations,omitempty"`
|
||||
Relationship *Relationship `json:"relationship,omitempty"`
|
||||
}
|
||||
|
||||
type Validation struct {
|
||||
Type string `json:"type"`
|
||||
Value *string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
type Relationship struct {
|
||||
Type string `json:"type"`
|
||||
Cardinality string `json:"cardinality"`
|
||||
ForeignKey *string `json:"foreign_key,omitempty"`
|
||||
Through *string `json:"through,omitempty"`
|
||||
}
|
||||
|
||||
type Endpoint struct {
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Entity Entity `json:"entity,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Auth bool `json:"auth,omitempty"`
|
||||
Permissions []string `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
type Page struct {
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Auth bool `json:"auth,omitempty"`
|
||||
Permissions []string `json:"permissions,omitempty"`
|
||||
Components []Component `json:"components,omitempty"` // List of components used in the page
|
||||
Styles []string `json:"styles,omitempty"` // List of stylesheets or CSS
|
||||
Script []string `json:"script,omitempty"` // List of scripts or JS files
|
||||
Metadata map[string]string `json:"metadata,omitempty"` // Additional metadata for the page
|
||||
}
|
||||
|
||||
type Component struct {
|
||||
Name string `json:"name"` // Name of the component
|
||||
Description *string `json:"description,omitempty"` // Optional description of the component
|
||||
Props []Prop `json:"props,omitempty"` // List of properties for the component
|
||||
Type string `json:"type"` // Type of the component (e.g., "form", "table", etc.)
|
||||
Entity Entity `json:"entity,omitempty"` // Optional entity this component is associated with
|
||||
Styles []string `json:"styles,omitempty"` // List of stylesheets or CSS for the component
|
||||
Script []string `json:"script,omitempty"` // List of scripts or JS files for the component
|
||||
}
|
||||
|
||||
type Prop struct {
|
||||
Name string `json:"name"` // Name of the property
|
||||
Description *string `json:"description,omitempty"` // Optional description of the property
|
||||
Type string `json:"type"` // Type of the property (e.g., "string", "number", "boolean", etc.)
|
||||
Required bool `json:"required,omitempty"` // Whether the property is required
|
||||
Default *string `json:"default,omitempty"` // Default value for the property
|
||||
Validations []Validation `json:"validations,omitempty"` // List of validations for the property
|
||||
Relationship *Relationship `json:"relationship,omitempty"` // Optional relationship
|
||||
}
|
Reference in New Issue
Block a user