diff --git a/packages/toolpad-app/src/toolpadDataSources/function/execFunction.ts b/packages/toolpad-app/src/toolpadDataSources/function/execFunction.ts index 4fc7a6688fd..daa34d4610a 100644 --- a/packages/toolpad-app/src/toolpadDataSources/function/execFunction.ts +++ b/packages/toolpad-app/src/toolpadDataSources/function/execFunction.ts @@ -4,12 +4,13 @@ import type * as harFormat from 'har-format'; import * as fs from 'fs/promises'; import fetch from 'node-fetch'; import * as path from 'path'; +import { SerializedError } from '@mui/toolpad-core'; import { FunctionResult } from './types'; import { LogEntry } from '../../components/Console'; import { FetchOptions } from './runtime/types'; import projectRoot from '../../server/projectRoot'; import { withHarInstrumentation, createHarLog } from '../../server/har'; -import { errorFrom } from '../../utils/errors'; +import { errorFrom, serializeError } from '../../utils/errors'; async function fetchRuntimeModule() { const filePath = path.resolve(projectRoot, './src/toolpadDataSources/function/dist/index.js'); @@ -118,7 +119,7 @@ export default async function execFunction( await jail.delete('TOOLPAD_BRIDGE'); let data; - let error: Error | undefined; + let error: SerializedError | undefined; try { const { code: userModuleJs } = await esbuild.transform(code, { @@ -151,7 +152,7 @@ export default async function execFunction( }, ); } catch (userError) { - error = errorFrom(userError); + error = serializeError(errorFrom(userError)); } return { data, logs, error, har }; diff --git a/packages/toolpad-app/src/toolpadDataSources/rest/shared.ts b/packages/toolpad-app/src/toolpadDataSources/rest/shared.ts index 4c785aea622..410670f274a 100644 --- a/packages/toolpad-app/src/toolpadDataSources/rest/shared.ts +++ b/packages/toolpad-app/src/toolpadDataSources/rest/shared.ts @@ -4,6 +4,7 @@ import { BindableAttrValues, JsRuntime, Serializable, + SerializedError, } from '@mui/toolpad-core'; import { evaluateBindable } from '@mui/toolpad-core/jsRuntime'; import { ensureSuffix, removePrefix } from '../../utils/strings'; @@ -18,7 +19,7 @@ import { UrlEncodedBody, } from './types'; import applyTransform from '../applyTransform'; -import { errorFrom } from '../../utils/errors'; +import { errorFrom, serializeError } from '../../utils/errors'; import { MOVIES_API_DEMO_URL } from '../demo'; export const HTTP_NO_BODY = new Set(['GET', 'HEAD']); @@ -223,7 +224,7 @@ export async function execfetch( } } - let error: Error | undefined; + let error: SerializedError | undefined; let untransformedData; let data; @@ -241,7 +242,7 @@ export async function execfetch( data = await applyTransform(jsRuntime, fetchQuery.transform, untransformedData); } } catch (rawError) { - error = errorFrom(rawError); + error = serializeError(errorFrom(rawError)); } return { data, untransformedData, error }; diff --git a/packages/toolpad-app/tsconfig.json b/packages/toolpad-app/tsconfig.json index 3a95e4bf143..e2524bae803 100644 --- a/packages/toolpad-app/tsconfig.json +++ b/packages/toolpad-app/tsconfig.json @@ -1,13 +1,14 @@ { "compilerOptions": { "paths": { - // TODO: remove when we move to typescript 4.7 (supports package exports) - "@mui/toolpad-core/runtime": ["../toolpad-core/dist/runtime"], - "@mui/toolpad-core/jsRuntime": ["../toolpad-core/dist/jsRuntime"], - "@mui/toolpad-core/jsBrowserRuntime": ["../toolpad-core/dist/jsBrowserRuntime"], - "@mui/toolpad-core/jsServerRuntime": ["../toolpad-core/dist/jsServerRuntime"], - "@mui/toolpad-core/objectKey": ["../toolpad-core/dist/objectKey"], - "@mui/toolpad-core/utils/*": ["../toolpad-core/dist/utils/*"] + // TODO: remove when typescript module resolution supports package exports. (v5.0 with module: 'bundler' ?) + "@mui/toolpad-core": ["../toolpad-core/dist/esm"], + "@mui/toolpad-core/runtime": ["../toolpad-core/dist/esm/runtime"], + "@mui/toolpad-core/jsRuntime": ["../toolpad-core/dist/esm/jsRuntime"], + "@mui/toolpad-core/jsBrowserRuntime": ["../toolpad-core/dist/esm/jsBrowserRuntime"], + "@mui/toolpad-core/jsServerRuntime": ["../toolpad-core/dist/esm/jsServerRuntime"], + "@mui/toolpad-core/objectKey": ["../toolpad-core/dist/esm/objectKey"], + "@mui/toolpad-core/utils/*": ["../toolpad-core/dist/esm/utils/*"] }, "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], diff --git a/packages/toolpad-components/tsconfig.json b/packages/toolpad-components/tsconfig.json index 6d059a2f066..e0519ff2ff6 100644 --- a/packages/toolpad-components/tsconfig.json +++ b/packages/toolpad-components/tsconfig.json @@ -2,9 +2,10 @@ "extends": "../../tsconfig.json", "compilerOptions": { "paths": { - // TODO: remove when we move to typescript 4.7 (supports package exports) - "@mui/toolpad-core/path": ["../toolpad-core/dist/path"], - "@mui/toolpad-core/objectKey": ["../toolpad-core/dist/objectKey"] + // TODO: remove when typescript module resolution supports package exports. (v5.0 with module: 'bundler' ?) + "@mui/toolpad-core": ["../toolpad-core/dist/esm"], + "@mui/toolpad-core/path": ["../toolpad-core/dist/esm/path"], + "@mui/toolpad-core/objectKey": ["../toolpad-core/dist/esm/objectKey"] }, "module": "esnext", "alwaysStrict": true, diff --git a/packages/toolpad-core/package.json b/packages/toolpad-core/package.json index 0a5145e99d4..e1594e72a3f 100644 --- a/packages/toolpad-core/package.json +++ b/packages/toolpad-core/package.json @@ -5,20 +5,57 @@ "author": "MUI Toolpad team", "homepage": "https://github.com/mui/mui-toolpad#readme", "license": "MIT", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/cjs/index.js", + "module": "dist/esm/index.js", + "types": "dist/esm/index.d.ts", "type": "module", "exports": { "./package.json": "./package.json", - ".": "./dist/index.js", - "./constants": "./dist/constants.js", - "./path": "./dist/path.js", - "./runtime": "./dist/runtime.js", - "./jsRuntime": "./dist/jsRuntime.js", - "./jsServerRuntime": "./dist/jsServerRuntime.js", - "./jsBrowserRuntime": "./dist/jsBrowserRuntime.js", - "./objectKey": "./dist/objectKey.js", - "./utils/*": "./dist/utils/*.js" + ".": { + "types": "./dist/esm/index.d.ts", + "import": "./dist/esm/index.js", + "require": "./dist/cjs/index.js" + }, + "./constants": { + "types": "./dist/esm/constants.d.ts", + "import": "./dist/esm/constants.js", + "require": "./dist/cjs/constants.js" + }, + "./path": { + "types": "./dist/esm/path.d.ts", + "import": "./dist/esm/path.js", + "require": "./dist/cjs/path.js" + }, + "./runtime": { + "types": "./dist/esm/runtime.d.ts", + "import": "./dist/esm/runtime.js", + "require": "./dist/cjs/runtime.js" + }, + "./jsRuntime": { + "types": "./dist/esm/jsRuntime.d.ts", + "import": "./dist/esm/jsRuntime.js", + "require": "./dist/cjs/jsRuntime.js" + }, + "./jsServerRuntime": { + "types": "./dist/esm/jsServerRuntime.d.ts", + "import": "./dist/esm/jsServerRuntime.js", + "require": "./dist/cjs/jsServerRuntime.js" + }, + "./jsBrowserRuntime": { + "types": "./dist/esm/jsBrowserRuntime.d.ts", + "import": "./dist/esm/jsBrowserRuntime.js", + "require": "./dist/cjs/jsBrowserRuntime.js" + }, + "./objectKey": { + "types": "./dist/esm/objectKey.d.ts", + "import": "./dist/esm/objectKey.js", + "require": "./dist/cjs/objectKey.js" + }, + "./utils/*": { + "types": "./dist/esm/utils/*.d.ts", + "import": "./dist/esm/utils/*.js", + "require": "./dist/cjs/utils/*.js" + } }, "files": [ "dist" @@ -29,10 +66,15 @@ }, "scripts": { "prebuild": "rimraf dist", - "build": "tsc", - "dev": "tsc --pretty --watch --preserveWatchOutput", + "cjsify": "mkdir -p ./dist/cjs && echo \"{ \\\"type\\\":\\\"commonjs\\\" }\" > ./dist/cjs/package.json", + "build": "concurrently \"yarn:build:*\" && yarn cjsify", + "build:esm": "tsc --outDir dist/esm --module esnext", + "build:cjs": "tsc --outDir dist/cjs --module commonjs", + "dev": "concurrently \"yarn:dev:*\" yarn:cjsify", + "dev:esm": "yarn build:esm --pretty --watch --preserveWatchOutput", + "dev:cjs": "yarn build:cjs --pretty --watch --preserveWatchOutput", "test": "echo \"Error: run tests from root\" && exit 1", - "check-types": "tsc" + "check-types": "yarn build" }, "bugs": { "url": "https://github.com/mui/mui-toolpad/issues" @@ -44,6 +86,7 @@ "react-error-boundary": "^3.1.4" }, "devDependencies": { + "concurrently": "^7.6.0", "react": "^18.2.0" }, "peerDependencies": { diff --git a/packages/toolpad-core/src/componentsContext.tsx b/packages/toolpad-core/src/componentsContext.tsx index cb1ffe4d6ce..9c0268d7d2f 100644 --- a/packages/toolpad-core/src/componentsContext.tsx +++ b/packages/toolpad-core/src/componentsContext.tsx @@ -1,5 +1,5 @@ -import { ToolpadComponents } from './types'; -import { createProvidedContext } from './utils/react'; +import { ToolpadComponents } from './types.js'; +import { createProvidedContext } from './utils/react.js'; const [useComponents, ComponentsContextProvider] = createProvidedContext('Components'); diff --git a/packages/toolpad-core/src/createComponent.tsx b/packages/toolpad-core/src/createComponent.tsx index 963309c425a..72e3bc80350 100644 --- a/packages/toolpad-core/src/createComponent.tsx +++ b/packages/toolpad-core/src/createComponent.tsx @@ -1,5 +1,5 @@ -import { TOOLPAD_COMPONENT } from './constants'; -import { ComponentConfig, ToolpadComponent } from './types'; +import { TOOLPAD_COMPONENT } from './constants.js'; +import { ComponentConfig, ToolpadComponent } from './types.js'; export default function createComponent

( Component: React.ComponentType

, diff --git a/packages/toolpad-core/src/index.tsx b/packages/toolpad-core/src/index.tsx index 20c1003843d..b5d52e0e0a7 100644 --- a/packages/toolpad-core/src/index.tsx +++ b/packages/toolpad-core/src/index.tsx @@ -5,7 +5,7 @@ export type { NodeErrorProps, Components, } from './runtime'; -export { Placeholder, Slots, useNode, ComponentsContext } from './runtime'; +export { Placeholder, Slots, useNode, ComponentsContext } from './runtime.js'; export type FlowDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse'; @@ -15,6 +15,6 @@ export * from './constants.js'; export { default as createComponent } from './createComponent.js'; -export * from './types'; +export * from './types.js'; -export * from './componentsContext'; +export * from './componentsContext.js'; diff --git a/packages/toolpad-core/src/jsBrowserRuntime.tsx b/packages/toolpad-core/src/jsBrowserRuntime.tsx index a5eb6587d57..e68dbf79d43 100644 --- a/packages/toolpad-core/src/jsBrowserRuntime.tsx +++ b/packages/toolpad-core/src/jsBrowserRuntime.tsx @@ -1,6 +1,6 @@ -import { TOOLPAD_LOADING_MARKER } from './jsRuntime'; -import { BindingEvaluationResult, JsRuntime } from './types'; -import { errorFrom } from './utils/errors'; +import { TOOLPAD_LOADING_MARKER } from './jsRuntime.js'; +import { BindingEvaluationResult, JsRuntime } from './types.js'; +import { errorFrom } from './utils/errors.js'; function createBrowserRuntime(): JsRuntime { let iframe: HTMLIFrameElement; diff --git a/packages/toolpad-core/src/jsRuntime.tsx b/packages/toolpad-core/src/jsRuntime.tsx index 28585c78313..e6acf0e507b 100644 --- a/packages/toolpad-core/src/jsRuntime.tsx +++ b/packages/toolpad-core/src/jsRuntime.tsx @@ -1,4 +1,4 @@ -import { BindableAttrValue, BindingEvaluationResult, JsRuntime } from './types'; +import { BindableAttrValue, BindingEvaluationResult, JsRuntime } from './types.js'; export const TOOLPAD_LOADING_MARKER = '__TOOLPAD_LOADING_MARKER__'; diff --git a/packages/toolpad-core/src/jsServerRuntime.tsx b/packages/toolpad-core/src/jsServerRuntime.tsx index 741dcf3b021..e9d679c20d0 100644 --- a/packages/toolpad-core/src/jsServerRuntime.tsx +++ b/packages/toolpad-core/src/jsServerRuntime.tsx @@ -7,8 +7,8 @@ import { QuickJSRuntime, } from 'quickjs-emscripten'; import * as React from 'react'; -import { BindingEvaluationResult, JsRuntime, Serializable } from './types'; -import { errorFrom } from './utils/errors'; +import { BindingEvaluationResult, JsRuntime, Serializable } from './types.js'; +import { errorFrom } from './utils/errors.js'; const JsRuntimeContext = React.createContext(null); diff --git a/packages/toolpad-core/src/path.ts b/packages/toolpad-core/src/path.ts index 39c6f1f32f8..da4773d4b8f 100644 --- a/packages/toolpad-core/src/path.ts +++ b/packages/toolpad-core/src/path.ts @@ -1,6 +1,6 @@ // TODO: Create a @mui/toolpad-utils package to house utilities like this one? -import { IMAGE_EXTENSIONS } from './constants'; +import { IMAGE_EXTENSIONS } from './constants.js'; export function getExtension(path: string): string { const splitPath = path.split('.'); diff --git a/packages/toolpad-core/src/runtime.tsx b/packages/toolpad-core/src/runtime.tsx index e11d0f0b433..c65e29d6603 100644 --- a/packages/toolpad-core/src/runtime.tsx +++ b/packages/toolpad-core/src/runtime.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; import { ErrorBoundary, FallbackProps } from 'react-error-boundary'; import mitt, { Emitter } from 'mitt'; -import { RuntimeEvents, ToolpadComponents } from './types'; +import { RuntimeEvents, ToolpadComponents } from './types.js'; import { RUNTIME_PROP_NODE_ID, RUNTIME_PROP_SLOTS } from './constants.js'; -import type { SlotType, ComponentConfig, RuntimeEvent, RuntimeError } from './types'; +import type { SlotType, ComponentConfig, RuntimeEvent, RuntimeError } from './types.js'; const ResetNodeErrorsKeyContext = React.createContext(0); diff --git a/packages/toolpad-core/src/types.ts b/packages/toolpad-core/src/types.ts index feec39da5bc..d77945e9971 100644 --- a/packages/toolpad-core/src/types.ts +++ b/packages/toolpad-core/src/types.ts @@ -1,6 +1,6 @@ import type * as React from 'react'; -import type { TOOLPAD_COMPONENT } from './constants'; -import type { Branded } from './utils/types'; +import type { TOOLPAD_COMPONENT } from './constants.js'; +import type { Branded } from './utils/types.js'; export type NodeId = Branded; @@ -328,7 +328,9 @@ export interface RuntimeError { export type FlowDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse'; -export interface SerializedError { +export type PlainObject = Record; + +export interface SerializedError extends PlainObject { message: string; name: string; stack?: string; diff --git a/packages/toolpad-core/src/utils/errors.ts b/packages/toolpad-core/src/utils/errors.ts index fac0e750f76..380d23a7f29 100644 --- a/packages/toolpad-core/src/utils/errors.ts +++ b/packages/toolpad-core/src/utils/errors.ts @@ -1,6 +1,6 @@ -import { SerializedError } from '../types'; -import { hasOwnProperty } from './collections'; -import { truncate } from './strings'; +import { SerializedError } from '../types.js'; +import { hasOwnProperty } from './collections.js'; +import { truncate } from './strings.js'; export function serializeError(error: Error & { code?: unknown }): SerializedError { const { message, name, stack, code } = error;