3
0

Moving server files to ./server

This commit is contained in:
Corteza Monorepo Migrator
2022-11-14 09:26:39 +01:00
parent 204738f7c9
commit 683c7c56e2
5750 changed files with 0 additions and 26430 deletions

View File

@@ -0,0 +1,19 @@
package schema
#_ioSpec: {
template: string
output: string
syntax: string | *"go"
if output =~ "\\.adoc$" {
syntax: "adoc"
}
}
#codegen: {
#_ioSpec
payload: _
} | {
bulk?: [...#_ioSpec]
payload: _
}

View File

@@ -0,0 +1,28 @@
package schema
import (
"strings"
)
#component: #_base & {
// copy field values from #_base
handle: handle, ident: ident, expIdent: expIdent
label: strings.ToTitle(ident)
platform: #baseHandle
resources: {
[key=_]: {"handle": key, "component": handle, "platform": platform} & #Resource
}
fqrt: platform + "::" + handle
// All known RBAC operations for this component
rbac: #rbacComponent & {
operations: {
grant: {
description: "Manage \(handle) permissions"
}
}
}
}

View File

@@ -0,0 +1,54 @@
package schema
import (
"strings"
"list"
)
#locale: {
resourceExpIdent: #expIdent
// @todo we need a better name here!
skipSvc: bool | *false
extended: bool | *false
resource: {
type: string
const: string | *("\(resourceExpIdent)ResourceTranslationType")
}
keys: {
[key=_]: #localeKey & {
name: key
_resourceExpIdent: resourceExpIdent
}
}
}
#localeKey: {
name: #handle
_resourceExpIdent: #expIdent
path: [...(#ident | {part: #ident, var: bool | *false})] | *([name])
expandedPath: [ for p in path {
if (p & {"p": #ident}) != _|_ {p, var: p.var}
if (p & string) != _|_ {"part": p, var: false}
}]
_suffix: strings.Join([ for p in expandedPath {strings.ToTitle(p.part)}], "")
struct: string | *("LocaleKey" + _resourceExpIdent + _suffix)
// As soon as we use vars in the path,
// custom handler must be present
_hasVars: list.Contains([ for p in path {p.var | false}], true)
customHandler: bool | *_hasVars
if customHandler {
decodeFunc: string | *("decodeTranslations" + _suffix)
encodeFunc: string | *("encodeTranslations" + _suffix)
serviceFunc: string | *("handle" + _resourceExpIdent + _suffix)
}
}

View File

@@ -0,0 +1,265 @@
package schema
import (
"strings"
)
#Model: {
ident: string
attributes: {
[name=_]: { "name": name }
} & {
[string]: #ModelAttribute
}
indexes: ({
[name=_]: { "name": name, "modelIdent": ident } & #ModelIndex
} & {
[string]: #ModelIndex
}) | *({})
}
// logic in struct fields is a bit different
#ModelAttribute: {
name: #ident
_words: strings.Replace(strings.Replace(name, "_", " ", -1), ".", " ", -1)
_ident: strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
// Golang type (built-in or other)
goType: string | *"string"
// lowercase (unexported, golang) identifier
ident: #ident | *_ident
// uppercase (exported, golang) identifier
expIdent: #expIdent | *strings.ToTitle(ident)
// store identifier
// @todo this should be moved to dal.ident
storeIdent: #ident | *name
// enable or disable store for this attribute
// @todo we should use dal prop for this, and extend it to support bool "false"
// so that it can be disabled
store: bool | *true
unique: bool | *false
sortable: bool | *false
descending: bool | *false
ignoreCase: bool | *false
// currently disabled since not used by anything
// it adds more than 4x overhead to the time it takes to generate the store code!
// #ModelAttributeJsonTag
dal?: #ModelAttributeDal
}
#ModelAttributeDal: {
type: #ModelAttributeDalType | *"Text"
fqType: "dal.Type\(type)"
nullable: bool | *false
if type == "ID" {
generatedByStore: bool | *false
default?: 0
}
if type == "Ref" {
refModelResType: #FQRT
attribute: #handle | *"id"
default?: 0
}
if type == "Timestamp" {
timezone: bool | *false
precision: number | *(-1)
defaultCurrentTimestamp?: true
}
if type == "Time" {
timezone: bool | *false
precision: number | *(-1)
defaultCurrentTimestamp?: true
}
if type == "Date" {
defaultCurrentTimestamp?: true
}
if type == "Number" {
precision: number | *(-1)
scale: number | *(-1)
default?: number
meta?: { [string]: _ }
}
if type == "Text" {
length: number | *0
default?: string
}
if type == "Boolean" {
default?: bool
}
if type == "Enum" {
values: []
default?: string
}
if type == "Geometry" {}
if type == "JSON" {
default?: string | bytes
defaultEmptyObject?: true
}
if type == "Blob" {
default?: bytes
}
if type == "UUID" {}
}
#ModelAttributeDalType:
"ID" | "Ref" |
"Timestamp" | "Time" | "Date" |
"Number" |
"Text" |
"Boolean" |
"Enum" |
"Geometry" |
"JSON" |
"Blob" |
"UUID"
IdField: {
// Expecting ID field to always have name ID
name: "id"
expIdent: "ID"
unique: true
// @todo someday we'll replace this with the "ID" type
goType: "uint64"
dal: { type: "ID" }
}
HandleField: {
// Expecting ID field to always have name handle
name: "handle"
unique: true
ignoreCase: true
goType: "string"
dal: { type: "Text", length: 64 }
}
AttributeUserRef: {
goType: "uint64"
dal: { type: "Ref", refModelResType: "corteza::system:user", default: 0 }
}
SortableTimestampField: {
sortable: true
goType: "time.Time"
dal: { type: "Timestamp", timezone: true, nullable: false }
}
SortableTimestampNowField: {
sortable: true
goType: "time.Time"
dal: { type: "Timestamp", timezone: true, nullable: false, defaultCurrentTimestamp: true }
}
SortableTimestampNilField: {
sortable: true
goType: "*time.Time"
dal: { type: "Timestamp", timezone: true, nullable: true }
}
#ModelAttributeJsonTag: {
name: string
_specs: {field: string | *name, omitEmpty: bool | *false, "string": bool | *false}
json: string | _specs | bool | *false
jsonTag?: string
// just wrap whatever we got in json
if (json & string) != _|_ {
jsonTag: "json:\"\(json)\""
}
// json enable,d wrap with ident as a JSON prop name
if (json & bool) != _|_ && json {
// generic json tag
jsonTag: "json:\"\(name)\""
}
// full-specs
if (json & bool) == _|_ && (json & _specs) != _|_ {
_omitEmpty: string | *""
if json.omitEmpty {
_omitEmpty: ",omitempty"
}
_string: string | *""
if json.string {
_string: ",string"
}
jsonTag: "json:\"\(json.field)\(_omitEmpty)\(_string)\""
}
}
#ModelIndex: close({
name: #ident
modelIdent: #ident
_attributes: { [_]: #ModelAttribute }
_words: strings.Replace(strings.Replace(name, "_", " ", -1), ".", " ", -1)
_ident: strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
// lowercase (unexported, golang) identifier
ident: #ident | *"\(modelIdent)_\(_ident)"
primary: bool | *(strings.ToLower(name) == "primary")
unique: bool | *(strings.Contains(name, "unique") || primary)
type: "BTREE" | *"BTREE"
// index predicate,
// condition that must be met for the index to be used
predicate?: string
attribute?: string
attributes?: [string, ...]
fields: [#ModelIndexField, ...]
if attribute != _|_ {
attributes: [string, ...] & [attribute]
}
if fields != _|_ && attributes != _|_ {
fields: [
for a in attributes {
{"attribute": a} & #ModelIndexField
}
]
}
})
#IndexFieldModifier: "LOWERCASE"
#ModelIndexField: close({
attribute: string
modifiers?: [#IndexFieldModifier, ...]
length?: number
sort?: "DESC" | "ASC"
nulls?: "FIRST" | "LAST"
})

View File

@@ -0,0 +1,49 @@
package schema
import (
"strings"
)
#_ENV: =~"^[A-Z][A-Z0-9_]*[A-Z0-9]?$"
//#_optName: =~ "^[a-zA-Z][a-zA-Z0-9\\s]*[a-zA-Z0-9]+$"
#optionsGroup: #_base & {
imports: [...string] | *([])
handle: #handle
title: string | *handle
description?: string
env: #_ENV | *(strings.ToUpper(strings.Replace(handle, "-", "_", -1)))
_envPrefix: env
options: {
[_opt=_]: #option & {
handle: _opt
env: #_ENV | *(_envPrefix + "_" + strings.ToUpper(strings.Replace(handle, " ", "_", -1)))
}
}
}
#option: {
handle: #handle
_words: strings.Replace(strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1), ".", " ", -1)
// lowercased (unexported, golang) identifier
ident: #ident | *strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
// upercased (exported, golang) identifier
expIdent: #expIdent | *strings.Replace(strings.ToTitle(_words), " ", "", -1)
type: string | *"string"
description?: string
// Default expression to be used
defaultGoExpr?: string
env?: #_ENV
// Plain default value to use when generating .env.example
defaultValue?: string
}

View File

@@ -0,0 +1,21 @@
package schema
#platform: {
ident: #baseHandle | *"corteza"
options: [...#optionsGroup]
components: [...{platform: ident} & #component]
resources: {
[key=#handle]: #Resource & {
"handle": key,
"platform": ident
}
}
// automation: {
// types: ....
// function ....
// }
}

View File

@@ -0,0 +1,61 @@
package schema
import (
"strings"
)
#rbacComponent: {
resource: {
type: string
}
operations: {
[key=_]: #rbacOperation & {
handle: key
}
}
}
#rbacResource: {
resourceExpIdent: #expIdent
operations: {
[key=_]: #rbacOperation & {
handle: key
_resourceExpIdent: resourceExpIdent
}
}
}
#rbacOperation: {
handle: #handle
description: string | *handle
_resourceExpIdent?: string
// Some string manipulation that will result in
// more pronouncable access-control check function name
// When check function name is not explicitly defined we try
// to use resource and operation name and generate easy-to-read name
//
// <res> + <op> => Can<Op><Res>
// <res> + <op:foo.bar.verb> => Can<Verb><Foo><Bar>On<Res>
_operation: strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1)
_opSplit: strings.Split(_operation, ".")
_opFlip: [_opSplit[len(_opSplit)-1]] + _opSplit[0:len(_opSplit)-1]
_opFinal: strings.Replace(strings.ToTitle(strings.Join(_opFlip, " ")), " ", "", -1)
if _resourceExpIdent == _|_ {
checkFuncName: #expIdent | *"Can\(_opFinal)"
}
if len(_opSplit) > 1 && _resourceExpIdent != _|_ {
checkFuncName: #expIdent | *"Can\(_opFinal)On\(_resourceExpIdent)"
}
if len(_opSplit) <= 1 && _resourceExpIdent != _|_ {
checkFuncName: #expIdent | *"Can\(_opFinal)\(_resourceExpIdent)"
}
}

View File

@@ -0,0 +1,137 @@
package schema
import (
"strings"
)
// fully qualified resource type
#FQRT: =~ "^corteza::(compose|system|federation|automation):[a-z][a-z0-9-]*$"
#Resource: {
#_base
// type: #resourceType | *""
imports: [...{ import: string }]
// copy field values from #_base
handle: handle, ident: ident, expIdent: expIdent
component: #baseHandle | *"component"
platform: #baseHandle | *"corteza"
// Fully qualified resource name
fqrt: #FQRT | *(platform + "::" + component + ":" + handle)
model: #Model & {
// use resource handle (plural) as model ident as default
// model ident represents a db table or a container name
ident: string | *"\(strings.Replace(handle, "-", "_", -1))s"
}
filter: {
"expIdent": #expIdent | *"\(expIdent)Filter"
struct: {
[name=_]: {"name": name} & #ModelAttribute
}
// generate filtering by-nil-state for the specified fields
"byNilState": [...string]
// generate filtering by-false-state for the specified fields
"byFalseState": [...string]
// generate query filter for the specified fields
"query": [...string]
// filter resources by fields (eq)
"byValue": [...string]
}
// operations: #Operations
features: {
// filtering by label
labels: bool | *true
// filtering by flag
flags: bool | *false
// support pagination
paging: bool | *true
// support sorting
sorting: bool | *true
// support resource check function
checkFn: bool | *true
}
// All parent resources
parents: [... #_base & {
// copy field values from #_base
handle: handle, ident: ident, expIdent: expIdent
refField: #expIdent | *(expIdent + "ID")
param: #ident | *(ident + "ID")
}]
// All known RBAC operations for this resource
rbac?: #rbacResource & {
resourceExpIdent: expIdent
}
locale?: #locale & {
resourceExpIdent: expIdent
resource: {
// @todo can we merge this with RBAC type (FQRN?)
type: component + ":" + handle
}
}
store?: {
// how is this resource represented (prefixed/suffixed functions) in the store
"ident": #ident | *ident
"identPlural": #ident | *"\(store.ident)s"
"expIdent": #expIdent | *strings.ToTitle(store.ident)
"expIdentPlural": #expIdent | *"\(store.expIdent)s"
api?: {
lookups: [...{
_expFields: [ for f in fields {strings.ToTitle(model.attributes[f].expIdent)}]
"expIdent": "Lookup\(store.expIdent)By" + strings.Join(_expFields, "")
description: string | *""
// fields used for the lookup (must exist in the struct)
fields: [...string]
// Skip null constraints
nullConstraint: [...string]
constraintCheck: bool | *false
}]
functions: [...{
expIdent: string
description: string | *""
args: [...{ident: #ident, goType: string, spread: bool | *false}]
return: [...string]
}]
}
}
}
#storeFunction: {
expIdent: #expIdent
args: [...string]
return: [...string]
}
#PkgResource: #Resource & {
package: {
ident: #ident
import: string
}
}

View File

@@ -0,0 +1,39 @@
package schema
import (
"strings"
)
// Identifier
#ident: =~"^[a-z][a-zA-Z0-9_]*$"
// Exported identifier
#expIdent: =~"^[A-Z][a-zA-Z0-9_]*$"
// More liberal then identifier, allows underscores and dots
#handle: =~"^[A-Za-z][a-zA-Z0-9_\\-\\.]*[a-zA-Z0-9]+$"
// More liberal then identifier
#baseHandle: =~"^[a-z][a-z0-9-]*[a-z0-9]+$"
#_base: {
// lowercase dash-separated words
// used to build ident and exported identifiers
handle: #baseHandle
_words: strings.Replace(strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1), ".", " ", -1)
// lowercase (unexported, golang) identifier
ident: #ident | *strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
// plural
identPlural: #ident | *"\(ident)s"
// uppercase (exported, golang) identifier
expIdent: #expIdent | *strings.Replace(strings.ToTitle(_words), " ", "", -1)
// plural exported
expIdentPlural: #expIdent | *"\(expIdent)s"
...
}