parent
eb7991a36d
commit
c1dd4d748e
@ -1,17 +1,23 @@ |
|||||||
import React from "react" |
import React from "react"; |
||||||
import { PluginApi, IRemixApi, Api, PluginClient, CompilationResult } from "@remixproject/plugin" |
import { |
||||||
|
PluginApi, |
||||||
|
IRemixApi, |
||||||
|
Api, |
||||||
|
PluginClient, |
||||||
|
CompilationResult, |
||||||
|
} from "@remixproject/plugin"; |
||||||
|
|
||||||
import { ContractName, Documentation, PublishedSite } from "./types" |
import { ContractName, Documentation, PublishedSite } from "./types"; |
||||||
|
|
||||||
export const AppContext = React.createContext({ |
export const AppContext = React.createContext({ |
||||||
clientInstance: {} as PluginApi<Readonly<IRemixApi>> & |
clientInstance: {} as PluginApi<Readonly<IRemixApi>> & |
||||||
PluginClient<Api, Readonly<IRemixApi>>, |
PluginClient<Api, Readonly<IRemixApi>>, |
||||||
contracts: new Map<ContractName, Documentation>(), |
contracts: new Map<ContractName, Documentation>(), |
||||||
setContracts: (contracts: Map<ContractName, Documentation>) => { |
setContracts: (contracts: Map<ContractName, Documentation>) => { |
||||||
console.log("Calling Set Contract Names") |
console.log("Calling Set Contract Names"); |
||||||
}, |
}, |
||||||
sites: [], |
sites: [], |
||||||
setSites: (sites: PublishedSite[]) => { |
setSites: (sites: PublishedSite[]) => { |
||||||
console.log("Calling Set Sites") |
console.log("Calling Set Sites"); |
||||||
} |
}, |
||||||
}) |
}); |
||||||
|
@ -1,11 +1,11 @@ |
|||||||
import React from 'react'; |
import React from "react"; |
||||||
import ReactDOM from 'react-dom'; |
import ReactDOM from "react-dom"; |
||||||
import App from './App'; |
import App from "./App"; |
||||||
import { Routes } from './routes' |
import { Routes } from "./routes"; |
||||||
|
|
||||||
ReactDOM.render( |
ReactDOM.render( |
||||||
<React.StrictMode> |
<React.StrictMode> |
||||||
<App /> |
<App /> |
||||||
</React.StrictMode>, |
</React.StrictMode>, |
||||||
document.getElementById('root') |
document.getElementById("root") |
||||||
); |
); |
||||||
|
@ -1,36 +1,31 @@ |
|||||||
import React from "react" |
import React from "react"; |
||||||
import { |
import { |
||||||
BrowserRouter as Router, |
BrowserRouter as Router, |
||||||
Switch, |
Switch, |
||||||
Route, |
Route, |
||||||
RouteProps, |
RouteProps, |
||||||
} from "react-router-dom" |
} from "react-router-dom"; |
||||||
|
|
||||||
import { ErrorView, HomeView } from "./views" |
import { ErrorView, HomeView } from "./views"; |
||||||
|
|
||||||
interface Props extends RouteProps { |
interface Props extends RouteProps { |
||||||
component: any // TODO: new (props: any) => React.Component
|
component: any; // TODO: new (props: any) => React.Component
|
||||||
from: string |
from: string; |
||||||
} |
} |
||||||
|
|
||||||
const CustomRoute = ({ component: Component, ...rest }: Props) => { |
const CustomRoute = ({ component: Component, ...rest }: Props) => { |
||||||
return ( |
return ( |
||||||
<Route |
<Route {...rest} render={(matchProps) => <Component {...matchProps} />} /> |
||||||
{...rest} |
); |
||||||
render={(matchProps) => ( |
}; |
||||||
<Component {...matchProps} /> |
|
||||||
)} |
|
||||||
/> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
export const Routes = () => ( |
export const Routes = () => ( |
||||||
<Router> |
<Router> |
||||||
<Switch> |
<Switch> |
||||||
<CustomRoute exact path="/" component={HomeView} from="/" /> |
<CustomRoute exact path="/" component={HomeView} from="/" /> |
||||||
<Route path="/error"> |
<Route path="/error"> |
||||||
<ErrorView /> |
<ErrorView /> |
||||||
</Route> |
</Route> |
||||||
</Switch> |
</Switch> |
||||||
</Router> |
</Router> |
||||||
) |
); |
||||||
|
@ -1,30 +1,30 @@ |
|||||||
import { CompiledContract, ABIParameter } from '@remixproject/plugin' |
import { CompiledContract, ABIParameter } from "@remixproject/plugin"; |
||||||
|
|
||||||
import sampleData from './sample-data/sample-artifact.json' |
import sampleData from "./sample-data/sample-artifact.json"; |
||||||
import sampleDataWithComments from './sample-data/sample-artifact-with-comments.json' |
import sampleDataWithComments from "./sample-data/sample-artifact-with-comments.json"; |
||||||
|
|
||||||
export const buildFakeArtifact: () => CompiledContract = () => { |
export const buildFakeArtifact: () => CompiledContract = () => { |
||||||
const result = sampleData as never as CompiledContract |
const result = (sampleData as never) as CompiledContract; |
||||||
return result |
return result; |
||||||
} |
}; |
||||||
|
|
||||||
export const buildFakeArtifactWithComments: () => CompiledContract = () => { |
export const buildFakeArtifactWithComments: () => CompiledContract = () => { |
||||||
const result = sampleDataWithComments as never as CompiledContract |
const result = (sampleDataWithComments as never) as CompiledContract; |
||||||
return result |
return result; |
||||||
} |
}; |
||||||
|
|
||||||
export const buildFakeABIParameter: () => ABIParameter = () => { |
export const buildFakeABIParameter: () => ABIParameter = () => { |
||||||
return { |
return { |
||||||
internalType: "address", |
internalType: "address", |
||||||
name: "allocator", |
name: "allocator", |
||||||
type: "address" |
type: "address", |
||||||
} |
}; |
||||||
} |
}; |
||||||
|
|
||||||
export const buildFakeABIParameterWithDocumentation: () => ABIParameter = () => { |
export const buildFakeABIParameterWithDocumentation: () => ABIParameter = () => { |
||||||
return { |
return { |
||||||
internalType: "address", |
internalType: "address", |
||||||
name: "allocator", |
name: "allocator", |
||||||
type: "address" |
type: "address", |
||||||
} |
}; |
||||||
} |
}; |
||||||
|
@ -1,2 +1,2 @@ |
|||||||
export * from './utils' |
export * from "./utils"; |
||||||
export * from './publisher' |
export * from "./publisher"; |
||||||
|
@ -1,13 +1,18 @@ |
|||||||
import { HTMLContent } from "./types"; |
import { HTMLContent } from "./types"; |
||||||
|
|
||||||
const IpfsClient = require('ipfs-mini') |
// tslint:disable-next-line
|
||||||
|
const IpfsClient = require("ipfs-mini"); |
||||||
|
|
||||||
export const publish = async (content: HTMLContent) => { |
export const publish = async (content: HTMLContent) => { |
||||||
const ipfs = new IpfsClient({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' }); |
const ipfs = new IpfsClient({ |
||||||
|
host: "ipfs.infura.io", |
||||||
|
port: 5001, |
||||||
|
protocol: "https", |
||||||
|
}); |
||||||
|
|
||||||
const documentHash = await ipfs.add(content) |
const documentHash = await ipfs.add(content); |
||||||
|
|
||||||
console.log("Document hash", documentHash) |
console.log("Document hash", documentHash); |
||||||
|
|
||||||
return documentHash |
return documentHash; |
||||||
} |
}; |
||||||
|
@ -1,36 +1,41 @@ |
|||||||
import { UserMethodDoc, DevMethodDoc, DeveloperDocumentation, UserDocumentation } from "@remixproject/plugin"; |
import { |
||||||
|
UserMethodDoc, |
||||||
|
DevMethodDoc, |
||||||
|
DeveloperDocumentation, |
||||||
|
UserDocumentation, |
||||||
|
} from "@remixproject/plugin"; |
||||||
|
|
||||||
export interface MethodsDocumentation { |
export interface MethodsDocumentation { |
||||||
[x: string]: UserMethodDoc | DevMethodDoc |
[x: string]: UserMethodDoc | DevMethodDoc; |
||||||
} |
} |
||||||
|
|
||||||
export interface ContractDocumentation { |
export interface ContractDocumentation { |
||||||
methods: MethodsDocumentation; |
methods: MethodsDocumentation; |
||||||
author: string; |
author: string; |
||||||
title: string; |
title: string; |
||||||
details: string; |
details: string; |
||||||
notice: string; |
notice: string; |
||||||
} |
} |
||||||
|
|
||||||
export type MethodDoc = DevMethodDoc & UserMethodDoc |
export type MethodDoc = DevMethodDoc & UserMethodDoc; |
||||||
|
|
||||||
export type TemplateDoc<T> = { [key in keyof T]: (...params: any[]) => string } |
export type TemplateDoc<T> = { [key in keyof T]: (...params: any[]) => string }; |
||||||
|
|
||||||
// Contract
|
// Contract
|
||||||
export type ContractDoc = DeveloperDocumentation & UserDocumentation |
export type ContractDoc = DeveloperDocumentation & UserDocumentation; |
||||||
|
|
||||||
export interface FunctionDocumentation { |
export interface FunctionDocumentation { |
||||||
name: string |
name: string; |
||||||
type: string |
type: string; |
||||||
devdoc?: Partial<MethodDoc> |
devdoc?: Partial<MethodDoc>; |
||||||
inputs: ParameterDocumentation[] |
inputs: ParameterDocumentation[]; |
||||||
outputs: ParameterDocumentation[] |
outputs: ParameterDocumentation[]; |
||||||
} |
} |
||||||
|
|
||||||
export interface ParameterDocumentation { |
export interface ParameterDocumentation { |
||||||
name: string |
name: string; |
||||||
type: string |
type: string; |
||||||
description: string |
description: string; |
||||||
} |
} |
||||||
|
|
||||||
export type HTMLContent = string |
export type HTMLContent = string; |
||||||
|
@ -1,93 +1,99 @@ |
|||||||
const open = require('open') |
// tslint:disable-next-line
|
||||||
|
const open = require("open"); |
||||||
import { getContractDoc, mergeParametersWithDevdoc, getFunctionDocumentation, getContractDocumentation } from './utils'; |
|
||||||
import { FunctionDescription } from '@remixproject/plugin'; |
import { |
||||||
import { buildFakeArtifactWithComments, buildFakeABIParameter } from './faker' |
getContractDoc, |
||||||
|
mergeParametersWithDevdoc, |
||||||
jest.setTimeout(10000) |
getFunctionDocumentation, |
||||||
|
getContractDocumentation, |
||||||
describe('Publisher tests', () => { |
} from "./utils"; |
||||||
|
import { FunctionDescription } from "@remixproject/plugin"; |
||||||
describe('getContractDocumentation', () => { |
import { buildFakeArtifactWithComments, buildFakeABIParameter } from "./faker"; |
||||||
test('getContractDocumentation', () => { |
|
||||||
const result = getContractDocumentation(buildFakeArtifactWithComments()) |
jest.setTimeout(10000); |
||||||
|
|
||||||
const result2 = { |
describe("Publisher tests", () => { |
||||||
methods: |
describe("getContractDocumentation", () => { |
||||||
{ |
test("getContractDocumentation", () => { |
||||||
'age(uint256)': |
const result = getContractDocumentation(buildFakeArtifactWithComments()); |
||||||
{ |
|
||||||
author: 'Mary A. Botanist', |
const result2 = { |
||||||
details: |
methods: { |
||||||
'The Alexandr N. Tetearing algorithm could increase precision', |
"age(uint256)": { |
||||||
params: [Object], |
author: "Mary A. Botanist", |
||||||
return: 'age in years, rounded up for partial years' |
details: |
||||||
} |
"The Alexandr N. Tetearing algorithm could increase precision", |
||||||
}, |
params: [Object], |
||||||
notice: |
return: "age in years, rounded up for partial years", |
||||||
'You can use this contract for only the most basic simulation', |
}, |
||||||
author: 'Larry A. Gardner', |
}, |
||||||
details: |
notice: "You can use this contract for only the most basic simulation", |
||||||
'All function calls are currently implemented without side effects', |
author: "Larry A. Gardner", |
||||||
title: 'A simulator for trees' |
details: |
||||||
} |
"All function calls are currently implemented without side effects", |
||||||
|
title: "A simulator for trees", |
||||||
expect(result).toBeDefined() |
}; |
||||||
}) |
|
||||||
}) |
expect(result).toBeDefined(); |
||||||
|
}); |
||||||
describe('getContractDoc', () => { |
}); |
||||||
test('getContractDoc', () => { |
|
||||||
|
describe("getContractDoc", () => { |
||||||
const template = getContractDoc("Fallout", buildFakeArtifactWithComments()); |
test("getContractDoc", () => { |
||||||
|
const template = getContractDoc( |
||||||
console.log("Template", template) |
"Fallout", |
||||||
|
buildFakeArtifactWithComments() |
||||||
expect(template).toBeDefined() |
); |
||||||
}) |
|
||||||
}) |
console.log("Template", template); |
||||||
|
|
||||||
describe('getFunctionDocumentation', () => { |
expect(template).toBeDefined(); |
||||||
test('getFunctionDocumentation', () => { |
}); |
||||||
const abiItem: FunctionDescription = { |
}); |
||||||
constant: false, |
|
||||||
inputs: [], |
describe("getFunctionDocumentation", () => { |
||||||
name: "Fal1out", |
test("getFunctionDocumentation", () => { |
||||||
outputs: [], |
const abiItem: FunctionDescription = { |
||||||
payable: true, |
constant: false, |
||||||
stateMutability: "payable", |
inputs: [], |
||||||
type: "function" |
name: "Fal1out", |
||||||
} |
outputs: [], |
||||||
|
payable: true, |
||||||
const result = getFunctionDocumentation(abiItem, {}) |
stateMutability: "payable", |
||||||
|
type: "function", |
||||||
expect(result).toBeDefined() |
}; |
||||||
}) |
|
||||||
}) |
const result = getFunctionDocumentation(abiItem, {}); |
||||||
|
|
||||||
describe('mergeParametersWithDevdoc', () => { |
expect(result).toBeDefined(); |
||||||
test('mergeParametersWithDevdoc', () => { |
}); |
||||||
const abiParameters = [buildFakeABIParameter()] |
}); |
||||||
const devParams = {} |
|
||||||
const result = mergeParametersWithDevdoc(abiParameters, devParams) |
describe("mergeParametersWithDevdoc", () => { |
||||||
|
test("mergeParametersWithDevdoc", () => { |
||||||
expect(result.length).toEqual(1) |
const abiParameters = [buildFakeABIParameter()]; |
||||||
}) |
const devParams = {}; |
||||||
|
const result = mergeParametersWithDevdoc(abiParameters, devParams); |
||||||
test('mergeParametersWithDevdoc with documentation', () => { |
|
||||||
const abiParameters = [buildFakeABIParameter()] |
expect(result.length).toEqual(1); |
||||||
const devParams = {} |
}); |
||||||
const result = mergeParametersWithDevdoc(abiParameters, devParams) |
|
||||||
|
test("mergeParametersWithDevdoc with documentation", () => { |
||||||
expect(result.length).toEqual(1) |
const abiParameters = [buildFakeABIParameter()]; |
||||||
}) |
const devParams = {}; |
||||||
}) |
const result = mergeParametersWithDevdoc(abiParameters, devParams); |
||||||
|
|
||||||
|
expect(result.length).toEqual(1); |
||||||
test.skip('html generation', async () => { |
}); |
||||||
await open('https://ipfs.io/ipfs/QmPYQyWyTrUZt3tjiPsEnkRQxedChYUjgEk9zLQ36SfpyW', { app: ['google chrome', '--incognito'] }); |
}); |
||||||
// start server
|
|
||||||
// generate html
|
test.skip("html generation", async () => { |
||||||
// server it
|
await open( |
||||||
}) |
"https://ipfs.io/ipfs/QmPYQyWyTrUZt3tjiPsEnkRQxedChYUjgEk9zLQ36SfpyW", |
||||||
}) |
{ app: ["google chrome", "--incognito"] } |
||||||
|
); |
||||||
|
// start server
|
||||||
|
// generate html
|
||||||
|
// server it
|
||||||
|
}); |
||||||
|
}); |
||||||
|
@ -1,94 +1,130 @@ |
|||||||
import { CompilationResult, CompiledContract, FunctionDescription, ABIDescription, DevMethodDoc, UserMethodDoc, ABIParameter, DeveloperDocumentation, UserDocumentation } from "@remixproject/plugin" |
import { |
||||||
|
CompilationResult, |
||||||
import { EthDocumentation, FileName, Documentation, ContractName } from '../types' |
CompiledContract, |
||||||
import { template } from './template' |
FunctionDescription, |
||||||
import { ContractDocumentation, MethodDoc, FunctionDocumentation, ParameterDocumentation, MethodsDocumentation } from './types' |
ABIDescription, |
||||||
|
DevMethodDoc, |
||||||
export const createDocumentation = (fileName: FileName, compilationResult: CompilationResult) => { |
UserMethodDoc, |
||||||
console.log("Filename", fileName) |
ABIParameter, |
||||||
const result = new Map<ContractName, Documentation>(); |
DeveloperDocumentation, |
||||||
|
UserDocumentation, |
||||||
const contracts = compilationResult.contracts[fileName] |
} from "@remixproject/plugin"; |
||||||
console.log("Contracts", contracts) |
|
||||||
|
import { |
||||||
Object.keys(contracts).forEach((name) => { |
EthDocumentation, |
||||||
console.log("CompiledContract", JSON.stringify(contracts[name])) |
FileName, |
||||||
result.set(name, getContractDoc(name, contracts[name])) |
Documentation, |
||||||
}) |
ContractName, |
||||||
|
} from "../types"; |
||||||
return result |
import { template } from "./template"; |
||||||
} |
import { |
||||||
|
ContractDocumentation, |
||||||
|
MethodDoc, |
||||||
|
FunctionDocumentation, |
||||||
|
ParameterDocumentation, |
||||||
|
MethodsDocumentation, |
||||||
|
} from "./types"; |
||||||
|
|
||||||
|
export const createDocumentation = ( |
||||||
|
fileName: FileName, |
||||||
|
compilationResult: CompilationResult |
||||||
|
) => { |
||||||
|
console.log("Filename", fileName); |
||||||
|
const result = new Map<ContractName, Documentation>(); |
||||||
|
|
||||||
|
const contracts = compilationResult.contracts[fileName]; |
||||||
|
console.log("Contracts", contracts); |
||||||
|
|
||||||
|
Object.keys(contracts).forEach((name) => { |
||||||
|
console.log("CompiledContract", JSON.stringify(contracts[name])); |
||||||
|
result.set(name, getContractDoc(name, contracts[name])); |
||||||
|
}); |
||||||
|
|
||||||
|
return result; |
||||||
|
}; |
||||||
|
|
||||||
export const getContractDoc = (name: string, contract: CompiledContract) => { |
export const getContractDoc = (name: string, contract: CompiledContract) => { |
||||||
const contractDoc: ContractDocumentation = getContractDocumentation(contract) |
const contractDoc: ContractDocumentation = getContractDocumentation(contract); |
||||||
|
|
||||||
const functionsDocumentation = contract.abi |
const functionsDocumentation = contract.abi.map((def: ABIDescription) => { |
||||||
.map((def: ABIDescription) => { |
if (def.type === "constructor") { |
||||||
if (def.type === 'constructor') { |
def.name = "constructor"; |
||||||
def.name = 'constructor' |
// because "constructor" is a string and not a { notice } object for userdoc we need to do that
|
||||||
// because "constructor" is a string and not a { notice } object for userdoc we need to do that
|
const methodDoc = { |
||||||
const methodDoc = { |
...(contract.devdoc.methods.constructor || {}), |
||||||
...(contract.devdoc.methods.constructor || {}), |
notice: contract.userdoc.methods.constructor as string, |
||||||
notice: contract.userdoc.methods.constructor as string |
}; |
||||||
} |
return getFunctionDocumentation(def, methodDoc); |
||||||
return getFunctionDocumentation(def, methodDoc) |
} else { |
||||||
} else { |
if (def.type === "fallback") { |
||||||
if (def.type === 'fallback') { |
def.name = "fallback"; |
||||||
def.name = 'fallback' |
} |
||||||
} |
const method = Object.keys(contractDoc.methods).find((key) => |
||||||
const method = Object.keys(contractDoc.methods).find((key) => key.includes(def.name as string)) as string |
key.includes(def.name as string) |
||||||
const methodDoc = contractDoc.methods[method] |
) as string; |
||||||
return getFunctionDocumentation(def as FunctionDescription, methodDoc) |
const methodDoc = contractDoc.methods[method]; |
||||||
} |
return getFunctionDocumentation(def as FunctionDescription, methodDoc); |
||||||
}) |
} |
||||||
|
}); |
||||||
return template(name, contractDoc, functionsDocumentation) |
|
||||||
} |
return template(name, contractDoc, functionsDocumentation); |
||||||
|
}; |
||||||
|
|
||||||
export const getContractDocumentation = (contract: CompiledContract) => { |
export const getContractDocumentation = (contract: CompiledContract) => { |
||||||
let methods: MethodsDocumentation = {}; |
const methods: MethodsDocumentation = {}; |
||||||
|
|
||||||
Object.keys(contract.userdoc.methods).map((item) => { |
Object.keys(contract.userdoc.methods).map((item) => { |
||||||
if (contract.devdoc.methods[item]) { |
if (contract.devdoc.methods[item]) { |
||||||
const finalResult = { |
const finalResult = { |
||||||
...contract.userdoc.methods[item], |
...contract.userdoc.methods[item], |
||||||
...contract.devdoc.methods[item] |
...contract.devdoc.methods[item], |
||||||
} |
}; |
||||||
methods[item] = finalResult |
methods[item] = finalResult; |
||||||
} else { |
} else { |
||||||
methods[item] = contract.userdoc.methods[item] |
methods[item] = contract.userdoc.methods[item]; |
||||||
} |
} |
||||||
}) |
}); |
||||||
|
|
||||||
const contractDoc = { ...contract.userdoc, ...contract.devdoc, methods } |
const contractDoc = { ...contract.userdoc, ...contract.devdoc, methods }; |
||||||
|
|
||||||
return contractDoc |
return contractDoc; |
||||||
} |
}; |
||||||
|
|
||||||
export const getFunctionDocumentation = (def: FunctionDescription, devdoc?: Partial<MethodDoc>) => { |
export const getFunctionDocumentation = ( |
||||||
const doc = devdoc || {} |
def: FunctionDescription, |
||||||
const devparams = doc.params || {} |
devdoc?: Partial<MethodDoc> |
||||||
const inputsWithDescription = mergeParametersWithDevdoc(def.inputs || [], devparams) |
) => { |
||||||
const outputsWithDescription = mergeParametersWithDevdoc(def.outputs || [], devparams) |
const doc = devdoc || {}; |
||||||
const type = def.constant ? 'view' : 'read' |
const devparams = doc.params || {}; |
||||||
|
const inputsWithDescription = mergeParametersWithDevdoc( |
||||||
|
def.inputs || [], |
||||||
|
devparams |
||||||
|
); |
||||||
|
const outputsWithDescription = mergeParametersWithDevdoc( |
||||||
|
def.outputs || [], |
||||||
|
devparams |
||||||
|
); |
||||||
|
const type = def.constant ? "view" : "read"; |
||||||
|
|
||||||
|
return { |
||||||
|
name: def.name, |
||||||
|
type, |
||||||
|
devdoc, |
||||||
|
inputs: inputsWithDescription, |
||||||
|
outputs: outputsWithDescription, |
||||||
|
} as FunctionDocumentation; |
||||||
|
}; |
||||||
|
|
||||||
|
export const mergeParametersWithDevdoc = ( |
||||||
|
params: ABIParameter[], |
||||||
|
devparams: any |
||||||
|
) => { |
||||||
|
return params.map((input) => { |
||||||
|
const description = devparams[input.name] || ""; |
||||||
return { |
return { |
||||||
name: def.name, |
name: input.name, |
||||||
type, |
type: input.type, |
||||||
devdoc: devdoc, |
description, |
||||||
inputs: inputsWithDescription, |
} as ParameterDocumentation; |
||||||
outputs: outputsWithDescription |
}); |
||||||
} as FunctionDocumentation |
}; |
||||||
} |
|
||||||
|
|
||||||
export const mergeParametersWithDevdoc = (params: ABIParameter[], devparams: any) => { |
|
||||||
return params.map((input) => { |
|
||||||
const description = devparams[input.name] || '' |
|
||||||
return { |
|
||||||
name: input.name, |
|
||||||
type: input.type, |
|
||||||
description |
|
||||||
} as ParameterDocumentation |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@ |
|||||||
export { HomeView } from "./HomeView" |
export { HomeView } from "./HomeView"; |
||||||
export { ErrorView } from "./ErrorView" |
export { ErrorView } from "./ErrorView"; |
||||||
|
Loading…
Reference in new issue