~edwargix/git.sr.ht

b04a8fc024a18ce8248613d9cc7cd1fd6080ee41 — Drew DeVault 3 years ago 1f4f2d1
API: design schema for custom readmes
M api/graph/api/generated.go => api/graph/api/generated.go +267 -0
@@ 113,7 113,9 @@ type ComplexityRoot struct {
		DeleteACL        func(childComplexity int, id int) int
		DeleteArtifact   func(childComplexity int, id int) int
		DeleteRepository func(childComplexity int, id int) int
		RemoveReadme     func(childComplexity int, repoID int) int
		UpdateACL        func(childComplexity int, repoID int, mode model.AccessMode, entity string) int
		UpdateReadme     func(childComplexity int, repoID int, html string) int
		UpdateRepository func(childComplexity int, id int, input map[string]interface{}) int
		UploadArtifact   func(childComplexity int, repoID int, revspec string, file graphql.Upload) int
	}


@@ 151,6 153,7 @@ type ComplexityRoot struct {
		Objects           func(childComplexity int, ids []string) int
		Owner             func(childComplexity int) int
		Path              func(childComplexity int, revspec *string, path string) int
		Readme            func(childComplexity int) int
		References        func(childComplexity int, cursor *model1.Cursor) int
		RevparseSingle    func(childComplexity int, revspec string) int
		Updated           func(childComplexity int) int


@@ 248,6 251,8 @@ type MutationResolver interface {
	DeleteACL(ctx context.Context, id int) (*model.ACL, error)
	UploadArtifact(ctx context.Context, repoID int, revspec string, file graphql.Upload) (*model.Artifact, error)
	DeleteArtifact(ctx context.Context, id int) (*model.Artifact, error)
	UpdateReadme(ctx context.Context, repoID int, html string) (string, error)
	RemoveReadme(ctx context.Context, repoID int) (*string, error)
}
type QueryResolver interface {
	Version(ctx context.Context) (*model.Version, error)


@@ 566,6 571,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in

		return e.complexity.Mutation.DeleteRepository(childComplexity, args["id"].(int)), true

	case "Mutation.removeREADME":
		if e.complexity.Mutation.RemoveReadme == nil {
			break
		}

		args, err := ec.field_Mutation_removeREADME_args(context.TODO(), rawArgs)
		if err != nil {
			return 0, false
		}

		return e.complexity.Mutation.RemoveReadme(childComplexity, args["repoId"].(int)), true

	case "Mutation.updateACL":
		if e.complexity.Mutation.UpdateACL == nil {
			break


@@ 578,6 595,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in

		return e.complexity.Mutation.UpdateACL(childComplexity, args["repoId"].(int), args["mode"].(model.AccessMode), args["entity"].(string)), true

	case "Mutation.updateREADME":
		if e.complexity.Mutation.UpdateReadme == nil {
			break
		}

		args, err := ec.field_Mutation_updateREADME_args(context.TODO(), rawArgs)
		if err != nil {
			return 0, false
		}

		return e.complexity.Mutation.UpdateReadme(childComplexity, args["repoId"].(int), args["html"].(string)), true

	case "Mutation.updateRepository":
		if e.complexity.Mutation.UpdateRepository == nil {
			break


@@ 813,6 842,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in

		return e.complexity.Repository.Path(childComplexity, args["revspec"].(*string), args["path"].(string)), true

	case "Repository.readme":
		if e.complexity.Repository.Readme == nil {
			break
		}

		return e.complexity.Repository.Readme(childComplexity), true

	case "Repository.references":
		if e.complexity.Repository.References == nil {
			break


@@ 1331,6 1367,12 @@ type Repository {
  description: String
  visibility: Visibility!

  # The repository's custom README, if set.
  #
  # NOTICE: This returns unsanitized HTML. It is the client's responsibility to
  # sanitize this for display on the web, if so desired.
  readme: String

  # If this repository was cloned from another, this is set to the original
  # clone URL.
  upstreamUrl: String


@@ 1607,6 1649,14 @@ type Mutation {

  # Deletes an artifact.
  deleteArtifact(id: Int!): Artifact! @access(scope: OBJECTS, kind: RW)

  # Updates the custom README associated with this repository. Note that the
  # provided HTML will be sanitized when displayed on the web; see
  # https://man.sr.ht/markdown/#post-processing
  updateREADME(repoId: Int!, html: String!): String! @access(scope: REPOSITORIES, kind: RW)

  # Removes the custom README associated with this repository.
  removeREADME(repoId: Int!): String @access(scope: REPOSITORIES, kind: RW)
}
`, BuiltIn: false},
}


@@ 1733,6 1783,21 @@ func (ec *executionContext) field_Mutation_deleteRepository_args(ctx context.Con
	return args, nil
}

func (ec *executionContext) field_Mutation_removeREADME_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 int
	if tmp, ok := rawArgs["repoId"]; ok {
		ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("repoId"))
		arg0, err = ec.unmarshalNInt2int(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["repoId"] = arg0
	return args, nil
}

func (ec *executionContext) field_Mutation_updateACL_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}


@@ 1766,6 1831,30 @@ func (ec *executionContext) field_Mutation_updateACL_args(ctx context.Context, r
	return args, nil
}

func (ec *executionContext) field_Mutation_updateREADME_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 int
	if tmp, ok := rawArgs["repoId"]; ok {
		ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("repoId"))
		arg0, err = ec.unmarshalNInt2int(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["repoId"] = arg0
	var arg1 string
	if tmp, ok := rawArgs["html"]; ok {
		ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("html"))
		arg1, err = ec.unmarshalNString2string(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["html"] = arg1
	return args, nil
}

func (ec *executionContext) field_Mutation_updateRepository_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}


@@ 3772,6 3861,143 @@ func (ec *executionContext) _Mutation_deleteArtifact(ctx context.Context, field 
	return ec.marshalNArtifact2ᚖgitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐArtifact(ctx, field.Selections, res)
}

func (ec *executionContext) _Mutation_updateREADME(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:     "Mutation",
		Field:      field,
		Args:       nil,
		IsMethod:   true,
		IsResolver: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	rawArgs := field.ArgumentMap(ec.Variables)
	args, err := ec.field_Mutation_updateREADME_args(ctx, rawArgs)
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	fc.Args = args
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		directive0 := func(rctx context.Context) (interface{}, error) {
			ctx = rctx // use context from middleware stack in children
			return ec.resolvers.Mutation().UpdateReadme(rctx, args["repoId"].(int), args["html"].(string))
		}
		directive1 := func(ctx context.Context) (interface{}, error) {
			scope, err := ec.unmarshalNAccessScope2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐAccessScope(ctx, "REPOSITORIES")
			if err != nil {
				return nil, err
			}
			kind, err := ec.unmarshalNAccessKind2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐAccessKind(ctx, "RW")
			if err != nil {
				return nil, err
			}
			if ec.directives.Access == nil {
				return nil, errors.New("directive access is not implemented")
			}
			return ec.directives.Access(ctx, nil, directive0, scope, kind)
		}

		tmp, err := directive1(rctx)
		if err != nil {
			return nil, graphql.ErrorOnPath(ctx, err)
		}
		if tmp == nil {
			return nil, nil
		}
		if data, ok := tmp.(string); ok {
			return data, nil
		}
		return nil, fmt.Errorf(`unexpected type %T from directive, should be string`, tmp)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) _Mutation_removeREADME(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:     "Mutation",
		Field:      field,
		Args:       nil,
		IsMethod:   true,
		IsResolver: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	rawArgs := field.ArgumentMap(ec.Variables)
	args, err := ec.field_Mutation_removeREADME_args(ctx, rawArgs)
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	fc.Args = args
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		directive0 := func(rctx context.Context) (interface{}, error) {
			ctx = rctx // use context from middleware stack in children
			return ec.resolvers.Mutation().RemoveReadme(rctx, args["repoId"].(int))
		}
		directive1 := func(ctx context.Context) (interface{}, error) {
			scope, err := ec.unmarshalNAccessScope2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐAccessScope(ctx, "REPOSITORIES")
			if err != nil {
				return nil, err
			}
			kind, err := ec.unmarshalNAccessKind2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐAccessKind(ctx, "RW")
			if err != nil {
				return nil, err
			}
			if ec.directives.Access == nil {
				return nil, errors.New("directive access is not implemented")
			}
			return ec.directives.Access(ctx, nil, directive0, scope, kind)
		}

		tmp, err := directive1(rctx)
		if err != nil {
			return nil, graphql.ErrorOnPath(ctx, err)
		}
		if tmp == nil {
			return nil, nil
		}
		if data, ok := tmp.(*string); ok {
			return data, nil
		}
		return nil, fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*string)
	fc.Result = res
	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}

func (ec *executionContext) _Query_version(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {


@@ 4757,6 4983,38 @@ func (ec *executionContext) _Repository_visibility(ctx context.Context, field gr
	return ec.marshalNVisibility2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐVisibility(ctx, field.Selections, res)
}

func (ec *executionContext) _Repository_readme(ctx context.Context, field graphql.CollectedField, obj *model.Repository) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:     "Repository",
		Field:      field,
		Args:       nil,
		IsMethod:   false,
		IsResolver: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	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 {
		return graphql.Null
	}
	res := resTmp.(*string)
	fc.Result = res
	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}

func (ec *executionContext) _Repository_upstreamUrl(ctx context.Context, field graphql.CollectedField, obj *model.Repository) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {


@@ 8426,6 8684,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
			if out.Values[i] == graphql.Null {
				invalids++
			}
		case "updateREADME":
			out.Values[i] = ec._Mutation_updateREADME(ctx, field)
			if out.Values[i] == graphql.Null {
				invalids++
			}
		case "removeREADME":
			out.Values[i] = ec._Mutation_removeREADME(ctx, field)
		default:
			panic("unknown field " + strconv.Quote(field.Name))
		}


@@ 8679,6 8944,8 @@ func (ec *executionContext) _Repository(ctx context.Context, sel ast.SelectionSe
			if out.Values[i] == graphql.Null {
				atomic.AddUint32(&invalids, 1)
			}
		case "readme":
			out.Values[i] = ec._Repository_readme(ctx, field, obj)
		case "upstreamUrl":
			out.Values[i] = ec._Repository_upstreamUrl(ctx, field, obj)
		case "accessControlList":

M api/graph/model/repository.go => api/graph/model/repository.go +2 -0
@@ 22,6 22,7 @@ type Repository struct {
	Name           string     `json:"name"`
	Description    *string    `json:"description"`
	UpstreamURL    *string    `json:"upstreamUrl"`
	Readme         *string    `json:"readme"`

	Path    string
	OwnerID int


@@ 96,6 97,7 @@ func (r *Repository) Fields() *database.ModelFields {
			{ "description", "description", &r.Description },
			{ "visibility", "visibility", &r.RawVisibility },
			{ "upstream_uri", "upstreamUrl", &r.UpstreamURL },
			{ "readme", "readme", &r.Readme },

			// Always fetch:
			{ "id", "", &r.ID },

M api/graph/schema.graphqls => api/graph/schema.graphqls +14 -0
@@ 84,6 84,12 @@ type Repository {
  description: String
  visibility: Visibility!

  # The repository's custom README, if set.
  #
  # NOTICE: This returns unsanitized HTML. It is the client's responsibility to
  # sanitize this for display on the web, if so desired.
  readme: String

  # If this repository was cloned from another, this is set to the original
  # clone URL.
  upstreamUrl: String


@@ 360,4 366,12 @@ type Mutation {

  # Deletes an artifact.
  deleteArtifact(id: Int!): Artifact! @access(scope: OBJECTS, kind: RW)

  # Updates the custom README associated with this repository. Note that the
  # provided HTML will be sanitized when displayed on the web; see
  # https://man.sr.ht/markdown/#post-processing
  updateREADME(repoId: Int!, html: String!): String! @access(scope: REPOSITORIES, kind: RW)

  # Removes the custom README associated with this repository.
  removeREADME(repoId: Int!): String @access(scope: REPOSITORIES, kind: RW)
}

M api/graph/schema.resolvers.go => api/graph/schema.resolvers.go +8 -0
@@ 392,6 392,14 @@ func (r *mutationResolver) DeleteArtifact(ctx context.Context, id int) (*model.A
	panic(fmt.Errorf("deleteArtifact: not implemented"))
}

func (r *mutationResolver) UpdateReadme(ctx context.Context, repoID int, html string) (string, error) {
	panic(fmt.Errorf("not implemented"))
}

func (r *mutationResolver) RemoveReadme(ctx context.Context, repoID int) (*string, error) {
	panic(fmt.Errorf("not implemented"))
}

func (r *queryResolver) Version(ctx context.Context) (*model.Version, error) {
	return &model.Version{
		Major:           0,