+ allow_user_resources?: string[]
}
export async function hash(message) {
- try {
- const msgUint8 = new TextEncoder().encode(message) // encode as (utf-8) Uint8Array
- const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8) // hash the message
- const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array
- const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
- return hashHex
- } catch {
- //subtle not available, trying pure js
- const hash = new Sha256()
- hash.update(message ?? '')
- const result = Array.from(await hash.digest())
- const hex = result.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
- return hex
- }
-}
\ No newline at end of file
+ try {
+ const msgUint8 = new TextEncoder().encode(message) // encode as (utf-8) Uint8Array
+ const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8) // hash the message
+ const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array
+ const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
+ return hashHex
+ } catch {
+ //subtle not available, trying pure js
+ const { Sha256 } = await import('@aws-crypto/sha256-js')
+ const hash = new Sha256()
+ hash.update(message ?? '')
+ const result = Array.from(await hash.digest())
+ const hex = result.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
+ return hex
+ }
+}
diff --git a/frontend/src/lib/components/copilot/chat/ContextElementBadge.svelte b/frontend/src/lib/components/copilot/chat/ContextElementBadge.svelte
index 186414c8dd..f30bdbe48f 100644
--- a/frontend/src/lib/components/copilot/chat/ContextElementBadge.svelte
+++ b/frontend/src/lib/components/copilot/chat/ContextElementBadge.svelte
@@ -64,13 +64,10 @@
{:else if contextElement.type === 'db'}
{#if contextElement.schema && contextElement.schema.lang === 'graphql'}
- {#await import('$lib/components/GraphqlSchemaViewer.svelte')}
+ {#await Promise.all([import('$lib/components/GraphqlSchemaViewer.svelte'), formatGraphqlSchema(contextElement.schema.schema)])}
- {:then Module}
-
+ {:then [Module, code]}
+
{/await}
{:else if contextElement.schema}
diff --git a/frontend/src/lib/components/copilot/lib.ts b/frontend/src/lib/components/copilot/lib.ts
index 538ab2a103..4d77ebd01a 100644
--- a/frontend/src/lib/components/copilot/lib.ts
+++ b/frontend/src/lib/components/copilot/lib.ts
@@ -1,6 +1,6 @@
import type { AIProvider, AIProviderModel } from '$lib/gen'
-import { workspaceStore, type DBSchema, type GraphqlSchema, type SQLSchema } from '$lib/stores'
-import { buildClientSchema, printSchema } from 'graphql'
+import { workspaceStore, type DBSchema, type SQLSchema } from '$lib/stores'
+import type { IntrospectionQuery } from 'graphql'
import OpenAI from 'openai'
import type {
ChatCompletionChunk,
@@ -587,43 +587,40 @@ export function addThousandsSeparator(n: number) {
return n.toFixed().replace(/\B(?=(\d{3})+(?!\d))/g, "'")
}
-export function stringifySchema(
- dbSchema: Omit | Omit
-) {
+export function stringifySchema(dbSchema: Omit): string {
const { schema, lang } = dbSchema
- if (lang === 'graphql') {
- let graphqlSchema = printSchema(buildClientSchema(schema))
- return graphqlSchema
- } else {
- let smallerSchema: {
- [schemaKey: string]: {
- [tableKey: string]: Array<[string, string, boolean, string?]>
- }
- } = {}
- for (const schemaKey in schema) {
- smallerSchema[schemaKey] = {}
- for (const tableKey in schema[schemaKey]) {
- smallerSchema[schemaKey][tableKey] = []
- for (const colKey in schema[schemaKey][tableKey]) {
- const col = schema[schemaKey][tableKey][colKey]
- const p: [string, string, boolean, string?] = [colKey, col.type, col.required]
- if (col.default) {
- p.push(col.default)
- }
- smallerSchema[schemaKey][tableKey].push(p)
+ let smallerSchema: {
+ [schemaKey: string]: {
+ [tableKey: string]: Array<[string, string, boolean, string?]>
+ }
+ } = {}
+ for (const schemaKey in schema) {
+ smallerSchema[schemaKey] = {}
+ for (const tableKey in schema[schemaKey]) {
+ smallerSchema[schemaKey][tableKey] = []
+ for (const colKey in schema[schemaKey][tableKey]) {
+ const col = schema[schemaKey][tableKey][colKey]
+ const p: [string, string, boolean, string?] = [colKey, col.type, col.required]
+ if (col.default) {
+ p.push(col.default)
}
+ smallerSchema[schemaKey][tableKey].push(p)
}
}
-
- let finalSchema: typeof smallerSchema | (typeof smallerSchema)['schemaKey'] = smallerSchema
- if (dbSchema.publicOnly) {
- finalSchema =
- smallerSchema.public || smallerSchema.PUBLIC || smallerSchema.dbo || smallerSchema
- } else if (lang === 'mysql' && Object.keys(smallerSchema).length === 1) {
- finalSchema = smallerSchema[Object.keys(smallerSchema)[0]]
- }
- return JSON.stringify(finalSchema)
}
+
+ let finalSchema: typeof smallerSchema | (typeof smallerSchema)['schemaKey'] = smallerSchema
+ if (dbSchema.publicOnly) {
+ finalSchema = smallerSchema.public || smallerSchema.PUBLIC || smallerSchema.dbo || smallerSchema
+ } else if (lang === 'mysql' && Object.keys(smallerSchema).length === 1) {
+ finalSchema = smallerSchema[Object.keys(smallerSchema)[0]]
+ }
+ return JSON.stringify(finalSchema)
+}
+
+export async function stringifyGraphqlSchema(schema: unknown): Promise {
+ const { buildClientSchema, printSchema } = await import('graphql')
+ return printSchema(buildClientSchema(schema as IntrospectionQuery))
}
function addDBSChema(scriptOptions: CopilotOptions, prompt: string) {
diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts
index 3fa1b3256a..1cf01ba344 100644
--- a/frontend/src/lib/utils.ts
+++ b/frontend/src/lib/utils.ts
@@ -17,8 +17,6 @@ export { sendUserToast }
import type { AnyMeltElement } from '@melt-ui/svelte'
import type { TriggerKind } from './components/triggers'
import { stateSnapshot } from './svelte5Utils.svelte'
-import { validate, dereference } from '@scalar/openapi-parser'
-
export namespace OpenApi {
export enum OpenApiVersion {
V2,
@@ -59,6 +57,7 @@ export namespace OpenApi {
* @throws Will throw an error if the specification is invalid or cannot be parsed.
*/
export async function parse(api: string): Promise<[OpenAPI.Document, OpenApiVersion]> {
+ const { validate, dereference } = await import('@scalar/openapi-parser')
const { valid, errors } = await validate(api)
if (!valid) {