forked from effect-app/boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
186 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { BlogPost } from "@effect-app-boilerplate/models/Blog" | ||
import { either } from "@effect-app/prelude/schema" | ||
import { CreatePost } from "../Blog.js" | ||
import { MutationErrors } from "../errors.js" | ||
import { GraphQueryRequest, GraphQueryResponse } from "./Query.js" | ||
import { makeMutationInput } from "./utils.js" | ||
|
||
const makeMutationInput_ = makeMutationInput(GraphQueryRequest.Api.props) | ||
|
||
// TODO: Add The follow-up Graph Query | ||
// - parse inputs, when string and starts with $, take from mutation output. | ||
@useClassNameForSchema | ||
@allowAnonymous | ||
@allowRoles("user") | ||
export class GraphMutationRequest extends Post("/graph/mutate")<GraphMutationRequest>()( | ||
{ | ||
CreatePost: optProp( | ||
makeMutationInput_(CreatePost.CreatePostRequest) | ||
) | ||
// UpdatePurchaseOrder: optProp( | ||
// makeMutationInput_(PurchaseOrders.Update.UpdatePurchaseOrderRequest) | ||
// ) | ||
} | ||
) {} | ||
|
||
const PostResult = props({ | ||
...GraphQueryResponse.Api.props, | ||
result: optProp(BlogPost) | ||
}) | ||
|
||
@useClassNameForSchema | ||
export class GraphMutationResponse extends Model<GraphMutationResponse>()({ | ||
// TODO: Support guaranteed optional sub-queries, like on Create/Update of PO | ||
// guarantee an optional return of PurchaseOrder | ||
// first must enable PO cache for guarantee. | ||
CreatePost: optProp( | ||
either( | ||
MutationErrors, | ||
props({ | ||
response: prop(CreatePost.CreatePostResponse), | ||
query: optProp(PostResult) | ||
}) | ||
) | ||
) | ||
// UpdatePurchaseOrder: optProp( | ||
// either( | ||
// MutationErrors, | ||
// props({ | ||
// response: optProp(Void), | ||
// query: optProp(POResult) | ||
// }) | ||
// ) | ||
// ) | ||
}) {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { either } from "@effect-app/prelude/schema" | ||
import { QueryErrors } from "../errors.js" | ||
import { BlogRsc } from "../index.js" | ||
import { makeInput } from "./utils.js" | ||
|
||
@useClassNameForSchema | ||
@allowAnonymous | ||
@allowRoles("user") | ||
export class GraphQueryRequest extends Post("/graph/query")<GraphQueryRequest>()({ | ||
// AllMe: optProp(makeInput(Me.All.GetMeRequest, true)), | ||
// AllMeEventlog: optProp(makeInput(Me.Eventlog.AllMeEventlogRequest, true)), | ||
// AllMeChangeRequests: optProp( | ||
// makeInput(Me.ChangeRequests.AllMeChangeRequestsRequest, true) | ||
// ), | ||
// AllMeCommentActivity: optProp( | ||
// makeInput(Me.CommentActivity.AllMeCommentActivityRequest, true) | ||
// ), | ||
// AllMeTasks: optProp(makeInput(Me.Tasks.AllMeTasksRequest, true)), | ||
|
||
FindBlogPost: optProp(makeInput(BlogRsc.FindPost.FindPostRequest)), | ||
GetAllBlogPosts: optProp(makeInput(BlogRsc.GetPosts.GetPostsRequest)) | ||
}) {} | ||
|
||
@useClassNameForSchema | ||
export class GraphQueryResponse extends Model<GraphQueryResponse>()({ | ||
// AllMe: optProp(either(QueryErrors, Me.All.GetMeResponse)), | ||
// AllMeEventlog: optProp(either(QueryErrors, Me.Eventlog.AllMeEventlogResponse)), | ||
// AllMeChangeRequests: optProp( | ||
// either(QueryErrors, Me.ChangeRequests.AllMeChangeRequestsResponse) | ||
// ), | ||
// AllMeCommentActivity: optProp( | ||
// either(QueryErrors, Me.CommentActivity.AllMeCommentActivityResponse) | ||
// ), | ||
// AllMeTasks: optProp(either(QueryErrors, Me.Tasks.AllMeTasksResponse)), | ||
|
||
FindBlogPost: optProp( | ||
either(QueryErrors, BlogRsc.FindPost.FindPostResponse) | ||
) | ||
}) {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { Property, PropertyRecord, SchemaAny, SchemaProperties } from "@effect-app/prelude/schema" | ||
|
||
export function makeInput<Self extends SchemaAny>( | ||
a: Self | ||
): SchemaProperties<{ | ||
input: Property<Self, "required", None, None> | ||
}> | ||
export function makeInput<Self extends SchemaAny>( | ||
a: Self, | ||
noInput: true | ||
): SchemaProperties<{ | ||
input: Property<Self, "optional", None, None> | ||
}> | ||
export function makeInput<Self extends SchemaAny>(a: Self, noInput?: boolean): any { | ||
return props(noInput ? { input: optProp(a) } : { input: prop(a) }) | ||
} | ||
|
||
export function makeMutationInput<Props extends PropertyRecord>(baseSchemaProps: Props) { | ||
return <Self extends SchemaAny>(a: Self) => { | ||
const query = props({ ...baseSchemaProps, result: optProp(bool) }) | ||
return props({ input: prop(a), query: optProp(query) }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
@useClassNameForSchema | ||
export class NotFoundError extends Model<NotFoundError>()({ | ||
_tag: prop(literal("NotFoundError")), | ||
message: prop(string) | ||
}) {} | ||
|
||
@useClassNameForSchema | ||
export class InvalidStateError extends Model<InvalidStateError>()({ | ||
_tag: prop(literal("InvalidStateError")), | ||
message: prop(string) | ||
}) {} | ||
|
||
@useClassNameForSchema | ||
export class ValidationError extends Model<ValidationError>()({ | ||
_tag: prop(literal("ValidationError")), | ||
errors: prop(array(unknown)) // meh | ||
}) {} | ||
|
||
@useClassNameForSchema | ||
export class NotLoggedInError extends Model<NotLoggedInError>()({ | ||
_tag: prop(literal("NotLoggedInError")) | ||
}) {} | ||
|
||
@useClassNameForSchema | ||
export class UnauthorizedError extends Model<UnauthorizedError>()({ | ||
_tag: prop(literal("UnauthorizedError")) | ||
}) {} | ||
|
||
@useClassNameForSchema | ||
export class OptimisticConcurrencyException extends Model<OptimisticConcurrencyException>()( | ||
{ | ||
_tag: prop(literal("OptimisticConcurrencyException")) | ||
} | ||
) {} | ||
|
||
const MutationOnlyErrors = { | ||
InvalidStateError, | ||
OptimisticConcurrencyException | ||
} | ||
|
||
const GeneralErrors = { | ||
NotFoundError, | ||
NotLoggedInError, | ||
UnauthorizedError, | ||
ValidationError | ||
} | ||
|
||
export const SupportedErrors = union({ | ||
...MutationOnlyErrors, | ||
...GeneralErrors | ||
}) | ||
["|>"](named("SupportedErrors")) | ||
["|>"](withDefaults) | ||
export type SupportedErrors = ParsedShapeOf<typeof SupportedErrors> | ||
|
||
// ideal? | ||
// export const QueryErrors = union({ ...GeneralErrors }) | ||
// ["|>"](named("QueryErrors")) | ||
// ["|>"](withDefaults) | ||
// export type QueryErrors = ParsedShapeOf<typeof QueryErrors> | ||
// export const MutationErrors = union({ ...GeneralErrors, ...GeneralErrors }) | ||
// ["|>"](named("MutationErrors")) | ||
// ["|>"](withDefaults) | ||
|
||
// export type MutationErrors = ParsedShapeOf<typeof MutationErrors> | ||
|
||
export const MutationErrors = SupportedErrors | ||
export const QueryErrors = SupportedErrors | ||
export type MutationErrors = ParsedShapeOf<typeof MutationErrors> | ||
export type QueryErrors = ParsedShapeOf<typeof QueryErrors> |