From fc32fc05321c00e2497de9ba892291a0af195f13 Mon Sep 17 00:00:00 2001 From: hichana Date: Tue, 26 Oct 2021 16:32:31 +0900 Subject: [PATCH 1/2] squash merge with TeamExponential submission for flip 18 api --- .gitignore | 1 + controller/projects.go | 18 ++--- generated.go | 130 +++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 15 +++++ model/models_gen.go | 10 ++- model/project.go | 80 ++++++++++++++++------- playground_test.go | 76 ++++++++++++++++++---- schema.graphql | 6 ++ storage/datastore/store.go | 12 ++++ storage/memory/store.go | 8 +++ 11 files changed, 311 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index 485dee64..090a1f02 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .idea +.DS_Store diff --git a/controller/projects.go b/controller/projects.go index ce558943..fb1559b9 100644 --- a/controller/projects.go +++ b/controller/projects.go @@ -57,14 +57,16 @@ func NewProjects( func (p *Projects) Create(user *model.User, input model.NewProject) (*model.InternalProject, error) { proj := &model.InternalProject{ - ID: uuid.New(), - Secret: uuid.New(), - PublicID: uuid.New(), - ParentID: input.ParentID, - Seed: input.Seed, - Title: input.Title, - Persist: false, - Version: p.version, + ID: uuid.New(), + Secret: uuid.New(), + PublicID: uuid.New(), + ParentID: input.ParentID, + Seed: input.Seed, + Title: input.Title, + Description: input.Description, + Readme: input.Readme, + Persist: false, + Version: p.version, } accounts, deltas, err := p.createInitialAccounts(proj.ID, input.Accounts) diff --git a/generated.go b/generated.go index 2b31609f..0f4e288a 100644 --- a/generated.go +++ b/generated.go @@ -94,11 +94,13 @@ type ComplexityRoot struct { Project struct { Accounts func(childComplexity int) int + Description func(childComplexity int) int ID func(childComplexity int) int Mutable func(childComplexity int) int ParentID func(childComplexity int) int Persist func(childComplexity int) int PublicID func(childComplexity int) int + Readme func(childComplexity int) int ScriptExecutions func(childComplexity int) int ScriptTemplates func(childComplexity int) int Seed func(childComplexity int) int @@ -447,6 +449,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Project.Accounts(childComplexity), true + case "Project.description": + if e.complexity.Project.Description == nil { + break + } + + return e.complexity.Project.Description(childComplexity), true + case "Project.id": if e.complexity.Project.ID == nil { break @@ -482,6 +491,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Project.PublicID(childComplexity), true + case "Project.readme": + if e.complexity.Project.Readme == nil { + break + } + + return e.complexity.Project.Readme(childComplexity), true + case "Project.scriptExecutions": if e.complexity.Project.ScriptExecutions == nil { break @@ -809,6 +825,8 @@ type Project { publicId: UUID! parentId: UUID title: String! + description: String! + readme: String! seed: Int! version: Version! persist: Boolean @@ -891,6 +909,8 @@ type Query { input NewProject { parentId: UUID title: String! + description: String! + readme: String! seed: Int! accounts: [String!] transactionTemplates: [NewProjectTransactionTemplate!] @@ -910,6 +930,8 @@ input NewProjectScriptTemplate { input UpdateProject { id: UUID! title: String + description: String + readme: String persist: Boolean } @@ -2500,6 +2522,80 @@ func (ec *executionContext) _Project_title(ctx context.Context, field graphql.Co return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Project_description(ctx context.Context, field graphql.CollectedField, obj *model.Project) (ret graphql.Marshaler) { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + ec.Tracer.EndFieldExecution(ctx) + }() + rctx := &graphql.ResolverContext{ + Object: "Project", + Field: field, + Args: nil, + IsMethod: false, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Project_readme(ctx context.Context, field graphql.CollectedField, obj *model.Project) (ret graphql.Marshaler) { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + ec.Tracer.EndFieldExecution(ctx) + }() + rctx := &graphql.ResolverContext{ + Object: "Project", + Field: field, + Args: nil, + IsMethod: false, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Readme, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNString2string(ctx, field.Selections, res) +} + func (ec *executionContext) _Project_seed(ctx context.Context, field graphql.CollectedField, obj *model.Project) (ret graphql.Marshaler) { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { @@ -5034,6 +5130,18 @@ func (ec *executionContext) unmarshalInputNewProject(ctx context.Context, obj in if err != nil { return it, err } + case "description": + var err error + it.Description, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "readme": + var err error + it.Readme, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } case "seed": var err error it.Seed, err = ec.unmarshalNInt2int(ctx, v) @@ -5292,6 +5400,18 @@ func (ec *executionContext) unmarshalInputUpdateProject(ctx context.Context, obj if err != nil { return it, err } + case "description": + var err error + it.Description, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "readme": + var err error + it.Readme, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } case "persist": var err error it.Persist, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) @@ -5689,6 +5809,16 @@ func (ec *executionContext) _Project(ctx context.Context, sel ast.SelectionSet, if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } + case "description": + out.Values[i] = ec._Project_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "readme": + out.Values[i] = ec._Project_readme(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } case "seed": out.Values[i] = ec._Project_seed(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/go.mod b/go.mod index 4f6e088e..8d002298 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/gorilla/websocket v1.4.2 github.com/hashicorp/golang-lru v0.5.4 github.com/kelseyhightower/envconfig v1.4.0 + github.com/microcosm-cc/bluemonday v1.0.15 // indirect github.com/mitchellh/mapstructure v1.1.2 github.com/onflow/cadence v0.18.0 github.com/onflow/flow-go v0.18.2-canary diff --git a/go.sum b/go.sum index 9032e2b4..a23d8691 100644 --- a/go.sum +++ b/go.sum @@ -111,10 +111,13 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -177,8 +180,10 @@ github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= @@ -359,6 +364,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -704,6 +711,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/microcosm-cc/bluemonday v1.0.15 h1:J4uN+qPng9rvkBZBoBb8YGR+ijuklIMpSOZZLjYpbeY= +github.com/microcosm-cc/bluemonday v1.0.15/go.mod h1:ZLvAzeakRwrGnzQEvstVzVt3ZpqOF2+sdFr0Om+ce30= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= @@ -907,7 +916,9 @@ github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubr github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.19.0 h1:hYz4ZVdUgjXTBUmrkrw55j1nHx68LfOKIQk5IYtyScg= github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -936,6 +947,7 @@ github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= @@ -999,6 +1011,7 @@ github.com/uber/jaeger-lib v2.3.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= @@ -1178,6 +1191,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 h1:0PC75Fz/kyMGhL0e1QnypqK2kQMqKt9csD1GnMJR+Zk= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/model/models_gen.go b/model/models_gen.go index e907c075..2dc97e34 100644 --- a/model/models_gen.go +++ b/model/models_gen.go @@ -15,6 +15,8 @@ type Event struct { type NewProject struct { ParentID *uuid.UUID `json:"parentId"` Title string `json:"title"` + Description string `json:"description"` + Readme string `json:"readme"` Seed int `json:"seed"` Accounts []string `json:"accounts"` TransactionTemplates []*NewProjectTransactionTemplate `json:"transactionTemplates"` @@ -74,9 +76,11 @@ type ProgramPosition struct { } type UpdateProject struct { - ID uuid.UUID `json:"id"` - Title *string `json:"title"` - Persist *bool `json:"persist"` + ID uuid.UUID `json:"id"` + Title *string `json:"title"` + Description *string `json:"description"` + Readme *string `json:"readme"` + Persist *bool `json:"persist"` } type UpdateScriptTemplate struct { diff --git a/model/project.go b/model/project.go index dd86f7db..9136809c 100644 --- a/model/project.go +++ b/model/project.go @@ -24,6 +24,7 @@ import ( "cloud.google.com/go/datastore" "github.com/Masterminds/semver" "github.com/google/uuid" + "github.com/microcosm-cc/bluemonday" "github.com/pkg/errors" ) @@ -34,6 +35,8 @@ type InternalProject struct { PublicID uuid.UUID ParentID *uuid.UUID Title string + Description string + Readme string Seed int TransactionCount int TransactionExecutionCount int @@ -53,13 +56,16 @@ func (p *InternalProject) IsOwnedBy(userID uuid.UUID) bool { // and marks it as mutable. func (p *InternalProject) ExportPublicMutable() *Project { return &Project{ - ID: p.ID, - PublicID: p.PublicID, - ParentID: p.ParentID, - Persist: p.Persist, - Seed: p.Seed, - Version: p.Version, - Mutable: true, + ID: p.ID, + Title: p.Title, + Description: p.Description, + Readme: p.Readme, + PublicID: p.PublicID, + ParentID: p.ParentID, + Persist: p.Persist, + Seed: p.Seed, + Version: p.Version, + Mutable: true, } } @@ -67,13 +73,16 @@ func (p *InternalProject) ExportPublicMutable() *Project { // and marks it as immutable. func (p *InternalProject) ExportPublicImmutable() *Project { return &Project{ - ID: p.ID, - PublicID: p.PublicID, - ParentID: p.ParentID, - Persist: p.Persist, - Seed: p.Seed, - Version: p.Version, - Mutable: false, + ID: p.ID, + Title: p.Title, + Description: p.Description, + Readme: p.Readme, + PublicID: p.PublicID, + ParentID: p.ParentID, + Persist: p.Persist, + Seed: p.Seed, + Version: p.Version, + Mutable: false, } } @@ -93,6 +102,8 @@ func (p *InternalProject) Load(ps []datastore.Property) error { PublicID string ParentID *string Title string + Description string + Readme string Seed int TransactionCount int TransactionExecutionCount int @@ -146,6 +157,8 @@ func (p *InternalProject) Load(ps []datastore.Property) error { } p.Title = tmp.Title + p.Description = tmp.Description + p.Readme = tmp.Readme p.Seed = tmp.Seed p.TransactionCount = tmp.TransactionCount p.TransactionExecutionCount = tmp.TransactionExecutionCount @@ -170,6 +183,17 @@ func (p *InternalProject) Save() ([]datastore.Property, error) { *version = p.Version.String() } + // blueMonday policy building: https://github.com/microcosm-cc/bluemonday#policy-building + bmUSC := bluemonday.UGCPolicy() + bmUSC.AllowImages() + bmUSC.AllowAttrs("src").OnElements("img") + + bmStrict := bluemonday.StrictPolicy() + + sanitizedTitle := bmStrict.Sanitize(p.Title) + sanitizedDescription := bmStrict.Sanitize(p.Description) + sanitizedReadme := bmUSC.Sanitize(p.Readme) + return []datastore.Property{ { Name: "ID", @@ -193,7 +217,15 @@ func (p *InternalProject) Save() ([]datastore.Property, error) { }, { Name: "Title", - Value: p.Title, + Value: sanitizedTitle, + }, + { + Name: "Description", + Value: sanitizedDescription, + }, + { + Name: "Readme", + Value: sanitizedReadme, }, { Name: "Seed", @@ -235,14 +267,16 @@ func (p *InternalProject) Save() ([]datastore.Property, error) { } type Project struct { - ID uuid.UUID - PublicID uuid.UUID - ParentID *uuid.UUID - Seed int - Version *semver.Version - Title string - Persist bool - Mutable bool + ID uuid.UUID + PublicID uuid.UUID + ParentID *uuid.UUID + Seed int + Version *semver.Version + Title string + Description string + Readme string + Persist bool + Mutable bool } type ProjectChildID struct { diff --git a/playground_test.go b/playground_test.go index 97d1265c..ffe340d7 100644 --- a/playground_test.go +++ b/playground_test.go @@ -48,12 +48,14 @@ import ( ) type Project struct { - ID string - Title string - Seed int - Persist bool - Version string - Accounts []struct { + ID string + Title string + Description string + Readme string + Seed int + Persist bool + Version string + Accounts []struct { ID string Address string DraftCode string @@ -63,10 +65,12 @@ type Project struct { } const MutationCreateProject = ` -mutation($title: String!, $seed: Int!, $accounts: [String!], $transactionTemplates: [NewProjectTransactionTemplate!]) { - createProject(input: { title: $title, seed: $seed, accounts: $accounts, transactionTemplates: $transactionTemplates }) { +mutation($title: String!, $description: String!, $readme: String!, $seed: Int!, $accounts: [String!], $transactionTemplates: [NewProjectTransactionTemplate!]) { + createProject(input: { title: $title, description: $description, readme: $readme, seed: $seed, accounts: $accounts, transactionTemplates: $transactionTemplates }) { id title + description + readme seed persist version @@ -106,9 +110,12 @@ type GetProjectResponse struct { } const MutationUpdateProjectPersist = ` -mutation($projectId: UUID!, $persist: Boolean!) { - updateProject(input: { id: $projectId, persist: $persist }) { +mutation($projectId: UUID!, $title: String!, $description: String!, $readme: String!, $persist: Boolean!) { + updateProject(input: { id: $projectId, title: $title, description: $description, readme: $readme, persist: $persist }) { id + title + description + readme persist } } @@ -116,8 +123,11 @@ mutation($projectId: UUID!, $persist: Boolean!) { type UpdateProjectResponse struct { UpdateProject struct { - ID string - Persist bool + ID string + Title string + Description string + Readme string + Persist bool } } @@ -450,6 +460,8 @@ func TestProjects(t *testing.T) { MutationCreateProject, &resp, client.Var("title", "foo"), + client.Var("description", "bar"), + client.Var("readme", "bah"), client.Var("seed", 42), ) require.NoError(t, err) @@ -479,6 +491,8 @@ func TestProjects(t *testing.T) { MutationCreateProject, &resp, client.Var("title", "foo"), + client.Var("description", "desc"), + client.Var("readme", "rtfm"), client.Var("seed", 42), client.Var("accounts", accounts), ) @@ -509,6 +523,8 @@ func TestProjects(t *testing.T) { &resp, client.Var("title", "foo"), client.Var("seed", 42), + client.Var("description", "desc"), + client.Var("readme", "rtfm"), client.Var("accounts", accounts), ) require.NoError(t, err) @@ -543,6 +559,8 @@ func TestProjects(t *testing.T) { &resp, client.Var("title", "foo"), client.Var("seed", 42), + client.Var("description", "desc"), + client.Var("readme", "rtfm"), client.Var("transactionTemplates", templates), ) require.NoError(t, err) @@ -598,6 +616,9 @@ func TestProjects(t *testing.T) { MutationUpdateProjectPersist, &resp, client.Var("projectId", project.ID), + client.Var("title", project.Title), + client.Var("description", project.Description), + client.Var("readme", project.Readme), client.Var("persist", true), ) @@ -615,12 +636,18 @@ func TestProjects(t *testing.T) { MutationUpdateProjectPersist, &resp, client.Var("projectId", project.ID), + client.Var("title", project.Title), + client.Var("description", project.Description), + client.Var("readme", project.Readme), client.Var("persist", true), client.AddCookie(c.SessionCookie()), ) require.NoError(t, err) assert.Equal(t, project.ID, resp.UpdateProject.ID) + assert.Equal(t, project.Title, resp.UpdateProject.Title) + assert.Equal(t, project.Description, resp.UpdateProject.Description) + assert.Equal(t, project.Readme, resp.UpdateProject.Readme) assert.True(t, resp.UpdateProject.Persist) }) } @@ -1892,12 +1919,18 @@ func TestAuthentication(t *testing.T) { MutationUpdateProjectPersist, &respA, client.Var("projectId", project.ID), + client.Var("title", project.Title), + client.Var("description", project.Description), + client.Var("readme", project.Readme), client.Var("persist", true), client.AddCookie(legacyauth.MockProjectSessionCookie(project.ID, project.Secret)), ) require.NoError(t, err) assert.Equal(t, project.ID, respA.UpdateProject.ID) + assert.Equal(t, project.Title, respA.UpdateProject.Title) + assert.Equal(t, project.Description, respA.UpdateProject.Description) + assert.Equal(t, project.Readme, respA.UpdateProject.Readme) assert.True(t, respA.UpdateProject.Persist) // a new session cookie should be set @@ -1910,6 +1943,9 @@ func TestAuthentication(t *testing.T) { MutationUpdateProjectPersist, &respB, client.Var("projectId", project.ID), + client.Var("title", project.Title), + client.Var("description", project.Description), + client.Var("readme", project.Readme), client.Var("persist", false), client.AddCookie(c.SessionCookie()), ) @@ -1917,6 +1953,9 @@ func TestAuthentication(t *testing.T) { // should be able to perform update using new session cookie assert.Equal(t, project.ID, respB.UpdateProject.ID) + assert.Equal(t, project.Title, respB.UpdateProject.Title) + assert.Equal(t, project.Description, respB.UpdateProject.Description) + assert.Equal(t, project.Readme, respB.UpdateProject.Readme) assert.False(t, respB.UpdateProject.Persist) }) @@ -1934,12 +1973,17 @@ func TestAuthentication(t *testing.T) { MutationCreateProject, &respA, client.Var("title", "foo"), + client.Var("description", "desc"), + client.Var("readme", "rtfm"), client.Var("seed", 42), client.AddCookie(&malformedCookie), ) require.NoError(t, err) projectID := respA.CreateProject.ID + projectTitle := respA.CreateProject.Title + projectDescription := respA.CreateProject.Description + projectReadme := respA.CreateProject.Readme assert.NotEmpty(t, projectID) assert.Equal(t, 42, respA.CreateProject.Seed) @@ -1953,6 +1997,9 @@ func TestAuthentication(t *testing.T) { MutationUpdateProjectPersist, &respB, client.Var("projectId", projectID), + client.Var("title", projectTitle), + client.Var("description", projectDescription), + client.Var("readme", projectReadme), client.Var("persist", true), client.AddCookie(c.SessionCookie()), ) @@ -1960,6 +2007,9 @@ func TestAuthentication(t *testing.T) { // should be able to perform update using new session cookie assert.Equal(t, projectID, respB.UpdateProject.ID) + assert.Equal(t, projectTitle, respB.UpdateProject.Title) + assert.Equal(t, projectDescription, respB.UpdateProject.Description) + assert.Equal(t, projectReadme, respB.UpdateProject.Readme) assert.True(t, respB.UpdateProject.Persist) }) @@ -2351,6 +2401,8 @@ func createProject(t *testing.T, c *Client) Project { &resp, client.Var("title", "foo"), client.Var("seed", 42), + client.Var("description", "desc"), + client.Var("readme", "rtfm"), client.Var("accounts", []string{}), client.Var("transactionTemplates", []string{}), ) diff --git a/schema.graphql b/schema.graphql index 716aa02f..44a82b71 100644 --- a/schema.graphql +++ b/schema.graphql @@ -12,6 +12,8 @@ type Project { publicId: UUID! parentId: UUID title: String! + description: String! + readme: String! seed: Int! version: Version! persist: Boolean @@ -94,6 +96,8 @@ type Query { input NewProject { parentId: UUID title: String! + description: String! + readme: String! seed: Int! accounts: [String!] transactionTemplates: [NewProjectTransactionTemplate!] @@ -113,6 +117,8 @@ input NewProjectScriptTemplate { input UpdateProject { id: UUID! title: String + description: String + readme: String persist: Boolean } diff --git a/storage/datastore/store.go b/storage/datastore/store.go index ab0d5a4c..d904b3ef 100644 --- a/storage/datastore/store.go +++ b/storage/datastore/store.go @@ -203,6 +203,18 @@ func (d *Datastore) UpdateProject(input model.UpdateProject, proj *model.Interna return err } + if input.Title != nil { + proj.Title = *input.Title + } + + if input.Description != nil { + proj.Description = *input.Description + } + + if input.Readme != nil { + proj.Readme = *input.Readme + } + if input.Persist != nil { proj.Persist = *input.Persist } diff --git a/storage/memory/store.go b/storage/memory/store.go index 5fbb5c3c..3a24e6ab 100644 --- a/storage/memory/store.go +++ b/storage/memory/store.go @@ -141,6 +141,14 @@ func (s *Store) UpdateProject(input model.UpdateProject, proj *model.InternalPro p.Title = *input.Title } + if input.Description != nil { + p.Description = *input.Description + } + + if input.Readme != nil { + p.Readme = *input.Readme + } + if input.Persist != nil { p.Persist = *input.Persist } From 97df29ed78bde1bf75c29a9f8cc24dfe413a5bf8 Mon Sep 17 00:00:00 2001 From: hichana Date: Sat, 6 Nov 2021 05:30:17 +0900 Subject: [PATCH 2/2] change scheme to make title, description and readme optional data members --- generated.go | 30 ++++++------------------------ schema.graphql | 6 +++--- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/generated.go b/generated.go index 0f4e288a..5327f382 100644 --- a/generated.go +++ b/generated.go @@ -824,9 +824,9 @@ type Project { id: UUID! publicId: UUID! parentId: UUID - title: String! - description: String! - readme: String! + title: String + description: String + readme: String seed: Int! version: Version! persist: Boolean @@ -2511,15 +2511,12 @@ func (ec *executionContext) _Project_title(ctx context.Context, field graphql.Co return graphql.Null } if resTmp == nil { - if !ec.HasError(rctx) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } res := resTmp.(string) rctx.Result = res ctx = ec.Tracer.StartFieldChildExecution(ctx) - return ec.marshalNString2string(ctx, field.Selections, res) + return ec.marshalOString2string(ctx, field.Selections, res) } func (ec *executionContext) _Project_description(ctx context.Context, field graphql.CollectedField, obj *model.Project) (ret graphql.Marshaler) { @@ -2548,15 +2545,12 @@ func (ec *executionContext) _Project_description(ctx context.Context, field grap return graphql.Null } if resTmp == nil { - if !ec.HasError(rctx) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } res := resTmp.(string) rctx.Result = res ctx = ec.Tracer.StartFieldChildExecution(ctx) - return ec.marshalNString2string(ctx, field.Selections, res) + return ec.marshalOString2string(ctx, field.Selections, res) } func (ec *executionContext) _Project_readme(ctx context.Context, field graphql.CollectedField, obj *model.Project) (ret graphql.Marshaler) { @@ -2585,15 +2579,12 @@ func (ec *executionContext) _Project_readme(ctx context.Context, field graphql.C return graphql.Null } if resTmp == nil { - if !ec.HasError(rctx) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } res := resTmp.(string) rctx.Result = res ctx = ec.Tracer.StartFieldChildExecution(ctx) - return ec.marshalNString2string(ctx, field.Selections, res) + return ec.marshalOString2string(ctx, field.Selections, res) } func (ec *executionContext) _Project_seed(ctx context.Context, field graphql.CollectedField, obj *model.Project) (ret graphql.Marshaler) { @@ -5806,19 +5797,10 @@ func (ec *executionContext) _Project(ctx context.Context, sel ast.SelectionSet, out.Values[i] = ec._Project_parentId(ctx, field, obj) case "title": out.Values[i] = ec._Project_title(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } case "description": out.Values[i] = ec._Project_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } case "readme": out.Values[i] = ec._Project_readme(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } case "seed": out.Values[i] = ec._Project_seed(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/schema.graphql b/schema.graphql index 44a82b71..aeca6b79 100644 --- a/schema.graphql +++ b/schema.graphql @@ -11,9 +11,9 @@ type Project { id: UUID! publicId: UUID! parentId: UUID - title: String! - description: String! - readme: String! + title: String + description: String + readme: String seed: Int! version: Version! persist: Boolean