added in graphql client

This commit is contained in:
Ankit Patial 2024-11-01 23:19:56 +05:30
parent 1fb2d7d154
commit 46c46a7e71
29 changed files with 2453 additions and 585 deletions

4
.env.development Normal file
View File

@ -0,0 +1,4 @@
WEB_PORT = 3006
GRAPH_PORT = 3009
GRAPH_URL = http://localhost:3009/query
VITE_GRAPH_URL = http://localhost:3009/query

3
.gitignore vendored
View File

@ -20,6 +20,3 @@ Thumbs.db
# Vite # Vite
vite.config.js.timestamp-* vite.config.js.timestamp-*
vite.config.ts.timestamp-* vite.config.ts.timestamp-*
# Houdini
$houdini

View File

@ -1,9 +0,0 @@
projects:
default:
schema:
- ./graph/*.graphql
- ./$houdini/graphql/schema.graphql
documents:
- './web/**/*.gql'
- './web/**/*.svelte'
- ./$houdini/graphql/documents.gql

13
codegen.ts Normal file
View File

@ -0,0 +1,13 @@
import { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: process.env.GRAPH_URL,
documents: ['./graph/*.ts'],
generates: {
'./graph/d.ts': {
plugins: ['typescript', 'typescript-operations']
}
}
};
export default config;

2229
deno.lock

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,33 @@
import prettier from 'eslint-config-prettier'; import prettier from 'eslint-config-prettier';
import eslint from '@eslint/js';
import svelte from 'eslint-plugin-svelte'; import svelte from 'eslint-plugin-svelte';
export default [prettier, ...svelte.configs['flat/prettier']]; import globals from 'globals';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
...svelte.configs['flat/recommended'],
prettier,
...svelte.configs['flat/prettier'],
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
process: true
}
}
},
{
files: ['**/*.svelte'],
languageOptions: {
parserOptions: {
parser: tseslint.parser
}
}
},
{
ignores: ['.svelte-kit/', 'web/public/build']
}
);

2
go.sum
View File

@ -43,8 +43,6 @@ github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
github.com/vektah/gqlparser v1.3.1 h1:8b0IcD3qZKWJQHSzynbDlrtP3IxVydZ2DZepCGofqfU= github.com/vektah/gqlparser v1.3.1 h1:8b0IcD3qZKWJQHSzynbDlrtP3IxVydZ2DZepCGofqfU=
github.com/vektah/gqlparser v1.3.1/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74= github.com/vektah/gqlparser v1.3.1/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74=
github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI=
github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww=
github.com/vektah/gqlparser/v2 v2.5.18 h1:zSND3GtutylAQ1JpWnTHcqtaRZjl+y3NROeW8vuNo6Y= github.com/vektah/gqlparser/v2 v2.5.18 h1:zSND3GtutylAQ1JpWnTHcqtaRZjl+y3NROeW8vuNo6Y=
github.com/vektah/gqlparser/v2 v2.5.18/go.mod h1:6HLzf7JKv9Fi3APymudztFQNmLXR5qJeEo6BOFcXVfc= github.com/vektah/gqlparser/v2 v2.5.18/go.mod h1:6HLzf7JKv9Fi3APymudztFQNmLXR5qJeEo6BOFcXVfc=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=

9
graph/auth.gql.ts Normal file
View File

@ -0,0 +1,9 @@
import { gql } from '@urql/svelte';
export const QryMe = gql`
query Me {
me {
id
displayName
}
}
`;

View File

@ -2,3 +2,17 @@ extend type Mutation {
login(username: String!, email: String!): Boolean! login(username: String!, email: String!): Boolean!
logout: Boolean! logout: Boolean!
} }
extend type Query {
"""
me, is current AuthUser info
"""
me: AuthUser
}
type AuthUser {
id: ID!
email: String!
displayName: String!
roleID: Int!
}

View File

@ -7,6 +7,8 @@ package graph
import ( import (
"context" "context"
"fmt" "fmt"
"gitserver.in/patialtech/rano/graph/model"
) )
// Login is the resolver for the login field. // Login is the resolver for the login field.
@ -18,3 +20,8 @@ func (r *mutationResolver) Login(ctx context.Context, username string, email str
func (r *mutationResolver) Logout(ctx context.Context) (bool, error) { func (r *mutationResolver) Logout(ctx context.Context) (bool, error) {
panic(fmt.Errorf("not implemented: Logout - logout")) panic(fmt.Errorf("not implemented: Logout - logout"))
} }
// Me is the resolver for the me field.
func (r *queryResolver) Me(ctx context.Context) (*model.AuthUser, error) {
panic(fmt.Errorf("not implemented: Me - me"))
}

51
graph/d.ts Normal file
View File

@ -0,0 +1,51 @@
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
export type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };
export type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: { input: string; output: string; }
String: { input: string; output: string; }
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
Any: { input: any; output: any; }
Map: { input: any; output: any; }
Time: { input: any; output: any; }
Void: { input: any; output: any; }
};
export type AuthUser = {
__typename?: 'AuthUser';
displayName: Scalars['String']['output'];
email: Scalars['String']['output'];
id: Scalars['ID']['output'];
roleID: Scalars['Int']['output'];
};
export type Mutation = {
__typename?: 'Mutation';
login: Scalars['Boolean']['output'];
logout: Scalars['Boolean']['output'];
};
export type MutationLoginArgs = {
email: Scalars['String']['input'];
username: Scalars['String']['input'];
};
export type Query = {
__typename?: 'Query';
heartBeat: Scalars['Boolean']['output'];
/** me, is current AuthUser info */
me?: Maybe<AuthUser>;
};
export type MeQueryVariables = Exact<{ [key: string]: never; }>;
export type MeQuery = { __typename?: 'Query', me?: { __typename?: 'AuthUser', id: string, displayName: string } | null };

View File

@ -0,0 +1,283 @@
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package generated
import (
"context"
"errors"
"strconv"
"sync/atomic"
"github.com/99designs/gqlgen/graphql"
"github.com/vektah/gqlparser/v2/ast"
"gitserver.in/patialtech/rano/graph/model"
)
// region ************************** generated!.gotpl **************************
// endregion ************************** generated!.gotpl **************************
// region ***************************** args.gotpl *****************************
// endregion ***************************** args.gotpl *****************************
// region ************************** directives.gotpl **************************
// endregion ************************** directives.gotpl **************************
// region **************************** field.gotpl *****************************
func (ec *executionContext) _AuthUser_id(ctx context.Context, field graphql.CollectedField, obj *model.AuthUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_AuthUser_id(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
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.marshalNID2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_AuthUser_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthUser",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type ID does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _AuthUser_email(ctx context.Context, field graphql.CollectedField, obj *model.AuthUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_AuthUser_email(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Email, nil
})
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) fieldContext_AuthUser_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthUser",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _AuthUser_displayName(ctx context.Context, field graphql.CollectedField, obj *model.AuthUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_AuthUser_displayName(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisplayName, nil
})
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) fieldContext_AuthUser_displayName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthUser",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _AuthUser_roleID(ctx context.Context, field graphql.CollectedField, obj *model.AuthUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_AuthUser_roleID(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.RoleID, nil
})
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.(int)
fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_AuthUser_roleID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthUser",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Int does not have child fields")
},
}
return fc, nil
}
// endregion **************************** field.gotpl *****************************
// region **************************** input.gotpl *****************************
// endregion **************************** input.gotpl *****************************
// region ************************** interface.gotpl ***************************
// endregion ************************** interface.gotpl ***************************
// region **************************** object.gotpl ****************************
var authUserImplementors = []string{"AuthUser"}
func (ec *executionContext) _AuthUser(ctx context.Context, sel ast.SelectionSet, obj *model.AuthUser) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, authUserImplementors)
out := graphql.NewFieldSet(fields)
deferred := make(map[string]*graphql.FieldSet)
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("AuthUser")
case "id":
out.Values[i] = ec._AuthUser_id(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "email":
out.Values[i] = ec._AuthUser_email(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "displayName":
out.Values[i] = ec._AuthUser_displayName(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "roleID":
out.Values[i] = ec._AuthUser_roleID(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch(ctx)
if out.Invalids > 0 {
return graphql.Null
}
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
for label, dfs := range deferred {
ec.processDeferredGroup(graphql.DeferredGroup{
Label: label,
Path: graphql.GetPath(ctx),
FieldSet: dfs,
Context: ctx,
})
}
return out
}
// endregion **************************** object.gotpl ****************************
// region ***************************** type.gotpl *****************************
func (ec *executionContext) marshalOAuthUser2ᚖgitserverᚗinᚋpatialtechᚋranoᚋgraphᚋmodelᚐAuthUser(ctx context.Context, sel ast.SelectionSet, v *model.AuthUser) graphql.Marshaler {
if v == nil {
return graphql.Null
}
return ec._AuthUser(ctx, sel, v)
}
// endregion ***************************** type.gotpl *****************************

View File

@ -12,6 +12,7 @@ import (
"github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/introspection" "github.com/99designs/gqlgen/graphql/introspection"
"github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/ast"
"gitserver.in/patialtech/rano/graph/model"
) )
// region ************************** generated!.gotpl ************************** // region ************************** generated!.gotpl **************************
@ -22,6 +23,7 @@ type MutationResolver interface {
} }
type QueryResolver interface { type QueryResolver interface {
HeartBeat(ctx context.Context) (bool, error) HeartBeat(ctx context.Context) (bool, error)
Me(ctx context.Context) (*model.AuthUser, error)
} }
// endregion ************************** generated!.gotpl ************************** // endregion ************************** generated!.gotpl **************************
@ -243,6 +245,57 @@ func (ec *executionContext) fieldContext_Query_heartBeat(_ context.Context, fiel
return fc, nil return fc, nil
} }
func (ec *executionContext) _Query_me(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query_me(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Me(rctx)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*model.AuthUser)
fc.Result = res
return ec.marshalOAuthUser2ᚖgitserverᚗinᚋpatialtechᚋranoᚋgraphᚋmodelᚐAuthUser(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Query_me(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_AuthUser_id(ctx, field)
case "email":
return ec.fieldContext_AuthUser_email(ctx, field)
case "displayName":
return ec.fieldContext_AuthUser_displayName(ctx, field)
case "roleID":
return ec.fieldContext_AuthUser_roleID(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type AuthUser", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query___type(ctx, field) fc, err := ec.fieldContext_Query___type(ctx, field)
if err != nil { if err != nil {
@ -480,6 +533,25 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
} }
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
case "me":
field := field
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_me(ctx, field)
return res
}
rrm := func(ctx context.Context) graphql.Marshaler {
return ec.OperationContext.RootResolverMiddleware(ctx,
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
case "__type": case "__type":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {

View File

@ -2256,6 +2256,36 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se
return res return res
} }
func (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) {
res, err := graphql.UnmarshalID(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
res := graphql.MarshalID(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
}
return res
}
func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) {
res, err := graphql.UnmarshalInt(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler {
res := graphql.MarshalInt(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
}
return res
}
func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) { func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) {
res, err := graphql.UnmarshalString(v) res, err := graphql.UnmarshalString(v)
return res, graphql.ErrorOnPath(ctx, err) return res, graphql.ErrorOnPath(ctx, err)

View File

@ -40,6 +40,13 @@ type DirectiveRoot struct {
} }
type ComplexityRoot struct { type ComplexityRoot struct {
AuthUser struct {
DisplayName func(childComplexity int) int
Email func(childComplexity int) int
ID func(childComplexity int) int
RoleID func(childComplexity int) int
}
Mutation struct { Mutation struct {
Login func(childComplexity int, username string, email string) int Login func(childComplexity int, username string, email string) int
Logout func(childComplexity int) int Logout func(childComplexity int) int
@ -47,6 +54,7 @@ type ComplexityRoot struct {
Query struct { Query struct {
HeartBeat func(childComplexity int) int HeartBeat func(childComplexity int) int
Me func(childComplexity int) int
} }
} }
@ -69,6 +77,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
_ = ec _ = ec
switch typeName + "." + field { switch typeName + "." + field {
case "AuthUser.displayName":
if e.complexity.AuthUser.DisplayName == nil {
break
}
return e.complexity.AuthUser.DisplayName(childComplexity), true
case "AuthUser.email":
if e.complexity.AuthUser.Email == nil {
break
}
return e.complexity.AuthUser.Email(childComplexity), true
case "AuthUser.id":
if e.complexity.AuthUser.ID == nil {
break
}
return e.complexity.AuthUser.ID(childComplexity), true
case "AuthUser.roleID":
if e.complexity.AuthUser.RoleID == nil {
break
}
return e.complexity.AuthUser.RoleID(childComplexity), true
case "Mutation.login": case "Mutation.login":
if e.complexity.Mutation.Login == nil { if e.complexity.Mutation.Login == nil {
break break
@ -95,6 +131,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Query.HeartBeat(childComplexity), true return e.complexity.Query.HeartBeat(childComplexity), true
case "Query.me":
if e.complexity.Query.Me == nil {
break
}
return e.complexity.Query.Me(childComplexity), true
} }
return 0, false return 0, false
} }
@ -203,6 +246,20 @@ var sources = []*ast.Source{
login(username: String!, email: String!): Boolean! login(username: String!, email: String!): Boolean!
logout: Boolean! logout: Boolean!
} }
extend type Query {
"""
me, is current AuthUser info
"""
me: AuthUser
}
type AuthUser {
id: ID!
email: String!
displayName: String!
roleID: Int!
}
`, BuiltIn: false}, `, BuiltIn: false},
{Name: "../index.graphql", Input: `# GraphQL schema example {Name: "../index.graphql", Input: `# GraphQL schema example
# #

View File

@ -2,6 +2,13 @@
package model package model
type AuthUser struct {
ID string `json:"id"`
Email string `json:"email"`
DisplayName string `json:"displayName"`
RoleID int `json:"roleID"`
}
type Mutation struct { type Mutation struct {
} }

View File

@ -1,23 +0,0 @@
/// <references types="houdini-svelte">
/** @type {import('houdini').ConfigFile} */
const config = {
watchSchema: {
url: process.env.GRAPH_HOST,
headers: {
Authentication() {
const token = localStorage.getItem('AUTH_TOKEN') ?? '';
return `Bearer ${token}`;
}
}
},
plugins: {
'houdini-svelte': {
projectDir: './web',
client: './web/lib/gqlClient',
include: './web/**/*.{svelte,graphql,gql,ts,js}'
}
}
};
export default config;

View File

@ -1,43 +1,46 @@
{ {
"name": "rano", "name": "rano",
"type": "module", "type": "module",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite dev", "dev": "vite dev",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", "codegen": "graphql-codegen --config codegen.ts",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch", "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"format": "prettier --write .", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
"lint": "prettier --check . && eslint ." "format": "prettier --write .",
}, "lint": "prettier --check . && eslint ."
"devDependencies": { },
"@sveltejs/adapter-static": "^3.0.5", "devDependencies": {
"@sveltejs/kit": "^2.7.2", "@graphql-codegen/cli": "^5.0.3",
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.8", "@graphql-codegen/typescript": "^4.1.1",
"@tailwindcss/aspect-ratio": "^0.4.2", "@graphql-codegen/typescript-operations": "^4.3.1",
"@tailwindcss/container-queries": "^0.1.1", "@sveltejs/adapter-static": "^3.0.5",
"@tailwindcss/forms": "^0.5.9", "@sveltejs/kit": "^2.7.2",
"@tailwindcss/typography": "^0.5.15", "@sveltejs/vite-plugin-svelte": "^4.0.0-next.8",
"@types/eslint": "^9.6.0", "@tailwindcss/aspect-ratio": "^0.4.2",
"autoprefixer": "^10.4.20", "@tailwindcss/container-queries": "^0.1.1",
"daisyui": "^4.12.13", "@tailwindcss/forms": "^0.5.9",
"eslint": "^9.7.0", "@tailwindcss/typography": "^0.5.15",
"eslint-config-prettier": "^9.1.0", "@types/eslint": "^9.6.0",
"eslint-plugin-svelte": "^2.36.0", "@urql/svelte": "^4.2.1",
"globals": "^15.0.0", "autoprefixer": "^10.4.20",
"graphql": "^16.9.0", "daisyui": "^4.12.13",
"houdini": "^1.3.0", "eslint": "^9.7.0",
"houdini-svelte": "^2.0.0", "eslint-config-prettier": "^9.1.0",
"prettier": "^3.3.2", "eslint-plugin-svelte": "^2.36.0",
"prettier-plugin-svelte": "^3.2.6", "globals": "^15.0.0",
"prettier-plugin-tailwindcss": "^0.6.5", "graphql": "^16.9.0",
"svelte": "^5.0.5", "prettier": "^3.3.2",
"svelte-check": "^4.0.5", "prettier-plugin-svelte": "^3.2.6",
"tailwindcss": "^3.4.14", "prettier-plugin-tailwindcss": "^0.6.5",
"typescript": "^5.0.0", "svelte": "^5.0.5",
"typescript-eslint": "^8.0.0", "svelte-check": "^4.0.5",
"vite": "^5.0.3" "tailwindcss": "^3.4.14",
} "typescript": "^5.0.0",
"typescript-eslint": "^8.0.0",
"vite": "^5.0.3"
}
} }

View File

@ -1,58 +0,0 @@
"""
The @defer directive may be specified on a fragment spread to imply de-prioritization, that causes the fragment to be omitted in the initial response, and delivered as a subsequent response afterward. A query with @defer directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred delivered in a subsequent response. @include and @skip take precedence over @defer.
"""
directive @defer(if: Boolean = true, label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT
"""
directive to map Go type
"""
directive @goField(
forceResolver: Boolean
name: String
omittable: Boolean
) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION
"""
directive to map Go type
example:-
type User @goModel(model: "github.com/my/app/models.User") {
id: ID! @goField(name: "todoId")
name: String!
@goField(forceResolver: true)
@goTag(key: "xorm", value: "-")
@goTag(key: "yaml")
}
"""
directive @goModel(
forceGenerate: Boolean
model: String
models: [String!]
) on ENUM | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION
directive @goTag(key: String!, value: String) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION
"""
Go type interface{}
"""
scalar Any
"""
type Map(Go type: map[string]interface{})
"""
scalar Map
type Mutation {
login(email: String!, username: String!): Boolean!
logout: Boolean!
}
type Query {
heartBeat: Boolean!
}
"""
Maps a Time GraphQL scalar to a Go time.Time struct.
"""
scalar Time
scalar Void

View File

@ -17,9 +17,9 @@ const config = {
assets: path.resolve(webDir, 'public') assets: path.resolve(webDir, 'public')
}, },
alias: { alias: {
$graph: path.resolve(webDir, 'graph'),
$image: path.resolve(webDir, 'assets', 'image'), $image: path.resolve(webDir, 'assets', 'image'),
$svg: path.resolve(webDir, 'assets', 'svg'), $svg: path.resolve(webDir, 'assets', 'svg')
$houdini: path.resolve('.', '$houdini')
}, },
paths: { paths: {
assets: process.env.ASSETS_HOST ?? '' assets: process.env.ASSETS_HOST ?? ''

View File

@ -1,6 +1,10 @@
version: '3' version: '3'
env: env:
ENV: development ENV: development
dotenv: ['.env.{{.ENV}}']
tasks: tasks:
gen: gen:
desc: use go generate, for graph files desc: use go generate, for graph files
@ -23,13 +27,13 @@ tasks:
desc: run graph server desc: run graph server
cmds: cmds:
- cmd: go run ./graph/server - cmd: go run ./graph/server
env:
GRAPH_PORT: 3009 codegen:
desc: generate graph types
cmds:
- cmd: deno task codegen
web: web:
desc: run web in dev mode desc: run web in dev mode
cmds: cmds:
- cmd: deno task dev - cmd: deno task dev
env:
WEB_PORT: 3006
GRAPH_HOST: http://localhost:3009/query

View File

@ -10,7 +10,7 @@
"sourceMap": true, "sourceMap": true,
"strict": true, "strict": true,
"moduleResolution": "bundler", "moduleResolution": "bundler",
"rootDirs": ["./web", "./.svelte-kit/types", "./$houdini/types"] "rootDirs": [".", "./.svelte-kit/types"]
} }
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files

View File

@ -1,9 +1,8 @@
import { sveltekit } from '@sveltejs/kit/vite'; import { sveltekit } from '@sveltejs/kit/vite';
import houdini from 'houdini/vite';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
export default defineConfig({ export default defineConfig({
plugins: [houdini(), sveltekit()], plugins: [sveltekit()],
server: { server: {
port: parseInt(process.env.WEB_PORT ?? '3001'), port: parseInt(process.env.WEB_PORT ?? '3001'),
fs: { fs: {

8
web/lib/client.ts Normal file
View File

@ -0,0 +1,8 @@
import { Client, cacheExchange, fetchExchange } from '@urql/svelte';
export function newClient(url: string) {
return new Client({
url,
exchanges: [cacheExchange, fetchExchange]
});
}

View File

@ -1,5 +0,0 @@
import { HoudiniClient } from '$houdini';
export default new HoudiniClient({
url: process.env.GRAPH_HOST
});

View File

@ -1,3 +0,0 @@
export function hello() {
console.log("hello");
}

View File

View File

@ -0,0 +1 @@
export let authUser = $state();

View File

@ -1,6 +1,10 @@
<script> <script lang="ts">
import "../app.css"; import { setContextClient } from '@urql/svelte';
const { children } = $props(); import { newClient } from '$lib/client';
import '../app.css';
const { children } = $props();
setContextClient(newClient(import.meta.env.VITE_GRAPH_URL ?? ''));
</script> </script>
{@render children()} {@render children()}