### Set Up Pylon Service with Bun Runtime Source: https://pylon.cronit.io/docs/guides/building-with-pylon/introduction This snippet demonstrates the initial setup for a Pylon service. It assumes the user has followed the 'Getting Started' guide and specifies 'Bun' as the preferred runtime environment for Pylon, highlighting compatibility with other runtimes. ```markdown This guilde will use `Bun` as the runtime environment, but you can use any other runtime environment that supports Pylon without any issues. ``` -------------------------------- ### Start Pylon Development Server Source: https://pylon.cronit.io/docs/getting-started Commands to navigate into the project directory and start the Pylon development server. This allows for real-time development and testing of the Pylon application. ```bash cd my-pylon npm run dev ``` -------------------------------- ### Initial Pylon GraphQL Configuration Source: https://pylon.cronit.io/docs/guides/building-with-pylon/hardcoded-data This shows the initial structure of the index.ts file before integrating the BookingStore. It defines a basic 'hello' query and exports the Pylon app instance. This serves as a starting point for Pylon configuration. ```typescript import {app} from '@getcronit/pylon' export const graphql = { Query: { hello: () => 'Hello World' }, Mutation: {} } export default app ``` -------------------------------- ### Install Pylon Dependencies Source: https://pylon.cronit.io/docs/guides/convert-from-hono-guide Commands to install Pylon development and runtime dependencies using Bun and npm. Bun is recommended for faster installations. ```bash bun add -D @getcronit/pylon-dev bun add @getcronit/pylon ``` ```bash npm install --save-dev @getcronit/pylon-dev bun add @getcronit/pylon ``` -------------------------------- ### Install Pylon Dependencies Source: https://pylon.cronit.io/docs/contributing/how-to-contribute Installs the necessary project dependencies for Pylon after cloning the repository. Requires Node.js and npm to be installed. ```bash cd pylon npm install ``` -------------------------------- ### Create a Basic GET Route Handler in Hono Source: https://pylon.cronit.io/docs/core-concepts/context-management This snippet shows a simple GET route handler using Hono's `app` instance. It defines a route '/hello' that returns a 'Hello, world!' response. This is a fundamental example of defining an HTTP endpoint within a Pylon application. ```typescript app.get('/hello', (ctx, next) => { return new Response('Hello, world!') }) ``` -------------------------------- ### Set Up Basic Pylon Application (TypeScript) Source: https://pylon.cronit.io/docs/guides/testing Initializes a basic Pylon application by importing the `app` instance and declaring an empty array for posts. This serves as the foundational structure for the Pylon project. ```typescript import {app} from '@getcronit/pylon' const posts: {id: number; title: string; content: string}[] = [] export default app ``` -------------------------------- ### Running the Application with Bun Source: https://pylon.cronit.io/docs/guides/convert-from-hono-guide This command demonstrates how to start the development server for your Pylon application using Bun. It's a concise command for quick local development and testing. ```shell bun run dev ``` -------------------------------- ### Dockerfile for Pylon Service (Bun) Source: https://pylon.cronit.io/docs/guides/convert-from-hono-guide A multi-stage Dockerfile for building and running a Pylon service using Bun. Includes steps for dependency installation, building, and creating a production-ready image. ```dockerfile # use the official Bun image # see all versions at https://hub.docker.com/r/oven/bun/tags FROM oven/bun:1 as base LABEL description="Offical docker image for Pylon services (Bun)" LABEL org.opencontainers.image.source="https://github.com/getcronit/pylon" LABEL maintainer="office@cronit.io" WORKDIR /usr/src/pylon # install dependencies into temp directory # this will cache them and speed up future builds FROM base AS install RUN mkdir -p /temp/dev COPY package.json bun.lockb /temp/dev/ RUN cd /temp/dev && bun install --frozen-lockfile # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod COPY package.json bun.lockb /temp/prod/ RUN cd /temp/prod && bun install --frozen-lockfile --production # copy node_modules from temp directory # then copy all (non-ignored) project files into the image FROM install AS prerelease COPY --from=install /temp/dev/node_modules node_modules COPY . . # [optional] tests & build ENV NODE_ENV=production # Create .pylon folder (mkdir) RUN mkdir -p .pylon # RUN bun test RUN bun run pylon build # copy production dependencies and source code into final image FROM base AS release COPY --from=install /temp/prod/node_modules node_modules COPY --from=prerelease /usr/src/pylon/.pylon .pylon COPY --from=prerelease /usr/src/pylon/package.json . ``` -------------------------------- ### Define Pylon Service with Basic Prisma Client Source: https://pylon.cronit.io/docs/integrations/databases Example of defining a Pylon GraphQL service that uses a PrismaClient instance to interact with a database. This includes example query and mutation operations. ```typescript import {app} from '@getcronit/pylon' import {PrismaClient} from '@prisma/client' const prisma = new PrismaClient() export const graphql = { Query: { // Example query using Prisma getUser: async (id: number) => { return await prisma.user.findUnique({ where: {id} }) } }, Mutation: { // Example mutation using Prisma createUser: async (data: any) => { return await prisma.user.create({ data }) } } } export default app ``` -------------------------------- ### Install prisma-extended-models Package Source: https://pylon.cronit.io/docs/integrations/databases Command to install the `@getcronit/prisma-extended-models` package, which simplifies Prisma integration with Pylon by providing extended model functionalities. ```bash bun add @getcronit/prisma-extended-models ``` -------------------------------- ### Running the Application with Node.js Source: https://pylon.cronit.io/docs/guides/convert-from-hono-guide This command demonstrates how to start the development server for your Pylon application using npm scripts, typically defined in your package.json. This is the standard way to run Node.js applications in development. ```shell npm run dev ``` -------------------------------- ### GraphQL Query Example with Resolved Relations Source: https://pylon.cronit.io/docs/integrations/databases An example GraphQL query demonstrating how to fetch posts and their associated author information, leveraging the automatic relation resolution provided by extended Prisma models. ```graphql query { allPosts { edges { node { id title content author { id name } } } } } ``` -------------------------------- ### Implement REST API GET /posts Endpoint with Pylon Source: https://pylon.cronit.io/docs/guides/testing This code snippet implements a REST API GET endpoint for fetching posts using the Pylon framework. It defines a 'posts' array and registers a handler for the '/posts' route that returns the posts as JSON. This is part of the src/index.ts file. ```typescript import {app} from '@getcronit/pylon' const posts: {id: number; title: string; content: string}[] = [ { id: 1, title: 'Hello, world!', content: 'This is the first post' }, { id: 2, title: 'Hello, Pylon!', content: 'This is the second post' } ] export const graphql = { // ... (previous code remains unchanged) } app.get('/posts', c => { return c.json(posts) }) export default app ``` -------------------------------- ### HonoJS REST Service Example Source: https://pylon.cronit.io/docs/guides/convert-from-hono-guide A basic HonoJS service demonstrating endpoints for fetching user and blog data, creating a blog post, and an additional post route. Requires Bun or Node.js. ```typescript import { Hono } from 'hono' const app = new Hono() const getUserById = async (id: string) => ({ id, name: 'John Doe', email: `john.doe${id}@example.com`, age: 30, posts: ['1', '2'] }) const getBlogById = async (id: string) => ({ id, title: 'Hello World', content: 'This is a blog post', authorId: '1' }) const createBlog = async (id: string, title: string, content: string, authorId: string) => ({ id, title, content, authorId }) app.get('/users', async(c) => { const id = c.req.query('id') if (!id) { c.status(400) return c.json({}) } const user = await getUserById(id) return c.json(user) }) app.get('/blog', async(c) => { const id = c.req.query('id') if (!id) { c.status(400) return c.json({}) } const blog = await getBlogById(id) return c.json(blog) }) app.post('/blogs', async(c) => { const {title, content, authorId} = await c.req.json() if (!title || !content || !authorId) { c.status(400) return c.json({}) } const blog = await createBlog('1', title, content, authorId) c.status(201) return c.json(blog) }) app.post('/post', (c) => { return c.json({message: 'a route that you want to keep'}) }) export default app ``` -------------------------------- ### Test REST API GET /posts Endpoint with Bun Source: https://pylon.cronit.io/docs/guides/testing This code snippet demonstrates testing the REST API GET /posts endpoint using Bun's testing framework. It imports the application and asserts that the response status is 200 and the returned JSON matches the expected array of posts. Ensure you run 'bun run build' before executing these tests. ```typescript import {describe, expect, test} from 'bun:test' // Make sure to run `bun run build` before running the tests import app from './.pylon/index' describe('GraphQL API', () => { // ... (previous tests remains unchanged) }) describe('REST API', () => { test('GET /posts', async () => { const res = await app.request('/posts') expect(res.status).toBe(200) const data = await res.json() expect(data).toEqual([ { id: 1, title: 'Hello, world!', content: 'This is the first post' }, { id: 2, title: 'Hello, Pylon!', content: 'This is the second post' }, { id: 3, title: 'New Post', content: 'This is a new post' } ]) }) }) ``` -------------------------------- ### Create Pylon Project with GQty Integration Source: https://pylon.cronit.io/docs/integrations/gqty This snippet demonstrates the command-line interface steps to create a new Pylon project, configure it to use Bun.js, and enable client generation for GQty integration. It specifies the target directory, runtime, template, dependency installation choice, and paths for client generation. ```bash create-pylon version 1.0.0 4:55:00 PM ? Target directory my-pylon ? Which runtime would you like to use? Bun.js (https://bunjs.dev) ? Which template would you like to use? Default ? Would you like to install dependencies? no ◐ Creating pylon in /Users/schettn/Documents/my-pylon 4:55:11 PM ✔ Pylon created 4:55:11 PM ? Would you like to enable client generation? (https://pylon.cronit.io/docs/integrations/gqty) yes ? Path to the root where the client should be generated . ? Path to generate the client to gqty/index.ts ? Port of the pylon server to generate the client from 3000 ◐ Updating pylon dev script to generate client 4:55:20 PM ✔ Pylon dev script updated 4:55:20 PM ╭───────────────────────────────────────────╮ │ │ │ Pylon successfully created in my-pylon. │ │ │ │ Happy coding! │ │ │ ╰───────────────────────────────────────────╯ ``` -------------------------------- ### Pothos GraphQL Schema Definition Example Source: https://pylon.cronit.io/docs/faq This snippet demonstrates how to define a simple 'hello' query using the Pothos GraphQL library. It requires explicit schema definition using SchemaBuilder and TypeScript types. ```typescript import { createYoga } from 'graphql-yoga'; import { createServer } from 'node:http'; import SchemaBuilder from '@pothos/core'; const builder = new SchemaBuilder({}); builder.queryType({ fields: (t) => ({ hello: t.string({ args: { name: t.arg.string(), }, resolve: (parent, { name }) => `hello, ${name || 'World'}`, }), }), }); ... ``` -------------------------------- ### Pylon GraphQL Mutation Example with Error Handling Source: https://pylon.cronit.io/docs/core-concepts/logging-and-monitoring An example of a Pylon GraphQL mutation that includes error handling for division by zero. Errors and informational logs are outputted, and if Sentry is configured, these will be sent to Sentry. ```typescript import {app} from '@getcronit/pylon' export const graphql = { Mutation: { divide: (a: number, b: number) => { if (b === 0) { console.error('Attempt to divide by zero') throw new Error('Division by zero is not allowed') } console.info(`Dividing ${a} by ${b}`) return a / b } } } export default app ``` -------------------------------- ### GraphQL Query Example for Pylon Service Source: https://pylon.cronit.io/docs/core-concepts/automatic-graphql-api-generation Demonstrates how to query a Pylon-generated GraphQL API using a sample 'sum' query. This example assumes a Pylon service is already defined with a 'sum' query resolver. The output shows the expected JSON response for a successful query. ```graphql query { sum(a: 5, b: 3) } ``` -------------------------------- ### Pylon Authentication Example with ZITADEL Source: https://pylon.cronit.io/docs/core-concepts/built-in-authentication-and-authorization Demonstrates how to set up authentication in a Pylon project using the `@requireAuth()` decorator to protect sensitive data. This requires Pylon's `auth` module and integration with ZITADEL. ```javascript import {app, auth, requireAuth} from '@getcronit/pylon' // Define your sensitive data service class SensitiveData { @requireAuth() static async getData() { return 'Sensitive Data' } } export const graphql = { Query: { sensitiveData: SensitiveData.getData } } app.use('*', auth.initialize()) export default app ``` -------------------------------- ### Manage Star Wars Characters with Pylon Custom API Source: https://pylon.cronit.io/docs/getting-started This example showcases building a custom Star Wars API with Pylon. It utilizes a `StarWarsStore` class to manage a list of characters, providing GraphQL queries for retrieving characters and mutations for adding and deleting them. The example highlights Pylon's support for custom classes and data management. ```typescript import {app} from '@getcronit/pylon' class StarWarsStore { private characters = [ {id: 1, name: 'Luke Skywalker', height: 172}, {id: 2, name: 'Darth Vader', height: 202} ] constructor() { // Bind methods in order to access `this` this.getCharacter = this.getCharacter.bind(this) this.getCharacters = this.getCharacters.bind(this) this.addCharacter = this.addCharacter.bind(this) this.deleteCharacter = this.deleteCharacter.bind(this) } getCharacter(id: number) { return this.characters.find(character => character.id === id) } getCharacters() { return this.characters } addCharacter(name: string, height: number) { const id = this.characters.length + 1 this.characters.push({id, name, height}) return {id, name, height} } deleteCharacter(id: number) { const character = this.getCharacter(id) if (character) { this.characters = this.characters.filter(c => c.id !== id) return character } return null } } const store = new StarWarsStore() export const graphql = { Query: { character: store.getCharacter, characters: store.getCharacters }, Mutation: { addCharacter: store.addCharacter, deleteCharacter: store.deleteCharacter } } export default app ``` -------------------------------- ### GraphQL Mutation Example for Pylon Service Source: https://pylon.cronit.io/docs/core-concepts/automatic-graphql-api-generation Illustrates how to execute a GraphQL mutation against a Pylon-generated API, using a sample 'divide' mutation. This example expects a Pylon service with a 'divide' mutation resolver. The provided output shows the expected JSON result after the mutation is applied. ```graphql mutation { divide(a: 10, b: 2) } ``` -------------------------------- ### Exporting a Singleton BookingStore Instance Source: https://pylon.cronit.io/docs/guides/building-with-pylon/hardcoded-data This snippet demonstrates how to create and export a singleton instance of the BookingStore class. This ensures that a single instance of the class is available throughout the application, which is crucial for maintaining consistent state. ```typescript const bookingStore = new BookingStore() export default bookingStore ``` -------------------------------- ### Environment Variable: Set a Binding Source: https://pylon.cronit.io/docs/guides/bindings-and-variables This example shows how to set an environment binding, `SECRET`, in a `.env` file. This is a common practice for managing sensitive information like API keys or database credentials that your Pylon application needs to access. ```dotenv SECRET=your-secret ``` -------------------------------- ### Pylon GraphQL Schema Definition Example Source: https://pylon.cronit.io/docs/faq This snippet shows how to define a simple 'hello' query using the Pylon framework. Pylon infers the GraphQL schema directly from the TypeScript resolver functions, eliminating the need for explicit schema definition. ```typescript import {app} from '@getcronit/pylon' export const graphql = { Query: { hello: (name: string) => { return `hello, ${name || 'World'}` } } } export default app ``` -------------------------------- ### Dockerfile for Pylon Application (Node.js) Source: https://pylon.cronit.io/docs/guides/convert-from-hono-guide This Dockerfile builds the Pylon application using a Node.js base image. It handles dependency installation, code copying, and sets up the production environment, including exposing port 3000 and defining the entrypoint for running the application. ```Dockerfile # run the app USER node EXPOSE 3000/tcp ENTRYPOINT [ "node", "/usr/src/pylon/.pylon/index.js" ] ``` ```Dockerfile # Use the official Node.js 20 image as the base FROM node:20-alpine as base LABEL description="Offical docker image for Pylon services (Node.js)" LABEL org.opencontainers.image.source="https://github.com/getcronit/pylon" LABEL maintainer="office@cronit.io" WORKDIR /usr/src/pylon # install dependencies into a temp directory # this will cache them and speed up future builds FROM base AS install RUN mkdir -p /temp/dev COPY package.json package-lock.json /temp/dev/ RUN cd /temp/dev && npm ci # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod COPY package.json package-lock.json /temp/prod/ RUN cd /temp/prod && npm ci --only=production # copy node_modules from temp directory # then copy all (non-ignored) project files into the image FROM install AS prerelease COPY --from=install /temp/dev/node_modules node_modules COPY . . # [optional] tests & build ENV NODE_ENV=production # Create .pylon folder (mkdir) RUN mkdir -p .pylon # RUN npm test RUN npm run pylon build # copy production dependencies and source code into final image FROM base AS release COPY --from=install /temp/prod/node_modules node_modules COPY --from=prerelease /usr/src/pylon/.pylon .pylon COPY --from=prerelease /usr/src/pylon/package.json . # run the app USER node EXPOSE 3000/tcp ENTRYPOINT [ "node", "/usr/src/pylon/.pylon/index.js" ] ``` -------------------------------- ### Implement GraphQL Query for Fetching Posts (TypeScript) Source: https://pylon.cronit.io/docs/guides/testing Adds a GraphQL schema to the Pylon application to enable fetching posts. It defines a `posts` array with sample data and exposes it under the `Query.posts` field. Remember to run `bun run build` after changes. ```typescript import {app} from '@getcronit/pylon' const posts: {id: number; title: string; content: string}[] = [ { id: 1, title: 'Hello, world!', content: 'This is the first post' }, { id: 2, title: 'Hello, Pylon!', content: 'This is the second post' } ] export const graphql = { Query: { posts } } export default app ``` -------------------------------- ### TypeScript: Access Bindings (Environment Variables) in Pylon Source: https://pylon.cronit.io/docs/guides/bindings-and-variables This example demonstrates how to access environment variables (bindings) within a Pylon GraphQL resolver. It retrieves a `SECRET` binding from the context and compares it with an incoming `Authorization` header to perform authentication. Ensure the binding is defined in `pylon.d.ts` and set in your environment. ```typescript // src/index.ts import {app, getContext} from '@getcronit/pylon' export const graphql = { hello: () => { const ctx = getContext() const secret = ctx.env.SECRET const authHeader = ctx.req.header('Authorization') if (authHeader !== secret) { return 'You are not authorized' } return 'You are authorized' } } ``` -------------------------------- ### Dockerfile for Pylon Project with Bun and Prisma Source: https://pylon.cronit.io/docs/integrations/databases This Dockerfile sets up a Pylon project environment using Bun for package management and Prisma for database interactions. It includes stages for installing development and production dependencies, generating Prisma schemas, and building the application. It also configures the final image for running the Pylon server. ```dockerfile FROM oven/bun:1 as base LABEL description="A Pylon project with Prisma" LABEL org.opencontainers.image.source="https://github.com/cronitio/my-pylon-project" LABEL maintainer="opensource@cronit.io" WORKDIR /usr/src/pylon # install dependencies into temp directory # this will cache them and speed up future builds FROM base AS install ARG NODE_VERSION=20 RUN apt update && apt install -y curl RUN curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o n && bash n $NODE_VERSION && rm n && npm install -g n RUN mkdir -p /temp/dev COPY package.json bun.lockb /temp/dev/ COPY prisma /temp/dev/prisma RUN cd /temp/dev && bun install --frozen-lockfile RUN cd /temp/dev && bun prisma generate # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod COPY package.json bun.lockb /temp/prod/ COPY prisma /temp/prod/prisma RUN cd /temp/prod && bun install --frozen-lockfile --production RUN cd /temp/prod && bun prisma generate # copy node_modules from temp directory # then copy all (non-ignored) project files into the image FROM install AS prerelease COPY --from=install /temp/dev/node_modules node_modules COPY . . # [optional] tests & build ENV NODE_ENV=production # Create .pylon folder (mkdir) RUN mkdir .pylon # RUN bun test RUN bun run pylon build # copy production dependencies and asource code into final image FROM base AS release RUN apt-get update -y && apt-get install -y openssl COPY --from=install /temp/prod/node_modules node_modules COPY --from=prerelease /usr/src/pylon/.pylon .pylon COPY --from=prerelease /usr/src/pylon/package.json . COPY --from=prerelease /usr/src/pylon/prisma prisma # run the app USER bun EXPOSE 3000/tcp ENTRYPOINT [ "bun", "run", "./node_modules/.bin/pylon-server" ] ``` -------------------------------- ### Define GraphQL Schema and Basic Route with Pylon App Instance Source: https://pylon.cronit.io/docs/core-concepts/context-management This snippet demonstrates how to define GraphQL queries and mutations using Pylon's `app` instance. It also shows how to set up a basic GET route '/hello' for the Hono application. The `app` instance from '@getcronit/pylon' is used to configure both GraphQL schema and HTTP routes. ```typescript import {app} from '@getcronit/pylon' export const graphql = { Query: { sum: (a: number, b: number) => a + b }, Mutation: { divide: (a: number, b: number) => a / b } } app.get('/hello', (ctx, next) => { return new Response('Hello, world!') }) export default app ``` -------------------------------- ### Test GraphQL Query for Fetching Posts (Bun Test) Source: https://pylon.cronit.io/docs/guides/testing Tests the GraphQL API's ability to fetch posts using Bun's testing framework. It sends a POST request to the `/graphql` endpoint with a query for posts and asserts the response status and data. ```typescript import {describe, expect, test} from 'bun:test' // Make sure to run `bun run build` before running the tests import app from './.pylon/index' describe('GraphQL API', () => { test('Query.posts', async () => { const res = await app.request('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: 'query { posts { id title content } }' }) }) expect(res.status).toBe(200) const data = await res.json() expect(data).toEqual({ data: { posts: [ { id: 1, title: 'Hello, world!', content: 'This is the first post' }, { id: 2, title: 'Hello, Pylon!', content: 'This is the second post' } ] } }) }) }) ``` -------------------------------- ### Pylon TypeScript with Shared Properties in Unions Source: https://pylon.cronit.io/docs/core-concepts/interfaces-and-unions Shows how Pylon handles shared properties in union types by automatically creating an interface for them. This example defines 'Foo' and 'Bar' types with a common 'id' field, demonstrating the generated GraphQL schema with an 'Example' interface. ```typescript type Bar = { id: ID title: string } type Foo = { id: ID name: string } type Example = Foo | Bar ``` ```graphql interface Example { id: ID! } type Foo implements Example { id: ID! name: String! } type Bar implements Example { id: ID! title: String! } ``` -------------------------------- ### Pylon Authorization Example with Roles Source: https://pylon.cronit.io/docs/core-concepts/built-in-authentication-and-authorization Shows how to implement authorization in Pylon by using the `@requireAuth()` decorator with a 'roles' parameter to restrict access to specific data based on user permissions. This assumes roles are defined in ZITADEL. ```javascript // Define your sensitive data service class SensitiveData { @requireAuth({ roles: ['admin'] }) static async getAdminData() { return 'Admin Data' } } // Define your GraphQL schema export const graphql = { Query: { sensitiveAdminData: SensitiveData.getAdminData } } app.use('*', auth.initialize()) export default app ``` -------------------------------- ### Update Pylon Scripts (JSON) Source: https://pylon.cronit.io/docs/release-notes/migrating-from-v1-to-v2 Modifies the `scripts` section in `package.json` to align with Pylon v2's new commands, such as changing the development start script to use `pylon dev` and updating the build script. ```json { "scripts": { "dev": "pylon dev -c 'bun run .pylon/index.js'" } } ``` ```json { "scripts": { "build": "pylon build" } } ``` -------------------------------- ### Define Pylon Service with Extended Prisma Models Source: https://pylon.cronit.io/docs/integrations/databases Example of defining a Pylon GraphQL service using extended Prisma models. This demonstrates how to use the generated models for queries like fetching a single post by ID and paginating all posts. ```typescript import {app} from '@getcronit/pylon' import {Post} from '../repository/models' export const graphql = { Query: { // Example query using extended Prisma models getPost: async (id: number) => { return await Post.get({ id }) }, allPosts: async () => { return await Post.paginate() } }, Mutation: { // Example mutation using extended Prisma models createPost: async (data: any) => { return await Post.create({ data }) } } } export default app ``` -------------------------------- ### Mocking Dependencies with Config in TypeScript Source: https://pylon.cronit.io/docs/guides/testing This snippet illustrates an alternative method for mocking dependencies using the './src/index.ts' file, specifically when the 'config' export is utilized. It shows how to import the handler, graphql, and config from './src/index' and pass both graphql and config objects to the handler function. This approach offers enhanced flexibility for testing scenarios involving configurations. ```typescript import {handler} from '@getcronit/pylon' import app, {graphql, config} from './src/index' app.use(handler({graphql, config})) ... your tests here ... ``` -------------------------------- ### Registering Booking Queries in Pylon Source: https://pylon.cronit.io/docs/guides/building-with-pylon/hardcoded-data This snippet updates the index.ts file to register the getBookings and getBookingById methods from the bookingStore instance as GraphQL queries. It removes the old 'hello' resolver and adds the new query resolvers, making them accessible via GraphQL. ```typescript import {app} from '@getcronit/pylon' import bookingStore from './lib/bookingStore' export const graphql = { Query: { bookings: bookingStore.getBookings, booking: bookingStore.getBookingById }, Mutation: {} } export default app ``` -------------------------------- ### Mocking Dependencies with Direct Import in TypeScript Source: https://pylon.cronit.io/docs/guides/testing This snippet demonstrates how to directly import and use the './src/index.ts' file for testing in a TypeScript project. It shows how to import the handler from '@getcronit/pylon' and set it up to handle GraphQL requests by passing the graphql object. This method provides more control over tests by allowing dependency mocking. ```typescript import {handler} from '@getcronit/pylon' import app, {graphql} from './src/index' app.use(handler({graphql})) ... your tests here ... ``` -------------------------------- ### Create a Sub-Router with Hono for Modular Routing Source: https://pylon.cronit.io/docs/core-concepts/context-management This snippet illustrates creating a standalone Hono router (`authRouter`) to avoid conflicts when using Pylon's `app` instance multiple times. It defines a GET route '/' for the auth router that returns 'Hello from Auth'. This approach promotes modularity and prevents issues with global middleware registration. ```typescript import {type Bindings, type Variables} from '@getcronit/pylon' import {Hono} from 'hono' const authRouter = new Hono<{ Bindings: Bindings Variables: Variables }>() authRouter.get('/', c => { return c.text('Hello from Auth') }) export default authRouter ``` -------------------------------- ### Expose JavaScript Math Class via Pylon Mutation Source: https://pylon.cronit.io/docs/getting-started This example demonstrates Pylon's ability to expose built-in JavaScript classes, such as the `Math` class, as GraphQL mutations. This allows remote clients to access and utilize standard JavaScript mathematical functions and constants. ```typescript import {app} from '@getcronit/pylon' export const graphql = { Mutation: { math: Math } } export default app ``` -------------------------------- ### GraphQL Resolver Throwing ServiceError Source: https://pylon.cronit.io/docs/core-concepts/plugins An example of a GraphQL query resolver (`hello`) within a Pylon application that deliberately throws a `ServiceError`. This error is designed to be caught and processed by the integrated Envelop plugins, such as the `useErrorHandler`. ```typescript export const graphql = { Query: { hello: () => { throw new ServiceError('Hello, world!', { code: 'HELLO_WORLD', statusCode: 400 }) } }, Mutation: {} } ``` -------------------------------- ### Test GraphQL Mutation for Creating Posts with Bun Source: https://pylon.cronit.io/docs/guides/testing This code snippet demonstrates how to test a GraphQL mutation for creating posts using Bun's testing framework. It imports the application and defines tests for querying posts and creating a new post. Ensure you run 'bun run build' before executing these tests. ```typescript import {describe, expect, test} from 'bun:test' // Make sure to run `bun run build` before running the tests import app from './.pylon/index' describe('GraphQL API', () => { test('Query.posts', async () => { const res = await app.request('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: 'query { posts { id title content } }' }) }) expect(res.status).toBe(200) const data = await res.json() expect(data).toEqual({ data: { posts: [ { id: 1, title: 'Hello, world!', content: 'This is the first post' }, { id: 2, title: 'Hello, Pylon!', content: 'This is the second post' } ] } }) }) test('Mutation.createPost', async () => { const res = await app.request('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: ` mutation { createPost(title: "New Post", content: "This is a new post") { id title content } } ` }) }) expect(res.status).toBe(200) const data = await res.json() expect(data).toEqual({ data: { createPost: { id: 3, title: 'New Post', content: 'This is a new post' } } }) }) }) ``` -------------------------------- ### Implement GraphQL Mutation for Creating Posts (TypeScript) Source: https://pylon.cronit.io/docs/guides/testing Extends the GraphQL schema to include a mutation for creating new posts. The `createPost` mutation adds a new post to the `posts` array and returns the created post. Ensure `bun run build` is executed after this modification. ```typescript import {app} from '@getcronit/pylon' const posts: {id: number; title: string; content: string}[] = [ { id: 1, title: 'Hello, world!', content: 'This is the first post' }, { id: 2, title: 'Hello, Pylon!', content: 'This is the second post' } ] export const graphql = { Query: { posts }, Mutation: { createPost: (title: string, content: string) => { const post = { id: posts.length + 1, title, content } posts.push(post) return post } } } export default app ``` -------------------------------- ### Implement Booking Retrieval Methods in TypeScript Source: https://pylon.cronit.io/docs/guides/building-with-pylon/hardcoded-data This TypeScript snippet adds methods to the `BookingStore` class to retrieve all bookings or a specific booking by its ID. The `getBookingById` method demonstrates how Pylon can handle method arguments automatically. ```typescript getBookings(): Booking[] { return this.bookings; } getBookingById(bookingId: number): Booking | null { return this.bookings.find((booking) => booking.id === bookingId) ?? null; } ``` -------------------------------- ### Enable Telemetry Debugging in Pylon Source: https://pylon.cronit.io/docs/telemetry To view the exact telemetry data being collected by Pylon, you can set the `PYLON_TELEMETRY_DEBUG` environment variable to `1`. This is useful for understanding what information is being sent and confirming your telemetry settings. No code examples are provided as this is an environment variable setting. ```shell PYLON_TELEMETRY_DEBUG=1 ``` -------------------------------- ### Mount a Sub-Router onto the Main Pylon App Instance Source: https://pylon.cronit.io/docs/core-concepts/context-management This snippet shows how to integrate a modular router (`authRouter`) into the main Pylon application (`app`). The `app.route('/auth', authRouter)` command mounts the auth router under the '/auth' path. This example assumes `authRouter` is defined elsewhere and demonstrates effective use of Pylon's routing capabilities. ```typescript import {app} from '@getcronit/pylon' import authRouter from './authRouter' app.route('/auth', authRouter) export const graphql = {...} export default app ``` -------------------------------- ### Fetch Starships Data with Pylon GraphQL Query Source: https://pylon.cronit.io/docs/getting-started This example demonstrates how to fetch a list of starships from an external API using Pylon's GraphQL capabilities. It defines a query that interacts with the Star Wars API and specifies the expected data structure using a TypeScript interface, ensuring only relevant data is returned. ```typescript import {app} from '@getcronit/pylon' interface Starship { name: string model: string manufacturer: string } export const graphql = { Query: { starships: async () => { const response = await fetch('https://swapi.dev/api/starships/') const data = await response.json() return data.results as Starship[] } } } export default app ``` -------------------------------- ### TypeScript: Configure tsconfig.json for Pylon Source: https://pylon.cronit.io/docs/guides/bindings-and-variables This snippet illustrates how to include the `pylon.d.ts` file in your project's TypeScript configuration. By adding `pylon.d.ts` to the `include` array in `tsconfig.json`, you ensure that TypeScript recognizes and utilizes the Pylon type definitions. ```json { "include": ["pylon.d.ts", "src/**/*.ts"] } ``` -------------------------------- ### Define Booking Interface and Class Structure in TypeScript Source: https://pylon.cronit.io/docs/guides/building-with-pylon/hardcoded-data This snippet defines the `Booking` interface for structuring booking data and initializes the `BookingStore` class with a private array to hold booking objects. It uses TypeScript for type safety. ```typescript interface Booking { id: number firstname: string lastname: string totalPrice?: number depositpaid: boolean bookingdates: { checkin: string checkout: string } additionalneeds?: string } class BookingStore { private bookings: Booking[] = [ { id: 1, firstname: 'Sally', lastname: 'Brown', totalPrice: 111, depositpaid: true, bookingdates: { checkin: '2013-02-23', checkout: '2014-10-23' }, additionalneeds: 'Breakfast' }, { id: 2, firstname: 'John', lastname: 'Doe', totalPrice: 222, depositpaid: false, bookingdates: { checkin: '2013-02-23', checkout: '2014-10-23' }, additionalneeds: 'Breakfast' }, { id: 3, firstname: 'Jane', lastname: 'Smith', totalPrice: 333, depositpaid: true, bookingdates: { checkin: '2013-02-23', checkout: '2014-10-23' }, additionalneeds: 'Breakfast' } ] } ``` -------------------------------- ### Pylon Securing Routes with Auth and Roles Source: https://pylon.cronit.io/docs/core-concepts/built-in-authentication-and-authorization Illustrates how to secure specific routes in a Pylon project using `app.use()` with the `auth.requireAuth()` middleware, enforcing both authentication and authorization for a given path. This example secures the '/admin' route for users with the 'admin' role. ```javascript import {auth, requireAuth} from '@getcronit/pylon' // Define your sensitive data service class SensitiveData { static async getData() { return 'Sensitive Data' } @requireAuth({ roles: ['admin'] }) static async getAdminData() { return 'Admin Data' } } export const graphql = { Query: { sensitiveData: SensitiveData.getData, sensitiveAdminData: SensitiveData.getAdminData } } // Enforce authentication for all routes app.use('*', auth.initialize()) // Secure a specific route with authentication and authorization app.use('/admin', auth.requireAuth({roles: ['admin']})) export default app ``` -------------------------------- ### Test REST API POST /posts Endpoint with Bun Source: https://pylon.cronit.io/docs/guides/testing This snippet demonstrates how to write tests for the REST API's POST /posts endpoint using Bun's testing framework. It includes tests for successful creation, missing title, and invalid form data. Ensure you run `bun run build` before executing these tests. ```typescript import {describe, expect, test} from 'bun:test' // Make sure to run `bun run build` before running the tests import app from './.pylon/index' describe('GraphQL API', () => { // ... (previous tests remains unchanged) }) describe('REST API', () => { test('GET /posts', async () => { const res = await app.request('/posts') expect(res.status).toBe(200) const data = await res.json() expect(data).toEqual([ { id: 1, title: 'Hello, world!', content: 'This is the first post' }, { id: 2, title: 'Hello, Pylon!', content: 'This is the second post' }, { id: 3, title: 'New Post', content: 'This is a new post' } ]) }) test('POST /posts - successful creation', async () => { const formData = new FormData() formData.append('title', 'REST Post') formData.append('content', 'This post was created via REST') const res = await app.request('/posts', { method: 'POST', body: formData }) expect(res.status).toBe(201) const data = await res.json() expect(data).toEqual({ id: 4, title: 'REST Post', content: 'This post was created via REST' }) expect(res.headers.get('X-Custom')).toBe('Thanks for creating!') }) test('POST /posts - missing title', async () => { const formData = new FormData() formData.append('content', 'This post has no title') const res = await app.request('/posts', { method: 'POST', body: formData }) expect(res.status).toBe(400) const text = await res.text() expect(text).toBe('Title and content are required') }) test('POST /posts - invalid form data', async () => { const res = await app.request('/posts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: 'Invalid Post', content: 'This post uses JSON instead of form data' }) }) expect(res.status).toBe(400) const text = await res.text() expect(text).toBe('Invalid form data') }) }) ``` -------------------------------- ### BookingStore addBooking Method Implementation Source: https://pylon.cronit.io/docs/guides/building-with-pylon/hardcoded-data This snippet shows the implementation of the addBooking method within the BookingStore class. It takes a booking object (excluding the ID), assigns a new ID, and pushes it to the internal bookings array. This method is intended for use as a GraphQL mutation. ```typescript addBooking(booking: Omit): Booking { const newBooking = { ...booking, id: this.bookings.length + 1 }; this.bookings.push(newBooking); return newBooking; } ```