diff --git a/.env.example b/.env.example
index e6f14f0..3273c9a 100644
--- a/.env.example
+++ b/.env.example
@@ -3,6 +3,7 @@ NEXTAUTH_SECRET="1234"
GITHUB_SECRET=""
GITHUB_ID=""
NEXT_PUBLIC_COMPILE_API_ENDPOINT="http://localhost:9000/api/build"
+NEXT_PUBLIC_JS_COMPILE_API_ENDPOINT="http://localhost:9000/api/build/js"
NEXT_PUBLIC_COMPILE_API_BASE_URL="http://localhost:9000"
NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT="ws://localhost:9000/language-server/c"
NEXT_PUBLIC_TESTNET_URL="xahau-test.net"
diff --git a/.gitignore b/.gitignore
index c98cdfc..e68f5bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,6 @@ yarn-error.log*
# yarn
.yarnrc.yml
.yarn/
+
+# esbuild
+public/esbuild.wasm
diff --git a/components/DeployEditor.tsx b/components/DeployEditor.tsx
index 2b13bb7..5aed6dd 100644
--- a/components/DeployEditor.tsx
+++ b/components/DeployEditor.tsx
@@ -31,7 +31,8 @@ const DeployEditor = () => {
const renderNav = () => (
(state.activeWat = idx)}>
{compiledFiles.map((file, index) => {
- return
+ const compiledViewableExtension = file.compiledExtension === 'wasm' ? 'wat' : 'js'
+ return
})}
)
@@ -41,8 +42,8 @@ const DeployEditor = () => {
compiledSize > FILESIZE_BREAKPOINTS[1]
? '$error'
: compiledSize > FILESIZE_BREAKPOINTS[0]
- ? '$warning'
- : '$success'
+ ? '$warning'
+ : '$success'
const isContentChanged = activeFile && activeFile.compiledValueSnapshot !== activeFile.content
// const hasDeployErrors = activeFile && activeFile.containsErrors;
@@ -58,7 +59,7 @@ const DeployEditor = () => {
}}
>
- Compiled {activeFile.name.split('.')[0] + '.wasm'}
+ Compiled {activeFile.name.split('.')[0] + '.' + activeFile.compiledExtension}
{activeFile?.lastCompiled && }
{activeFile.compiledContent?.byteLength && (
@@ -73,7 +74,7 @@ const DeployEditor = () => {
)}
{isContentChanged && (
@@ -128,14 +129,14 @@ const DeployEditor = () => {
) : (
{
- monaco.languages.register({ id: 'wat' })
- monaco.languages.setLanguageConfiguration('wat', wat.config)
- monaco.languages.setMonarchTokensProvider('wat', wat.tokens)
+ monaco.languages.register({ id: activeFile.language })
+ monaco.languages.setLanguageConfiguration(activeFile.language, wat.config)
+ monaco.languages.setMonarchTokensProvider(activeFile.language, wat.tokens)
}}
onMount={editor => {
editor.updateOptions({
diff --git a/components/HooksEditor.tsx b/components/HooksEditor.tsx
index 2128f35..a3bdd0f 100644
--- a/components/HooksEditor.tsx
+++ b/components/HooksEditor.tsx
@@ -200,15 +200,15 @@ const HooksEditor = () => {
defaultValue={file?.content}
// onChange={val => (state.files[snap.active].content = val)} // Auto save?
beforeMount={monaco => {
- // if (!snap.editorCtx) {
- // snap.files.forEach(file =>
- // monaco.editor.createModel(
- // file.content,
- // file.language,
- // monaco.Uri.parse(`file:///work/c/${file.name}`)
- // )
- // )
- // }
+ if (!snap.editorCtx) {
+ snap.files.forEach(file =>
+ monaco.editor.createModel(
+ file.content,
+ file.language,
+ monaco.Uri.parse(`file:///work/c/${file.name}`)
+ )
+ )
+ }
// create the web socket
if (!subscriptionRef.current) {
@@ -223,6 +223,21 @@ const HooksEditor = () => {
extensions: ['.txt'],
mimetypes: ['text/plain'],
})
+
+ monaco.languages.register({
+ id: 'typescript',
+ extensions: ['.ts', '.js'],
+ mimetypes: ['text/plain'],
+ })
+
+ // Set global variables
+ snap.files.filter(file => file.content.includes('declare global'))
+ .forEach(file => {
+ monaco.languages.typescript.javascriptDefaults.addExtraLib(
+ file.content
+ )
+ })
+
MonacoServices.install(monaco)
const webSocket = createWebSocket(
process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || ''
diff --git a/components/Navigation.tsx b/components/Navigation.tsx
index e4e9d23..36918e9 100644
--- a/components/Navigation.tsx
+++ b/components/Navigation.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { useState } from 'react'
import Link from 'next/link'
import { useSnapshot } from 'valtio'
@@ -27,8 +27,9 @@ import {
DialogTrigger
} from './Dialog'
import PanelBox from './PanelBox'
-import { templateFileIds } from '../state/constants'
+import { templateCFileIds, templateJSFileIds } from '../state/constants'
import { styled } from '../stitches.config'
+import { Tab, Tabs } from './Tabs'
const ImageWrapper = styled(Flex, {
position: 'relative',
@@ -45,9 +46,17 @@ const ImageWrapper = styled(Flex, {
}
})
+const cEnabled = !!process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT
+const jsEnabled = !!process.env.NEXT_PUBLIC_JS_COMPILE_API_ENDPOINT
+
+type Languages = 'C' | 'JavaScript'
+
+const defaultLanguage: Languages = cEnabled ? 'C' : 'JavaScript'
+
const Navigation = () => {
const router = useRouter()
const snap = useSnapshot(state)
+ const [language, setLanguage] = useState(defaultLanguage)
const slug = router.query?.slug
const gistId = Array.isArray(slug) ? slug[0] : null
@@ -261,34 +270,64 @@ const Navigation = () => {
- {Object.values(templateFileIds).map(template => (
-
- {template.icon()}
- {template.name}
+ {cEnabled && jsEnabled && (
+
+ setLanguage(header as Languages)}>
+
+
+
+
+ )}
+
+ {language === 'C' ? Object.values(templateCFileIds).map(template => (
+
+ {template.icon()}
+ {template.name}
+
+ {template.description}
+
+ )) : Object.values(templateJSFileIds).map(template => (
+
+ {template.icon()}
+ {template.name}
- {template.description}
-
- ))}
+ {template.description}
+
+ ))}
+
diff --git a/components/RunScript/index.tsx b/components/RunScript/index.tsx
index c26cf99..91a2c81 100644
--- a/components/RunScript/index.tsx
+++ b/components/RunScript/index.tsx
@@ -214,7 +214,7 @@ const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => {
setIframeCode('')
}}
>
- {name}
+ Run Script
diff --git a/components/SetHookDialog.tsx b/components/SetHookDialog.tsx
index b10d524..d9cf510 100644
--- a/components/SetHookDialog.tsx
+++ b/components/SetHookDialog.tsx
@@ -276,8 +276,41 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
+ {activeFile?.language === 'javascript' &&
+
+
+
+ {
+ if (e.key === '.' || e.key === ',') {
+ e.preventDefault()
+ }
+ }}
+ step="1"
+ defaultValue={10000}
+ css={{
+ '-moz-appearance': 'textfield',
+ '&::-webkit-outer-spin-button': {
+ '-webkit-appearance': 'none',
+ margin: 0
+ },
+ '&::-webkit-inner-spin-button ': {
+ '-webkit-appearance': 'none',
+ margin: 0
+ }
+ }}
+ />
+
+ {errors.JSHookFee?.type === 'required' && (
+ Hook Fee is required
+ )}
+
+ }
-
+
= React.memo(
setValue('Fee', Math.round(Number(res.base_fee || '')).toString())
}
}
- } catch (err) {}
+ } catch (err) { }
setEstimateLoading(false)
}}
@@ -338,7 +371,7 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
{errors.Fee?.type === 'required' && (
- Fee is required
+ SetHook Fee is required
)}
{/*
diff --git a/components/Tabs.tsx b/components/Tabs.tsx
index c0ff81f..a687dbe 100644
--- a/components/Tabs.tsx
+++ b/components/Tabs.tsx
@@ -43,6 +43,7 @@ interface Props {
regex: string | RegExp
error: string
}
+ css?: Record
onCreateNewTab?: (name: string) => any
onRenameTab?: (index: number, nwName: string, oldName?: string) => any
onCloseTab?: (index: number, header?: string) => any
@@ -65,7 +66,8 @@ export const Tabs = ({
headerExtraValidation,
extensionRequired,
defaultExtension = '',
- allowedExtensions
+ allowedExtensions,
+ css
}: Props) => {
const [active, setActive] = useState(activeIndex || 0)
const tabs: TabProps[] = children.map(elem => elem.props)
@@ -205,7 +207,8 @@ export const Tabs = ({
flexWrap: 'nowrap',
marginBottom: '$2',
width: '100%',
- overflow: 'auto'
+ overflow: 'auto',
+ ...css
}}
>
{tabs.map((tab, idx) => (
@@ -347,28 +350,28 @@ export const Tabs = ({
)}
{keepAllAlive
? tabs.map((tab, idx) => {
- // TODO Maybe rule out fragments as children
- if (!isValidElement(tab.children)) {
- if (active !== idx) return null
- return tab.children
- }
- let key = tab.children.key || tab.header || idx
- let { children } = tab
- let { style, ...props } = children.props
- return (
-
- )
- })
+ // TODO Maybe rule out fragments as children
+ if (!isValidElement(tab.children)) {
+ if (active !== idx) return null
+ return tab.children
+ }
+ let key = tab.children.key || tab.header || idx
+ let { children } = tab
+ let { style, ...props } = children.props
+ return (
+
+ )
+ })
: tabs[active] && (
- {tabs[active].children}
- )}
+ {tabs[active].children}
+ )}
>
)
}
diff --git a/content/transactions.json b/content/transactions.json
index 18e29cd..ba07b0f 100644
--- a/content/transactions.json
+++ b/content/transactions.json
@@ -30,7 +30,7 @@
"Account": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"TransactionType": "CheckCash",
"Amount": {
- "$value": "100",
+ "$value": "1",
"$type": "amount.xrp"
},
"DeliverMin": {
@@ -75,7 +75,7 @@
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"TransactionType": "EscrowCreate",
"Amount": {
- "$value": "100",
+ "$value": "1",
"$type": "amount.xrp"
},
"Destination": {
@@ -138,7 +138,7 @@
"$value": ""
},
"Amount": {
- "$value": "100",
+ "$value": "1",
"$type": "amount.xrp"
},
"Fee": "12",
@@ -149,7 +149,7 @@
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"TransactionType": "PaymentChannelCreate",
"Amount": {
- "$value": "100",
+ "$value": "1",
"$type": "amount.xrp"
},
"Destination": {
@@ -168,7 +168,7 @@
"TransactionType": "PaymentChannelFund",
"Channel": "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198",
"Amount": {
- "$value": "200",
+ "$value": "2",
"$type": "amount.xrp"
},
"Expiration": 543171558,
@@ -262,7 +262,7 @@
"URITokenID": "B792B56B558C89C4E942E41B5DB66074E005CB198DB70C26C707AAC2FF5F74CB",
"Destination": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Amount": {
- "$value": "100",
+ "$value": "1",
"$type": "amount.xrp"
},
"Fee": "10",
@@ -280,10 +280,10 @@
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"URITokenID": "B792B56B558C89C4E942E41B5DB66074E005CB198DB70C26C707AAC2FF5F74CB",
"Amount": {
- "$value": "100",
+ "$value": "1",
"$type": "amount.xrp"
},
"Fee": "10",
"Sequence": 1
}
-]
\ No newline at end of file
+]
diff --git a/next.config.js b/next.config.js
index 8b0f92e..e78bb79 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,3 +1,6 @@
+const CopyPlugin = require('copy-webpack-plugin');
+const path = require('path');
+
/** @type {import('next').NextConfig} */
module.exports = {
reactStrictMode: true,
@@ -15,6 +18,18 @@ module.exports = {
test: [/\.md$/, /hook-bundle\.js$/],
use: 'raw-loader'
})
+ if (!isServer) {
+ config.plugins.push(
+ new CopyPlugin({
+ patterns: [
+ {
+ from: path.resolve(__dirname, 'node_modules/esbuild-wasm/esbuild.wasm'),
+ to: path.resolve(__dirname, 'public/esbuild.wasm')
+ }
+ ]
+ })
+ );
+ }
return config
}
}
diff --git a/package.json b/package.json
index fc9dc98..82af27e 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"base64-js": "^1.5.1",
"comment-parser": "^1.3.1",
"dinero.js": "^1.9.1",
+ "esbuild-wasm": "^0.24.2",
"file-saver": "^2.0.5",
"filesize": "^8.0.7",
"javascript-time-ago": "^2.3.11",
@@ -38,7 +39,7 @@
"lodash.xor": "^4.5.0",
"monaco-editor": "^0.33.0",
"next": "^12.0.4",
- "next-auth": "^4.10.3",
+ "next-auth": "^4.24.11",
"next-plausible": "^3.2.0",
"next-themes": "^0.1.1",
"normalize-url": "^7.0.2",
@@ -77,12 +78,16 @@
"@types/pako": "^1.0.2",
"@types/react": "17.0.31",
"browserify": "^17.0.0",
+ "copy-webpack-plugin": "^12.0.2",
"eslint": "7.32.0",
"eslint-config-next": "11.1.2",
"raw-loader": "^4.0.2",
- "typescript": "4.4.4"
+ "typescript": "^4.9.5"
},
"resolutions": {
"ripple-binary-codec": "=1.6.0"
+ },
+ "engines": {
+ "node": ">=22.0.0"
}
}
diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts
index 94345ea..d47067b 100644
--- a/pages/api/auth/[...nextauth].ts
+++ b/pages/api/auth/[...nextauth].ts
@@ -1,5 +1,11 @@
import NextAuth from 'next-auth'
+declare module "next-auth" {
+ interface User {
+ username: string
+ }
+}
+
export default NextAuth({
// Configure one or more authentication providers
providers: [
diff --git a/pages/develop/[[...slug]].tsx b/pages/develop/[[...slug]].tsx
index e3af2f3..150a48c 100644
--- a/pages/develop/[[...slug]].tsx
+++ b/pages/develop/[[...slug]].tsx
@@ -150,7 +150,7 @@ const Home: NextPage = () => {
const activeFile = snap.files[snap.active] as IFile | undefined
const activeFileExt = getFileExtention(activeFile?.name)
- const canCompile = activeFileExt === 'c' || activeFileExt === 'wat'
+ const canCompile = ['c', 'wat', 'js', 'ts'].includes(activeFileExt || '')
return (
{
>
- {canCompile && (
- !snap.compiling && snap.files.length && compileCode(snap.active)}
- >
-
+ {canCompile && (
+ !snap.compiling && snap.files.length && compileCode(snap.active)}
>
-
- }>
-
-
- )}
- {activeFileExt === 'js' && (
- !snap.compiling && snap.files.length && compileCode(snap.active)}
- >
- }>
+
+
+
+
+ )}
+
+ )}
+ {activeFileExt === 'js' && (
+ !snap.compiling && snap.files.length && compileCode(snap.active)}
>
-
-
-
- )}
+
+
+ )}
+
{
// Save the file to global state
saveFile(false, activeId)
+
const file = state.files[activeId]
- if (file.name.endsWith('.wat')) {
- return compileWat(activeId)
- }
- if (!process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT) {
- throw Error('Missing env!')
- }
// Bail out if we're already compiling
if (state.compiling) {
// if compiling is ongoing return // TODO Inform user about it.
@@ -31,6 +28,66 @@ export const compileCode = async (activeId: number) => {
// Set loading state to true
state.compiling = true
state.logs = []
+
+ if (file.name.endsWith('.wat')) {
+ return compileWat(activeId)
+ }
+
+ if (file.name.endsWith('.js') || file.name.endsWith('.ts')) {
+ return compileJs(activeId)
+ }
+
+ return compileC(activeId)
+}
+
+export const compileWat = async (activeId: number) => {
+ const file = state.files[activeId]
+ try {
+ const wabt = await (await import('wabt')).default()
+ const module = wabt.parseWat(file.name, file.content);
+ module.resolveNames();
+ module.validate();
+ const { buffer } = module.toBinary({
+ log: false,
+ write_debug_names: true,
+ });
+
+ file.compiledContent = ref(buffer)
+ file.lastCompiled = new Date()
+ file.compiledValueSnapshot = file.content
+ file.compiledWatContent = file.content
+ file.compiledExtension = 'wasm'
+
+ toast.success('Compiled successfully!', { position: 'bottom-center' })
+ state.logs.push({
+ type: 'success',
+ message: `File ${state.files?.[activeId]?.name} compiled successfully. Ready to deploy.`,
+ link: Router.asPath.replace('develop', 'deploy'),
+ linkText: 'Go to deploy'
+ })
+ } catch (err) {
+ console.log(err)
+ let message = "Error compiling WAT file!"
+ if (err instanceof Error) {
+ message = err.message
+ }
+ state.logs.push({
+ type: 'error',
+ message
+ })
+ toast.error(`Error occurred while compiling!`, { position: 'bottom-center' })
+ file.containsErrors = true
+ }
+ state.compiling = false
+}
+
+export const compileC = async (activeId: number) => {
+ const file = state.files[activeId]
+
+ if (!process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT) {
+ throw Error('Missing env!')
+ }
+
try {
file.containsErrors = false
let res: Response
@@ -88,6 +145,7 @@ export const compileCode = async (activeId: number) => {
file.lastCompiled = new Date()
file.compiledValueSnapshot = file.content
file.compiledWatContent = wast
+ file.compiledExtension = 'wasm'
} catch (error) {
throw Error('Invalid compilation result produced, check your code for errors and try again!')
}
@@ -127,25 +185,157 @@ export const compileCode = async (activeId: number) => {
}
}
-export const compileWat = async (activeId: number) => {
- if (state.compiling) return;
+function customResolver(tree: Record): esbuild.Plugin {
+ const map = new Map(Object.entries(tree))
+ return {
+ name: 'example',
+ setup: (build: esbuild.PluginBuild) => {
+ build.onResolve({ filter: /.*/, }, (args: esbuild.OnResolveArgs) => {
+ if (args.kind === 'entry-point') {
+ return { path: '/' + args.path }
+ }
+ if (args.kind === 'import-statement') {
+ const dirname = Path.dirname(args.importer)
+ const basePath = Path.join(dirname, args.path)
+ // If extension is specified, try that path directly
+ if (Path.extname(args.path)) {
+ return { path: basePath }
+ }
+ // If no extension specified, try .ts and .js in order
+ const extensions = ['.ts', '.js']
+ for (const ext of extensions) {
+ const pathWithExt = basePath + ext
+ if (map.has(pathWithExt.replace(/^\//, ''))) {
+ return { path: pathWithExt }
+ }
+ }
+ }
+ throw Error('not resolvable')
+ })
+
+ build.onLoad({ filter: /.*/ }, (args: esbuild.OnLoadArgs) => {
+ const path = args.path.replace(/^\//, '')
+ if (!map.has(path)) {
+ throw Error('not loadable')
+ }
+ const ext = Path.extname(path)
+ const contents = map.get(path)!
+ const loader = (ext === '.ts') ? 'ts' :
+ (ext === '.js') ? 'js' :
+ 'default'
+ return { contents, loader }
+ })
+ }
+ }
+}
+
+function validateExportContent(content: string): void {
+ const words = content
+ .split(",")
+ .map((word) => word.trim())
+ .filter((word) => word.length > 0);
+ if (!words.includes("Hook")) {
+ throw Error("Invalid export: Hook is required");
+ }
+ if (!words.every((word) => word === "Hook" || word === "Callback")) {
+ throw Error("Invalid export: Only Hook and Callback are allowed");
+ }
+}
+
+
+function clean(content: string): string {
+ const importPattern = /^\s*import\s+.*?;\s*$/gm;
+ const exportPattern = /^\s*export\s*\{([^}]*)\};?\s*$/gm;
+ const commentPattern = /^\s*\/\/.*$/gm;
+
+ const match = exportPattern.exec(content);
+ if (!match) {
+ throw Error("Invalid export: No export found");
+ }
+ const exportContent = match[1];
+ validateExportContent(exportContent);
+ let cleanedCode = content.replace(importPattern, "");
+ cleanedCode = cleanedCode.replace(exportPattern, "");
+ cleanedCode = cleanedCode.replace(commentPattern, "");
+ cleanedCode = cleanedCode.trim();
+ return cleanedCode;
+}
+
+export const compileJs = async (activeId: number) => {
const file = state.files[activeId]
- state.compiling = true
- state.logs = []
+
+ if (!process.env.NEXT_PUBLIC_JS_COMPILE_API_ENDPOINT) {
+ throw Error('Missing env!')
+ }
+
+ const tree = state.files.reduce((prev, file) => {
+ prev[file.name] = file.content
+ return prev
+ }, {} as Record)
+
+ if (!(window as any).isEsbuildRunning) {
+ (window as any).isEsbuildRunning = true
+ await esbuild.initialize({
+ wasmURL: '/esbuild.wasm',
+ })
+ }
+
try {
- const wabt = await (await import('wabt')).default()
- const module = wabt.parseWat(file.name, file.content);
- module.resolveNames();
- module.validate();
- const { buffer } = module.toBinary({
- log: false,
- write_debug_names: true,
- });
+ const result = await esbuild.build({
+ entryPoints: [file.name],
+ bundle: true,
+ format: "esm",
+ write: false,
+ plugins: [customResolver(tree)]
+ })
- file.compiledContent = ref(buffer)
+ let compiledContent = clean(result.outputFiles?.[0].text)
+ file.language = 'javascript'
+ const res = await fetch(process.env.NEXT_PUBLIC_JS_COMPILE_API_ENDPOINT, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ output: 'bc',
+ compress: true,
+ strip: true,
+ files: [
+ {
+ type: 'js',
+ options: '-O3',
+ name: file.name,
+ src: compiledContent
+ }
+ ]
+ })
+ })
+
+ const json = await res.json()
+
+ state.compiling = false
+ if (!json.success) {
+ const errors = [json.message]
+ if (json.tasks && json.tasks.length > 0) {
+ json.tasks.forEach((task: any) => {
+ if (!task.success) {
+ errors.push(task?.console)
+ }
+ })
+ }
+ throw errors
+ }
+
+ if (!json.success) {
+ throw new Error(json.error || 'Failed to compile JavaScript')
+ }
+
+ const binary = await decodeBinary(json.output)
+ file.compiledContent = ref(binary)
file.lastCompiled = new Date()
file.compiledValueSnapshot = file.content
- file.compiledWatContent = file.content
+ file.compiledWatContent = compiledContent
+ file.compiledExtension = 'js'
toast.success('Compiled successfully!', { position: 'bottom-center' })
state.logs.push({
@@ -156,16 +346,28 @@ export const compileWat = async (activeId: number) => {
})
} catch (err) {
console.log(err)
- let message = "Error compiling WAT file!"
- if (err instanceof Error) {
- message = err.message
+
+ if (err instanceof Array && typeof err[0] === 'string') {
+ err.forEach(message => {
+ state.logs.push({
+ type: 'error',
+ message
+ })
+ })
+ } else if (err instanceof Error) {
+ state.logs.push({
+ type: 'error',
+ message: err.message
+ })
+ } else {
+ state.logs.push({
+ type: 'error',
+ message: 'Something went wrong, come back later!'
+ })
}
- state.logs.push({
- type: 'error',
- message
- })
+
+ state.compiling = false
toast.error(`Error occurred while compiling!`, { position: 'bottom-center' })
file.containsErrors = true
}
- state.compiling = false
}
diff --git a/state/actions/deployHook.tsx b/state/actions/deployHook.tsx
index e7dd322..302d2b1 100644
--- a/state/actions/deployHook.tsx
+++ b/state/actions/deployHook.tsx
@@ -91,8 +91,9 @@ export const prepareDeployHookTx = async (
CreateCode: arrayBufferToHex(activeFile?.compiledContent).toUpperCase(),
HookOn: calculateHookOn(hookOnValues),
HookNamespace,
- HookApiVersion: 0,
+ HookApiVersion: activeFile.language === 'javascript' ? 1 : 0,
Flags: 1,
+ Fee: data.JSHookFee,
// ...(filteredHookGrants.length > 0 && { HookGrants: filteredHookGrants }),
...(filteredHookParameters.length > 0 && {
HookParameters: filteredHookParameters
@@ -241,9 +242,8 @@ export const deleteHook = async (account: IAccount & { name?: string }) => {
})
state.deployLogs.push({
type: 'error',
- message: `[${submitRes.engine_result || submitRes.error}] ${
- submitRes.engine_result_message || submitRes.error_exception
- }`
+ message: `[${submitRes.engine_result || submitRes.error}] ${submitRes.engine_result_message || submitRes.error_exception
+ }`
})
}
} catch (err) {
diff --git a/state/actions/fetchFiles.ts b/state/actions/fetchFiles.ts
index fc6fd00..5c4a139 100644
--- a/state/actions/fetchFiles.ts
+++ b/state/actions/fetchFiles.ts
@@ -1,9 +1,37 @@
import { Octokit } from '@octokit/core'
import state, { IFile } from '../index'
-import { templateFileIds } from '../constants'
+import { templateCFileIds, templateJSFileIds } from '../constants'
const octokit = new Octokit()
+const fileNameToFile = (files: any, filename: string) => ({
+ name: files[filename]?.filename || 'untitled.c',
+ language: files[filename]?.language?.toLowerCase() || '',
+ content: files[filename]?.content || ''
+})
+
+const sortFiles = (a: IFile, b: IFile) => {
+ const aBasename = a.name.split('.')?.[0]
+ const aExt = a.name.split('.').pop() || ''
+ const bBasename = b.name.split('.')?.[0]
+ const bExt = b.name.split('.').pop() || ''
+
+ // default priority is undefined == 0
+ const extPriority: Record = {
+ c: 3,
+ wat: 3,
+ md: 2,
+ h: -1
+ }
+
+ // Sort based on extention priorities
+ const comp = (extPriority[bExt] || 0) - (extPriority[aExt] || 0)
+ if (comp !== 0) return comp
+
+ // Otherwise fallback to alphabetical sorting
+ return aBasename.localeCompare(bBasename)
+}
+
/**
* Fetches files from Github Gists based on gistId and stores them in global state
*/
@@ -17,62 +45,70 @@ export const fetchFiles = async (gistId: string) => {
})
try {
const res = await octokit.request('GET /gists/{gist_id}', { gist_id: gistId })
+ if (!res.data.files) throw Error('No files could be fetched from given gist id!')
+
+ const isCTemplate = (id: string) =>
+ Object.values(templateCFileIds)
+ .map(v => v.id)
+ .includes(id)
- const isTemplate = (id: string) =>
- Object.values(templateFileIds)
+ const isJSTemplate = (id: string) =>
+ Object.values(templateJSFileIds)
.map(v => v.id)
.includes(id)
- if (isTemplate(gistId)) {
- // fetch headers
- const headerRes = await fetch(
- `${process.env.NEXT_PUBLIC_COMPILE_API_BASE_URL}/api/header-files`
- )
- if (!headerRes.ok) throw Error('Failed to fetch headers')
+ let files: IFile[] = []
- const headerJson = await headerRes.json()
- const headerFiles: Record =
+ if (isCTemplate(gistId)) {
+ const template = Object.values(templateCFileIds).find(tmp => tmp.id === gistId)
+ let headerFiles: Record =
{}
- Object.entries(headerJson).forEach(([key, value]) => {
- const fname = `${key}.h`
- headerFiles[fname] = { filename: fname, content: value as string, language: 'C' }
- })
- const files = {
+ if (template?.headerId) {
+ const resHeader = await octokit.request('GET /gists/{gist_id}', { gist_id: template.headerId })
+ if (!resHeader.data.files) throw new Error('No header files could be fetched from given gist id!')
+ headerFiles = resHeader.data.files as any
+ } else {
+ // fetch headers
+ const headerRes = await fetch(
+ `${process.env.NEXT_PUBLIC_COMPILE_API_BASE_URL}/api/header-files`
+ )
+ if (!headerRes.ok) throw Error('Failed to fetch headers')
+
+ const headerJson = await headerRes.json()
+ Object.entries(headerJson).forEach(([key, value]) => {
+ const fname = `${key}.h`
+ headerFiles[fname] = { filename: fname, content: value as string, language: 'C' }
+ })
+ }
+ const _files = {
...res.data.files,
...headerFiles
}
- res.data.files = files
- }
-
- if (!res.data.files) throw Error('No files could be fetched from given gist id!')
-
- const files: IFile[] = Object.keys(res.data.files).map(filename => ({
- name: res.data.files?.[filename]?.filename || 'untitled.c',
- language: res.data.files?.[filename]?.language?.toLowerCase() || '',
- content: res.data.files?.[filename]?.content || ''
- }))
-
- files.sort((a, b) => {
- const aBasename = a.name.split('.')?.[0]
- const aExt = a.name.split('.').pop() || ''
- const bBasename = b.name.split('.')?.[0]
- const bExt = b.name.split('.').pop() || ''
-
- // default priority is undefined == 0
- const extPriority: Record = {
- c: 3,
- wat: 3,
- md: 2,
- h: -1
+ files = Object.keys(_files)
+ .map((filename) => fileNameToFile(_files, filename))
+ files.sort(sortFiles)
+ } else if (isJSTemplate(gistId)) {
+ // fetch JS headers(eg. global.d.ts)
+ const template = Object.values(templateJSFileIds).find(tmp => tmp.id === gistId)
+ if (template?.headerId) {
+ const resHeader = await octokit.request('GET /gists/{gist_id}', { gist_id: template.headerId })
+ if (!resHeader.data.files) throw Error('No header files could be fetched from given gist id!')
+ files = Object.keys(resHeader.data.files)
+ .map((filename) => fileNameToFile(resHeader.data.files, filename))
+ files.sort(sortFiles)
}
- // Sort based on extention priorities
- const comp = (extPriority[bExt] || 0) - (extPriority[aExt] || 0)
- if (comp !== 0) return comp
-
- // Otherwise fallback to alphabetical sorting
- return aBasename.localeCompare(bBasename)
- })
+ // Put entry point files at the beginning
+ files = [
+ ...Object.keys(res.data.files).map((filename) => fileNameToFile(res.data.files, filename)),
+ ...files
+ ]
+ } else {
+ const _files = res.data.files
+ files = Object.keys(_files)
+ .map((filename) => fileNameToFile(_files, filename))
+ files.sort(sortFiles)
+ }
state.logs.push({
type: 'success',
diff --git a/state/constants/templates.ts b/state/constants/templates.ts
index 2b4a5de..fd19e13 100644
--- a/state/constants/templates.ts
+++ b/state/constants/templates.ts
@@ -4,38 +4,69 @@ import Notary from '../../components/icons/Notary'
import Peggy from '../../components/icons/Peggy'
import Starter from '../../components/icons/Starter'
-export const templateFileIds = {
+type Template = {
+ id: string
+ name: string
+ description: string
+ headerId?: string
+ icon: () => JSX.Element
+}
+
+export const templateCFileIds: Record = {
starter: {
id: '1f8109c80f504e6326db2735df2f0ad6', // Forked
name: 'Starter',
description:
'Just a basic starter with essential imports, just accepts any transaction coming through',
+ headerId: '028e8ce6d6d674776970caf8acc77ecc',
icon: Starter
},
firewall: {
id: '1cc30f39c8a0b9c55b88c312669ca45e', // Forked
name: 'Firewall',
description: 'This Hook essentially checks a blacklist of accounts',
+ headerId: '028e8ce6d6d674776970caf8acc77ecc',
icon: Firewall
},
notary: {
id: '87b6f5a8c2f5038fb0f20b8b510efa10', // Forked
name: 'Notary',
description: 'Collecting signatures for multi-sign transactions',
+ headerId: '028e8ce6d6d674776970caf8acc77ecc',
icon: Notary
},
carbon: {
id: '953662b22d065449f8ab6f69bc2afe41', // Forked
name: 'Carbon',
description: 'Send a percentage of sum to an address',
+ headerId: '028e8ce6d6d674776970caf8acc77ecc',
icon: Carbon
},
peggy: {
id: '049784a83fa068faf7912f663f7b6471', // Forked
name: 'Peggy',
description: 'An oracle based stable coin hook',
+ headerId: '028e8ce6d6d674776970caf8acc77ecc',
icon: Peggy
}
}
+export const templateJSFileIds: Record = {
+ starter: {
+ id: '894137a0ebd67568c877237140f4586f',
+ name: 'Starter',
+ description:
+ 'Just a basic starter with essential imports, just accepts any transaction coming through',
+ headerId: 'e64b8286f04b3ab84cab63ec3abd8771',
+ icon: Starter
+ },
+ carbon: {
+ id: '9fa48d4fba17b2bbe2148eb9c3f15914',
+ name: 'Carbon',
+ description: 'Send a percentage of sum to an address',
+ headerId: 'e64b8286f04b3ab84cab63ec3abd8771',
+ icon: Carbon
+ }
+}
+
export const apiHeaderFiles = ['hookapi.h', 'sfcodes.h', 'macro.h', 'extern.h', 'error.h']
diff --git a/state/index.ts b/state/index.ts
index d317655..b0d9101 100644
--- a/state/index.ts
+++ b/state/index.ts
@@ -13,6 +13,7 @@ export interface IFile {
name: string
language: string
content: string
+ compiledExtension?: 'wasm' | 'js'
compiledValueSnapshot?: string
compiledContent?: ArrayBuffer | null
compiledWatContent?: string | null
diff --git a/utils/setHook.ts b/utils/setHook.ts
index 2a0e562..db441db 100644
--- a/utils/setHook.ts
+++ b/utils/setHook.ts
@@ -11,6 +11,7 @@ export type SetHookData = {
value: keyof TTS
label: string
}[]
+ JSHookFee?: string
Fee: string
HookNamespace: string
HookParameters: {
@@ -90,4 +91,4 @@ export function fromHex(hex: string) {
str += String.fromCharCode(parseInt(hex.substring(i, i + 2), 16))
}
return str
-}
\ No newline at end of file
+}
diff --git a/yarn.lock b/yarn.lock
index a5192a9..9e95323 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -64,6 +64,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.20.13":
+ version "7.26.7"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.7.tgz#f4e7fe527cd710f8dc0618610b61b4b060c3c341"
+ integrity sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
"@babel/types@^7.16.7":
version "7.17.0"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz"
@@ -530,10 +537,10 @@
"@octokit/webhooks-types" "5.2.0"
aggregate-error "^3.1.0"
-"@panva/hkdf@^1.0.1":
- version "1.0.1"
- resolved "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.0.1.tgz"
- integrity sha512-mMyQ9vjpuFqePkfe5bZVIf/H3Dmk6wA8Kjxff9RcO4kqzJo+Ek9pGKwZHpeMr7Eku0QhLXMCd7fNCSnEnRMubg==
+"@panva/hkdf@^1.0.2":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.2.1.tgz#cb0d111ef700136f4580349ff0226bf25c853f23"
+ integrity sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==
"@radix-ui/colors@^0.1.7":
version "0.1.8"
@@ -929,6 +936,11 @@
resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz"
integrity sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==
+"@sindresorhus/merge-streams@^2.1.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958"
+ integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==
+
"@stitches/react@^1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@stitches/react/-/react-1.2.8.tgz#954f8008be8d9c65c4e58efa0937f32388ce3a38"
@@ -980,6 +992,11 @@
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz"
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
+"@types/json-schema@^7.0.9":
+ version "7.0.15"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
+ integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
+
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
@@ -1206,11 +1223,25 @@ aggregate-error@^3.1.0:
clean-stack "^2.0.0"
indent-string "^4.0.0"
+ajv-formats@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
+ integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==
+ dependencies:
+ ajv "^8.0.0"
+
ajv-keywords@^3.5.2:
version "3.5.2"
resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
+ajv-keywords@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16"
+ integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+
ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
@@ -1221,6 +1252,16 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
+ajv@^8.0.0, ajv@^8.9.0:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6"
+ integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+ fast-uri "^3.0.1"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
+
ajv@^8.0.1:
version "8.10.0"
resolved "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz"
@@ -1485,6 +1526,13 @@ braces@^3.0.1:
dependencies:
fill-range "^7.0.1"
+braces@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
+ integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
+ dependencies:
+ fill-range "^7.1.1"
+
brorand@^1.0.1, brorand@^1.0.5, brorand@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz"
@@ -1832,10 +1880,22 @@ convert-source-map@~1.1.0:
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860"
integrity sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==
-cookie@^0.4.1:
- version "0.4.2"
- resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
- integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
+cookie@^0.7.0:
+ version "0.7.2"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7"
+ integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==
+
+copy-webpack-plugin@^12.0.2:
+ version "12.0.2"
+ resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz#935e57b8e6183c82f95bd937df658a59f6a2da28"
+ integrity sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==
+ dependencies:
+ fast-glob "^3.3.2"
+ glob-parent "^6.0.1"
+ globby "^14.0.0"
+ normalize-path "^3.0.0"
+ schema-utils "^4.2.0"
+ serialize-javascript "^6.0.2"
core-js-pure@^3.20.2:
version "3.21.1"
@@ -2223,6 +2283,11 @@ es6-symbol@^3.1.1, es6-symbol@^3.1.3:
d "^1.0.1"
ext "^1.1.2"
+esbuild-wasm@^0.24.2:
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.24.2.tgz#1ab3b4b858ecf226a3c1a63455358ecea704c500"
+ integrity sha512-03/7Z1gD+ohDnScFztvI4XddTAbKVmMEzCvvkBpQdWKEXJ+73dTyeNrmdxP1Q0zpDMFjzUJwtK4rLjqwiHbzkw==
+
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
@@ -2492,6 +2557,17 @@ fast-glob@^3.2.9:
merge2 "^1.3.0"
micromatch "^4.0.4"
+fast-glob@^3.3.2, fast-glob@^3.3.3:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818"
+ integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.8"
+
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
@@ -2512,6 +2588,11 @@ fast-safe-stringify@^2.0.7:
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
+fast-uri@^3.0.1:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748"
+ integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==
+
fastq@^1.6.0:
version "1.13.0"
resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz"
@@ -2548,6 +2629,13 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
+fill-range@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
+ integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
+ dependencies:
+ to-regex-range "^5.0.1"
+
find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz"
@@ -2648,6 +2736,13 @@ glob-parent@^5.1.2:
dependencies:
is-glob "^4.0.1"
+glob-parent@^6.0.1:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
+ integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
+ dependencies:
+ is-glob "^4.0.3"
+
glob-to-regexp@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz"
@@ -2708,6 +2803,18 @@ globby@^11.0.3:
merge2 "^1.4.1"
slash "^3.0.0"
+globby@^14.0.0:
+ version "14.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-14.1.0.tgz#138b78e77cf5a8d794e327b15dce80bf1fb0a73e"
+ integrity sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==
+ dependencies:
+ "@sindresorhus/merge-streams" "^2.1.0"
+ fast-glob "^3.3.3"
+ ignore "^7.0.3"
+ path-type "^6.0.0"
+ slash "^5.1.0"
+ unicorn-magic "^0.3.0"
+
goober@^2.1.1:
version "2.1.8"
resolved "https://registry.npmjs.org/goober/-/goober-2.1.8.tgz"
@@ -2828,6 +2935,11 @@ ignore@^5.2.0:
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
+ignore@^7.0.3:
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.3.tgz#397ef9315dfe0595671eefe8b633fec6943ab733"
+ integrity sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==
+
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz"
@@ -3122,10 +3234,10 @@ javascript-time-ago@^2.3.11:
dependencies:
relative-time-format "^1.0.7"
-jose@^4.1.4, jose@^4.3.7:
- version "4.10.0"
- resolved "https://registry.yarnpkg.com/jose/-/jose-4.10.0.tgz#2e0b7bcc80dd0775f8a4588e55beb9460c37d60a"
- integrity sha512-KEhB/eLGLomWGPTb+/RNbYsTjIyx03JmbqAyIyiXBuNSa7CmNrJd5ysFhblayzs/e/vbOPMUaLnjHUMhGp4yLw==
+jose@^4.15.5, jose@^4.15.9:
+ version "4.15.9"
+ resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.9.tgz#9b68eda29e9a0614c042fa29387196c7dd800100"
+ integrity sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
@@ -3671,6 +3783,14 @@ micromatch@^4.0.2, micromatch@^4.0.4:
braces "^3.0.1"
picomatch "^2.2.3"
+micromatch@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
+ integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
+ dependencies:
+ braces "^3.0.3"
+ picomatch "^2.3.1"
+
miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
@@ -3772,17 +3892,17 @@ natural-compare@^1.4.0:
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-next-auth@^4.10.3:
- version "4.10.3"
- resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.10.3.tgz#0a952dd5004fd2ac2ba414c990922cf9b33951a3"
- integrity sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ==
+next-auth@^4.24.11:
+ version "4.24.11"
+ resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.24.11.tgz#16eeb76d37fbc8fe887561b454f8167f490c381f"
+ integrity sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==
dependencies:
- "@babel/runtime" "^7.16.3"
- "@panva/hkdf" "^1.0.1"
- cookie "^0.4.1"
- jose "^4.3.7"
+ "@babel/runtime" "^7.20.13"
+ "@panva/hkdf" "^1.0.2"
+ cookie "^0.7.0"
+ jose "^4.15.5"
oauth "^0.9.15"
- openid-client "^5.1.0"
+ openid-client "^5.4.0"
preact "^10.6.3"
preact-render-to-string "^5.1.19"
uuid "^8.3.2"
@@ -3842,6 +3962,11 @@ node-gyp-build@^4.3.0:
resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz"
integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==
+normalize-path@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
+ integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
normalize-url@^7.0.2:
version "7.0.3"
resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-7.0.3.tgz"
@@ -3857,9 +3982,9 @@ object-assign@^4.1.1:
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-object-hash@^2.0.1:
+object-hash@^2.2.0:
version "2.2.0"
- resolved "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
object-inspect@^1.11.0, object-inspect@^1.9.0:
@@ -3939,10 +4064,10 @@ octokit@^1.7.0:
"@octokit/plugin-throttling" "^3.5.1"
"@octokit/types" "^6.26.0"
-oidc-token-hash@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz"
- integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==
+oidc-token-hash@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz#9a229f0a1ce9d4fc89bcaee5478c97a889e7b7b6"
+ integrity sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==
once@^1.3.0, once@^1.4.0:
version "1.4.0"
@@ -3959,15 +4084,15 @@ open@^7.4.2:
is-docker "^2.0.0"
is-wsl "^2.1.1"
-openid-client@^5.1.0:
- version "5.1.4"
- resolved "https://registry.npmjs.org/openid-client/-/openid-client-5.1.4.tgz"
- integrity sha512-36/PZY3rDgiIFj2uCL9a1fILPmIwu3HksoWO4mukgXe74ZOsEisJMMqTMfmPNw6j/7kO0mBc2xqy4eYRrB8xPA==
+openid-client@^5.4.0:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.7.1.tgz#34cace862a3e6472ed7d0a8616ef73b7fb85a9c3"
+ integrity sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==
dependencies:
- jose "^4.1.4"
+ jose "^4.15.9"
lru-cache "^6.0.0"
- object-hash "^2.0.1"
- oidc-token-hash "^5.0.1"
+ object-hash "^2.2.0"
+ oidc-token-hash "^5.0.3"
optionator@^0.9.1:
version "0.9.1"
@@ -4114,6 +4239,11 @@ path-type@^4.0.0:
resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+path-type@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-6.0.0.tgz#2f1bb6791a91ce99194caede5d6c5920ed81eb51"
+ integrity sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==
+
pbkdf2@^3.0.3, pbkdf2@^3.0.9:
version "3.1.2"
resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz"
@@ -4140,7 +4270,7 @@ picocolors@^1.0.0:
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
-picomatch@^2.2.3:
+picomatch@^2.2.3, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -4269,7 +4399,7 @@ raf@^3.4.1:
dependencies:
performance-now "^2.1.0"
-randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
+randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
@@ -4489,6 +4619,11 @@ regenerator-runtime@^0.13.4:
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
+regenerator-runtime@^0.14.0:
+ version "0.14.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
+ integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
+
regexify-string@^1.0.17:
version "1.0.17"
resolved "https://registry.npmjs.org/regexify-string/-/regexify-string-1.0.17.tgz"
@@ -4731,6 +4866,16 @@ schema-utils@^3.0.0:
ajv "^6.12.5"
ajv-keywords "^3.5.2"
+schema-utils@^4.2.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.0.tgz#3b669f04f71ff2dfb5aba7ce2d5a9d79b35622c0"
+ integrity sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==
+ dependencies:
+ "@types/json-schema" "^7.0.9"
+ ajv "^8.9.0"
+ ajv-formats "^2.1.1"
+ ajv-keywords "^5.1.0"
+
semver@^5.5.0, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
@@ -4748,6 +4893,13 @@ semver@^7.2.1, semver@^7.3.4, semver@^7.3.5:
dependencies:
lru-cache "^6.0.0"
+serialize-javascript@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2"
+ integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
+ dependencies:
+ randombytes "^2.1.0"
+
set-immediate-shim@~1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz"
@@ -4821,6 +4973,11 @@ slash@^3.0.0:
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+slash@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce"
+ integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==
+
slice-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz"
@@ -5166,10 +5323,10 @@ typeforce@^1.11.5:
resolved "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz"
integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==
-typescript@4.4.4:
- version "4.4.4"
- resolved "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz"
- integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
+typescript@^4.9.5:
+ version "4.9.5"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
+ integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
umd@^3.0.0:
version "3.0.3"
@@ -5197,6 +5354,11 @@ undeclared-identifiers@^1.1.2:
simple-concat "^1.0.0"
xtend "^4.0.1"
+unicorn-magic@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz#4efd45c85a69e0dd576d25532fbfa22aa5c8a104"
+ integrity sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==
+
unified@^10.0.0:
version "10.1.2"
resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df"