diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a355b309cead8..1d631f4a7dc2c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,6 +2,7 @@ /packages/shared-data/pricing.ts @supabase/billing /packages/shared-data/plans.ts @supabase/billing /packages/common/telemetry-constants.ts @supabase/growth-eng +/packages/dev-tools/ @supabase/growth-eng /packages/pg-meta @supabase/postgres @avallete /packages/ui-patterns @supabase/design @@ -22,4 +23,4 @@ /apps/studio/data/sql/queries/ @supabase/postgres @avallete -/packages/shared-data/compute-disk-limits.ts @supabase/infra \ No newline at end of file +/packages/shared-data/compute-disk-limits.ts @supabase/infra diff --git a/apps/cms/package.json b/apps/cms/package.json index cf248894b9001..da9b2ce3be4eb 100644 --- a/apps/cms/package.json +++ b/apps/cms/package.json @@ -20,9 +20,9 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@payloadcms/admin-bar": "^3.52.0", - "@payloadcms/db-postgres": "^3.52.0", - "@payloadcms/live-preview-react": "^3.52.0", + "@payloadcms/admin-bar": "^3.74.0", + "@payloadcms/db-postgres": "^3.74.0", + "@payloadcms/live-preview-react": "^3.74.0", "@payloadcms/next": "3.52.0", "@payloadcms/payload-cloud": "3.60.0", "@payloadcms/plugin-form-builder": "3.52.0", diff --git a/apps/docs/app/api/ai/docs/route.ts b/apps/docs/app/api/ai/docs/route.ts index 8e3df4206a643..d8c5b49c1ec00 100644 --- a/apps/docs/app/api/ai/docs/route.ts +++ b/apps/docs/app/api/ai/docs/route.ts @@ -1,10 +1,9 @@ import { SupabaseClient } from '@supabase/supabase-js' -import { ApplicationError, UserError, clippy } from 'ai-commands/edge' +import { ApplicationError, clippy, UserError } from 'ai-commands/edge' +import { isFeatureEnabled } from 'common/enabled-features' import { NextRequest, NextResponse } from 'next/server' import OpenAI from 'openai' -import { isFeatureEnabled } from 'common/enabled-features' - export const runtime = 'edge' /* To avoid OpenAI errors, restrict to the Vercel Edge Function regions that overlap with the OpenAI API regions. @@ -57,7 +56,8 @@ export async function POST(req: NextRequest) { } const useAltSearchIndex = !isFeatureEnabled('search:fullIndex') - const response = await clippy(openai, supabaseClient, messages, { + // @ts-ignore: We have 6 version of openai and the types are not compatible with each other, we need to consolidate to one + const response = await clippy(openai as any, supabaseClient, messages, { useAltSearchIndex, }) diff --git a/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx b/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx index c56f34d0fe9dd..c88b9525ed57a 100644 --- a/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx +++ b/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx @@ -8,6 +8,7 @@ import { memo, useState } from 'react' import { useIsLoggedIn, useIsUserLoading, useUser } from 'common' import { isFeatureEnabled } from 'common/enabled-features' +import { DevToolbarTrigger } from 'dev-tools' import { Button, buttonVariants, cn } from 'ui' import { AuthenticatedDropdownMenu, CommandMenuTriggerInput } from 'ui-patterns' import { getCustomContent } from '../../../lib/custom-content/getCustomContent' @@ -43,6 +44,7 @@ const TopNavBar: FC = () => {
+ diff --git a/apps/docs/content/guides/getting-started/mcp.mdx b/apps/docs/content/guides/getting-started/mcp.mdx index 30addfc75149a..3a6c8982a94be 100644 --- a/apps/docs/content/guides/getting-started/mcp.mdx +++ b/apps/docs/content/guides/getting-started/mcp.mdx @@ -30,6 +30,86 @@ To verify the client has access to the MCP server tools, try asking it to query For curated, ready-to-use prompts that work well with IDEs and AI agents, see our [AI Prompts](/guides/getting-started/ai-prompts) collection. +## Available tools + +The Supabase MCP server provides tools organized into feature groups. All groups except Storage are enabled by default. You can enable or disable specific groups using the [configuration panel above](#step-2-configure-your-ai-tool). + +### Database + +- `list_tables` - List all tables in the database +- `list_extensions` - List available/installed Postgres extensions +- `list_migrations` - List database migrations +- `apply_migration` - Apply a database migration +- `execute_sql` - Execute SQL queries + +### Debugging + +- `get_logs` - Retrieve service logs (API, Postgres, Edge Functions, Auth, Storage, Realtime) +- `get_advisors` - Get security and performance advisors + +### Development + +- `get_project_url` - Get the API URL for a project +- `get_publishable_keys` - Get anon/public keys +- `generate_typescript_types` - Generate TypeScript types from schema + +### Edge Functions + +- `list_edge_functions` - List all Edge Functions +- `get_edge_function` - Get a specific Edge Function +- `deploy_edge_function` - Deploy an Edge Function + +### Account management + + + +Disabled when using project-scoped mode (`project_ref` parameter). + + + +- `list_projects` / `get_project` - List or get project details +- `create_project` / `pause_project` / `restore_project` - Manage projects +- `list_organizations` / `get_organization` - Organization management +- `get_cost` / `confirm_cost` - Cost information + +### Docs + +- `search_docs` - Search Supabase documentation + +### Branching (experimental) + + + +Requires a paid plan. + + + +- `create_branch` / `list_branches` / `delete_branch` - Branch management +- `merge_branch` / `reset_branch` / `rebase_branch` - Branch operations + +### Storage (disabled by default) + +- `list_storage_buckets` - List storage buckets +- `get_storage_config` / `update_storage_config` - Storage configuration + +## Configuration options + +The [configuration panel above](#step-2-configure-your-ai-tool) can set these options for you. If you prefer to configure manually, the following URL query parameters are available: + +| Parameter | Description | Example | +| ------------------- | ---------------------------------------------------- | ------------------------- | +| `read_only=true` | Execute all queries as a read-only Postgres user | `?read_only=true` | +| `project_ref=` | Scope to a specific project (disables account tools) | `?project_ref=abc123` | +| `features=` | Enable only specific tool groups (comma-separated) | `?features=database,docs` | + +Parameters can be combined: `https://mcp.supabase.com/mcp?project_ref=abc123&read_only=true` + + + +When using [Supabase CLI](/docs/guides/cli) for local development, the MCP server is available at `http://localhost:54321/mcp`. + + + ## Manual authentication By default the hosted Supabase MCP server uses [dynamic client registration](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization#dynamic-client-registration) to authenticate with your Supabase org. This means that you don't need to manually create a personal access token (PAT) or OAuth app to use the server. @@ -108,10 +188,10 @@ We recommend the following best practices to mitigate security risks when using - **Don't connect to production**: Use the MCP server with a development project, not production. LLMs are great at helping design and test applications, so leverage them in a safe environment without exposing real data. Be sure that your development environment contains non-production data (or obfuscated data). - **Don't give to your customers**: The MCP server operates under the context of your developer permissions, so you should not give it to your customers or end users. Instead, use it internally as a developer tool to help you build and test your applications. -- **Read-only mode**: If you must connect to real data, set the server to [read-only](https://github.com/supabase-community/supabase-mcp#read-only-mode) mode, which executes all queries as a read-only Postgres user. -- **Project scoping**: Scope your MCP server to a [specific project](https://github.com/supabase-community/supabase-mcp#project-scoped-mode), limiting access to only that project's resources. This prevents LLMs from accessing data from other projects in your Supabase account. +- **Read-only mode**: If you must connect to real data, set the server to [read-only](#configuration-options) mode, which executes all queries as a read-only Postgres user. +- **Project scoping**: Scope your MCP server to a [specific project](#configuration-options), limiting access to only that project's resources. This prevents LLMs from accessing data from other projects in your Supabase account. - **Branching**: Use Supabase's [branching feature](/docs/guides/deployment/branching) to create a development branch for your database. This allows you to test changes in a safe environment before merging them to production. -- **Feature groups**: The server allows you to enable or disable specific [tool groups](https://github.com/supabase-community/supabase-mcp#feature-groups), so you can control which tools are available to the LLM. This helps reduce the attack surface and limits the actions that LLMs can perform to only those that you need. +- **Feature groups**: Restrict which [tool groups](#available-tools) are available using the `features` [configuration option](#configuration-options). This helps reduce the attack surface and limits the actions that LLMs can perform to only those that you need. ## On GitHub diff --git a/apps/docs/features/app.providers.tsx b/apps/docs/features/app.providers.tsx index 99e73b93c98c6..6d6caf07877e5 100644 --- a/apps/docs/features/app.providers.tsx +++ b/apps/docs/features/app.providers.tsx @@ -1,6 +1,7 @@ import type { PropsWithChildren } from 'react' import { FeatureFlagProvider, IS_PLATFORM, ThemeProvider } from 'common' +import { DevToolbar, DevToolbarProvider } from 'dev-tools' import { SonnerToaster, TooltipProvider } from 'ui' import SiteLayout from '~/layouts/SiteLayout' import { API_URL } from '~/lib/constants' @@ -19,22 +20,25 @@ function GlobalProviders({ children }: PropsWithChildren) { - - - - - -
- - {children} - - - -
-
- -
-
+ + + + + + +
+ + {children} + + + +
+
+ + +
+
+
diff --git a/apps/docs/package.json b/apps/docs/package.json index a3d5c5914c101..4e4ab01a5fe36 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -63,6 +63,7 @@ "common": "workspace:*", "common-tags": "^1.8.2", "config": "workspace:*", + "dev-tools": "workspace:*", "eslint-config-supabase": "workspace:*", "framer-motion": "^11.0.3", "github-slugger": "^2.0.0", diff --git a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx index e78f9cefaadc1..895917be4f992 100644 --- a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx +++ b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx @@ -119,16 +119,16 @@ const EdgeFunctionDetailsLayout = ({ label: 'Logs', href: `/project/${ref}/functions/${functionSlug}/logs`, }, - { - label: 'Code', - href: `/project/${ref}/functions/${functionSlug}/code`, - }, ] : []), { label: 'Details', href: `/project/${ref}/functions/${functionSlug}/details`, }, + { + label: 'Code', + href: `/project/${ref}/functions/${functionSlug}/code`, + }, ] : [] @@ -264,15 +264,15 @@ const EdgeFunctionDetailsLayout = ({ /> )} - {IS_PLATFORM && ( - <> - - - - - + + + + + + {IS_PLATFORM && ( + <>

Download via CLI

-
- -
-
-
+ + )} +
+ +
+
+
+ {IS_PLATFORM && ( + <> {!!functionSlug && ( + {IS_PLATFORM && ( + + )}
} isEditing={isEditing} onEditSubmit={(value) => { - if (originalId !== null) { + if (IS_PLATFORM && originalId !== null) { handleFileNameChange(originalId, value) } }} @@ -424,7 +427,7 @@ export const FileExplorerAndEditor = ({ } }} onDoubleClick={() => { - if (originalId !== null) { + if (IS_PLATFORM && originalId !== null) { handleStartRename(originalId) } }} @@ -445,36 +448,38 @@ export const FileExplorerAndEditor = ({ />
- e.stopPropagation()}> - { - if (originalId !== null) handleStartRename(originalId) - }} - onFocusCapture={(e) => e.stopPropagation()} - > - - Rename file - - - {files.length > 1 && ( - <> - - { - if (originalId !== null) { - handleFileDelete(originalId) - } - }} - onFocusCapture={(e) => e.stopPropagation()} - > - - Delete file - - - )} - + {IS_PLATFORM && ( + e.stopPropagation()}> + { + if (originalId !== null) handleStartRename(originalId) + }} + onFocusCapture={(e) => e.stopPropagation()} + > + + Rename file + + + {files.length > 1 && ( + <> + + { + if (originalId !== null) { + handleFileDelete(originalId) + } + }} + onFocusCapture={(e) => e.stopPropagation()} + > + + Delete file + + + )} + + )} ) }} @@ -509,6 +514,7 @@ export const FileExplorerAndEditor = ({ padding: { top: 20, bottom: 20 }, lineNumbersMinChars: 3, fixedOverflowWidgets: true, + readOnly: !IS_PLATFORM, }} /> )} diff --git a/apps/studio/data/edge-functions/edge-function-body-query.ts b/apps/studio/data/edge-functions/edge-function-body-query.ts index 772a91ca6f25f..8ee38e9a930b4 100644 --- a/apps/studio/data/edge-functions/edge-function-body-query.ts +++ b/apps/studio/data/edge-functions/edge-function-body-query.ts @@ -72,7 +72,6 @@ export const useEdgeFunctionBodyQuery = ( useQuery({ queryKey: edgeFunctionsKeys.body(projectRef, slug), queryFn: ({ signal }) => getEdgeFunctionBody({ projectRef, slug }, signal), - enabled: - IS_PLATFORM && enabled && typeof projectRef !== 'undefined' && typeof slug !== 'undefined', + enabled: enabled && typeof projectRef !== 'undefined' && typeof slug !== 'undefined', ...options, }) diff --git a/apps/studio/lib/api/self-hosted/functions/fileSystemStore.ts b/apps/studio/lib/api/self-hosted/functions/fileSystemStore.ts index 3cd98f49239f3..f5b783866a820 100644 --- a/apps/studio/lib/api/self-hosted/functions/fileSystemStore.ts +++ b/apps/studio/lib/api/self-hosted/functions/fileSystemStore.ts @@ -3,7 +3,7 @@ import { readdir, stat } from 'node:fs/promises' import path from 'node:path' import { pathToFileURL } from 'node:url' -import { FunctionArtifact } from './types' +import { FunctionArtifact, FunctionFileEntry } from './types' export class FileSystemFunctionsArtifactStore { constructor(private folderPath: string) {} @@ -29,6 +29,34 @@ export class FileSystemFunctionsArtifactStore { return parseFolderToFunctionArtifact(functionFolder) } + + async getFileEntriesBySlug(slug: string): Promise> { + if (slug === 'main') return [] + + const functionFolderPath = path.resolve(this.folderPath, slug) + if (!functionFolderPath.startsWith(path.resolve(this.folderPath) + path.sep)) return [] + + const entries = await readdir(functionFolderPath, { + recursive: true, + withFileTypes: true, + }) + + const fileEntries = await Promise.all( + entries + .filter((entry) => entry.isFile()) + .map(async (entry) => { + const absolutePath = path.join(entry.parentPath, entry.name) + const fileStat = await stat(absolutePath) + return { + absolutePath, + relativePath: path.relative(functionFolderPath, absolutePath), + size: fileStat.size, + } + }) + ) + + return fileEntries + } } async function parseFolderToFunctionArtifact( diff --git a/apps/studio/lib/api/self-hosted/functions/types.ts b/apps/studio/lib/api/self-hosted/functions/types.ts index 0a124c6966989..31f22cc79bc83 100644 --- a/apps/studio/lib/api/self-hosted/functions/types.ts +++ b/apps/studio/lib/api/self-hosted/functions/types.ts @@ -4,3 +4,11 @@ export type FunctionArtifact = { created_at: number updated_at: number } + +export type FunctionFileEntry = { + /** Absolute path on disk */ + absolutePath: string + /** Path relative to the function folder, used as the multipart filename */ + relativePath: string + size: number +} diff --git a/apps/studio/package.json b/apps/studio/package.json index 68d43465df21a..49615234eecee 100644 --- a/apps/studio/package.json +++ b/apps/studio/package.json @@ -84,6 +84,7 @@ "cron-parser": "^4.9.0", "cronstrue": "^2.50.0", "crypto-js": "^4.2.0", + "dev-tools": "workspace:*", "d3-geo": "^3.1.1", "dayjs": "^1.11.10", "dnd-core": "^16.0.1", diff --git a/apps/studio/pages/_app.tsx b/apps/studio/pages/_app.tsx index 3156d1c20c08f..5875b41e480ff 100644 --- a/apps/studio/pages/_app.tsx +++ b/apps/studio/pages/_app.tsx @@ -23,22 +23,11 @@ import { loader } from '@monaco-editor/react' import * as Sentry from '@sentry/nextjs' import { HydrationBoundary, QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' -import dayjs from 'dayjs' -import customParseFormat from 'dayjs/plugin/customParseFormat' -import duration from 'dayjs/plugin/duration' -import relativeTime from 'dayjs/plugin/relativeTime' -import timezone from 'dayjs/plugin/timezone' -import utc from 'dayjs/plugin/utc' -import Head from 'next/head' -import { NuqsAdapter } from 'nuqs/adapters/next/pages' -import { type ComponentProps, ErrorInfo, useCallback } from 'react' -import { ErrorBoundary } from 'react-error-boundary' - import { FeatureFlagProvider, - getFlags, TelemetryTagManager, ThemeProvider, + getFlags, useThemeSandbox, } from 'common' import MetaFaviconsPagesRouter from 'common/MetaFavicons/pages-router' @@ -49,8 +38,15 @@ import FeaturePreviewModal from 'components/interfaces/App/FeaturePreview/Featur import { MonacoThemeProvider } from 'components/interfaces/App/MonacoThemeProvider' import { RouteValidationWrapper } from 'components/interfaces/App/RouteValidationWrapper' import { MainScrollContainerProvider } from 'components/layouts/MainScrollContainerContext' +import { DevToolbar, DevToolbarProvider } from 'dev-tools' import { GlobalErrorBoundaryState } from 'components/ui/ErrorBoundary/GlobalErrorBoundaryState' import { useRootQueryClient } from 'data/query-client' +import dayjs from 'dayjs' +import customParseFormat from 'dayjs/plugin/customParseFormat' +import duration from 'dayjs/plugin/duration' +import relativeTime from 'dayjs/plugin/relativeTime' +import timezone from 'dayjs/plugin/timezone' +import utc from 'dayjs/plugin/utc' import { customFont, sourceCodePro } from 'fonts' import { useCustomContent } from 'hooks/custom-content/useCustomContent' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' @@ -58,6 +54,10 @@ import { AuthProvider } from 'lib/auth' import { API_URL, BASE_PATH, IS_PLATFORM, useDefaultProvider } from 'lib/constants' import { ProfileProvider } from 'lib/profile' import { Telemetry } from 'lib/telemetry' +import Head from 'next/head' +import { NuqsAdapter } from 'nuqs/adapters/next/pages' +import { type ComponentProps, ErrorInfo, useCallback } from 'react' +import { ErrorBoundary } from 'react-error-boundary' import { AiAssistantStateContextProvider } from 'state/ai-assistant-state' import type { AppPropsWithLayout } from 'types' import { SonnerToaster, TooltipProvider } from 'ui' @@ -173,19 +173,22 @@ function CustomApp({ Component, pageProps }: AppPropsWithLayout) { enableSystem disableTransitionOnChange > - - - - - {getLayout()} - - - - - - - - + + + + + + {getLayout()} + + + + + + + + + + diff --git a/apps/studio/pages/api/v1/projects/[ref]/functions/[slug]/body.ts b/apps/studio/pages/api/v1/projects/[ref]/functions/[slug]/body.ts new file mode 100644 index 0000000000000..0ffb91ed3165a --- /dev/null +++ b/apps/studio/pages/api/v1/projects/[ref]/functions/[slug]/body.ts @@ -0,0 +1,81 @@ +import { createReadStream } from 'node:fs' +import { pipeline } from 'node:stream/promises' +import { type NextApiRequest, type NextApiResponse } from 'next' + +import apiWrapper from '@/lib/api/apiWrapper' +import { getFunctionsArtifactStore } from '@/lib/api/self-hosted/functions' +import { uuidv4 } from '@/lib/helpers' + +export default function handlerWithErrorCatching(req: NextApiRequest, res: NextApiResponse) { + return apiWrapper(req, res, handler, { withAuth: true }) +} + +async function handler(req: NextApiRequest, res: NextApiResponse) { + const { method } = req + + switch (method) { + case 'GET': + return handleGet(req, res) + default: + res.setHeader('Allow', ['GET']) + res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } }) + } +} + +async function handleGet(req: NextApiRequest, res: NextApiResponse) { + const slugParam = req.query.slug + const slug = Array.isArray(slugParam) ? slugParam[0] : slugParam + if (!slug) { + res.status(404).json({ error: { message: `Missing function 'slug' parameter` } }) + return + } + + const store = getFunctionsArtifactStore() + const fileEntries = await store.getFileEntriesBySlug(slug) + + const boundary = `----FormBoundary${uuidv4().replace(/-/g, '')}` + const totalSize = fileEntries.reduce((sum, entry) => sum + entry.size, 0) + + const metadata = { + // mock id, should be "__" + deployment_id: uuidv4(), + original_size: totalSize, + compressed_size: totalSize, + module_count: fileEntries.length, + } + + res.setHeader('Content-Type', `multipart/form-data; boundary=${boundary}`) + res.status(200) + + // Write metadata part + const metadataJson = JSON.stringify(metadata) + res.write( + `--${boundary}\r\n` + + `Content-Disposition: form-data; name="metadata"\r\n` + + `Content-Type: application/json\r\n` + + `\r\n` + + metadataJson + + `\r\n` + ) + + // Stream each file part + for (const entry of fileEntries) { + const safeName = entry.relativePath + .replace(/[\r\n]/g, '') + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + const encodedName = encodeURIComponent(entry.relativePath) + res.write( + `--${boundary}\r\n` + + `Content-Disposition: form-data; name="file"; filename="${safeName}"; filename*=UTF-8''${encodedName}\r\n` + + `Content-Type: text/plain\r\n` + + `\r\n` + ) + await pipeline(createReadStream(entry.absolutePath), res, { end: false }) + res.write(`\r\n`) + } + + // Write closing boundary + res.write(`--${boundary}--\r\n`) + res.end() +} diff --git a/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx b/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx index d0026fc5c0c82..76cc03bb879de 100644 --- a/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx +++ b/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx @@ -7,7 +7,7 @@ import { toast } from 'sonner' import { formatFunctionBodyToFiles } from '@/components/interfaces/EdgeFunctions/EdgeFunctions.utils' import { FileData } from '@/components/ui/FileExplorerAndEditor/FileExplorerAndEditor.types' import { useLatest } from '@/hooks/misc/useLatest' -import { useParams } from 'common' +import { IS_PLATFORM, useParams } from 'common' import { DeployEdgeFunctionWarningModal } from 'components/interfaces/EdgeFunctions/DeployEdgeFunctionWarningModal' import { DefaultLayout } from 'components/layouts/DefaultLayout' import EdgeFunctionDetailsLayout from 'components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout' @@ -214,33 +214,35 @@ const CodePage = () => { orgSlug: org?.slug, }} /> -
- - ) : ( -
- -
- ) - } - tooltip={{ - content: { - side: 'top', - text: !canDeployFunction - ? 'You need additional permissions to update edge functions' - : undefined, - }, - }} - > - Deploy updates -
-
+ {IS_PLATFORM && ( +
+ + ) : ( +
+ +
+ ) + } + tooltip={{ + content: { + side: 'top', + text: !canDeployFunction + ? 'You need additional permissions to update edge functions' + : undefined, + }, + }} + > + Deploy updates +
+
+ )} )} diff --git a/apps/studio/public/monaco-editor/basic-languages/javascript/javascript.js b/apps/studio/public/monaco-editor/basic-languages/javascript/javascript.js new file mode 100644 index 0000000000000..286829896976d --- /dev/null +++ b/apps/studio/public/monaco-editor/basic-languages/javascript/javascript.js @@ -0,0 +1,10 @@ +/*!----------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) + * Released under the MIT license + * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt + *-----------------------------------------------------------------------------*/ +define("vs/basic-languages/javascript/javascript", ["require","require"],(require)=>{ +"use strict";var moduleExports=(()=>{var x=Object.create;var a=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var y=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var w=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),h=(e,t)=>{for(var n in t)a(e,n,{get:t[n],enumerable:!0})},s=(e,t,n,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of f(t))!k.call(e,r)&&r!==n&&a(e,r,{get:()=>t[r],enumerable:!(c=u(t,r))||c.enumerable});return e},g=(e,t,n)=>(s(e,t,"default"),n&&s(n,t,"default")),p=(e,t,n)=>(n=e!=null?x(b(e)):{},s(t||!e||!e.__esModule?a(n,"default",{value:e,enumerable:!0}):n,e)),v=e=>s(a({},"__esModule",{value:!0}),e);var d=w((C,l)=>{var A=p(y("vs/editor/editor.api"));l.exports=A});var _={};h(_,{conf:()=>$,language:()=>T});var i={};g(i,p(d()));var m={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],onEnterRules:[{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,afterText:/^\s*\*\/$/,action:{indentAction:i.languages.IndentAction.IndentOutdent,appendText:" * "}},{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,action:{indentAction:i.languages.IndentAction.None,appendText:" * "}},{beforeText:/^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,action:{indentAction:i.languages.IndentAction.None,appendText:"* "}},{beforeText:/^(\t|(\ \ ))*\ \*\/\s*$/,action:{indentAction:i.languages.IndentAction.None,removeText:1}}],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string","comment"]},{open:"`",close:"`",notIn:["string","comment"]},{open:"/**",close:" */",notIn:["string"]}],folding:{markers:{start:new RegExp("^\\s*//\\s*#?region\\b"),end:new RegExp("^\\s*//\\s*#?endregion\\b")}}},o={defaultToken:"invalid",tokenPostfix:".ts",keywords:["abstract","any","as","asserts","bigint","boolean","break","case","catch","class","continue","const","constructor","debugger","declare","default","delete","do","else","enum","export","extends","false","finally","for","from","function","get","if","implements","import","in","infer","instanceof","interface","is","keyof","let","module","namespace","never","new","null","number","object","out","package","private","protected","public","override","readonly","require","global","return","satisfies","set","static","string","super","switch","symbol","this","throw","true","try","type","typeof","undefined","unique","unknown","var","void","while","with","yield","async","await","of"],operators:["<=",">=","==","!=","===","!==","=>","+","-","**","*","/","%","++","--","<<",">",">>>","&","|","^","!","~","&&","||","??","?",":","=","+=","-=","*=","**=","/=","%=","<<=",">>=",">>>=","&=","|=","^=","@"],symbols:/[=>](?!@symbols)/,"@brackets"],[/!(?=([^=]|$))/,"delimiter"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/(@digits)[eE]([\-+]?(@digits))?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?/,"number.float"],[/0[xX](@hexdigits)n?/,"number.hex"],[/0[oO]?(@octaldigits)n?/,"number.octal"],[/0[bB](@binarydigits)n?/,"number.binary"],[/(@digits)n?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string_double"],[/'/,"string","@string_single"],[/`/,"string","@string_backtick"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@jsdoc"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],jsdoc:[[/[^\/*]+/,"comment.doc"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],regexp:[[/(\{)(\d+(?:,\d*)?)(\})/,["regexp.escape.control","regexp.escape.control","regexp.escape.control"]],[/(\[)(\^?)(?=(?:[^\]\\\/]|\\.)+)/,["regexp.escape.control",{token:"regexp.escape.control",next:"@regexrange"}]],[/(\()(\?:|\?=|\?!)/,["regexp.escape.control","regexp.escape.control"]],[/[()]/,"regexp.escape.control"],[/@regexpctl/,"regexp.escape.control"],[/[^\\\/]/,"regexp"],[/@regexpesc/,"regexp.escape"],[/\\\./,"regexp.invalid"],[/(\/)([dgimsuy]*)/,[{token:"regexp",bracket:"@close",next:"@pop"},"keyword.other"]]],regexrange:[[/-/,"regexp.escape.control"],[/\^/,"regexp.invalid"],[/@regexpesc/,"regexp.escape"],[/[^\]]/,"regexp"],[/\]/,{token:"regexp.escape.control",next:"@pop",bracket:"@close"}]],string_double:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],string_single:[[/[^\\']+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/'/,"string","@pop"]],string_backtick:[[/\$\{/,{token:"delimiter.bracket",next:"@bracketCounting"}],[/[^\\`$]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/`/,"string","@pop"]],bracketCounting:[[/\{/,"delimiter.bracket","@bracketCounting"],[/\}/,"delimiter.bracket","@pop"],{include:"common"}]}};var $=m,T={defaultToken:"invalid",tokenPostfix:".js",keywords:["break","case","catch","class","continue","const","constructor","debugger","default","delete","do","else","export","extends","false","finally","for","from","function","get","if","import","in","instanceof","let","new","null","return","set","static","super","switch","symbol","this","throw","true","try","typeof","undefined","var","void","while","with","yield","async","await","of"],typeKeywords:[],operators:o.operators,symbols:o.symbols,escapes:o.escapes,digits:o.digits,octaldigits:o.octaldigits,binarydigits:o.binarydigits,hexdigits:o.hexdigits,regexpctl:o.regexpctl,regexpesc:o.regexpesc,tokenizer:o.tokenizer};return v(_);})(); +return moduleExports; +}); diff --git a/apps/studio/public/monaco-editor/basic-languages/markdown/markdown.js b/apps/studio/public/monaco-editor/basic-languages/markdown/markdown.js new file mode 100644 index 0000000000000..b9edf5109787f --- /dev/null +++ b/apps/studio/public/monaco-editor/basic-languages/markdown/markdown.js @@ -0,0 +1,10 @@ +/*!----------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) + * Released under the MIT license + * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt + *-----------------------------------------------------------------------------*/ +define("vs/basic-languages/markdown/markdown", ["require","require"],(require)=>{ +"use strict";var moduleExports=(()=>{var s=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var l=(t,e)=>{for(var o in e)s(t,o,{get:e[o],enumerable:!0})},m=(t,e,o,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of c(e))!i.call(t,n)&&n!==o&&s(t,n,{get:()=>e[n],enumerable:!(a=r(e,n))||a.enumerable});return t};var d=t=>m(s({},"__esModule",{value:!0}),t);var b={};l(b,{conf:()=>p,language:()=>g});var p={comments:{blockComment:[""]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">",notIn:["string"]}],surroundingPairs:[{open:"(",close:")"},{open:"[",close:"]"},{open:"`",close:"`"}],folding:{markers:{start:new RegExp("^\\s*"),end:new RegExp("^\\s*")}}},g={defaultToken:"",tokenPostfix:".md",control:/[\\`*_\[\]{}()#+\-\.!]/,noncontrol:/[^\\`*_\[\]{}()#+\-\.!]/,escapes:/\\(?:@control)/,jsescapes:/\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/,empty:["area","base","basefont","br","col","frame","hr","img","input","isindex","link","meta","param"],tokenizer:{root:[[/^\s*\|/,"@rematch","@table_header"],[/^(\s{0,3})(#+)((?:[^\\#]|@escapes)+)((?:#+)?)/,["white","keyword","keyword","keyword"]],[/^\s*(=+|\-+)\s*$/,"keyword"],[/^\s*((\*[ ]?)+)\s*$/,"meta.separator"],[/^\s*>+/,"comment"],[/^\s*([\*\-+:]|\d+\.)\s/,"keyword"],[/^(\t|[ ]{4})[^ ].*$/,"string"],[/^\s*~~~\s*((?:\w|[\/\-#])+)?\s*$/,{token:"string",next:"@codeblock"}],[/^\s*```\s*((?:\w|[\/\-#])+).*$/,{token:"string",next:"@codeblockgh",nextEmbedded:"$1"}],[/^\s*```\s*$/,{token:"string",next:"@codeblock"}],{include:"@linecontent"}],table_header:[{include:"@table_common"},[/[^\|]+/,"keyword.table.header"]],table_body:[{include:"@table_common"},{include:"@linecontent"}],table_common:[[/\s*[\-:]+\s*/,{token:"keyword",switchTo:"table_body"}],[/^\s*\|/,"keyword.table.left"],[/^\s*[^\|]/,"@rematch","@pop"],[/^\s*$/,"@rematch","@pop"],[/\|/,{cases:{"@eos":"keyword.table.right","@default":"keyword.table.middle"}}]],codeblock:[[/^\s*~~~\s*$/,{token:"string",next:"@pop"}],[/^\s*```\s*$/,{token:"string",next:"@pop"}],[/.*$/,"variable.source"]],codeblockgh:[[/```\s*$/,{token:"string",next:"@pop",nextEmbedded:"@pop"}],[/[^`]+/,"variable.source"]],linecontent:[[/&\w+;/,"string.escape"],[/@escapes/,"escape"],[/\b__([^\\_]|@escapes|_(?!_))+__\b/,"strong"],[/\*\*([^\\*]|@escapes|\*(?!\*))+\*\*/,"strong"],[/\b_[^_]+_\b/,"emphasis"],[/\*([^\\*]|@escapes)+\*/,"emphasis"],[/`([^\\`]|@escapes)+`/,"variable"],[/\{+[^}]+\}+/,"string.target"],[/(!?\[)((?:[^\]\\]|@escapes)*)(\]\([^\)]+\))/,["string.link","","string.link"]],[/(!?\[)((?:[^\]\\]|@escapes)*)(\])/,"string.link"],{include:"html"}],html:[[/<(\w+)\/>/,"tag"],[/<(\w+)(\-|\w)*/,{cases:{"@empty":{token:"tag",next:"@tag.$1"},"@default":{token:"tag",next:"@tag.$1"}}}],[/<\/(\w+)(\-|\w)*\s*>/,{token:"tag"}],[//,"comment","@pop"],[/