Skip to content

Commit

Permalink
[pocketbase#872] changed the schema required validator to be optional…
Browse files Browse the repository at this point in the history
… for auth collections
  • Loading branch information
ganigeorgiev committed Nov 16, 2022
1 parent 4528f07 commit 6e9cf98
Show file tree
Hide file tree
Showing 45 changed files with 1,166 additions and 445 deletions.
660 changes: 660 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ git clone https://github.com/your_username/pocketbase.git

## Making changes in the Go code

PocketBase is a Go package, which means that in order to run the project you'll have to create a Go `main` program that imports the package.
PocketBase is distributed as a Go package, which means that in order to run the project you'll have to create a Go `main` program that imports the package.

The repository already includes such program, located in `/examples/base`, that is also used for the prebuilt executables.

Expand Down
26 changes: 16 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p align="center">
<a href="https://pocketbase.io" target="_blank" rel="noopener">
<img src="https://i.imgur.com/ZfD4BHO.png" alt="PocketBase - open source backend in 1 file" />
<img src="https://i.imgur.com/1Ag0seN.png" alt="PocketBase - open source backend in 1 file" />
</a>
</p>

Expand All @@ -10,10 +10,6 @@
<a href="https://pkg.go.dev/github.com/pocketbase/pocketbase" target="_blank" rel="noopener"><img src="https://godoc.org/github.com/ganigeorgiev/fexpr?status.svg" alt="Go package documentation" /></a>
</p>

> **⚠️ This is a pre-release branch, contains breaking changes and works only with JS SDK v0.8+ and Dart SDK v0.5+!**
>
> **For more details on the changes please check the [v0.8.0-rc release notes](https://github.com/pocketbase/pocketbase/releases/tag/v0.8.0-rc1).**
[PocketBase](https://pocketbase.io) is an open source Go backend, consisting of:

- embedded database (_SQLite_) with **realtime subscriptions**
Expand Down Expand Up @@ -67,15 +63,15 @@ func main() {
app := pocketbase.New()

app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
// add new "GET /api/hello" route to the app router (echo)
// add new "GET /hello" route to the app router (echo)
e.Router.AddRoute(echo.Route{
Method: http.MethodGet,
Path: "/api/hello",
Path: "/hello",
Handler: func(c echo.Context) error {
return c.String(200, "Hello world!")
},
Middlewares: []echo.MiddlewareFunc{
apis.RequireAdminOrRecordAuth(),
apis.ActivityLogger(app),
},
})

Expand Down Expand Up @@ -120,12 +116,22 @@ All reports will be promptly addressed and you'll be credited accordingly.
## Contributing

PocketBase is free and open source project licensed under the [MIT License](LICENSE.md).
You are free to do whatever you want with it, even offering it as a paid service.

You could help continuing its development by:

- [Contribute to the source code](CONTRIBUTING.md)
- [Suggest new features and report issues](https://github.com/pocketbase/pocketbase/issues)
- [Donate a small amount](https://pocketbase.io/support-us)

> Please note that PocketBase was initially created to serve as a new backend for my other open source project - [Presentator](https://presentator.io) (see [#183](https://github.com/presentator/presentator/issues/183)),
so all feature requests will be first aligned with what we need for Presentator v3.
PRs for _small features_ (eg. adding new OAuth2 providers), bug and documentation fixes, etc. are more than welcome.

But please refrain creating PRs for _big features_ without previously discussing the implementation details. Reviewing big PRs often requires a lot of time and tedious back-and-forth communication.
PocketBase has a [roadmap](https://github.com/orgs/pocketbase/projects/2)
and I try to work on issues in a specific order and PRs often come in out of nowhere and skew all initial planning.

Don't get upset if I close your PR, even if it is well executed and tested. This doesn't mean that it will never be merged.
Later we can always refer to it and/or take pieces of your implementation when the time to work on the issue come in (don't worry you'll be credited in the release notes).

_Please also note that PocketBase was initially created to serve as a new backend for my other open source project - [Presentator](https://presentator.io) (see [#183](https://github.com/presentator/presentator/issues/183)),
so all feature requests will be first aligned with what we need for Presentator v3._
12 changes: 8 additions & 4 deletions apis/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ func TestCollectionImport(t *testing.T) {
ExpectedStatus: 400,
ExpectedContent: []string{
`"data":{`,
`"collections":{"code":"collections_import_failure"`,
`"collections":{"code":"collections_import_validate_failure"`,
},
ExpectedEvents: map[string]int{
"OnCollectionsBeforeImportRequest": 1,
Expand Down Expand Up @@ -887,6 +887,10 @@ func TestCollectionImport(t *testing.T) {
"type": "text"
}
]
},
{
"name": "auth_without_schema",
"type": "auth"
}
]
}`),
Expand All @@ -897,15 +901,15 @@ func TestCollectionImport(t *testing.T) {
ExpectedEvents: map[string]int{
"OnCollectionsBeforeImportRequest": 1,
"OnCollectionsAfterImportRequest": 1,
"OnModelBeforeCreate": 2,
"OnModelAfterCreate": 2,
"OnModelBeforeCreate": 3,
"OnModelAfterCreate": 3,
},
AfterTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
collections := []*models.Collection{}
if err := app.Dao().CollectionQuery().All(&collections); err != nil {
t.Fatal(err)
}
expected := 9
expected := 10
if len(collections) != expected {
t.Fatalf("Expected %d collections, got %d", expected, len(collections))
}
Expand Down
14 changes: 3 additions & 11 deletions daos/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,23 +298,15 @@ func TestImportCollections(t *testing.T) {
expectError: true,
expectCollectionsCount: 7,
},
{
name: "check db constraints",
jsonData: `[
{"name": "import_test", "schema": []}
]`,
deleteMissing: false,
expectError: true,
expectCollectionsCount: 7,
},
{
name: "minimal collection import",
jsonData: `[
{"name": "import_test", "schema": [{"name":"test", "type": "text"}]}
{"name": "import_test1", "schema": [{"name":"test", "type": "text"}]},
{"name": "import_test2", "type": "auth"}
]`,
deleteMissing: false,
expectError: false,
expectCollectionsCount: 8,
expectCollectionsCount: 9,
},
{
name: "minimal collection import + failed beforeRecordsSync",
Expand Down
14 changes: 14 additions & 0 deletions forms/collection_upsert.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func (form *CollectionUpsert) Validate() error {
// validates using the type's own validation rules + some collection's specific
validation.Field(
&form.Schema,
validation.By(form.checkMinSchemaFields),
validation.By(form.ensureNoSystemFieldsChange),
validation.By(form.ensureNoFieldsTypeChange),
validation.By(form.ensureExistingRelationCollectionId),
Expand Down Expand Up @@ -255,6 +256,19 @@ func (form *CollectionUpsert) ensureNoAuthFieldName(value any) error {
return nil
}

func (form *CollectionUpsert) checkMinSchemaFields(value any) error {
if form.Type == models.CollectionTypeAuth {
return nil // auth collections doesn't require having additional schema fields
}

v, ok := value.(schema.Schema)
if !ok || len(v.Fields()) == 0 {
return validation.ErrRequired
}

return nil
}

func (form *CollectionUpsert) ensureNoSystemFieldsChange(value any) error {
v, _ := value.(schema.Schema)

Expand Down
3 changes: 2 additions & 1 deletion forms/collection_upsert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ func TestCollectionUpsertValidateAndSubmit(t *testing.T) {
jsonData string
expectedErrors []string
}{
{"empty create", "", "{}", []string{"name", "schema"}},
{"empty create (base)", "", "{}", []string{"name", "schema"}},
{"empty create (auth)", "", `{"type":"auth"}`, []string{"name"}},
{"empty update", "demo2", "{}", []string{}},
{
"create failure",
Expand Down
29 changes: 26 additions & 3 deletions forms/collections_import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,25 @@ func TestCollectionsImportSubmit(t *testing.T) {
"OnModelBeforeCreate": 2,
},
},
{
name: "test empty base collection schema",
jsonData: `{
"collections": [
{
"name": "import1"
},
{
"name": "import2",
"type": "auth"
}
]
}`,
expectError: true,
expectCollectionsCount: 7,
expectEvents: map[string]int{
"OnModelBeforeCreate": 2,
},
},
{
name: "all imported collections has valid data",
jsonData: `{
Expand All @@ -110,14 +129,18 @@ func TestCollectionsImportSubmit(t *testing.T) {
"type":"bool"
}
]
},
{
"name": "import3",
"type": "auth"
}
]
}`,
expectError: false,
expectCollectionsCount: 9,
expectCollectionsCount: 10,
expectEvents: map[string]int{
"OnModelBeforeCreate": 2,
"OnModelAfterCreate": 2,
"OnModelBeforeCreate": 3,
"OnModelAfterCreate": 3,
},
},
{
Expand Down
11 changes: 4 additions & 7 deletions models/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,9 @@ func (s *Schema) AddField(newField *SchemaField) {
// Internally calls each individual field's validator and additionally
// checks for invalid renamed fields and field name duplications.
func (s Schema) Validate() error {
return validation.Validate(&s.fields, validation.Required, validation.By(func(value any) error {
return validation.Validate(&s.fields, validation.By(func(value any) error {
fields := s.fields // use directly the schema value to avoid unnecessary interface casting

if len(fields) == 0 {
return validation.NewError("validation_invalid_schema", "Invalid schema format.")
}

ids := []string{}
names := []string{}
for i, field := range fields {
Expand Down Expand Up @@ -204,8 +200,9 @@ func (s *Schema) UnmarshalJSON(data []byte) error {

// Value implements the [driver.Valuer] interface.
func (s Schema) Value() (driver.Value, error) {
if len(s.fields) == 0 {
return nil, nil
if s.fields == nil {
// initialize an empty slice to ensure that `[]` is returned
s.fields = []*SchemaField{}
}

data, err := json.Marshal(s.fields)
Expand Down
4 changes: 2 additions & 2 deletions models/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func TestSchemaValidate(t *testing.T) {
// no fields
{
schema.NewSchema(),
true,
false,
},
// duplicated field ids
{
Expand Down Expand Up @@ -342,7 +342,7 @@ func TestSchemaValue(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if v1 != nil {
if v1 != "[]" {
t.Fatalf("Expected nil, got %v", v1)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import{S as ke,i as be,s as ge,e as r,w as b,b as g,c as _e,f as k,g as h,h as n,m as me,x as G,P as re,Q as we,k as ve,R as Ce,n as Pe,t as J,a as Y,o as _,d as pe,L as Me,C as Se,p as $e,r as H,u as je,O as Ae}from"./index.6508bdfc.js";import{S as Be}from"./SdkTabs.2815f3ec.js";function ue(a,l,o){const s=a.slice();return s[5]=l[o],s}function de(a,l,o){const s=a.slice();return s[5]=l[o],s}function fe(a,l){let o,s=l[5].code+"",m,f,i,u;function d(){return l[4](l[5])}return{key:a,first:null,c(){o=r("button"),m=b(s),f=g(),k(o,"class","tab-item"),H(o,"active",l[1]===l[5].code),this.first=o},m(v,C){h(v,o,C),n(o,m),n(o,f),i||(u=je(o,"click",d),i=!0)},p(v,C){l=v,C&4&&s!==(s=l[5].code+"")&&G(m,s),C&6&&H(o,"active",l[1]===l[5].code)},d(v){v&&_(o),i=!1,u()}}}function he(a,l){let o,s,m,f;return s=new Ae({props:{content:l[5].body}}),{key:a,first:null,c(){o=r("div"),_e(s.$$.fragment),m=g(),k(o,"class","tab-item"),H(o,"active",l[1]===l[5].code),this.first=o},m(i,u){h(i,o,u),me(s,o,null),n(o,m),f=!0},p(i,u){l=i;const d={};u&4&&(d.content=l[5].body),s.$set(d),(!f||u&6)&&H(o,"active",l[1]===l[5].code)},i(i){f||(J(s.$$.fragment,i),f=!0)},o(i){Y(s.$$.fragment,i),f=!1},d(i){i&&_(o),pe(s)}}}function Oe(a){var ae,ne;let l,o,s=a[0].name+"",m,f,i,u,d,v,C,K=a[0].name+"",U,R,q,P,D,j,W,M,N,X,Q,A,Z,V,y=a[0].name+"",I,x,L,B,E,S,O,w=[],ee=new Map,te,T,p=[],le=new Map,$;P=new Be({props:{js:`
import{S as ke,i as be,s as ge,e as r,w as b,b as g,c as _e,f as k,g as h,h as n,m as me,x as G,P as re,Q as we,k as ve,R as Ce,n as Pe,t as J,a as Y,o as _,d as pe,L as Me,C as Se,p as $e,r as H,u as je,O as Ae}from"./index.a3407df6.js";import{S as Be}from"./SdkTabs.55ea51c0.js";function ue(a,l,o){const s=a.slice();return s[5]=l[o],s}function de(a,l,o){const s=a.slice();return s[5]=l[o],s}function fe(a,l){let o,s=l[5].code+"",m,f,i,u;function d(){return l[4](l[5])}return{key:a,first:null,c(){o=r("button"),m=b(s),f=g(),k(o,"class","tab-item"),H(o,"active",l[1]===l[5].code),this.first=o},m(v,C){h(v,o,C),n(o,m),n(o,f),i||(u=je(o,"click",d),i=!0)},p(v,C){l=v,C&4&&s!==(s=l[5].code+"")&&G(m,s),C&6&&H(o,"active",l[1]===l[5].code)},d(v){v&&_(o),i=!1,u()}}}function he(a,l){let o,s,m,f;return s=new Ae({props:{content:l[5].body}}),{key:a,first:null,c(){o=r("div"),_e(s.$$.fragment),m=g(),k(o,"class","tab-item"),H(o,"active",l[1]===l[5].code),this.first=o},m(i,u){h(i,o,u),me(s,o,null),n(o,m),f=!0},p(i,u){l=i;const d={};u&4&&(d.content=l[5].body),s.$set(d),(!f||u&6)&&H(o,"active",l[1]===l[5].code)},i(i){f||(J(s.$$.fragment,i),f=!0)},o(i){Y(s.$$.fragment,i),f=!1},d(i){i&&_(o),pe(s)}}}function Oe(a){var ae,ne;let l,o,s=a[0].name+"",m,f,i,u,d,v,C,K=a[0].name+"",U,R,q,P,D,j,W,M,N,X,Q,A,Z,V,y=a[0].name+"",I,x,L,B,E,S,O,w=[],ee=new Map,te,T,p=[],le=new Map,$;P=new Be({props:{js:`
import PocketBase from 'pocketbase';
const pb = new PocketBase('${a[3]}');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import{S as Ne,i as Ue,s as je,O as ze,e as a,w as k,b as p,c as ae,f as b,g as c,h as o,m as ne,x as re,P as qe,Q as xe,k as Ie,R as Je,n as Ke,t as U,a as j,o as d,d as ie,L as Qe,C as He,p as We,r as x,u as Ge}from"./index.6508bdfc.js";import{S as Xe}from"./SdkTabs.2815f3ec.js";function Le(r,l,s){const n=r.slice();return n[5]=l[s],n}function Ee(r,l,s){const n=r.slice();return n[5]=l[s],n}function Fe(r,l){let s,n=l[5].code+"",m,_,i,f;function v(){return l[4](l[5])}return{key:r,first:null,c(){s=a("button"),m=k(n),_=p(),b(s,"class","tab-item"),x(s,"active",l[1]===l[5].code),this.first=s},m(g,w){c(g,s,w),o(s,m),o(s,_),i||(f=Ge(s,"click",v),i=!0)},p(g,w){l=g,w&4&&n!==(n=l[5].code+"")&&re(m,n),w&6&&x(s,"active",l[1]===l[5].code)},d(g){g&&d(s),i=!1,f()}}}function Ve(r,l){let s,n,m,_;return n=new ze({props:{content:l[5].body}}),{key:r,first:null,c(){s=a("div"),ae(n.$$.fragment),m=p(),b(s,"class","tab-item"),x(s,"active",l[1]===l[5].code),this.first=s},m(i,f){c(i,s,f),ne(n,s,null),o(s,m),_=!0},p(i,f){l=i;const v={};f&4&&(v.content=l[5].body),n.$set(v),(!_||f&6)&&x(s,"active",l[1]===l[5].code)},i(i){_||(U(n.$$.fragment,i),_=!0)},o(i){j(n.$$.fragment,i),_=!1},d(i){i&&d(s),ie(n)}}}function Ye(r){var Be,Me;let l,s,n=r[0].name+"",m,_,i,f,v,g,w,B,I,S,E,ce,F,M,de,J,V=r[0].name+"",K,ue,pe,z,Q,D,W,T,G,fe,X,C,Y,he,Z,be,h,me,P,_e,ke,ve,ee,ge,te,ye,Se,$e,oe,we,le,O,se,R,q,$=[],Te=new Map,Ce,H,y=[],Re=new Map,A;g=new Xe({props:{js:`
import{S as Ne,i as Ue,s as je,O as ze,e as a,w as k,b as p,c as ae,f as b,g as c,h as o,m as ne,x as re,P as qe,Q as xe,k as Ie,R as Je,n as Ke,t as U,a as j,o as d,d as ie,L as Qe,C as He,p as We,r as x,u as Ge}from"./index.a3407df6.js";import{S as Xe}from"./SdkTabs.55ea51c0.js";function Le(r,l,s){const n=r.slice();return n[5]=l[s],n}function Ee(r,l,s){const n=r.slice();return n[5]=l[s],n}function Fe(r,l){let s,n=l[5].code+"",m,_,i,f;function v(){return l[4](l[5])}return{key:r,first:null,c(){s=a("button"),m=k(n),_=p(),b(s,"class","tab-item"),x(s,"active",l[1]===l[5].code),this.first=s},m(g,w){c(g,s,w),o(s,m),o(s,_),i||(f=Ge(s,"click",v),i=!0)},p(g,w){l=g,w&4&&n!==(n=l[5].code+"")&&re(m,n),w&6&&x(s,"active",l[1]===l[5].code)},d(g){g&&d(s),i=!1,f()}}}function Ve(r,l){let s,n,m,_;return n=new ze({props:{content:l[5].body}}),{key:r,first:null,c(){s=a("div"),ae(n.$$.fragment),m=p(),b(s,"class","tab-item"),x(s,"active",l[1]===l[5].code),this.first=s},m(i,f){c(i,s,f),ne(n,s,null),o(s,m),_=!0},p(i,f){l=i;const v={};f&4&&(v.content=l[5].body),n.$set(v),(!_||f&6)&&x(s,"active",l[1]===l[5].code)},i(i){_||(U(n.$$.fragment,i),_=!0)},o(i){j(n.$$.fragment,i),_=!1},d(i){i&&d(s),ie(n)}}}function Ye(r){var Be,Me;let l,s,n=r[0].name+"",m,_,i,f,v,g,w,B,I,S,E,ce,F,M,de,J,V=r[0].name+"",K,ue,pe,z,Q,D,W,T,G,fe,X,C,Y,he,Z,be,h,me,P,_e,ke,ve,ee,ge,te,ye,Se,$e,oe,we,le,O,se,R,q,$=[],Te=new Map,Ce,H,y=[],Re=new Map,A;g=new Xe({props:{js:`
import PocketBase from 'pocketbase';
const pb = new PocketBase('${r[3]}');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import{S as je,i as He,s as Je,O as We,e as s,w as v,b as p,c as re,f as h,g as r,h as a,m as ce,x as de,P as Ue,Q as Ne,k as Qe,R as ze,n as Ke,t as j,a as H,o as c,d as ue,L as Ye,C as Ve,p as Ge,r as J,u as Xe}from"./index.6508bdfc.js";import{S as Ze}from"./SdkTabs.2815f3ec.js";function Be(i,l,o){const n=i.slice();return n[5]=l[o],n}function Fe(i,l,o){const n=i.slice();return n[5]=l[o],n}function xe(i,l){let o,n=l[5].code+"",m,_,d,b;function g(){return l[4](l[5])}return{key:i,first:null,c(){o=s("button"),m=v(n),_=p(),h(o,"class","tab-item"),J(o,"active",l[1]===l[5].code),this.first=o},m(k,R){r(k,o,R),a(o,m),a(o,_),d||(b=Xe(o,"click",g),d=!0)},p(k,R){l=k,R&4&&n!==(n=l[5].code+"")&&de(m,n),R&6&&J(o,"active",l[1]===l[5].code)},d(k){k&&c(o),d=!1,b()}}}function Me(i,l){let o,n,m,_;return n=new We({props:{content:l[5].body}}),{key:i,first:null,c(){o=s("div"),re(n.$$.fragment),m=p(),h(o,"class","tab-item"),J(o,"active",l[1]===l[5].code),this.first=o},m(d,b){r(d,o,b),ce(n,o,null),a(o,m),_=!0},p(d,b){l=d;const g={};b&4&&(g.content=l[5].body),n.$set(g),(!_||b&6)&&J(o,"active",l[1]===l[5].code)},i(d){_||(j(n.$$.fragment,d),_=!0)},o(d){H(n.$$.fragment,d),_=!1},d(d){d&&c(o),ue(n)}}}function et(i){var qe,Ie;let l,o,n=i[0].name+"",m,_,d,b,g,k,R,C,N,y,F,pe,x,D,he,Q,M=i[0].name+"",z,be,K,q,Y,I,G,P,X,O,Z,fe,ee,$,te,me,ae,_e,f,ve,E,ge,ke,we,le,Se,oe,Re,ye,Oe,se,$e,ne,L,ie,A,U,S=[],Ae=new Map,Ee,V,w=[],Te=new Map,T;k=new Ze({props:{js:`
import{S as je,i as He,s as Je,O as We,e as s,w as v,b as p,c as re,f as h,g as r,h as a,m as ce,x as de,P as Ue,Q as Ne,k as Qe,R as ze,n as Ke,t as j,a as H,o as c,d as ue,L as Ye,C as Ve,p as Ge,r as J,u as Xe}from"./index.a3407df6.js";import{S as Ze}from"./SdkTabs.55ea51c0.js";function Be(i,l,o){const n=i.slice();return n[5]=l[o],n}function Fe(i,l,o){const n=i.slice();return n[5]=l[o],n}function xe(i,l){let o,n=l[5].code+"",m,_,d,b;function g(){return l[4](l[5])}return{key:i,first:null,c(){o=s("button"),m=v(n),_=p(),h(o,"class","tab-item"),J(o,"active",l[1]===l[5].code),this.first=o},m(k,R){r(k,o,R),a(o,m),a(o,_),d||(b=Xe(o,"click",g),d=!0)},p(k,R){l=k,R&4&&n!==(n=l[5].code+"")&&de(m,n),R&6&&J(o,"active",l[1]===l[5].code)},d(k){k&&c(o),d=!1,b()}}}function Me(i,l){let o,n,m,_;return n=new We({props:{content:l[5].body}}),{key:i,first:null,c(){o=s("div"),re(n.$$.fragment),m=p(),h(o,"class","tab-item"),J(o,"active",l[1]===l[5].code),this.first=o},m(d,b){r(d,o,b),ce(n,o,null),a(o,m),_=!0},p(d,b){l=d;const g={};b&4&&(g.content=l[5].body),n.$set(g),(!_||b&6)&&J(o,"active",l[1]===l[5].code)},i(d){_||(j(n.$$.fragment,d),_=!0)},o(d){H(n.$$.fragment,d),_=!1},d(d){d&&c(o),ue(n)}}}function et(i){var qe,Ie;let l,o,n=i[0].name+"",m,_,d,b,g,k,R,C,N,y,F,pe,x,D,he,Q,M=i[0].name+"",z,be,K,q,Y,I,G,P,X,O,Z,fe,ee,$,te,me,ae,_e,f,ve,E,ge,ke,we,le,Se,oe,Re,ye,Oe,se,$e,ne,L,ie,A,U,S=[],Ae=new Map,Ee,V,w=[],Te=new Map,T;k=new Ze({props:{js:`
import PocketBase from 'pocketbase';
const pb = new PocketBase('${i[3]}');
Expand Down
Loading

0 comments on commit 6e9cf98

Please sign in to comment.