diff --git a/.changeset/config.json b/.changeset/config.json index f9bfe7d8a3..3abf698da5 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,14 +7,7 @@ "access": "public", "baseBranch": "develop", "updateInternalDependencies": "patch", - "ignore": [ - "integration-tests-api", - "integration-tests-modules", - "@medusajs/dashboard", - "@medusajs/admin-shared", - "@medusajs/admin-bundler", - "@medusajs/vite-plugin-extension" - ], + "ignore": ["integration-tests-api", "integration-tests-modules"], "snapshot": { "useCalculatedVersion": true }, diff --git a/.eslintrc.js b/.eslintrc.js index 43fc335610..e1bccc2377 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -83,6 +83,8 @@ module.exports = { "./packages/medusa/tsconfig.json", "./packages/admin-next/dashboard/tsconfig.json", + "./packages/admin-next/admin-sdk/tsconfig.json", + "./packages/admin-next/admin-vite-plugin/tsconfig.json", "./packages/inventory/tsconfig.spec.json", "./packages/stock-location/tsconfig.spec.json", @@ -267,5 +269,54 @@ module.exports = { ], }, }, + { + files: [ + "packages/admin-next/app/**/*.ts", + "packages/admin-next/app/**/*.tsx", + ], + plugins: ["unused-imports", "react-refresh"], + extends: [ + "plugin:react/recommended", + "plugin:react/jsx-runtime", + "plugin:react-hooks/recommended", + ], + parser: "@typescript-eslint/parser", + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features + sourceType: "module", // Allows for the use of imports + project: "./packages/admin-next/app/tsconfig.json", + }, + globals: { + __BASE__: "readonly", + }, + env: { + browser: true, + }, + rules: { + "prettier/prettier": "error", + "react/prop-types": "off", + "new-cap": "off", + "require-jsdoc": "off", + "valid-jsdoc": "off", + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + "no-unused-expressions": "off", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "warn", + { + vars: "all", + varsIgnorePattern: "^_", + args: "after-used", + argsIgnorePattern: "^_", + }, + ], + }, + }, ], } diff --git a/.github/workflows/test-cli-with-database.yml b/.github/workflows/test-cli-with-database.yml index 9e0bdf7281..d36f3c3d7b 100644 --- a/.github/workflows/test-cli-with-database.yml +++ b/.github/workflows/test-cli-with-database.yml @@ -45,7 +45,7 @@ jobs: uses: ./.github/actions/setup-server with: cache-extension: "cli-test" - node-version: "16.14" + node-version: 18 - name: Install Medusa cli run: npm i -g @medusajs/medusa-cli@preview diff --git a/integration-tests/api/medusa-config.js b/integration-tests/api/medusa-config.js index a0ea9b81ea..d5869f3cf1 100644 --- a/integration-tests/api/medusa-config.js +++ b/integration-tests/api/medusa-config.js @@ -17,6 +17,9 @@ process.env.LOG_LEVEL = "error" module.exports = { plugins: [], + admin: { + disable: true, + }, projectConfig: { redis_url: redisUrl, database_url: DB_URL, diff --git a/integration-tests/modules/medusa-config.js b/integration-tests/modules/medusa-config.js index acd77847ae..21f730f4dc 100644 --- a/integration-tests/modules/medusa-config.js +++ b/integration-tests/modules/medusa-config.js @@ -31,6 +31,9 @@ const customFulfillmentProvider = { } module.exports = { + admin: { + disable: true, + }, plugins: [], projectConfig: { database_url: DB_URL, diff --git a/packages/admin-next/admin-bundler/README.md b/packages/admin-next/admin-bundler/README.md deleted file mode 100644 index ecfe9dffd9..0000000000 --- a/packages/admin-next/admin-bundler/README.md +++ /dev/null @@ -1 +0,0 @@ -# cli diff --git a/packages/admin-next/admin-bundler/bin/medusa-admin.js b/packages/admin-next/admin-bundler/bin/medusa-admin.js deleted file mode 100755 index 05470b3f67..0000000000 --- a/packages/admin-next/admin-bundler/bin/medusa-admin.js +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env node -function start() { - return import("../dist/cli/index.mjs"); -} - -start(); diff --git a/packages/admin-next/admin-bundler/package.json b/packages/admin-next/admin-bundler/package.json deleted file mode 100644 index e5f2029f43..0000000000 --- a/packages/admin-next/admin-bundler/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@medusajs/admin-bundler", - "version": "0.0.0", - "scripts": { - "build": "rimraf dist && tsup" - }, - "bin": { - "medusa-admin": "./bin/medusa-admin.js" - }, - "main": "dist/index.js", - "types": "dist/index.d.ts", - "module": "dist/index.mjs", - "files": [ - "dist" - ], - "devDependencies": { - "rimraf": "5.0.1", - "tsup": "^8.0.1", - "typescript": "^5.3.3" - }, - "dependencies": { - "@medusajs/ui-preset": "^1.1.3", - "@medusajs/vite-plugin-extension": "*", - "@vitejs/plugin-react": "^4.2.1", - "autoprefixer": "^10.4.16", - "commander": "^11.1.0", - "deepmerge": "^4.3.1", - "glob": "^7.1.6", - "postcss": "^8.4.32", - "tailwindcss": "^3.3.6", - "vite": "5.0.10" - }, - "packageManager": "yarn@3.2.1" -} diff --git a/packages/admin-next/admin-bundler/src/api/build.ts b/packages/admin-next/admin-bundler/src/api/build.ts deleted file mode 100644 index ed64b7720f..0000000000 --- a/packages/admin-next/admin-bundler/src/api/build.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { resolve } from "path" -import { build as command } from "vite" - -import { createViteConfig } from "./create-vite-config" - -type BuildArgs = { - root?: string -} - -export async function build({ root }: BuildArgs) { - const config = await createViteConfig({ - build: { - outDir: resolve(process.cwd(), "build"), - }, - }) - - if (!config) { - return - } - - await command(config) -} diff --git a/packages/admin-next/admin-bundler/src/api/bundle.ts b/packages/admin-next/admin-bundler/src/api/bundle.ts deleted file mode 100644 index b37706bce2..0000000000 --- a/packages/admin-next/admin-bundler/src/api/bundle.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { readFileSync } from "fs" -import glob from "glob" -import { relative, resolve } from "path" -import { build as command } from "vite" - -type BundleArgs = { - root?: string | undefined - watch?: boolean | undefined -} - -export async function bundle({ watch, root }: BundleArgs) { - const resolvedRoot = root - ? resolve(process.cwd(), root) - : resolve(process.cwd(), "src", "admin") - - const files = glob.sync(`${resolvedRoot}/**/*.{ts,tsx,js,jsx}`) - - const input: Record = {} - for (const file of files) { - const relativePath = relative(resolvedRoot, file) - input[relativePath] = file - } - - const packageJson = JSON.parse( - readFileSync(resolve(process.cwd(), "package.json"), "utf-8") - ) - const external = [ - ...Object.keys(packageJson.dependencies), - "@medusajs/ui", - "@medusajs/ui-preset", - "react", - "react-dom", - "react-router-dom", - "react-hook-form", - ] - - await command({ - build: { - watch: watch ? {} : undefined, - rollupOptions: { - input: input, - external: external, - }, - }, - }) -} diff --git a/packages/admin-next/admin-bundler/src/api/create-vite-config.ts b/packages/admin-next/admin-bundler/src/api/create-vite-config.ts deleted file mode 100644 index 89fc8e9a81..0000000000 --- a/packages/admin-next/admin-bundler/src/api/create-vite-config.ts +++ /dev/null @@ -1,253 +0,0 @@ -import inject from "@medusajs/vite-plugin-extension" -import react from "@vitejs/plugin-react" -import deepmerge from "deepmerge" -import { createRequire } from "module" -import path from "path" -import { type Config } from "tailwindcss" -import { ContentConfig } from "tailwindcss/types/config" -import { InlineConfig, Logger, createLogger, mergeConfig } from "vite" - -const require = createRequire(import.meta.url) - -export async function createViteConfig( - inline: InlineConfig -): Promise { - const root = process.cwd() - const logger = createCustomLogger() - - let dashboardRoot: string | null = null - - try { - dashboardRoot = path.dirname(require.resolve("@medusajs/dashboard")) - } catch (err) { - dashboardRoot = null - } - - if (!dashboardRoot) { - logger.error( - "Unable to find @medusajs/dashboard. Please install it in your project, or specify the root directory." - ) - return null - } - - const { plugins, userConfig } = (await loadConfig(root, logger)) ?? {} - - let viteConfig: InlineConfig = mergeConfig(inline, { - plugins: [ - react(), - inject({ - sources: plugins, - }), - ], - configFile: false, - root: dashboardRoot, - css: { - postcss: { - plugins: [ - require("tailwindcss")({ - config: createTwConfig(process.cwd(), dashboardRoot), - }), - require("autoprefixer"), - ], - }, - }, - } satisfies InlineConfig) - - if (userConfig) { - viteConfig = await userConfig(viteConfig) - } - - return viteConfig -} - -function mergeTailwindConfigs(config1: Config, config2: Config): Config { - const content1 = config1.content - const content2 = config2.content - - let mergedContent: ContentConfig - - if (Array.isArray(content1) && Array.isArray(content2)) { - mergedContent = [...content1, ...content2] - } else if (!Array.isArray(content1) && !Array.isArray(content2)) { - mergedContent = { - files: [...content1.files, ...content2.files], - relative: content1.relative || content2.relative, - extract: { ...content1.extract, ...content2.extract }, - transform: { ...content1.transform, ...content2.transform }, - } - } else { - throw new Error("Cannot merge content fields of different types") - } - - const mergedConfig = deepmerge(config1, config2) - mergedConfig.content = mergedContent - - console.log(config1.presets, config2.presets) - - // Ensure presets only contain unique values - mergedConfig.presets = config1.presets || [] - - return mergedConfig -} - -function createTwConfig(root: string, dashboardRoot: string) { - const uiRoot = path.join( - path.dirname(require.resolve("@medusajs/ui")), - "**/*.{js,jsx,ts,tsx}" - ) - - const baseConfig: Config = { - presets: [require("@medusajs/ui-preset")], - content: [ - `${root}/src/admin/**/*.{js,jsx,ts,tsx}`, - `${dashboardRoot}/src/**/*.{js,jsx,ts,tsx}`, - uiRoot, - ], - darkMode: "class", - theme: { - extend: {}, - }, - plugins: [], - } - - let userConfig: Config | null = null - const extensions = ["js", "cjs", "mjs", "ts", "cts", "mts"] - - for (const ext of extensions) { - try { - userConfig = require(path.join(root, `tailwind.config.${ext}`)) - break - } catch (err) { - console.log("Failed to load tailwind config with extension", ext, err) - userConfig = null - } - } - - if (!userConfig) { - return baseConfig - } - - return mergeTailwindConfigs(baseConfig, userConfig) -} - -function createCustomLogger() { - const logger = createLogger("info", { - prefix: "medusa-admin", - }) - const loggerInfo = logger.info - - logger.info = (msg, opts) => { - if ( - msg.includes("hmr invalidate") && - msg.includes( - "Could not Fast Refresh. Learn more at https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react#consistent-components-exports" - ) - ) { - return - } - - loggerInfo(msg, opts) - } - - return logger -} - -interface PluginOptions extends Record { - enableUI?: boolean -} - -type Plugin = - | string - | { - resolve: string - options?: PluginOptions - } - -interface MedusaConfig extends Record { - plugins?: Plugin[] -} - -async function loadConfig(root: string, logger: Logger) { - const configPath = path.resolve(root, "medusa-config.js") - - const config: MedusaConfig = await import(configPath) - .then((c) => c) - .catch((e) => { - if (e.code === "ERR_MODULE_NOT_FOUND") { - logger.warn( - "Root 'medusa-config.js' file not found; extensions won't load. If running Admin UI as a standalone app, use the 'standalone' option.", - { - timestamp: true, - } - ) - } else { - logger.error( - `An error occured while attempting to load '${configPath}':\n${e}`, - { - timestamp: true, - } - ) - } - - return null - }) - - if (!config) { - return - } - - if (!config.plugins?.length) { - logger.info( - "No plugins in 'medusa-config.js', no extensions will load. To enable Admin UI extensions, add them to the 'plugins' array in 'medusa-config.js'.", - { - timestamp: true, - } - ) - return - } - - const uiPlugins = config.plugins - .filter((p) => typeof p !== "string" && p.options?.enableUI) - .map((p: Plugin) => { - return typeof p === "string" ? p : p.resolve - }) - - const extensionSources = uiPlugins.map((p) => { - return path.resolve(require.resolve(p), "dist", "admin") - }) - - const rootSource = path.resolve(process.cwd(), "src", "admin") - - extensionSources.push(rootSource) - - const adminPlugin = config.plugins.find((p) => - typeof p === "string" - ? p === "@medusajs/admin" - : p.resolve === "@medusajs/admin" - ) - - if (!adminPlugin) { - logger.info( - "No @medusajs/admin in 'medusa-config.js', no extensions will load. To enable Admin UI extensions, add it to the 'plugins' array in 'medusa-config.js'.", - { - timestamp: true, - } - ) - return - } - - const adminPluginOptions = - typeof adminPlugin !== "string" && !!adminPlugin.options - ? adminPlugin.options - : {} - - const viteConfig = adminPluginOptions.withFinal as - | ((config: InlineConfig) => InlineConfig) - | ((config: InlineConfig) => Promise) - | undefined - - return { - plugins: extensionSources, - userConfig: viteConfig, - } -} diff --git a/packages/admin-next/admin-bundler/src/api/dev.ts b/packages/admin-next/admin-bundler/src/api/dev.ts deleted file mode 100644 index 74eb7870ef..0000000000 --- a/packages/admin-next/admin-bundler/src/api/dev.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createServer } from "vite" -// @ts-ignore -import { createViteConfig } from "./create-vite-config" - -type DevArgs = { - port?: number | undefined - host?: string | boolean | undefined -} - -export async function dev({ port = 5173, host }: DevArgs) { - const config = await createViteConfig({ - server: { - port, - host, - }, - }) - - if (!config) { - return - } - - const server = await createServer(config) - - await server.listen() - - server.printUrls() - server.bindCLIShortcuts({ print: true }) -} diff --git a/packages/admin-next/admin-bundler/src/cli/create-cli.ts b/packages/admin-next/admin-bundler/src/cli/create-cli.ts deleted file mode 100644 index b7827cff01..0000000000 --- a/packages/admin-next/admin-bundler/src/cli/create-cli.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Command } from "commander" - -import { build } from "../api/build" -import { bundle } from "../api/bundle" -import { dev } from "../api/dev" - -export async function createCli() { - const program = new Command() - - program.name("medusa-admin") - - program - .command("dev") - .description("Starts the development server") - .action(dev) - - program - .command("build") - .description("Builds the admin dashboard") - .action(build) - - program - .command("bundle") - .description("Bundles the admin dashboard") - .action(bundle) - - return program -} diff --git a/packages/admin-next/admin-bundler/src/cli/index.ts b/packages/admin-next/admin-bundler/src/cli/index.ts deleted file mode 100644 index fd04d6859b..0000000000 --- a/packages/admin-next/admin-bundler/src/cli/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createCli } from "./create-cli" - -createCli() - .then(async (cli) => cli.parseAsync(process.argv)) - .catch((err) => { - console.error(err) - process.exit(1) - }) diff --git a/packages/admin-next/admin-bundler/src/index.ts b/packages/admin-next/admin-bundler/src/index.ts deleted file mode 100644 index d1f47a1452..0000000000 --- a/packages/admin-next/admin-bundler/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { build } from "./api/build.js" -export { bundle } from "./api/bundle.js" -export { dev } from "./api/dev.js" diff --git a/packages/admin-next/admin-sdk/README.md b/packages/admin-next/admin-sdk/README.md new file mode 100644 index 0000000000..7a99c70c28 --- /dev/null +++ b/packages/admin-next/admin-sdk/README.md @@ -0,0 +1 @@ +# `@medusajs/admin-sdk` diff --git a/packages/admin-next/admin-sdk/package.json b/packages/admin-next/admin-sdk/package.json new file mode 100644 index 0000000000..46b8a21eec --- /dev/null +++ b/packages/admin-next/admin-sdk/package.json @@ -0,0 +1,44 @@ +{ + "name": "@medusajs/admin-sdk", + "version": "0.0.1", + "description": "Admin SDK for Medusa.", + "author": "Kasper Kristensen ", + "scripts": { + "build": "tsup && copyfiles -f ./src/index.html ./src/entry.tsx ./src/index.css ./dist" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "package.json" + ], + "devDependencies": { + "@medusajs/types": "^1.11.16", + "@types/compression": "^1.7.5", + "@types/connect-history-api-fallback": "^1.5.4", + "copyfiles": "^2.4.1", + "express": "^4.18.2", + "tsup": "^8.0.1", + "typescript": "^5.3.3" + }, + "dependencies": { + "@medusajs/admin-vite-plugin": "0.0.1", + "@medusajs/dashboard": "0.0.1", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.16", + "commander": "^11.1.0", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "deepmerge": "^4.3.1", + "glob": "^7.1.6", + "postcss": "^8.4.32", + "tailwindcss": "^3.3.6", + "vite": "^5.2.11", + "vite-plugin-node-polyfills": "^0.21.0" + }, + "peerDependencies": { + "express": "^4.18.2", + "react-dom": "^18.0.0" + }, + "packageManager": "yarn@3.2.1" +} diff --git a/packages/admin-next/admin-sdk/src/entry.tsx b/packages/admin-next/admin-sdk/src/entry.tsx new file mode 100644 index 0000000000..84a8f37b2e --- /dev/null +++ b/packages/admin-next/admin-sdk/src/entry.tsx @@ -0,0 +1,9 @@ +import App from "@medusajs/dashboard" +import React from "react" +import { createRoot } from "react-dom/client" + +import "./index.css" + +const container = document.getElementById("root") +const root = createRoot(container!) +root.render() \ No newline at end of file diff --git a/packages/admin-next/admin-sdk/src/index.css b/packages/admin-next/admin-sdk/src/index.css new file mode 100644 index 0000000000..c9b2a6f230 --- /dev/null +++ b/packages/admin-next/admin-sdk/src/index.css @@ -0,0 +1,5 @@ +@import "@medusajs/dashboard/css"; + +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/packages/admin-next/admin-sdk/src/index.html b/packages/admin-next/admin-sdk/src/index.html new file mode 100644 index 0000000000..07f49710e1 --- /dev/null +++ b/packages/admin-next/admin-sdk/src/index.html @@ -0,0 +1,13 @@ + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/packages/admin-next/admin-sdk/src/index.ts b/packages/admin-next/admin-sdk/src/index.ts new file mode 100644 index 0000000000..3d6f8b53b8 --- /dev/null +++ b/packages/admin-next/admin-sdk/src/index.ts @@ -0,0 +1,5 @@ +export { build } from "./lib/build" +export { develop } from "./lib/develop" +export { serve } from "./lib/serve" + +export * from "./types" diff --git a/packages/admin-next/admin-sdk/src/lib/build.ts b/packages/admin-next/admin-sdk/src/lib/build.ts new file mode 100644 index 0000000000..79f9007a40 --- /dev/null +++ b/packages/admin-next/admin-sdk/src/lib/build.ts @@ -0,0 +1,17 @@ +import { BundlerOptions } from "../types" +import { getViteConfig } from "./config" + +export async function build(options: BundlerOptions) { + const vite = await import("vite") + + const viteConfig = await getViteConfig(options) + + try { + await vite.build( + vite.mergeConfig(viteConfig, { mode: "production", logLevel: "silent" }) + ) + } catch (error) { + console.error(error) + throw new Error("Failed to build admin panel") + } +} diff --git a/packages/admin-next/admin-sdk/src/lib/config.ts b/packages/admin-next/admin-sdk/src/lib/config.ts new file mode 100644 index 0000000000..a9c67bc276 --- /dev/null +++ b/packages/admin-next/admin-sdk/src/lib/config.ts @@ -0,0 +1,111 @@ +import path from "path" +import { Config } from "tailwindcss" +import type { InlineConfig } from "vite" +import { nodePolyfills } from "vite-plugin-node-polyfills" + +import { BundlerOptions } from "../types" + +export async function getViteConfig( + options: BundlerOptions +): Promise { + const { searchForWorkspaceRoot } = await import("vite") + const { default: react } = await import("@vitejs/plugin-react") + const { default: inject } = await import("@medusajs/admin-vite-plugin") + + const getPort = await import("get-port") + const hmrPort = await getPort.default() + + const root = path.resolve(__dirname, "./") + + return { + root: path.resolve(__dirname, "./"), + base: options.path, + build: { + emptyOutDir: true, + outDir: path.resolve(process.cwd(), options.outDir), + }, + optimizeDeps: { + include: ["@medusajs/dashboard", "react-dom/client"], + }, + define: { + __BASE__: JSON.stringify(options.path), + /** + * TODO: Accept backend url from config to support hosting the admin elsewhere. + * The empty string should be the default value, as that ensures that requests + * are made to the server that serves the admin dashboard. + */ + __BACKEND_URL__: JSON.stringify(""), + }, + server: { + open: true, + fs: { + allow: [ + searchForWorkspaceRoot(process.cwd()), + path.resolve(__dirname, "../../medusa"), + path.resolve(__dirname, "../../app"), + ], + }, + hmr: { + port: hmrPort, + }, + middlewareMode: true, + }, + css: { + postcss: { + plugins: [ + require("tailwindcss")({ + config: createTailwindConfig(root), + }), + ], + }, + }, + /** + * TODO: Remove polyfills, they are currently only required for the + * `axios` dependency in the dashboard. Once we have the new SDK, + * we should remove this, and leave it up to the user to include + * polyfills if they need them. + */ + plugins: [ + react(), + inject(), + nodePolyfills({ + include: ["crypto", "util", "stream"], + }), + ], + } +} + +function createTailwindConfig(entry: string) { + const root = path.join(entry, "**/*.{js,ts,jsx,tsx}") + const html = path.join(entry, "index.html") + + let dashboard = "" + + try { + dashboard = path.join( + path.dirname(require.resolve("@medusajs/dashboard")), + "**/*.{js,ts,jsx,tsx}" + ) + } catch (_e) { + // ignore + } + + let ui: string = "" + + try { + ui = path.join( + path.dirname(require.resolve("@medusajs/ui")), + "**/*.{js,ts,jsx,tsx}" + ) + } catch (_e) { + // ignore + } + + const config: Config = { + presets: [require("@medusajs/ui-preset")], + content: [html, root, dashboard, ui], + darkMode: "class", + } + + return config +} diff --git a/packages/admin-next/admin-sdk/src/lib/develop.ts b/packages/admin-next/admin-sdk/src/lib/develop.ts new file mode 100644 index 0000000000..cb6823faa1 --- /dev/null +++ b/packages/admin-next/admin-sdk/src/lib/develop.ts @@ -0,0 +1,24 @@ +import express from "express" + +import { BundlerOptions } from "../types" +import { getViteConfig } from "./config" + +const router = express.Router() + +export async function develop(options: BundlerOptions) { + const vite = await import("vite") + + try { + const viteConfig = await getViteConfig(options) + const server = await vite.createServer( + vite.mergeConfig(viteConfig, { logLevel: "info", mode: "development" }) + ) + + router.use(server.middlewares) + } catch (error) { + console.error(error) + throw new Error("Could not start development server") + } + + return router +} diff --git a/packages/admin-next/admin-sdk/src/lib/serve.ts b/packages/admin-next/admin-sdk/src/lib/serve.ts new file mode 100644 index 0000000000..235393eec8 --- /dev/null +++ b/packages/admin-next/admin-sdk/src/lib/serve.ts @@ -0,0 +1,53 @@ +import { Request, Response, Router, static as static_ } from "express" +import fs from "fs" +import { ServerResponse } from "http" +import path from "path" + +type ServeOptions = { + outDir: string +} + +const router = Router() + +export async function serve(options: ServeOptions) { + const htmlPath = path.resolve(options.outDir, "index.html") + + /** + * The admin UI should always be built at this point, but in the + * rare case that another plugin terminated a previous startup, the admin + * may not have been built correctly. Here we check if the admin UI + * build files exist, and if not, we throw an error, providing the + * user with instructions on how to fix their build. + */ + + const indexExists = fs.existsSync(htmlPath) + + if (!indexExists) { + throw new Error( + `Could not find the admin UI build files. Please run "medusa-admin build" or enable "autoRebuild" in the plugin options to build the admin UI.` + ) + } + + const html = fs.readFileSync(htmlPath, "utf-8") + + const sendHtml = (_req: Request, res: Response) => { + res.setHeader("Cache-Control", "no-cache") + res.setHeader("Vary", "Origin, Cache-Control") + res.send(html) + } + + const setStaticHeaders = (res: ServerResponse) => { + res.setHeader("Cache-Control", "max-age=31536000, immutable") + res.setHeader("Vary", "Origin, Cache-Control") + } + + router.get("/", sendHtml) + router.use( + static_(options.outDir, { + setHeaders: setStaticHeaders, + }) + ) + router.get(`/*`, sendHtml) + + return router +} diff --git a/packages/admin-next/admin-sdk/src/types.ts b/packages/admin-next/admin-sdk/src/types.ts new file mode 100644 index 0000000000..ef9b8132bc --- /dev/null +++ b/packages/admin-next/admin-sdk/src/types.ts @@ -0,0 +1,4 @@ +import { AdminOptions } from "@medusajs/types" + +export type BundlerOptions = Required> & + Pick diff --git a/packages/admin-next/admin-bundler/tsconfig.json b/packages/admin-next/admin-sdk/tsconfig.json similarity index 75% rename from packages/admin-next/admin-bundler/tsconfig.json rename to packages/admin-next/admin-sdk/tsconfig.json index 98f1c02d5c..1c1cf0601e 100644 --- a/packages/admin-next/admin-bundler/tsconfig.json +++ b/packages/admin-next/admin-sdk/tsconfig.json @@ -1,6 +1,8 @@ { "compilerOptions": { + "jsx": "react", "outDir": "dist", + "rootDir": "src", "target": "ES2020", "module": "ES2020", "moduleResolution": "bundler", @@ -14,5 +16,6 @@ "esModuleInterop": true, "noFallthroughCasesInSwitch": true }, - "include": ["src"] + "include": ["src"], + "exclude": ["tsup.config.ts", "node_modules", "dist"] } diff --git a/packages/admin-next/admin-bundler/tsup.config.ts b/packages/admin-next/admin-sdk/tsup.config.ts similarity index 54% rename from packages/admin-next/admin-bundler/tsup.config.ts rename to packages/admin-next/admin-sdk/tsup.config.ts index b94cf8b9bc..8fc9026926 100644 --- a/packages/admin-next/admin-bundler/tsup.config.ts +++ b/packages/admin-next/admin-sdk/tsup.config.ts @@ -1,7 +1,8 @@ import { defineConfig } from "tsup" export default defineConfig({ - entry: ["./src/index.ts", "./src/cli/index.ts"], - format: ["esm"], + entry: ["src/index.ts"], + format: ["cjs"], dts: true, + clean: true, }) diff --git a/packages/admin-next/admin-shared/package.json b/packages/admin-next/admin-shared/package.json index 81b227e8ae..2bfaf2c33c 100644 --- a/packages/admin-next/admin-shared/package.json +++ b/packages/admin-next/admin-shared/package.json @@ -1,8 +1,14 @@ { "name": "@medusajs/admin-shared", - "version": "0.0.0", + "description": "Shared code for Medusa admin packages.", + "version": "0.0.1", + "author": "Kasper Kristensen ", "types": "dist/index.d.ts", "main": "dist/index.js", + "files": [ + "dist", + "package.json" + ], "scripts": { "build": "tsc" }, diff --git a/packages/admin-next/vite-plugin-extension/README.md b/packages/admin-next/admin-vite-plugin/README.md similarity index 100% rename from packages/admin-next/vite-plugin-extension/README.md rename to packages/admin-next/admin-vite-plugin/README.md diff --git a/packages/admin-next/vite-plugin-extension/package.json b/packages/admin-next/admin-vite-plugin/package.json similarity index 81% rename from packages/admin-next/vite-plugin-extension/package.json rename to packages/admin-next/admin-vite-plugin/package.json index c3bc9395dc..cb4bda3b0a 100644 --- a/packages/admin-next/vite-plugin-extension/package.json +++ b/packages/admin-next/admin-vite-plugin/package.json @@ -1,6 +1,6 @@ { - "name": "@medusajs/vite-plugin-extension", - "version": "0.0.0", + "name": "@medusajs/admin-vite-plugin", + "version": "0.0.1", "main": "dist/index.js", "types": "dist/index.d.ts", "module": "dist/index.mjs", @@ -11,19 +11,20 @@ } }, "files": [ - "dist" + "dist", + "package.json" ], "scripts": { "build": "tsup" }, "devDependencies": { "@babel/types": "7.22.5", - "@medusajs/admin-shared": "*", + "@medusajs/admin-shared": "0.0.1", "@types/babel__traverse": "7.20.5", "@types/node": "^20.10.4", "tsup": "8.0.1", "typescript": "5.3.3", - "vite": "5.0.10" + "vite": "^5.2.11" }, "peerDependencies": { "vite": "^5.0.0" diff --git a/packages/admin-next/vite-plugin-extension/src/index.ts b/packages/admin-next/admin-vite-plugin/src/index.ts similarity index 96% rename from packages/admin-next/vite-plugin-extension/src/index.ts rename to packages/admin-next/admin-vite-plugin/src/index.ts index b76fb350ea..5aa7140866 100644 --- a/packages/admin-next/vite-plugin-extension/src/index.ts +++ b/packages/admin-next/admin-vite-plugin/src/index.ts @@ -18,7 +18,7 @@ import { InjectionZone, injectionZones } from "@medusajs/admin-shared" const traverse = (_traverse as any).default as typeof _traverse -const VIRTUAL_PREFIX = "/@virtual/medusajs-vite-plugin-extension/" +const VIRTUAL_PREFIX = "/@virtual/medusajs-admin-vite-plugin/" const IMPORT_PREFIX = "medusa-admin:" const WIDGET_MODULE = `${IMPORT_PREFIX}widgets/` @@ -321,7 +321,7 @@ export default function inject(args?: InjectArgs): PluginOption { async function generateWidgetEntrypoint(zone: InjectionZone) { const files = ( await Promise.all( - Array.from(_sources).map((source) => + Array.from(_sources).map(async (source) => traverseDirectory(`${source}/widgets`) ) ) @@ -463,7 +463,7 @@ export default function inject(args?: InjectArgs): PluginOption { async function generateRouteEntrypoint(get: "page" | "link") { const files = ( await Promise.all( - Array.from(_sources).map((source) => + Array.from(_sources).map(async (source) => traverseDirectory(`${source}/routes`, "page", { min: 1 }) ) ) @@ -496,11 +496,11 @@ export default function inject(args?: InjectArgs): PluginOption { const exportString = `export default { ${get}s: [${validatedRoutes - .map((file, index) => - get === "page" + .map((file, index) => { + return get === "page" ? `{ path: "${createPath(file)}", file: "${file}" }` : `{ path: "${createPath(file)}", ...routeConfig${index}.link }` - ) + }) .join(", ")}], }` @@ -610,7 +610,7 @@ export default function inject(args?: InjectArgs): PluginOption { async function generateSettingEntrypoint(get: "page" | "card") { const files = ( await Promise.all( - Array.from(_sources).map((source) => + Array.from(_sources).map(async (source) => traverseDirectory(`${source}/settings`, "page", { min: 1, max: 1 }) ) ) @@ -643,11 +643,11 @@ export default function inject(args?: InjectArgs): PluginOption { const exportString = `export default { ${get}s: [${validatedSettings - .map((file, index) => - get === "page" + .map((file, index) => { + return get === "page" ? `{ path: "${createPath(file)}", file: "${file}" }` : `{ path: "${createPath(file)}", ...settingConfig${index}.card }` - ) + }) .join(", ")}], }` @@ -701,7 +701,7 @@ export default function inject(args?: InjectArgs): PluginOption { const module = server.moduleGraph.getModuleById(moduleId) if (module) { - server.reloadModule(module) + await server.reloadModule(module) } } } @@ -719,7 +719,7 @@ export default function inject(args?: InjectArgs): PluginOption { const module = server.moduleGraph.getModuleById(fullModuleId) if (module) { - server.reloadModule(module) + await server.reloadModule(module) } } } @@ -737,7 +737,7 @@ export default function inject(args?: InjectArgs): PluginOption { const module = server.moduleGraph.getModuleById(fullModuleId) if (module) { - server.reloadModule(module) + await server.reloadModule(module) } } } @@ -754,7 +754,7 @@ export default function inject(args?: InjectArgs): PluginOption { if (module) { _extensionGraph.delete(file) - server.reloadModule(module) + await server.reloadModule(module) } } } @@ -775,7 +775,7 @@ export default function inject(args?: InjectArgs): PluginOption { } return { - name: "@medusajs/vite-plugin-extension", + name: "@medusajs/admin-vite-plugin", configureServer(s) { server = s logger = s.config.logger @@ -835,8 +835,8 @@ export default function inject(args?: InjectArgs): PluginOption { return }) - watcher.on("unlink", (file) => { - handleExtensionUnlink(file) + watcher.on("unlink", async (file) => { + await handleExtensionUnlink(file) return }) }, @@ -876,9 +876,9 @@ export default function inject(args?: InjectArgs): PluginOption { return null }, - closeBundle() { + async closeBundle() { if (watcher) { - watcher.close() + await watcher.close() } }, } diff --git a/packages/admin-next/vite-plugin-extension/tsconfig.json b/packages/admin-next/admin-vite-plugin/tsconfig.json similarity index 100% rename from packages/admin-next/vite-plugin-extension/tsconfig.json rename to packages/admin-next/admin-vite-plugin/tsconfig.json diff --git a/packages/admin-next/vite-plugin-extension/tsup.config.ts b/packages/admin-next/admin-vite-plugin/tsup.config.ts similarity index 70% rename from packages/admin-next/vite-plugin-extension/tsup.config.ts rename to packages/admin-next/admin-vite-plugin/tsup.config.ts index 5f73ddd831..48fbeed022 100644 --- a/packages/admin-next/vite-plugin-extension/tsup.config.ts +++ b/packages/admin-next/admin-vite-plugin/tsup.config.ts @@ -1,7 +1,7 @@ -import { defineConfig } from "tsup"; +import { defineConfig } from "tsup" export default defineConfig({ entry: ["./src/index.ts"], format: ["cjs", "esm"], dts: true, -}); +}) diff --git a/packages/admin-next/dashboard/package.json b/packages/admin-next/dashboard/package.json index 0896feab65..bac0cb4f24 100644 --- a/packages/admin-next/dashboard/package.json +++ b/packages/admin-next/dashboard/package.json @@ -1,19 +1,30 @@ { "name": "@medusajs/dashboard", - "private": true, - "version": "0.0.0", + "version": "0.0.1", "scripts": { "generate:static": "node ./scripts/generate-countries.js && prettier --write ./src/lib/countries.ts && node ./scripts/generate-currencies.js && prettier --write ./src/lib/currencies.ts", "dev": "vite", - "build": "vite build", + "build": "tsup && node ./scripts/generate-types.js", + "build:preview": "vite build", "preview": "vite preview", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0" }, - "main": "index.html", + "main": "dist/app.js", + "module": "dist/app.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/app.mjs", + "require": "./dist/app.js", + "types": "./dist/index.d.ts" + }, + "./css": { + "import": "./dist/app.css", + "require": "./dist/app.css" + } + }, "files": [ - "index.html", - "public", - "src", + "dist", "package.json" ], "dependencies": { @@ -21,8 +32,8 @@ "@dnd-kit/core": "^6.1.0", "@dnd-kit/sortable": "^8.0.0", "@hookform/resolvers": "3.3.2", - "@medusajs/icons": "workspace:^", - "@medusajs/ui": "workspace:^", + "@medusajs/icons": "1.2.1", + "@medusajs/ui": "3.0.0", "@radix-ui/react-collapsible": "1.0.3", "@radix-ui/react-hover-card": "^1.0.7", "@tanstack/react-query": "^5.28.14", @@ -47,13 +58,12 @@ "react-jwt": "^1.2.0", "react-resizable-panels": "^2.0.16", "react-router-dom": "6.20.1", - "zod": "3.22.4" + "zod": "^3.22.4" }, "devDependencies": { - "@medusajs/medusa": "workspace:^", - "@medusajs/types": "workspace:^", - "@medusajs/ui-preset": "workspace:^", - "@medusajs/vite-plugin-extension": "workspace:^", + "@medusajs/admin-vite-plugin": "0.0.1", + "@medusajs/types": "1.11.16", + "@medusajs/ui-preset": "1.1.3", "@types/node": "^20.11.15", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", @@ -62,8 +72,9 @@ "postcss": "^8.4.33", "prettier": "^3.1.1", "tailwindcss": "^3.4.1", + "tsup": "^8.0.2", "typescript": "5.2.2", - "vite": "5.0.10" + "vite": "^5.2.11" }, "packageManager": "yarn@3.2.1" } diff --git a/packages/admin-next/dashboard/scripts/generate-types.js b/packages/admin-next/dashboard/scripts/generate-types.js new file mode 100644 index 0000000000..097a86c1d5 --- /dev/null +++ b/packages/admin-next/dashboard/scripts/generate-types.js @@ -0,0 +1,38 @@ +/** + * We can't use the `tsc` command to generate types for the project because it + * will generate types for each file in the project, which isn't needed. We only + * need a single file that exports the App component. + */ +async function generateTypes() { + const fs = require("fs") + const path = require("path") + + const distDir = path.resolve(__dirname, "../dist") + const filePath = path.join(distDir, "index.d.ts") + + const fileContent = ` +import * as react_jsx_runtime from "react/jsx-runtime" + +declare const App: () => react_jsx_runtime.JSX.Element + +export default App +` + + // Ensure the dist directory exists + if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir) + } + + // Write the content to the index.d.ts file + fs.writeFileSync(filePath, fileContent.trim(), "utf8") + + console.log(`File created at ${filePath}`) +} + +;(async () => { + try { + await generateTypes() + } catch (e) { + console.error(e) + } +})() diff --git a/packages/admin-next/dashboard/src/app.tsx b/packages/admin-next/dashboard/src/app.tsx index 7c7dd7e07f..0e0cc415c2 100644 --- a/packages/admin-next/dashboard/src/app.tsx +++ b/packages/admin-next/dashboard/src/app.tsx @@ -1,14 +1,18 @@ import { Toaster } from "@medusajs/ui" import { QueryClientProvider } from "@tanstack/react-query" +import { I18n } from "./components/utilities/i18n" import { queryClient } from "./lib/medusa" import { RouterProvider } from "./providers/router-provider" import { ThemeProvider } from "./providers/theme-provider" +import "./index.css" + function App() { return ( + diff --git a/packages/admin-next/dashboard/src/components/common/file-upload/file-upload.tsx b/packages/admin-next/dashboard/src/components/common/file-upload/file-upload.tsx index f1b2ab6947..ac8ea7141f 100644 --- a/packages/admin-next/dashboard/src/components/common/file-upload/file-upload.tsx +++ b/packages/admin-next/dashboard/src/components/common/file-upload/file-upload.tsx @@ -64,9 +64,11 @@ export const FileUpload = ({ const fileList = Array.from(files) const fileObj = fileList.map((file) => { + const id = Math.random().toString(36).substring(7) + const previewUrl = URL.createObjectURL(file) return { - id: crypto.randomUUID(), + id: id, url: previewUrl, file, } diff --git a/packages/admin-next/dashboard/src/components/layout/main-layout/main-layout.tsx b/packages/admin-next/dashboard/src/components/layout/main-layout/main-layout.tsx index 68cfb2649f..1ef5b4c5ec 100644 --- a/packages/admin-next/dashboard/src/components/layout/main-layout/main-layout.tsx +++ b/packages/admin-next/dashboard/src/components/layout/main-layout/main-layout.tsx @@ -13,13 +13,12 @@ import { Avatar, Text } from "@medusajs/ui" import * as Collapsible from "@radix-ui/react-collapsible" import { useTranslation } from "react-i18next" +import { ComponentType } from "react" import { useStore } from "../../../hooks/api/store" import { Skeleton } from "../../common/skeleton" import { NavItem, NavItemProps } from "../../layout/nav-item" import { Shell } from "../../layout/shell" -import extensions from "medusa-admin:routes/links" - export const MainLayout = () => { return ( @@ -167,6 +166,10 @@ const CoreRouteSection = () => { ) } +const extensions = { + links: null as { path: string; label: string; icon?: ComponentType }[] | null, +} + const ExtensionRouteSection = () => { if (!extensions.links || extensions.links.length === 0) { return null diff --git a/packages/admin-next/dashboard/src/components/localization/localized-date-picker/localized-date-picker.tsx b/packages/admin-next/dashboard/src/components/localization/localized-date-picker/localized-date-picker.tsx index 892c726ea9..b84f047a11 100644 --- a/packages/admin-next/dashboard/src/components/localization/localized-date-picker/localized-date-picker.tsx +++ b/packages/admin-next/dashboard/src/components/localization/localized-date-picker/localized-date-picker.tsx @@ -1,7 +1,7 @@ import { DatePicker } from "@medusajs/ui" import { ComponentPropsWithoutRef } from "react" import { useTranslation } from "react-i18next" -import { languages } from "../../../i18n/config" +import { languages } from "../../../i18n/languages" type LocalizedDatePickerProps = Omit< ComponentPropsWithoutRef, @@ -14,8 +14,9 @@ export const LocalizedDatePicker = ({ }: LocalizedDatePickerProps) => { const { i18n, t } = useTranslation() - const locale = languages.find((lang) => lang.code === i18n.language) - ?.date_locale + const locale = languages.find( + (lang) => lang.code === i18n.language + )?.date_locale const translations = { cancel: t("actions.cancel"), diff --git a/packages/admin-next/dashboard/src/components/error/error-boundary/error-boundary.tsx b/packages/admin-next/dashboard/src/components/utilities/error-boundary/error-boundary.tsx similarity index 100% rename from packages/admin-next/dashboard/src/components/error/error-boundary/error-boundary.tsx rename to packages/admin-next/dashboard/src/components/utilities/error-boundary/error-boundary.tsx diff --git a/packages/admin-next/dashboard/src/components/error/error-boundary/index.ts b/packages/admin-next/dashboard/src/components/utilities/error-boundary/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/components/error/error-boundary/index.ts rename to packages/admin-next/dashboard/src/components/utilities/error-boundary/index.ts diff --git a/packages/admin-next/dashboard/src/components/utilities/i18n/i18n.tsx b/packages/admin-next/dashboard/src/components/utilities/i18n/i18n.tsx new file mode 100644 index 0000000000..608a320e05 --- /dev/null +++ b/packages/admin-next/dashboard/src/components/utilities/i18n/i18n.tsx @@ -0,0 +1,23 @@ +import i18n from "i18next" +import LanguageDetector from "i18next-browser-languagedetector" +import { initReactI18next } from "react-i18next" + +import { defaultI18nOptions } from "../../../i18n/config" + +export const I18n = () => { + if (i18n.isInitialized) { + return null + } + + i18n + .use( + new LanguageDetector(null, { + lookupCookie: "lng", + lookupLocalStorage: "lng", + }) + ) + .use(initReactI18next) + .init(defaultI18nOptions) + + return null +} diff --git a/packages/admin-next/dashboard/src/components/utilities/i18n/index.ts b/packages/admin-next/dashboard/src/components/utilities/i18n/index.ts new file mode 100644 index 0000000000..ec2c30488a --- /dev/null +++ b/packages/admin-next/dashboard/src/components/utilities/i18n/index.ts @@ -0,0 +1 @@ +export * from "./i18n" diff --git a/packages/admin-next/dashboard/src/hooks/use-date.tsx b/packages/admin-next/dashboard/src/hooks/use-date.tsx index 6a039cac22..af8769f712 100644 --- a/packages/admin-next/dashboard/src/hooks/use-date.tsx +++ b/packages/admin-next/dashboard/src/hooks/use-date.tsx @@ -2,7 +2,7 @@ import { format, formatDistance, sub } from "date-fns" import { enUS } from "date-fns/locale" import { useTranslation } from "react-i18next" -import { languages } from "../i18n/config" +import { languages } from "../i18n/languages" export const useDate = () => { const { i18n } = useTranslation() diff --git a/packages/admin-next/dashboard/src/i18n/config.ts b/packages/admin-next/dashboard/src/i18n/config.ts index 2b561e8c81..966cbfaafd 100644 --- a/packages/admin-next/dashboard/src/i18n/config.ts +++ b/packages/admin-next/dashboard/src/i18n/config.ts @@ -1,34 +1,19 @@ -import { enUS } from "date-fns/locale" -import i18n from "i18next" -import LanguageDetector from "i18next-browser-languagedetector" -import Backend, { type HttpBackendOptions } from "i18next-http-backend" -import { initReactI18next } from "react-i18next" +import { InitOptions } from "i18next" -import { Language } from "./types" +import translations from "./translations" -void i18n - .use(Backend) - .use(LanguageDetector) - .use(initReactI18next) - .init({ - fallbackLng: "en-US", - load: "languageOnly", - debug: process.env.NODE_ENV === "development", - interpolation: { - escapeValue: false, - }, - backend: { - loadPath: "/locales/{{lng}}/{{ns}}.json", - }, - }) - -export const languages: Language[] = [ - { - code: "en-US", - display_name: "English (US)", - ltr: true, - date_locale: enUS, +export const defaultI18nOptions: InitOptions = { + debug: process.env.NODE_ENV === "development", + detection: { + caches: ["cookie", "localStorage", "header"], + lookupCookie: "lng", + lookupLocalStorage: "lng", + order: ["cookie", "localStorage", "header"], }, -] - -export default i18n + fallbackLng: "en", + interpolation: { + escapeValue: false, + }, + resources: translations, + supportedLngs: Object.keys(translations), +} diff --git a/packages/admin-next/dashboard/src/i18n/languages.ts b/packages/admin-next/dashboard/src/i18n/languages.ts new file mode 100644 index 0000000000..b35fa74797 --- /dev/null +++ b/packages/admin-next/dashboard/src/i18n/languages.ts @@ -0,0 +1,11 @@ +import { enUS } from "date-fns/locale" +import { Language } from "./types" + +export const languages: Language[] = [ + { + code: "en-US", + display_name: "English (US)", + ltr: true, + date_locale: enUS, + }, +] diff --git a/packages/admin-next/dashboard/src/i18n/translations/$schema.json b/packages/admin-next/dashboard/src/i18n/translations/$schema.json new file mode 100644 index 0000000000..7214957f47 --- /dev/null +++ b/packages/admin-next/dashboard/src/i18n/translations/$schema.json @@ -0,0 +1,315 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "type": "object", + "properties": { + "$schema": { + "type": "string" + }, + "general": { + "type": "object", + "properties": { + "cancel": { + "type": "string" + }, + "save": { + "type": "string" + }, + "create": { + "type": "string" + }, + "delete": { + "type": "string" + }, + "edit": { + "type": "string" + }, + "extensions": { + "type": "string" + }, + "details": { + "type": "string" + } + }, + "required": [ + "cancel", + "save", + "create", + "createItem", + "delete", + "deleteItem", + "edit", + "editItem", + "extensions", + "details" + ] + }, + "products": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "variants": { + "type": "string" + }, + "availableInSalesChannels": { + "type": "string" + } + }, + "required": ["domain", "variants", "availableInSalesChannels"] + }, + "categories": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "collections": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "inventory": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "customers": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "customerGroups": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "orders": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "draftOrders": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "discounts": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "promotions": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "taxRegions": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "taxRates": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "fields": { + "type": "object" + } + }, + "required": ["domain"] + }, + "campaigns": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "giftCards": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "pricing": { + "type": "object", + "properties": { + "domain": { + "type": "string" + } + }, + "required": ["domain"] + }, + "users": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "role": { + "type": "string" + }, + "roles": { + "type": "object", + "properties": { + "admin": { + "type": "string" + }, + "member": { + "type": "string" + }, + "developer": { + "type": "string" + } + }, + "required": ["admin", "member", "developer"] + } + }, + "required": ["domain", "role", "roles"] + }, + "statuses": { + "type": "object", + "properties": { + "scheduled": { + "type": "string" + }, + "expired": { + "type": "string" + }, + "active": { + "type": "string" + }, + "disabled": { + "type": "string" + } + } + }, + "fields": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "handle": { + "type": "string" + }, + "type": { + "type": "string" + }, + "category": { + "type": "string" + }, + "categories": { + "type": "string" + }, + "collection": { + "type": "string" + }, + "discountable": { + "type": "string" + }, + "tags": { + "type": "string" + }, + "sales_channels": { + "type": "string" + } + }, + "required": [ + "title", + "description", + "name", + "email", + "password", + "subtitle", + "handle", + "type", + "category", + "categories", + "collection", + "discountable", + "tags", + "sales_channels" + ] + } + }, + "required": [ + "general", + "products", + "categories", + "collections", + "inventory", + "customers", + "customerGroups", + "orders", + "draftOrders", + "discounts", + "giftCards", + "pricing", + "users", + "fields" + ] +} diff --git a/packages/admin-next/dashboard/src/i18n/translations/en.json b/packages/admin-next/dashboard/src/i18n/translations/en.json new file mode 100644 index 0000000000..458c3366ad --- /dev/null +++ b/packages/admin-next/dashboard/src/i18n/translations/en.json @@ -0,0 +1,1682 @@ +{ + "$schema": "./$schema.json", + "general": { + "ascending": "Ascending", + "descending": "Descending", + "add": "Add", + "start": "Start", + "end": "End", + "open": "Open", + "close": "Close", + "apply": "Apply", + "range": "Range", + "search": "Search", + "of": "of", + "results": "results", + "pages": "pages", + "next": "Next", + "prev": "Prev", + "is": "is", + "timeline": "Timeline", + "success": "Success", + "warning": "Warning", + "error": "Error", + "select": "Select", + "selected": "Selected", + "enabled": "Enabled", + "disabled": "Disabled", + "expired": "Expired", + "active": "Active", + "revoked": "Revoked", + "admin": "Admin", + "store": "Store", + "details": "Details", + "items_one": "{{count}} item", + "items_other": "{{count}} items", + "countSelected": "{{count}} selected", + "countOfTotalSelected": "{{count}} of {{total}} selected", + "plusCount": "+ {{count}}", + "plusCountMore": "+ {{count}} more", + "areYouSure": "Are you sure?", + "noRecordsFound": "No records found", + "typeToConfirm": "Please type {val} to confirm:", + "noResultsTitle": "No results", + "noResultsMessage": "Try changing the filters or search query", + "noSearchResults": "No search results", + "noSearchResultsFor": "No search results for <0>'{{query}}'", + "noRecordsTitle": "No records", + "noRecordsMessage": "There are no records to show", + "unsavedChangesTitle": "Are you sure you want to leave this page?", + "unsavedChangesDescription": "You have unsaved changes that will be lost if you leave this page.", + "includesTaxTooltip": "Enter the total amount including tax. The net amount excluding tax will be automatically calculated and saved." + }, + "validation": { + "mustBeInt": "The value must be a whole number.", + "mustBePositive": "The value must be a positive number." + }, + "nav": { + "general": "General", + "developer": "Developer", + "extensions": "Extensions", + "settings": "Settings" + }, + "actions": { + "save": "Save", + "saveAsDraft": "Save as draft", + "publish": "Publish", + "create": "Create", + "delete": "Delete", + "remove": "Remove", + "revoke": "Revoke", + "cancel": "Cancel", + "enable": "Enable", + "disable": "Disable", + "complete": "Complete", + "viewDetails": "View details", + "back": "Back", + "close": "Close", + "continue": "Continue", + "confirm": "Confirm", + "edit": "Edit", + "download": "Download", + "clearAll": "Clear all", + "apply": "Apply", + "add": "Add" + }, + "filters": { + "date": { + "today": "Today", + "lastSevenDays": "Last 7 days", + "lastThirtyDays": "Last 30 days", + "lastNinetyDays": "Last 90 days", + "lastTwelveMonths": "Last 12 months", + "custom": "Custom", + "from": "From", + "to": "To" + }, + "compare": { + "lessThan": "Less than", + "greaterThan": "Greater than", + "exact": "Exact", + "range": "Range", + "lessThanLabel": "less than {{value}}", + "greaterThanLabel": "greater than {{value}}", + "andLabel": "and" + }, + "addFilter": "Add filter" + }, + "errorBoundary": { + "badRequestTitle": "Bad request", + "badRequestMessage": "The request was invalid.", + "notFoundTitle": "Not found", + "notFoundMessage": "The page you are looking for does not exist.", + "internalServerErrorTitle": "Internal server error", + "internalServerErrorMessage": "An error occurred on the server.", + "defaultTitle": "An error occurred", + "defaultMessage": "An error occurred while rendering this page." + }, + "addresses": { + "shippingAddress": { + "header": "Shipping Address", + "editHeader": "Edit Shipping Address", + "editLabel": "Shipping address", + "label": "Shipping address" + }, + "billingAddress": { + "header": "Billing Address", + "editHeader": "Edit Billing Address", + "editLabel": "Billing address", + "label": "Billing address", + "sameAsShipping": "Same as shipping address" + }, + "contactHeading": "Contact", + "locationHeading": "Location" + }, + "email": { + "editHeader": "Edit Email", + "editLabel": "Email", + "label": "Email" + }, + "transferOwnership": { + "header": "Transfer Ownership", + "label": "Transfer ownership", + "details": { + "order": "Order details", + "draft": "Draft details" + }, + "currentOwner": { + "label": "Current owner", + "hint": "The current owner of the order." + }, + "newOwner": { + "label": "New owner", + "hint": "The new owner to transfer the order to." + }, + "validation": { + "mustBeDifferent": "The new owner must be different from the current owner.", + "required": "New owner is required." + } + }, + "sales_channels": { + "availableIn": "Available in <0>{{x}} of <1>{{y}} sales channels" + }, + "products": { + "domain": "Products", + "create": { + "header": "Create Product", + "hint": "Create a new product to sell in your store.", + "tabs": { + "details": "Details", + "variants": "Variants" + }, + "variants": { + "header": "Variants", + "productVariants": { + "label": "Product variants", + "hint": "Variants left unchecked won't be created. This ranking will affect how the variants are ranked in your frontend.", + "alert": "Add options to create variants." + }, + "productOptions": { + "label": "Product options", + "hint": "Define the options for the product, e.g. color, size, etc." + } + }, + "successToast": "Product {{title}} was successfully created." + }, + "deleteWarning": "You are about to delete the product {{title}}. This action cannot be undone.", + "variants": "Variants", + "attributes": "Attributes", + "editProduct": "Edit Product", + "editAttributes": "Edit Attributes", + "organization": "Organize", + "editOrganization": "Edit Organization", + "editOptions": "Edit Options", + "editPrices": "Edit prices", + "media": { + "label": "Media", + "editHint": "Add media to the product to showcase it in your storefront.", + "uploadImagesLabel": "Upload images", + "uploadImagesHint": "Drag and drop images here or click to upload.", + "invalidFileType": "'{{name}}' is not a supported file type. Supported file types are: {{types}}.", + "deleteWarning_one": "You are about to delete {{count}} image. This action cannot be undone.", + "deleteWarning_other": "You are about to delete {{count}} images. This action cannot be undone.", + "deleteWarningWithThumbnail_one": "You are about to delete {{count}} image including the thumbnail. This action cannot be undone.", + "deleteWarningWithThumbnail_other": "You are about to delete {{count}} images including the thumbnail. This action cannot be undone.", + "thumbnailTooltip": "Thumbnail", + "galleryLabel": "Gallery", + "downloadImageLabel": "Download current image", + "deleteImageLabel": "Delete current image", + "noMediaLabel": "The product has no associated media." + }, + "discountableHint": "When unchecked discounts will not be applied to this product.", + "noSalesChannels": "Not available in any sales channels", + "variantCount_one": "{{count}} variant", + "variantCount_other": "{{count}} variants", + "deleteVariantWarning": "You are about to delete the variant {{title}}. This action cannot be undone.", + "productStatus": { + "draft": "Draft", + "published": "Published", + "proposed": "Proposed", + "rejected": "Rejected" + }, + "fields": { + "title": { + "label": "Title", + "hint": "Give your product a short and clear title.<0/>50-60 characters is the recommended length for search engines." + }, + "subtitle": { + "label": "Subtitle" + }, + "handle": { + "label": "Handle", + "tooltip": "The handle is used to reference the product in your storefront. If not specified, the handle will be generated from the product title." + }, + "description": { + "label": "Description", + "hint": "Give your product a short and clear description.<0/>120-160 characters is the recommended length for search engines." + }, + "discountable": { + "label": "Discountable", + "hint": "When unchecked discounts will not be applied to this product" + }, + "type": { + "label": "Type" + }, + "collection": { + "label": "Collection" + }, + "categories": { + "label": "Categories" + }, + "tags": { + "label": "Tags" + }, + "sales_channels": { + "label": "Sales channels", + "hint": "This product will only be available in the default sales channel if left untouched" + }, + "countryOrigin": { + "label": "Country of origin" + }, + "material": { + "label": "Material" + }, + "width": { + "label": "Width" + }, + "length": { + "label": "Length" + }, + "height": { + "label": "Height" + }, + "weight": { + "label": "Weight" + }, + "options": { + "label": "Product options", + "hint": "Options are used to define the color, size, etc. of the product", + "add": "Add option", + "optionTitle": "Option title", + "variations": "Variations (comma-separated)" + }, + "variants": { + "label": "Product variants", + "hint": "Variants left unchecked won't be created, This ranking will affect how the variants are ranked in your frontend." + }, + "mid_code": { + "label": "Mid code" + }, + "hs_code": { + "label": "HS code" + } + }, + "variant": { + "edit": { + "header": "Edit Variant" + }, + "create": { + "header": "Create Variant" + }, + "inventory": { + "header": "Stock & Inventory", + "editItemDetails": "Edit item details", + "manageInventoryLabel": "Manage inventory", + "manageInventoryHint": "When enabled the inventory level will be regulated when orders and returns are created.", + "allowBackordersLabel": "Allow backorders", + "allowBackordersHint": "When enabled the variant can be sold even if the inventory level is below zero.", + "toast": { + "levelsBatch": "Inventory levels updated.", + "update": "Inventory item updated successfully", + "updateLevel": "Inventory level updated successfully" + } + } + }, + "options": { + "header": "Options", + "edit": { + "header": "Edit Option", + "successToast": "Option {{title}} was successfully updated." + }, + "create": { + "header": "Create Option", + "successToast": "Option {{title}} was successfully created." + } + }, + "toasts": { + "delete": { + "success": { + "header": "Product deleted", + "description": "{{title}} was successfully deleted." + }, + "error": { + "header": "Failed to delete product" + } + } + } + }, + "collections": { + "domain": "Collections", + "createCollection": "Create Collection", + "createCollectionHint": "Create a new collection to organize your products.", + "editCollection": "Edit Collection", + "handleTooltip": "The handle is used to reference the collection in your storefront. If not specified, the handle will be generated from the collection title.", + "deleteWarning": "You are about to delete the collection {{title}}. This action cannot be undone.", + "removeSingleProductWarning": "You are about to remove the product {{title}} from the collection. This action cannot be undone.", + "removeProductsWarning_one": "You are about to remove {{count}} product from the collection. This action cannot be undone.", + "removeProductsWarning_other": "You are about to remove {{count}} products from the collection. This action cannot be undone." + }, + "categories": { + "domain": "Categories", + "organization": { + "header": "Organization", + "pathLabel": "Path", + "pathExpandTooltip": "Show full path", + "childrenLabel": "Children" + }, + "fields": { + "visibility": "Visibility", + "active": "Active", + "inactive": "Inactive", + "internal": "Internal", + "public": "Public" + } + }, + "inventory": { + "domain": "Inventory", + "reserved": "Reserved", + "available": "Available", + "locationLevels": "Location levels", + "associatedVariants": "Associated variants", + "manageLocations": "Manage locations", + "deleteWarning": "You are about to delete an inventory item. This action cannot be undone.", + "reservation": { + "header": "Reservation of {{itemName}}", + "editItemDetails": "Edit item details", + "orderID": "Order ID", + "description": "Description", + "location": "Location", + "inStockAtLocation": "In stock at this location", + "availableAtLocation": "Available at this location", + "reservedAtLocation": "Reserved at this location", + "reservedAmount": "Reserve amount", + "create": "Create reservation", + "itemToReserve": "Item to reserve", + "quantityPlaceholder": "How many do you want to reserve?", + "descriptionPlaceholder": "What type of reservation is this?", + "successToast": "Reservation was successfully created.", + "updateSuccessToast": "Reservation was successfully updated.", + "deleteSuccessToast": "Reservation was successfully deleted." + } + }, + "giftCards": { + "domain": "Gift Cards", + "editGiftCard": "Edit Gift Card", + "createGiftCard": "Create Gift Card", + "createGiftCardHint": "Manually create a gift card that can be used as a payment method in your store.", + "selectRegionFirst": "Select a region first", + "deleteGiftCardWarning": "You are about to delete the gift card {{code}}. This action cannot be undone.", + "balanceHigherThanValue": "The balance cannot be higher than the original amount.", + "balanceLowerThanZero": "The balance cannot be negative.", + "expiryDateHint": "Countries have different laws regarding gift card expiry dates. Make sure to check local regulations before setting an expiry date.", + "regionHint": "Changing the region of the gift card will also change its currency, potentially affecting its monetary value.", + "enabledHint": "Specify if the gift card is enabled or disabled.", + "balance": "Balance", + "currentBalance": "Current balance", + "initialBalance": "Initial balance", + "personalMessage": "Personal message", + "recipient": "Recipient" + }, + "customers": { + "domain": "Customers", + "create": { + "header": "Create Customer", + "hint": "Create a new customer to manage their details.", + "successToast": "Customer {{email}} was successfully created." + }, + "edit": { + "header": "Edit Customer", + "emailDisabledTooltip": "The email address cannot be changed for registered customers.", + "successToast": "Customer {{email}} was successfully updated." + }, + "delete": { + "title": "Delete Customer", + "description": "You are about to delete the customer {{email}}. This action cannot be undone.", + "successToast": "Customer {{email}} was successfully deleted." + }, + "fields": { + "guest": "Guest", + "registered": "Registered", + "groups": "Groups" + } + }, + "customerGroups": { + "domain": "Customer Groups", + "create": { + "header": "Create Customer Group", + "hint": "Create a new customer group to segment your customers.", + "successToast": "Customer group {{name}} was successfully created." + }, + "edit": { + "header": "Edit Customer Group", + "successToast": "Customer group {{name}} was successfully updated." + }, + "delete": { + "title": "Delete Customer Group", + "description": "You are about to delete the customer group {{name}}. This action cannot be undone.", + "successToast": "Customer group {{name}} was successfully deleted." + }, + "customers": { + "alreadyAddedTooltip": "The customer has already been added to the group.", + "add": { + "successToast_one": "Customer was successfully added to the group.", + "successToast_other": "Customers were successfully added to the group." + }, + "remove": { + "title_one": "Remove customer", + "title_other": "Remove customers", + "description_one": "You are about to remove {{count}} customer from the customer group. This action cannot be undone.", + "description_other": "You are about to remove {{count}} customers from the customer group. This action cannot be undone." + } + } + }, + "orders": { + "domain": "Orders", + "cancelWarning": "You are about to cancel the order {{id}}. This action cannot be undone.", + "onDateFromSalesChannel": "{{date}} from {{salesChannel}}", + "summary": { + "requestReturn": "Request return", + "allocateItems": "Allocate items", + "editItems": "Edit items" + }, + "payment": { + "title": "Payments", + "isReadyToBeCaptured": "Payment {{id}} is ready to be captured.", + "totalPaidByCustomer": "Total paid by customer", + "capture": "Capture", + "refund": "Refund", + "statusLabel": "Payment status", + "statusTitle": "Payment Status", + "status": { + "notPaid": "Not paid", + "awaiting": "Awaiting", + "captured": "Captured", + "partiallyRefunded": "Partially refunded", + "refunded": "Refunded", + "canceled": "Canceled", + "requiresAction": "Requires action" + } + }, + "edits": { + "title": "Edit order", + "currentItems": "Current items", + "currentItemsDescription": "Adjust item quantity or remove.", + "addItemsDescription": "You can add new items to the order.", + "addItems": "Add items", + "amountPaid": "Amount paid", + "newTotal": "New total", + "differenceDue": "Difference due" + }, + "returns": { + "details": "Details", + "chooseItems": "Choose items", + "refundAmount": "Refund amount", + "locationDescription": "Choose which location you want to return the items to.", + "shippingDescription": "Choose which method you want to use for this return.", + "noInventoryLevel": "No inventory level", + "sendNotification": "Send notification", + "sendNotificationHint": "Notify customer of created return.", + "customRefund": "Custom refund", + "shippingPriceTooltip1": "Custom refund is enabled", + "noShippingOptions": "There are no shipping options for the region", + "shippingPriceTooltip2": "Shipping needs to be selected", + "customRefundHint": "If you want to refund something else instead of the total refund.", + "customShippingPrice": "Custom shipping", + "customShippingPriceHint": "Custom shipping cost.", + "noInventoryLevelDesc": "The selected location does not have an inventory level for the selected items. The return can be requested but can’t be received until an inventory level is created for the selected location.", + "refundableAmountLabel": "Refundable amount", + "refundableAmountHeader": "Refundable Amount", + "returnableQuantityLabel": "Returnable quantity", + "returnableQuantityHeader": "Returnable Quantity" + }, + "reservations": { + "allocatedLabel": "Allocated", + "notAllocatedLabel": "Not allocated" + }, + "fulfillment": { + "cancelWarning": "You are about to cancel a fulfillment. This action cannot be undone.", + "unfulfilledItems": "Unfulfilled Items", + "statusLabel": "Fulfillment status", + "statusTitle": "Fulfillment Status", + "awaitingFullfillmentBadge": "Awaiting fulfillment", + "number": "Fulfillment #{{number}}", + "status": { + "notFulfilled": "Not fulfilled", + "partiallyFulfilled": "Partially fulfilled", + "fulfilled": "Fulfilled", + "partiallyShipped": "Partially shipped", + "shipped": "Shipped", + "partiallyReturned": "Partially returned", + "returned": "Returned", + "canceled": "Canceled", + "requiresAction": "Requires action" + }, + "toast": { + "canceled": "Fulfillment successfully canceled", + "fulfillmentShipped": "Cannot cancel an already shipped fulfillment" + }, + "trackingLabel": "Tracking", + "shippingFromLabel": "Shipping from", + "itemsLabel": "Items" + }, + "refund": { + "title": "Create Refund", + "sendNotificationHint": "Notify customers about the created refund.", + "systemPayment": "System payment", + "systemPaymentDesc": "One or more of your payments is a system payment. Be aware, that captures and refunds are not handled by Medusa for such payments.", + "error": { + "amountToLarge": "Cannot refund more than the original order amount.", + "amountNegative": "Refund amount must be a positive number.", + "reasonRequired": "Please select a refund reason." + } + }, + "customer": { + "contactLabel": "Contact", + "editEmail": "Edit email", + "transferOwnership": "Transfer ownership", + "editBillingAddress": "Edit billing address", + "editShippingAddress": "Edit shipping address" + }, + "activity": { + "header": "Activity", + "showMoreActivities_one": "Show {{count}} more activity", + "showMoreActivities_other": "Show {{count}} more activities", + "comment": { + "label": "Comment", + "placeholder": "Leave a comment", + "addButtonText": "Add comment", + "deleteButtonText": "Delete comment" + }, + "events": { + "placed": { + "title": "Order placed", + "fromSalesChannel": "from {{salesChannel}}" + }, + "canceled": { + "title": "Order canceled" + }, + "payment": { + "awaiting": "Awaiting payment", + "captured": "Payment captured", + "canceled": "Payment canceled" + }, + "fulfillment": { + "created": "Fulfillment created", + "canceled": "Fulfillment canceled", + "shipped": "Fulfillment shipped", + "itemsFulfilledFrom_one": "{{count}} item fulfilled from {{location}}", + "itemsFulfilledFrom_other": "{{count}} items fulfilled from {{location}}", + "itemsFulfilled_one": "{{count}} item fulfilled", + "itemsFulfilled_other": "{{count}} items fulfilled" + }, + "return": { + "created": "Return created" + }, + "note": { + "comment": "Comment", + "byLine": "by {{author}}" + } + } + } + }, + "draftOrders": { + "domain": "Draft Orders", + "deleteWarning": "You are about to delete the draft order {{id}}. This action cannot be undone.", + "paymentLinkLabel": "Payment link", + "cartIdLabel": "Cart ID", + "markAsPaid": { + "label": "Mark as paid", + "warningTitle": "Mark as Paid", + "warningDescription": "You are about to mark the draft order as paid. This action cannot be undone, and collecting payment will not be possible later." + }, + "status": { + "open": "Open", + "completed": "Completed" + }, + "create": { + "createDraftOrder": "Create Draft Order", + "createDraftOrderHint": "Create a new draft order to manage the details of an order before it is placed.", + "chooseRegionHint": "Choose region", + "existingItemsLabel": "Existing items", + "existingItemsHint": "Add existing products to the draft order.", + "customItemsLabel": "Custom items", + "customItemsHint": "Add custom items to the draft order.", + "addExistingItemsAction": "Add existing items", + "addCustomItemAction": "Add custom item", + "noCustomItemsAddedLabel": "No custom items added yet", + "noExistingItemsAddedLabel": "No existing items added yet", + "chooseRegionTooltip": "Choose a region first", + "useExistingCustomerLabel": "Use existing customer", + "addShippingMethodsAction": "Add shipping methods", + "unitPriceOverrideLabel": "Unit price override", + "shippingOptionLabel": "Shipping option", + "shippingOptionHint": "Choose the shipping option for the draft order.", + "shippingPriceOverrideLabel": "Shipping price override", + "shippingPriceOverrideHint": "Override the shipping price for the draft order.", + "sendNotificationLabel": "Send notification", + "sendNotificationHint": "Send a notification to the customer when the draft order is created." + }, + "validation": { + "requiredEmailOrCustomer": "Email or customer is required.", + "requiredItems": "At least one item is required.", + "invalidEmail": "Email must be a valid email address." + } + }, + "shipping": { + "title": "Location & Shipping", + "domain": "Location & Shipping", + "description": "Choose where you ship and how much you charge for shipping at checkout. Define shipping options specific for your locations.", + "createLocation": "Create location", + "createLocationDetailsHint": "Specify the details of the location.", + "deleteLocation": "Delete location", + "from": "Shipping from", + "add": "Add shipping", + "connectProvider": "Connect provider", + "addZone": "Add shipping zone", + "enablePickup": "Enable pickup", + "enableDelivery": "Enable delivery", + "deleteLocation": { + "label": "Delete Location", + "confirm": "Are you sure you want to delete {{name}} location", + "success": "{{name}} location successfully deleted" + }, + "noRecords": { + "action": "Add Location", + "title": "No inventory locations", + "message": "Please create an invnetory location first." + }, + "create": { + "title": "Add shipping for {{location}}", + "delivery": "Delivery", + "pickup": "Pickup", + "type": "Shipping type" + }, + "fulfillmentSet": { + "placeholder": "Not covered by any shipping zones.", + "salesChannels": "Connected Sales Channels", + "delete": "Delete shipping", + "disableWarning": "Are you sure that you wnat to disable \"{{name}}\"? This will delete all assocciated service zones and shipping options.", + "create": { + "title": "Add service zone for {{fulfillmentSet}}" + }, + "toast": { + "disable": "\"{{name}}\" disabled" + }, + "addZone": "Add service zone", + "pickup": { + "title": "Pick up", + "enable": "Enable pickup", + "offers": "Offers pick up in" + }, + "delivery": { + "title": "Shipping", + "enable": "Enable delivery", + "offers": "Offers shippping to" + } + }, + "serviceZone": { + "create": { + "title": "Add service zone for {{fulfillmentSet}}", + "subtitle": "Service zone", + "description": "A service zone is a geographical region that can be shipped to from a specific location. You can later on add any number of shipping options to this zone. ", + "zoneName": "Zone name" + }, + "edit": { + "title": "Edit Service Zone" + }, + "deleteWarning": "Are you sure you want to delete \"{{name}}\". This will also delete all assocciated shipping options.", + "toast": { + "delete": "Zone \"{{name}}\" deleted successfully." + }, + "editPrices": "Edit prices", + "editOption": "Edit option", + "optionsLength_one": "shipping option", + "optionsLength_other": "shipping options", + "returnOptionsLength_one": "return option", + "returnOptionsLength_other": "return options", + "shippingOptionsPlaceholder": "Not covered by any shipping options.", + "addOption": "Add option", + "shippingOptions": "Shipping options", + "returnOptions": "Return options", + "areas": { + "title": "Areas affected by this rule", + "description": "Select the geographical areas where this shipping zone should apply.", + "manage": "Manage areas", + "error": "Please select at least one country for this service zone." + } + }, + "shippingOptions": { + "create": { + "title": "Create a shipping option for {{zone}}", + "subtitle": "General information", + "description": "To start selling, all you need is a name and a price", + "details": "Details", + "pricing": "Pricing", + "allocation": "Shipping amount", + "fixed": "Fixed", + "fixedDescription": "Shipping option's price is always the same amount.", + "enable": "Enable in store", + "enableDescription": "Enable or disable the shipping option visiblity in store", + "calculated": "Calculated", + "calculatedDescription": "Shipping option's price is calculated by the fulfillment provider.", + "profile": "Shipping profile" + }, + "deleteWarning": "Are you sure you want to delete \"{{name}}\"?", + "toast": { + "delete": "Shipping option \"{{name}}\" deleted successfully." + }, + "inStore": "Store", + "edit": { + "title": "Edit Shipping Option", + "provider": "Fulfillment provider" + } + }, + "returnOptions": { + "create": { + "title": "Create a return option for {{zone}}" + } + }, + "salesChannels": { + "title": "Connected Sales Channels", + "placeholder": "No connected channels yet.", + "connectChannels": "Connect Channels" + } + }, + "shippingProfile": { + "domain": "Shipping Profiles", + "create": { + "header": "Create Shipping Profile", + "hint": "Create a new shipping profile to group products with similar shipping requirements.", + "successToast": "Shipping profile {{name}} was successfully created." + }, + "delete": { + "title": "Delete Shipping Profile", + "description": "You are about to delete the shipping profile {{name}}. This action cannot be undone.", + "successToast": "Shipping profile {{name}} was successfully deleted." + }, + "tooltip": { + "type": "Enter shipping profile type, for example: Express, Freight, etc." + } + }, + "discounts": { + "domain": "Discounts", + "startDate": "Start date", + "createDiscountTitle": "Create Discount", + "validDuration": "Duration of the discount", + "redemptionsLimit": "Redemptions limit", + "endDate": "End date", + "type": "Discount type", + "percentageDiscount": "Percentage discount", + "freeShipping": "Free shipping", + "fixedDiscount": "Fixed discount", + "fixedAmount": "Fixed amount", + "validRegions": "Valid regions", + "deleteWarning": "You are about to delete the discount {{code}}. This action cannot be undone.", + "editDiscountDetails": "Edit Discount Details", + "editDiscountConfiguration": "Edit Discount Configuration", + "hasStartDate": "Discount has a start date", + "hasEndDate": "Discount has an expiry date", + "startDateHint": "Schedule the discount to activate in the future.", + "endDateHint": "Schedule the discount to deactivate in the future.", + "codeHint": "Discount code applies from when you hit the publish button and forever if left untouched.", + "hasUsageLimit": "Limit the number of redemptions?", + "usageLimitHint": "Limit applies across all customers, not per customer.", + "titleHint": "The code your customers will enter during checkout. This will appear on your customer's invoice.\nUppercase letters and numbers only.", + "hasDurationLimit": "Availability duration", + "durationHint": "Set the duration of the discount", + "chooseValidRegions": "Choose valid regions", + "conditionsHint": "Create conditions to apply on the discount", + "isTemplateDiscount": "Is this a template discount?", + "percentageDescription": "Discount applied in %", + "fixedDescription": "Amount discount", + "shippingDescription": "Override delivery amount", + "selectRegionFirst": "Select a region first", + "templateHint": "Template discounts allow you to define a set of rules that can be used across a group of discounts. This is useful in campaigns that should generate unique codes for each user, but where the rules for all unique codes should be the same.", + "conditions": { + "editHeader": "Edit Discount Conditions", + "editHint": "Specify conditions for when the discount can be applied to a cart.", + "manageTypesAction": "Manage condition types", + "including": { + "products_one": "Discount applies to <0/> product", + "products_other": "Discount applies to <0/> products", + "customer_groups_one": "Discount applies to <0/> customer group", + "customer_groups_other": "Discount applies to <0/> customer groups", + "product_tags_one": "Discount applies to <0/> tag", + "product_tags_other": "Discount applies to <0/> tags", + "product_collections_one": "Discount applies to <0/> product collection", + "product_collections_other": "Discount applies to <0/> product collections", + "product_types_one": "Discount applies to <0/> product type", + "product_types_other": "Discount applies to <0/> product types" + }, + "excluding": { + "products": "Discount applies to <1>all products except <0/>", + "customer_groups": "Discount applies to <1>all customer groups except <0/>", + "product_tags": "Discount applies to <1>all product tags except <0/>", + "product_collections": "Discount applies to <1>all product collections except <0/>", + "product_types": "Discount applies to <1>all product types except <0/>" + }, + "edit": { + "appliesTo": "Discount applies to", + "except": { + "products_one": "product, except", + "products_other": "products, except", + "product_tags_one": "product tag, except", + "product_tags_other": "product tags, except", + "product_types_one": "product type, except", + "product_types_other": "product types, except", + "product_collections_one": "product collection, except", + "product_collections_other": "product collections, except", + "customer_groups_one": "customer group, except", + "customer_groups_other": "customer groups, except" + } + } + }, + "discountStatus": { + "scheduled": "Scheduled", + "expired": "Expired", + "active": "Active", + "disabled": "Disabled" + } + }, + "taxRates": { + "domain": "Tax Rates", + "fields": { + "isCombinable": "Is combinable?", + "appliesTo": "Tax Rate applies to", + "customer_groups": "Customer Group", + "product_collections": "Product Collection", + "product_tags": "Product Tag", + "product_types": "Product Type", + "products": "Product" + }, + "edit": { + "title": "Edit Tax Rate", + "description": "Edits tax rate for a tax region" + }, + "create": { + "title": "Create Tax Rate Override", + "description": "Creates tax rate overrides for a tax region" + } + }, + "taxRegions": { + "domain": "Tax Regions", + "description": "Manage your region's tax structure", + "create": { + "title": "Create Tax Region", + "description": "Creates a tax region with default tax rate" + }, + "create-child": { + "title": "Create Default Rate for Province", + "description": "Creates a tax region for a province with default tax rate" + }, + "removeWarning": "You are about to remove {{tax_region_name}}. This action cannot be undone.", + "fields": { + "rate": { + "name": "Rate", + "hint": "Tax rate to apply for a region or province" + }, + "is_combinable": { + "name": "Is combinable", + "hint": "If this tax rate can be combined with the default rate from province or parent" + } + } + }, + "promotions": { + "domain": "Promotions", + "fields": { + "method": "Method", + "type": "Type", + "value_type": "Value Type", + "value": "Value", + "campaign": "Campaign", + "allocation": "Allocation", + "addCondition": "Add condition", + "clearAll": "Clear all", + "conditions": { + "rules": { + "title": "Who can use this code?", + "description": "Is the customer allowed to add the promotion code? Discount code can be used by all customers if left untouched. Choose between attributes, operators, and values to set up the conditions." + }, + "target-rules": { + "title": "What needs to be in the cart to unlock the promotion?", + "description": "If these conditions match, we enable a promotion action on the target items. Choose between attributes, operators, and values to set up the conditions." + }, + "buy-rules": { + "title": "What will the promotion be applied to?", + "description": "The promotion will be applied to items that match these conditions" + } + } + }, + "errors": { + "requiredField": "Required field" + }, + "create": {}, + "edit": { + "title": "Edit Promotion Details", + "rules": { + "title": "Edit rules" + }, + "target-rules": { + "title": "Edit target rules" + }, + "buy-rules": { + "title": "Edit buy rules" + } + }, + "addToCampaign": { + "title": "Add Promotion To Campaign" + }, + "form": { + "required": "Required", + "and": "AND", + "selectAttribute": "Select Attribute", + "campaign": { + "existing": { + "title": "Existing Campaign", + "description": "Would you like to add promotion to an existing campaign?" + }, + "new": { + "title": "New Campaign", + "description": "Would you like to create a new campaign with this promotion?" + }, + "none": { + "title": "Without Campaign", + "description": "Proceed without associating promotion with campaign" + } + }, + "status": { + "title": "Status" + }, + "method": { + "code": { + "title": "Promotion code", + "description": "Customers must enter this at checkout" + }, + "automatic": { + "title": "Automatic", + "description": "Customers will see this at checkout" + } + }, + "max_quantity": { + "title": "Maximum Quantity", + "description": "Maximum quantity of items this promotion applies to" + }, + "type": { + "standard": { + "title": "Standard", + "description": "A standard promotion" + }, + "buyget": { + "title": "Buy Get", + "description": "Buy X get Y promotion" + } + }, + "allocation": { + "each": { + "title": "Each", + "description": "Applies value on each item" + }, + "across": { + "title": "Across", + "description": "Applies value across items" + } + }, + "code": { + "title": "Code", + "description": "The code your customers will enter during checkout." + }, + "value": { + "title": "Value" + }, + "value_type": { + "fixed": { + "title": "Fixed amount", + "description": "eg. 100" + }, + "percentage": { + "title": "Percentage", + "description": "eg. 8%" + } + } + }, + "deleteWarning": "You are about to delete the promotion {{code}}. This action cannot be undone.", + "createPromotionTitle": "Create Promotion", + "type": "Promotion type" + }, + "campaigns": { + "domain": "Campaigns", + "details": "Campaign details", + "status": { + "active": "active", + "expired": "expired", + "scheduled": "scheduled" + }, + "delete": { + "title": "Are you sure?", + "description": "You are about to delete the campaign '{{name}}'. This action cannot be undone.", + "successToast": "Campaign '{{name}}' was successfully created." + }, + "edit": { + "header": "Edit Campaign", + "successToast": "Campaign '{{name}}' was successfully updated." + }, + "create": { + "hint": "Create a promotional campaign", + "header": "Create Campaign", + "successToast": "Campaign '{{name}}' was successfully created." + }, + "fields": { + "name": "Name", + "identifier": "Identifier", + "start_date": "Start date", + "end_date": "End date", + "total_spend": "Total spend", + "budget_limit": "Budget limit" + }, + "budget": { + "create": { + "hint": "Create a budget for the campaign", + "header": "Campaign Budget" + }, + "details": "Campaign budget", + "fields": { + "type": "Type", + "currency": "Currency", + "limit": "Limit", + "used": "Used" + }, + "type": { + "spend": { + "title": "Spend", + "description": "Limit usage based on a currency value" + }, + "usage": { + "title": "Usage", + "description": "Limit usage based on how many times its used" + } + } + }, + "promotions": { + "remove": { + "title": "Remove promotion from campaign", + "description": "You are about to remove {{count}} promotion(s) from the campaign. This action cannot be undone." + }, + "alreadyAdded": "This promotion has already been added to the campaign.", + "toast": { + "success": "Successfully added {{count}} promotion(s) to campaign" + } + }, + "deleteCampaignWarning": "You are about to delete the campaign {{name}}. This action cannot be undone.", + "totalSpend": "<0>{{amount}} <1>{{currency}}" + }, + "pricing": { + "domain": "Pricing", + "create": { + "header": "Create Price List", + "hint": "Create a new price list to manage the prices of your products." + }, + "edit": { + "header": "Edit Price List" + }, + "configuration": { + "header": "Configuration", + "editHeader": "Edit Price List Configuration" + }, + "warnings": { + "delete": "You are about to delete the price list {{name}}. This action cannot be undone." + }, + "status": { + "draft": "Draft", + "expired": "Expired", + "active": "Active", + "scheduled": "Scheduled" + }, + "type": { + "sale": "Sale", + "override": "Override" + }, + "products": { + "deleteProductsPricesWarning_one": "You are about to delete {{count}} product price. This action cannot be undone.", + "deleteProductsPricesWarning_other": "You are about to delete {{count}} product prices. This action cannot be undone." + }, + "prices": { + "addPrices": "Add prices", + "editPrices": "Edit prices" + }, + "table": { + "pricesHeader": "Prices" + }, + "fields": { + "typeHint": "Choose the type of price you want to create.", + "saleTypeHint": "Sale prices are temporary price changes for products.", + "overrideTypeHint": "Overrides are usually used to create customer-specific prices.", + "startDateLabel": "Price list has a start date?", + "startDateHint": "Schedule the price list to activate in the future.", + "endDateLabel": "Price list has an expiry date?", + "endDateHint": "Schedule the price list to deactivate in the future.", + "customerAvailabilityLabel": "Customer availability", + "customerAvailabilityHint": "Choose which customer groups the price list should be applied to.", + "customerAvailabilityNoSelectionLabel": "No customer groups selected", + "priceOverridesLabel": "Price overrides" + }, + "actions": { + "addCustomerGroups": "Add customer groups" + } + }, + "profile": { + "domain": "Profile", + "manageYourProfileDetails": "Manage your profile details", + "fields": { + "languageLabel": "Language", + "usageInsightsLabel": "Usage insights" + }, + "edit": { + "header": "Edit Profile", + "languageHint": "The language you want to use in the admin dashboard. This will not change the language of your store.", + "languagePlaceholder": "Select language", + "usageInsightsHint": "Share usage insights and help us improve Medusa. You can read more about what we collect and how we use it in our <0>documentation." + }, + "toast": { + "edit": "Profiles changes saved" + } + }, + "users": { + "domain": "Users", + "editUser": "Edit User", + "inviteUser": "Invite User", + "inviteUserHint": "Invite a new user to your store.", + "sendInvite": "Send invite", + "pendingInvites": "Pending Invites", + "deleteInviteWarning": "You are about to delete the invite for {{email}}. This action cannot be undone.", + "resendInvite": "Resend invite", + "copyInviteLink": "Copy invite link", + "expiredOnDate": "Expired on {{date}}", + "validFromUntil": "Valid from <0>{{from}} - <1>{{until}}", + "acceptedOnDate": "Accepted on {{date}}", + "inviteStatus": { + "accepted": "Accepted", + "pending": "Pending", + "expired": "Expired" + }, + "roles": { + "admin": "Admin", + "developer": "Developer", + "member": "Member" + }, + "deleteUserWarning": "You are about to delete the user {{name}}. This action cannot be undone.", + "invite": "Invite" + }, + "store": { + "domain": "Store", + "manageYourStoresDetails": "Manage your store's details", + "editStore": "Edit store", + "defaultCurrency": "Default currency", + "defaultRegion": "Default region", + "swapLinkTemplate": "Swap link template", + "paymentLinkTemplate": "Payment link template", + "inviteLinkTemplate": "Invite link template", + "currencies": "Currencies", + "addCurrencies": "Add currencies", + "removeCurrencyWarning_one": "You are about to remove {{count}} currency from your store. Ensure that you have removed all prices using the currency before proceeding.", + "removeCurrencyWarning_other": "You are about to remove {{count}} currencies from your store. Ensure that you have removed all prices using the currencies before proceeding.", + "currencyAlreadyAdded": "The currency has already been added to your store.", + "edit": { + "header": "Edit Store" + }, + "toast": { + "update": "Store successfully updated", + "currenciesUpdated": "Currencies updated successfully", + "currenciesRemoved": "Removed currencies from the store successfully" + } + }, + "regions": { + "domain": "Regions", + "createRegion": "Create Region", + "createRegionHint": "Manage tax rates and providers for a set of countries.", + "addCountries": "Add countries", + "editRegion": "Edit Region", + "countriesHint": "Add the countries that should be included in this region.", + "deleteRegionWarning": "You are about to delete the region {{name}}. This action cannot be undone.", + "removeCountriesWarning_one": "You are about to remove {{count}} country from the region. This action cannot be undone.", + "removeCountriesWarning_other": "You are about to remove {{count}} countries from the region. This action cannot be undone.", + "removeCountryWarning": "You are about to remove the country {{name}} from the region. This action cannot be undone.", + "taxInclusiveHint": "When enabled prices in the region will be tax inclusive.", + "providersHint": " Add which payment providers should be available in this region.", + "shippingOptions": "Shipping Options", + "deleteShippingOptionWarning": "You are about to delete the shipping option {{name}}. This action cannot be undone.", + "return": "Return", + "outbound": "Outbound", + "priceType": "Price Type", + "flatRate": "Flat Rate", + "calculated": "Calculated", + "toast": { + "delete": "Region deleted successfully", + "edit": "Region edit saved", + "create": "Region created successfully", + "countries": "Region countries updated successfully" + }, + "shippingOption": { + "createShippingOption": "Create Shipping Option", + "createShippingOptionHint": "Create a new shipping option for the region.", + "editShippingOption": "Edit Shipping Option", + "fulfillmentMethod": "Fulfillment Method", + "type": { + "outbound": "Outbound", + "outboundHint": "Use this if you are creating a shipping option for sending products to the customer.", + "return": "Return", + "returnHint": "Use this if you are creating a shipping option for the customer to return products to you." + }, + "priceType": { + "label": "Price Type", + "flatRate": "Flat rate", + "calculated": "Calculated" + }, + "availability": { + "adminOnly": "Admin only", + "adminOnlyHint": "When enabled the shipping option will only be available in the admin dashboard, and not in the storefront." + }, + "taxInclusiveHint": "When enabled, the shipping option's price will be tax inclusive.", + "requirements": { + "label": "Requirements", + "hint": "Specify the requirements for the shipping option." + } + } + }, + "taxes": { + "domain": "Tax Regions", + "domainDescription": "Manage your tax region", + "countries": { + "taxCountriesHint": "Tax settings apply to the listed countries." + }, + "settings": { + "editTaxSettings": "Edit Tax Settings", + "taxProviderLabel": "Tax provider", + "systemTaxProviderLabel": "System Tax Provider", + "calculateTaxesAutomaticallyLabel": "Calculate taxes automatically", + "calculateTaxesAutomaticallyHint": "When enabled, tax rates will be calculated automatically and applied to carts. When disabled, taxes must be manually computed at checkout. Manual taxes are recommended for usage with third-party tax providers.", + "applyTaxesOnGiftCardsLabel": "Apply taxes on gift cards", + "applyTaxesOnGiftCardsHint": "When enabled, taxes will be applied to gift cards at checkout. In some countries, tax regulations require the application of taxes to gift cards upon purchase.", + "defaultTaxRateLabel": "Default tax rate", + "defaultTaxCodeLabel": "Default tax code" + }, + "defaultRate": { + "sectionTitle": "Default Tax Rate" + }, + "taxRate": { + "sectionTitle": "Tax Rates", + "createTaxRate": "Create Tax Rate", + "createTaxRateHint": "Create a new tax rate for the region.", + "deleteRateDescription": "You are about to delete the tax rate {{name}}. This action cannot be undone.", + "editTaxRate": "Edit Tax Rate", + "editRateAction": "Edit rate", + "editOverridesAction": "Edit overrides", + "editOverridesTitle": "Edit Tax Rate Overrides", + "editOverridesHint": "Specify the overrides for the tax rate.", + "deleteTaxRateWarning": "You are about to delete the tax rate {{name}}. This action cannot be undone.", + "productOverridesLabel": "Product overrides", + "productOverridesHint": "Specify the product overrides for the tax rate.", + "addProductOverridesAction": "Add product overrides", + "productTypeOverridesLabel": "Product type overrides", + "productTypeOverridesHint": "Specify the product type overrides for the tax rate.", + "addProductTypeOverridesAction": "Add product type overrides", + "shippingOptionOverridesLabel": "Shipping option overrides", + "shippingOptionOverridesHint": "Specify the shipping option overrides for the tax rate.", + "addShippingOptionOverridesAction": "Add shipping option overrides", + "productOverridesHeader": "Products", + "productTypeOverridesHeader": "Product Types", + "shippingOptionOverridesHeader": "Shipping Options" + } + }, + "locations": { + "domain": "Locations", + "editLocation": "Edit location", + "addSalesChannels": "Add sales channels", + "noLocationsFound": "No locations found", + "selectLocations": "Select locations that stock the item.", + "deleteLocationWarning": "You are about to delete the location {{name}}. This action cannot be undone.", + "removeSalesChannelsWarning_one": "You are about to remove {{count}} sales channel from the location.", + "removeSalesChannelsWarning_other": "You are about to remove {{count}} sales channels from the location.", + "toast": { + "create": "Location created sucessfully", + "update": "Location updated sucessfully", + "removeChannel": "Sales channel removed sucessfully" + } + }, + "reservations": { + "domain": "Reservations", + "deleteWarning": "You are about to delete a reservation. This action cannot be undone." + }, + "salesChannels": { + "domain": "Sales Channels", + "createSalesChannel": "Create Sales Channel", + "createSalesChannelHint": "Create a new sales channel to sell your products on.", + "enabledHint": "Specify if the sales channel is enabled or disabled.", + "removeProductsWarning_one": "You are about to remove {{count}} product from {{sales_channel}}.", + "removeProductsWarning_other": "You are about to remove {{count}} products from {{sales_channel}}.", + "addProducts": "Add Products", + "editSalesChannel": "Edit sales channel", + "productAlreadyAdded": "The product has already been added to the sales channel.", + "deleteSalesChannelWarning": "You are about to delete the sales channel {{name}}. This action cannot be undone.", + "toast": { + "create": "Sales channel created successfully", + "update": "Sales channel updated successfully", + "delete": "Sales channel deleted successfully" + } + }, + "apiKeyManagement": { + "domain": { + "publishable": "Publishable API Keys", + "secret": "Secret API Keys" + }, + "status": { + "active": "Active", + "revoked": "Revoked" + }, + "type": { + "publishable": "Publishable", + "secret": "Secret" + }, + "create": { + "createPublishableHeader": "Create Publishable API Key", + "createPublishableHint": "Create a new publishable API key to limit the scope of requests to specific sales channels.", + "createSecretHeader": "Create Secret API Key", + "createSecretHint": "Create a new secret API key to access the Medusa API.", + "secretKeyCreatedHeader": "Secret Key Created", + "secretKeyCreatedHint": "Your new secret key has been generated. Copy and securely store it now. This is the only time it will be displayed.", + "copySecretTokenSuccess": "Secret key was copied to clipboard.", + "copySecretTokenFailure": "Failed to copy secret key to clipboard.", + "successToast": "API key was successfully created." + }, + "edit": { + "header": "Edit API Key", + "successToast": "API key {{title}} was successfully updated." + }, + "salesChannels": { + "successToast_one": "{{count}} sales channel was successfully added to the API key.", + "successToast_other": "{{count}} sales channels were successfully added to the API key.", + "alreadyAddedTooltip": "The sales channel has already been added to the API key." + }, + "delete": { + "warning": "You are about to delete the API key {{title}}. This action cannot be undone.", + "successToast": "API key {{title}} was successfully deleted." + }, + "revoke": { + "warning": "You are about to revoke the API key {{title}}. This action cannot be undone.", + "successToast": "API key {{title}} was successfully revoked." + }, + "removeSalesChannel": { + "warning": "You are about to remove the sales channel {{name}} from the API key. This action cannot be undone.", + "warningBatch_one": "You are about to remove {{count}} sales channel from the API key. This action cannot be undone.", + "warningBatch_other": "You are about to remove {{count}} sales channels from the API key. This action cannot be undone.", + "successToast": "Sales channel was successfully removed from the API key.", + "successToastBatch_one": "{{count}} sales channel was successfully removed from the API key.", + "successToastBatch_other": "{{count}} sales channels were successfully removed from the API key." + }, + "actions": { + "revoke": "Revoke API key", + "copy": "Copy API key", + "copySuccessToast": "API key was copied to clipboard." + }, + "table": { + "lastUsedAtHeader": "Last Used At", + "createdAtHeader": "Revoked At" + }, + "fields": { + "lastUsedAtLabel": "Last used at", + "revokedByLabel": "Revoked by", + "createdByLabel": "Created by" + } + }, + "returnReasons": { + "domain": "Return Reasons", + "calloutHint": "Manage the reasons to categorize returns.", + "deleteReasonWarning": "You are about to delete the return reason {{label}}. This action cannot be undone.", + "createReason": "Create Return Reason", + "createReasonHint": "Create a new return reason to categorize returns.", + "editReason": "Edit Return Reason", + "valueTooltip": "The value should be a unique identifier for the return reason." + }, + "login": { + "forgotPassword": "Forgot password? - <0>Reset", + "title": "Log in", + "hint": "to continue to Medusa" + }, + "invite": { + "title": "Create your account", + "hint": "to continue to Medusa", + "createAccount": "Create account", + "alreadyHaveAccount": "Already have an account? - <0>Log in", + "emailTooltip": "Your email cannot be changed. If you would like to use another email, a new invite must be sent.", + "invalidInvite": "The invite is invalid or has expired.", + "successTitle": "Your account has been created", + "successHint": "Get started with Medusa Admin right away.", + "successAction": "Sign in to start using Medusa", + "invalidTokenTitle": "Your invite token is invalid", + "invalidTokenHint": "Try requesting a new invite link.", + "passwordMismatch": "Passwords do not match", + "toast": { + "accepted": "Invite successfully accepted" + } + }, + "resetPassword": { + "title": "Reset password", + "hint": "Enter your email below, and we will send you instructions on how to reset your password.", + "email": "Email", + "sendResetInstructions": "Send reset instructions", + "backToLogin": "You can always go back - <0>Log in", + "newPasswordHint": "Choose a new password below.", + "invalidTokenTitle": "Your reset token is invalid", + "invalidTokenHint": "Try requesting a new reset link.", + "expiredTokenTitle": "Your reset token has expired", + "goToResetPassword": "Go to Reset Password", + "resetPassword": "Reset password", + "tokenExpiresIn": "Token expires in <0>{{time}} minutes", + "successfulRequest": "We have sent you an email with instructions on how to reset your password. If you don't receive an email, please check your spam folder or try again." + }, + "workflowExecutions": { + "domain": "Workflows", + "transactionIdLabel": "Transaction ID", + "workflowIdLabel": "Workflow ID", + "progressLabel": "Progress", + "stepsCompletedLabel_one": "{{completed}} of {{count}} step", + "stepsCompletedLabel_other": "{{completed}} of {{count}} steps", + "history": { + "sectionTitle": "History", + "runningState": "Running...", + "awaitingState": "Awaiting", + "failedState": "Failed", + "definitionLabel": "Definition", + "outputLabel": "Output", + "compensateInputLabel": "Compensate input", + "revertedLabel": "Reverted", + "errorLabel": "Error" + }, + "state": { + "done": "Done", + "failed": "Failed", + "reverted": "Reverted", + "invoking": "Invoking", + "compensating": "Compensating", + "notStarted": "Not started" + }, + "transaction": { + "state": { + "waitingToCompensate": "Waiting to compensate" + } + }, + "step": { + "state": { + "skipped": "Skipped", + "dormant": "Dormant", + "timeout": "Timeout" + } + } + }, + "errors": { + "serverError": "Server error - Try again later.", + "invalidCredentials": "Wrong email or password" + }, + "statuses": { + "scheduled": "Scheduled", + "expired": "Expired", + "active": "Active", + "enabled": "Enabled", + "disabled": "Disabled" + }, + "fields": { + "amount": "Amount", + "refundAmount": "Refund amount", + "name": "Name", + "default": "Default", + "lastName": "Last Name", + "firstName": "First Name", + "title": "Title", + "description": "Description", + "email": "Email", + "password": "Password", + "repeatPassword": "Repeat Password", + "confirmPassword": "Confirm Password", + "newPassword": "New Password", + "repeatNewPassword": "Repeat New Password", + "categories": "Categories", + "configurations": "Configurations", + "conditions": "Conditions", + "category": "Category", + "collection": "Collection", + "discountable": "Discountable", + "handle": "Handle", + "subtitle": "Subtitle", + "limit": "Limit", + "tags": "Tags", + "type": "Type", + "reason": "Reason", + "note": "Note", + "none": "none", + "all": "all", + "percentage": "Percentage", + "sales_channels": "Sales Channels", + "customer_groups": "Customer Groups", + "product_tags": "Product Tags", + "product_types": "Product Types", + "product_collections": "Product Collections", + "status": "Status", + "code": "Code", + "value": "Value", + "disabled": "Disabled", + "dynamic": "Dynamic", + "normal": "Normal", + "years": "Years", + "months": "Months", + "days": "Days", + "hours": "Hours", + "minutes": "Minutes", + "totalRedemptions": "Total Redemptions", + "countries": "Countries", + "paymentProviders": "Payment Providers", + "fulfillmentProviders": "Fulfillment Providers", + "fulfillmentProvider": "Fulfillment Provider", + "providers": "Providers", + "availability": "Availability", + "inventory": "Inventory", + "optional": "Optional", + "note": "Note", + "taxInclusivePricing": "Tax inclusive pricing", + "taxRate": "Tax Rate", + "taxCode": "Tax Code", + "currency": "Currency", + "address": "Address", + "address2": "Apartment, suite, etc.", + "city": "City", + "postalCode": "Postal Code", + "country": "Country", + "state": "State", + "province": "Province", + "company": "Company", + "phone": "Phone", + "metadata": "Metadata", + "selectCountry": "Select country", + "products": "Products", + "variants": "Variants", + "orders": "Orders", + "account": "Account", + "total": "Total", + "totalExclTax": "Total excl. tax", + "subtotal": "Subtotal", + "shipping": "Shipping", + "tax": "Tax", + "created": "Created", + "key": "Key", + "customer": "Customer", + "date": "Date", + "order": "Order", + "fulfillment": "Fulfillment", + "provider": "Provider", + "payment": "Payment", + "items": "Items", + "salesChannel": "Sales Channel", + "region": "Region", + "discount": "Discount", + "role": "Role", + "sent": "Sent", + "salesChannels": "Sales Channels", + "product": "Product", + "createdAt": "Created at", + "updatedAt": "Updated at", + "revokedAt": "Revoked at", + "true": "True", + "false": "False", + "giftCard": "Gift Card", + "tag": "Tag", + "dateIssued": "Date issued", + "issuedDate": "Issued date", + "expiryDate": "Expiry date", + "price": "Price", + "priceTemplate": "Price {{regionOrCountry}}", + "height": "Height", + "width": "Width", + "length": "Length", + "weight": "Weight", + "midCode": "MID code", + "hsCode": "HS code", + "ean": "EAN", + "upc": "UPC", + "inventoryQuantity": "Inventory quantity", + "barcode": "Barcode", + "countryOfOrigin": "Country of origin", + "material": "Material", + "thumbnail": "Thumbnail", + "sku": "SKU", + "managedInventory": "Managed inventory", + "allowBackorder": "Allow backorder", + "inStock": "In stock", + "location": "Location", + "quantity": "Quantity", + "variant": "Variant", + "id": "ID", + "parent": "Parent", + "minSubtotal": "Min. Subtotal", + "maxSubtotal": "Max. Subtotal", + "shippingProfile": "Shipping Profile", + "summary": "Summary", + "details": "Details", + "label": "Label", + "rate": "Rate", + "requiresShipping": "Requires shipping", + "unitPrice": "Unit price", + "startDate": "Start date", + "endDate": "End date", + "draft": "Draft", + "values": "Values" + }, + "metadata": { + "warnings": { + "ignoredKeys": "This entities metadata contains complex values that we currently don't support editing through the admin UI. Due to this, the following keys are currently not being displayed: {{keys}}. You can still edit these values using the API." + } + }, + "dateTime": { + "years_one": "Year", + "years_other": "Years", + "months_one": "Month", + "months_other": "Months", + "weeks_one": "Week", + "weeks_other": "Weeks", + "days_one": "Day", + "days_other": "Days", + "hours_one": "Hour", + "hours_other": "Hours", + "minutes_one": "Minute", + "minutes_other": "Minutes", + "seconds_one": "Second", + "seconds_other": "Seconds" + } +} diff --git a/packages/admin-next/dashboard/src/i18n/translations/index.ts b/packages/admin-next/dashboard/src/i18n/translations/index.ts new file mode 100644 index 0000000000..23676c85ce --- /dev/null +++ b/packages/admin-next/dashboard/src/i18n/translations/index.ts @@ -0,0 +1,7 @@ +import en from "./en.json" + +export default { + en: { + translation: en, + }, +} diff --git a/packages/admin-next/dashboard/src/i18n/types.ts b/packages/admin-next/dashboard/src/i18n/types.ts index 35ebd4b677..b97c794028 100644 --- a/packages/admin-next/dashboard/src/i18n/types.ts +++ b/packages/admin-next/dashboard/src/i18n/types.ts @@ -1,8 +1,8 @@ import type { Locale } from "date-fns" -import en from "../../public/locales/en-US/translation.json" +import enUS from "./translations/en.json" const resources = { - translation: en, + translation: enUS, } as const export type Resources = typeof resources diff --git a/packages/admin-next/dashboard/src/lib/client/common.ts b/packages/admin-next/dashboard/src/lib/client/common.ts index 5c46bacd08..53c84cf790 100644 --- a/packages/admin-next/dashboard/src/lib/client/common.ts +++ b/packages/admin-next/dashboard/src/lib/client/common.ts @@ -1,7 +1,6 @@ import { stringify } from "qs" -const baseUrl = - import.meta.env.VITE_MEDUSA_ADMIN_BACKEND_URL || "http://localhost:9000" +const baseUrl = __BACKEND_URL__ ?? "http://localhost:9000" const commonHeaders: HeadersInit = { Accept: "application/json", diff --git a/packages/admin-next/dashboard/src/lib/medusa.ts b/packages/admin-next/dashboard/src/lib/medusa.ts index 1edaff40b1..54703f9d30 100644 --- a/packages/admin-next/dashboard/src/lib/medusa.ts +++ b/packages/admin-next/dashboard/src/lib/medusa.ts @@ -1,8 +1,7 @@ import Medusa from "@medusajs/medusa-js" import { QueryClient } from "@tanstack/react-query" -export const MEDUSA_BACKEND_URL = - import.meta.env.VITE_MEDUSA_ADMIN_BACKEND_URL || "http://localhost:9000" +export const MEDUSA_BACKEND_URL = __BACKEND_URL__ ?? "http://localhost:9000" export const queryClient = new QueryClient({ defaultOptions: { diff --git a/packages/admin-next/dashboard/src/main.tsx b/packages/admin-next/dashboard/src/main.tsx index 1a7a8db9a5..3c8eee43d9 100644 --- a/packages/admin-next/dashboard/src/main.tsx +++ b/packages/admin-next/dashboard/src/main.tsx @@ -1,8 +1,6 @@ import React from "react" import ReactDOM from "react-dom/client" import App from "./app.js" -import "./i18n/config.js" -import "./index.css" ReactDOM.createRoot(document.getElementById("root")!).render( diff --git a/packages/admin-next/dashboard/src/providers/router-provider/route-extensions.tsx b/packages/admin-next/dashboard/src/providers/router-provider/route-extensions.tsx index f82326e45a..2bdd274390 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/route-extensions.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/route-extensions.tsx @@ -1,16 +1,18 @@ import { RouteObject } from "react-router-dom" -import routes from "medusa-admin:routes/pages" +// import routes from "medusa-admin:routes/pages" + +export const RouteExtensions: RouteObject[] = [] /** * UI Route extensions. */ -export const RouteExtensions: RouteObject[] = routes.pages.map((ext) => { - return { - path: ext.path, - async lazy() { - const { default: Component } = await import(/* @vite-ignore */ ext.file) - return { Component } - }, - } -}) +// export const RouteExtensions: RouteObject[] = routes.pages.map((ext) => { +// return { +// path: ext.path, +// async lazy() { +// const { default: Component } = await import(/* @vite-ignore */ ext.file) +// return { Component } +// }, +// } +// }) diff --git a/packages/admin-next/dashboard/src/providers/router-provider/route-map.tsx b/packages/admin-next/dashboard/src/providers/router-provider/route-map.tsx index 0ddf799cfc..4601f7a80e 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/route-map.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/route-map.tsx @@ -15,9 +15,9 @@ import { import { Outlet, RouteObject } from "react-router-dom" import { ProtectedRoute } from "../../components/authentication/protected-route" -import { ErrorBoundary } from "../../components/error/error-boundary" import { MainLayout } from "../../components/layout/main-layout" import { SettingsLayout } from "../../components/layout/settings-layout" +import { ErrorBoundary } from "../../components/utilities/error-boundary" import { InventoryItemRes, PriceListRes } from "../../types/api-responses" import { RouteExtensions } from "./route-extensions" diff --git a/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx b/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx index 296b9fedf6..87b6041774 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx @@ -5,7 +5,9 @@ import { import { RouteMap } from "./route-map" -const router = createBrowserRouter(RouteMap) +const router = createBrowserRouter(RouteMap, { + basename: __BASE__ || "/", +}) export const RouterProvider = () => { return diff --git a/packages/admin-next/dashboard/src/providers/router-provider/settings-extensions.tsx b/packages/admin-next/dashboard/src/providers/router-provider/settings-extensions.tsx index cd95feda75..cedebff407 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/settings-extensions.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/settings-extensions.tsx @@ -1,15 +1,19 @@ -import settings from "medusa-admin:settings/pages" import { RouteObject } from "react-router-dom" +// import settings from "medusa-admin:settings/pages" + /** * UI Settings extensions. */ -export const SettingsExtensions: RouteObject[] = settings.pages.map((ext) => { - return { - path: `/settings${ext.path}`, - async lazy() { - const { default: Component } = await import(/* @vite-ignore */ ext.file) - return { Component } - }, - } -}) + +export const SettingsExtensions: RouteObject[] = [] + +// export const SettingsExtensions: RouteObject[] = settings.pages.map((ext) => { +// return { +// path: `/settings${ext.path}`, +// async lazy() { +// const { default: Component } = await import(/* @vite-ignore */ ext.file) +// return { Component } +// }, +// } +// }) diff --git a/packages/admin-next/dashboard/src/routes/categories/details/details.tsx b/packages/admin-next/dashboard/src/routes/categories/details/details.tsx index f2b6b1cf9c..faaa235126 100644 --- a/packages/admin-next/dashboard/src/routes/categories/details/details.tsx +++ b/packages/admin-next/dashboard/src/routes/categories/details/details.tsx @@ -1,28 +1,30 @@ -import { Container, Heading } from "@medusajs/ui"; +import { Container, Heading } from "@medusajs/ui" -import after from "medusa-admin:widgets/product_category/details/after"; -import before from "medusa-admin:widgets/product_category/details/before"; +// import after from "medusa-admin:widgets/product_category/details/after" +// import before from "medusa-admin:widgets/product_category/details/before" export const CategoryDetails = () => { return (
- {before.widgets.map((w, i) => { + {/* {before.widgets.map((w, i) => { return (
- ); - })} + ) + })} */} + Category - {after.widgets.map((w, i) => { + + {/* {after.widgets.map((w, i) => { return (
- ); - })} + ) + })} */}
- ); -}; + ) +} diff --git a/packages/admin-next/dashboard/src/routes/categories/list/list.tsx b/packages/admin-next/dashboard/src/routes/categories/list/list.tsx index 9048fd8161..285b6af1c5 100644 --- a/packages/admin-next/dashboard/src/routes/categories/list/list.tsx +++ b/packages/admin-next/dashboard/src/routes/categories/list/list.tsx @@ -1,28 +1,30 @@ -import { Container, Heading } from "@medusajs/ui"; +import { Container, Heading } from "@medusajs/ui" -import after from "medusa-admin:widgets/product_category/list/after"; -import before from "medusa-admin:widgets/product_category/list/before"; +// import after from "medusa-admin:widgets/product_category/list/after" +// import before from "medusa-admin:widgets/product_category/list/before" export const CategoriesList = () => { return (
- {before.widgets.map((w, i) => { + {/* {before.widgets.map((w, i) => { return (
- ); - })} + ) + })} */} + Categories - {after.widgets.map((w, i) => { + + {/* {after.widgets.map((w, i) => { return (
- ); - })} + ) + })} */}
- ); -}; + ) +} diff --git a/packages/admin-next/dashboard/src/routes/discounts/discount-detail/discount-detail.tsx b/packages/admin-next/dashboard/src/routes/discounts/discount-detail/discount-detail.tsx index 23bcafaa40..e23a6426f2 100644 --- a/packages/admin-next/dashboard/src/routes/discounts/discount-detail/discount-detail.tsx +++ b/packages/admin-next/dashboard/src/routes/discounts/discount-detail/discount-detail.tsx @@ -10,8 +10,8 @@ import { DiscountConditionsSection } from "./components/discount-conditions-sect import { RedemptionsSection } from "./components/discount-redemptions-section" import { discountLoader, expand } from "./loader" -import after from "medusa-admin:widgets/discount/details/after" -import before from "medusa-admin:widgets/discount/details/before" +// import after from "medusa-admin:widgets/discount/details/after" +// import before from "medusa-admin:widgets/discount/details/before" export const DiscountDetail = () => { const initialData = useLoaderData() as Awaited< @@ -33,13 +33,14 @@ export const DiscountDetail = () => { return (
- {before.widgets.map((w, i) => { + {/* {before.widgets.map((w, i) => { return (
) - })} + })} */} +
@@ -49,13 +50,15 @@ export const DiscountDetail = () => {
- {after.widgets.map((w, i) => { + + {/* {after.widgets.map((w, i) => { return (
) - })} + })} */} +
diff --git a/packages/admin-next/dashboard/src/routes/discounts/discount-list/discount-list.tsx b/packages/admin-next/dashboard/src/routes/discounts/discount-list/discount-list.tsx index d543729208..82e70cf459 100644 --- a/packages/admin-next/dashboard/src/routes/discounts/discount-list/discount-list.tsx +++ b/packages/admin-next/dashboard/src/routes/discounts/discount-list/discount-list.tsx @@ -1,18 +1,20 @@ -import after from "medusa-admin:widgets/discount/list/after" -import before from "medusa-admin:widgets/discount/list/before" +// import after from "medusa-admin:widgets/discount/list/after" +// import before from "medusa-admin:widgets/discount/list/before" import { DiscountListTable } from "./components/discount-list-table" export const DiscountsList = () => { return (
- {before.widgets.map((w, i) => ( + {/* {before.widgets.map((w, i) => ( - ))} + ))} */} + - {after.widgets.map((w, i) => ( + + {/* {after.widgets.map((w, i) => ( - ))} + ))} */}
) } diff --git a/packages/admin-next/dashboard/src/v2-routes/products/product-detail/product-detail.tsx b/packages/admin-next/dashboard/src/v2-routes/products/product-detail/product-detail.tsx index 7dd0488e90..8ae7322d8b 100644 --- a/packages/admin-next/dashboard/src/v2-routes/products/product-detail/product-detail.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/products/product-detail/product-detail.tsx @@ -9,12 +9,13 @@ import { ProductSalesChannelSection } from "./components/product-sales-channel-s import { ProductVariantSection } from "./components/product-variant-section" import { productLoader } from "./loader" -import after from "medusa-admin:widgets/product/details/after" -import before from "medusa-admin:widgets/product/details/before" -import sideAfter from "medusa-admin:widgets/product/details/side/after" -import sideBefore from "medusa-admin:widgets/product/details/side/before" -import { ProductOrganizationSection } from "./components/product-organization-section" +// import after from "medusa-admin:widgets/product/details/after" +// import before from "medusa-admin:widgets/product/details/before" +// import sideAfter from "medusa-admin:widgets/product/details/side/after" +// import sideBefore from "medusa-admin:widgets/product/details/side/before" + import { useProduct } from "../../../hooks/api/products" +import { ProductOrganizationSection } from "./components/product-organization-section" // TODO: Use product domain translations only export const ProductDetail = () => { @@ -37,50 +38,50 @@ export const ProductDetail = () => { return (
- {before.widgets.map((w, i) => { + {/* {before.widgets.map((w, i) => { return (
) - })} + })} */}
-
+
- {after.widgets.map((w, i) => { + {/* {after.widgets.map((w, i) => { return (
) - })} + })} */}
-
- {sideBefore.widgets.map((w, i) => { +
+ {/* {sideBefore.widgets.map((w, i) => { return (
) - })} + })} */} - {sideAfter.widgets.map((w, i) => { + {/* {sideAfter.widgets.map((w, i) => { return (
) - })} + })} */}
diff --git a/packages/admin-next/dashboard/src/v2-routes/products/product-list/product-list.tsx b/packages/admin-next/dashboard/src/v2-routes/products/product-list/product-list.tsx index 11513802c8..a5f36e79f5 100644 --- a/packages/admin-next/dashboard/src/v2-routes/products/product-list/product-list.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/products/product-list/product-list.tsx @@ -1,18 +1,9 @@ -import after from "medusa-admin:widgets/product/list/after" -import before from "medusa-admin:widgets/product/list/before" - import { ProductListTable } from "./components/product-list-table" export const ProductList = () => { return (
- {before.widgets.map((w, i) => ( - - ))} - {after.widgets.map((w, i) => ( - - ))}
) } diff --git a/packages/admin-next/dashboard/src/v2-routes/products/product-media/components/edit-product-media-form/edit-product-media-form.tsx b/packages/admin-next/dashboard/src/v2-routes/products/product-media/components/edit-product-media-form/edit-product-media-form.tsx index bd7e71d80f..878e97e2df 100644 --- a/packages/admin-next/dashboard/src/v2-routes/products/product-media/components/edit-product-media-form/edit-product-media-form.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/products/product-media/components/edit-product-media-form/edit-product-media-form.tsx @@ -9,15 +9,15 @@ import { useTranslation } from "react-i18next" import { z } from "zod" import { Link } from "react-router-dom" +import { + FileType, + FileUpload, +} from "../../../../../components/common/file-upload" import { Form } from "../../../../../components/common/form" import { RouteFocusModal, useRouteModal, } from "../../../../../components/route-modal" -import { - FileType, - FileUpload, -} from "../../../../../components/common/file-upload" import { useUpdateProduct } from "../../../../../hooks/api/products" type ProductMediaViewProps = { @@ -400,8 +400,10 @@ const getDefaultValues = (images: Image[] | null, thumbnail: string | null) => { })) || [] if (thumbnail && !media.some((mediaItem) => mediaItem.url === thumbnail)) { + const id = Math.random().toString(36).substring(7) + media.unshift({ - id: crypto.randomUUID(), + id: id, url: thumbnail, isThumbnail: true, file: null, diff --git a/packages/admin-next/dashboard/src/v2-routes/profile/profile-detail/components/profile-general-section/profile-general-section.tsx b/packages/admin-next/dashboard/src/v2-routes/profile/profile-detail/components/profile-general-section/profile-general-section.tsx index ec8300b49c..c6f33ff06c 100644 --- a/packages/admin-next/dashboard/src/v2-routes/profile/profile-detail/components/profile-general-section/profile-general-section.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/profile/profile-detail/components/profile-general-section/profile-general-section.tsx @@ -2,7 +2,7 @@ import { UserDTO } from "@medusajs/types" import { Button, Container, Heading, StatusBadge, Text } from "@medusajs/ui" import { useTranslation } from "react-i18next" import { Link } from "react-router-dom" -import { languages } from "../../../../../i18n/config" +import { languages } from "../../../../../i18n/languages" type ProfileGeneralSectionProps = { user: UserDTO diff --git a/packages/admin-next/dashboard/src/v2-routes/profile/profile-edit/components/edit-profile-form/edit-profile-form.tsx b/packages/admin-next/dashboard/src/v2-routes/profile/profile-edit/components/edit-profile-form/edit-profile-form.tsx index 188e55df45..b33721a17b 100644 --- a/packages/admin-next/dashboard/src/v2-routes/profile/profile-edit/components/edit-profile-form/edit-profile-form.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/profile/profile-edit/components/edit-profile-form/edit-profile-form.tsx @@ -11,7 +11,7 @@ import { useRouteModal, } from "../../../../../components/route-modal" import { useUpdateUser } from "../../../../../hooks/api/users" -import { languages } from "../../../../../i18n/config" +import { languages } from "../../../../../i18n/languages" type EditProfileProps = { user: Partial> diff --git a/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-detail/promotion-detail.tsx b/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-detail/promotion-detail.tsx index 6412740bff..b72f267538 100644 --- a/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-detail/promotion-detail.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-detail/promotion-detail.tsx @@ -7,9 +7,6 @@ import { PromotionConditionsSection } from "./components/promotion-conditions-se import { PromotionGeneralSection } from "./components/promotion-general-section" import { promotionLoader } from "./loader" -import after from "medusa-admin:widgets/promotion/details/after" -import before from "medusa-admin:widgets/promotion/details/before" - export const PromotionDetail = () => { const initialData = useLoaderData() as Awaited< ReturnType @@ -27,14 +24,6 @@ export const PromotionDetail = () => { return (
- {before.widgets.map((w, i) => { - return ( -
- -
- ) - })} -
@@ -57,14 +46,6 @@ export const PromotionDetail = () => {
- {after.widgets.map((w, i) => { - return ( -
- -
- ) - })} -
diff --git a/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-list/promotions-list.tsx b/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-list/promotions-list.tsx index 3ac5e93ffd..7dd8f27ab8 100644 --- a/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-list/promotions-list.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/promotions/promotion-list/promotions-list.tsx @@ -1,20 +1,9 @@ -import after from "medusa-admin:widgets/promotion/list/after" -import before from "medusa-admin:widgets/promotion/list/before" - import { PromotionListTable } from "./components/promotion-list-table" export const PromotionsList = () => { return (
- {before.widgets.map((w, i) => ( - - ))} - - - {after.widgets.map((w, i) => ( - - ))}
) } diff --git a/packages/admin-next/dashboard/src/vite-env.d.ts b/packages/admin-next/dashboard/src/vite-env.d.ts index 0b8f7010d7..7f76c97df9 100644 --- a/packages/admin-next/dashboard/src/vite-env.d.ts +++ b/packages/admin-next/dashboard/src/vite-env.d.ts @@ -8,3 +8,6 @@ interface ImportMetaEnv { interface ImportMeta { readonly env: ImportMetaEnv } + +declare const __BACKEND_URL__: string | undefined +declare const __BASE__: string diff --git a/packages/admin-next/dashboard/tsconfig.build.json b/packages/admin-next/dashboard/tsconfig.build.json new file mode 100644 index 0000000000..571b0fdc9e --- /dev/null +++ b/packages/admin-next/dashboard/tsconfig.build.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noImplicitAny": false, + "composite": true + } +} diff --git a/packages/admin-next/dashboard/tsup.config.ts b/packages/admin-next/dashboard/tsup.config.ts new file mode 100644 index 0000000000..4328f60dad --- /dev/null +++ b/packages/admin-next/dashboard/tsup.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from "tsup" + +export default defineConfig({ + entry: ["./src/app.tsx"], + format: ["cjs", "esm"], + external: [ + "medusa-admin:settings/pages", + "medusa-admin:routes/pages", + "medusa-admin:widgets/promotion/list/after", + "medusa-admin:widgets/promotion/list/before", + "medusa-admin:widgets/promotion/details/after", + "medusa-admin:widgets/promotion/details/before", + "medusa-admin:widgets/product/list/after", + "medusa-admin:widgets/product/list/before", + "medusa-admin:widgets/product/details/after", + "medusa-admin:widgets/product/details/before", + "medusa-admin:widgets/product/details/side/after", + "medusa-admin:widgets/product/details/side/before", + "medusa-admin:routes/links", + ], + tsconfig: "tsconfig.build.json", + clean: true, +}) diff --git a/packages/admin-next/dashboard/vite.config.mts b/packages/admin-next/dashboard/vite.config.mts index 2e26c6462c..7910421547 100644 --- a/packages/admin-next/dashboard/vite.config.mts +++ b/packages/admin-next/dashboard/vite.config.mts @@ -1,22 +1,18 @@ -import inject from "@medusajs/vite-plugin-extension" +import inject from "@medusajs/admin-vite-plugin" import react from "@vitejs/plugin-react" import { defineConfig } from "vite" +const BASE = "/" +const BACKEND_URL = "http://localhost:9000" + // https://vitejs.dev/config/ export default defineConfig({ plugins: [react(), inject()], + define: { + __BASE__: JSON.stringify(BASE), + __BACKEND_URL__: JSON.stringify(BACKEND_URL), + }, server: { open: true, }, - build: { - rollupOptions: { - output: { - manualChunks: { - react: ["react"], - "react-dom": ["react-dom"], - "react-router-dom": ["react-router-dom"], - }, - }, - }, - }, }) diff --git a/packages/cli/medusa-cli/src/create-cli.ts b/packages/cli/medusa-cli/src/create-cli.ts index e04ca8bbd0..d8e3db39f7 100644 --- a/packages/cli/medusa-cli/src/create-cli.ts +++ b/packages/cli/medusa-cli/src/create-cli.ts @@ -117,7 +117,7 @@ function buildLocalCommands(cli, isLocalProject) { .option(`v2`, { type: `boolean`, describe: `Install Medusa with the V2 feature flag enabled. WARNING: Medusa V2 is still in development and shouldn't be used in production.`, - default: false + default: false, }), desc: `Create a new Medusa project.`, handler: handlerP(newStarter), @@ -238,6 +238,19 @@ function buildLocalCommands(cli, isLocalProject) { }) ), }) + .command({ + command: `build`, + desc: `Build your project.`, + builder: (_) => _, + handler: handlerP( + getCommandHandler(`build`, (args, cmd) => { + process.env.NODE_ENV = process.env.NODE_ENV || `development` + cmd(args) + + return new Promise((resolve) => {}) + }) + ), + }) .command({ command: `start-cluster`, desc: `Start development server in cluster mode (beta).`, diff --git a/packages/core/types/package.json b/packages/core/types/package.json index d594a087fe..c1959fb408 100644 --- a/packages/core/types/package.json +++ b/packages/core/types/package.json @@ -28,6 +28,7 @@ "rimraf": "^5.0.1", "typeorm": "^0.3.16", "typescript": "^5.1.6", + "vite": "^5.2.11", "winston": "^3.8.2" }, "scripts": { diff --git a/packages/core/types/src/common/config-module.ts b/packages/core/types/src/common/config-module.ts index d8a42eb34b..a903e9d360 100644 --- a/packages/core/types/src/common/config-module.ts +++ b/packages/core/types/src/common/config-module.ts @@ -3,8 +3,42 @@ import { InternalModuleDeclaration, } from "../modules-sdk" -import { RedisOptions } from "ioredis" -import { LoggerOptions } from "typeorm" +import type { RedisOptions } from "ioredis" +import type { LoggerOptions } from "typeorm" +import type { InlineConfig } from "vite" + +/** + * @interface + * + * Admin dashboard configurations. + */ +export type AdminOptions = { + /** + * Whether to disable the admin dashboard. If set to `true`, the admin dashboard is disabled, + * in both development and production environments. The default value is `false`. + */ + disable?: boolean + /** + * The path to the admin dashboard. The default value is `/app`. + * + * The value cannot be one of the reserved paths: + * - `/admin` + * - `/store` + * - `/auth` + * - `/` + */ + path?: `/${string}` + /** + * The directory where the admin build is output. This is where the build process will place the generated files. + * The default value is `./build`. + */ + outDir?: string + /** + * Configure the Vite configuration for the admin dashboard. This function receives the default Vite configuration + * and returns the modified configuration. The default value is `undefined`. + */ + vite?: (config: InlineConfig) => InlineConfig +} /** * @interface @@ -632,6 +666,11 @@ export type ConfigModule = { */ projectConfig: ProjectConfigOptions + /** + * Admin dashboard configurations. + */ + admin?: AdminOptions + /** * On your Medusa backend, you can use [Plugins](https://docs.medusajs.com/development/plugins/overview) to add custom features or integrate third-party services. * For example, installing a plugin to use Stripe as a payment processor. diff --git a/packages/medusa/package.json b/packages/medusa/package.json index ff770bfc78..d0f7dcd302 100644 --- a/packages/medusa/package.json +++ b/packages/medusa/package.json @@ -23,14 +23,12 @@ "license": "MIT", "devDependencies": { "@medusajs/types": "^1.11.16", - "@swc/core": "^1.4.8", "@swc/jest": "^0.2.36", "@types/express": "^4.17.17", "@types/ioredis": "^4.28.10", "@types/jsonwebtoken": "^8.5.9", "@types/lodash": "^4.14.191", "@types/multer": "^1.4.7", - "@types/papaparse": "^5.3.7", "cross-env": "^5.2.1", "jest": "^25.5.4", "medusa-interfaces": "^1.3.9", @@ -51,6 +49,7 @@ "medusa-interfaces": "^1.3.7" }, "dependencies": { + "@medusajs/admin-sdk": "0.0.1", "@medusajs/core-flows": "^0.0.9", "@medusajs/link-modules": "^0.2.11", "@medusajs/medusa-cli": "^1.3.22", @@ -58,6 +57,7 @@ "@medusajs/orchestration": "^0.5.7", "@medusajs/utils": "^1.11.9", "@medusajs/workflows-sdk": "^0.1.6", + "@swc/core": "^1.4.8", "awilix": "^8.0.0", "body-parser": "^1.19.0", "boxen": "^5.0.1", diff --git a/packages/medusa/src/commands/build.ts b/packages/medusa/src/commands/build.ts new file mode 100644 index 0000000000..f4f205533c --- /dev/null +++ b/packages/medusa/src/commands/build.ts @@ -0,0 +1,156 @@ +import { ConfigModule } from "@medusajs/types" +import { transformFile } from "@swc/core" +import { getConfigFile } from "medusa-core-utils" +import fs from "node:fs/promises" +import path from "path" + +type BuildArgs = { + directory: string +} + +type FileConfig = { + inputDir: string + outputDir: string + targetExtension?: string +} + +const INPUT_DIR = "./src" +const OUTPUT_DIR = "./dist" + +const COMPILE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"] +const IGNORE_EXTENSIONS = [".md"] + +async function clean(path: string) { + await fs.rm(path, { recursive: true }).catch(() => {}) +} + +async function findFiles(dir: string): Promise { + try { + const files = await fs.readdir(dir, { withFileTypes: true }) + const paths = await Promise.all( + files.map(async (file) => { + const res = path.join(dir, file.name) + return file.isDirectory() ? findFiles(res) : res + }) + ) + return paths.flat() + } catch (e) { + console.log(`Failed to read directory ${dir}`) + throw e + } +} + +const getOutputPath = (file: string, config: FileConfig) => { + const { inputDir, outputDir, targetExtension } = config + + const inputDirName = path.basename(inputDir) + const outputDirName = path.basename(outputDir) + + const relativePath = file.replace(inputDirName, outputDirName) + let outputPath = relativePath + + if (targetExtension) { + const currentExtension = path.extname(outputPath) + outputPath = outputPath.replace(currentExtension, targetExtension) + } + + return outputPath +} + +const writeToOut = async ( + file: string, + content: string, + config: FileConfig +) => { + const outputPath = getOutputPath(file, config) + + await fs.mkdir(outputPath.replace(/\/[^/]+$/, ""), { recursive: true }) + await fs.writeFile(outputPath, content) +} + +async function copyToOut(file: string, config: FileConfig) { + const outputPath = getOutputPath(file, config) + const dirNameRegex = new RegExp("\\" + path.sep + "([^\\" + path.sep + "]+)$") + + await fs.mkdir(outputPath.replace(dirNameRegex, ""), { recursive: true }) + await fs.copyFile(file, outputPath) +} + +const medusaTransform = async (file: string) => { + if (COMPILE_EXTENSIONS.some((ext) => file.endsWith(ext))) { + const outputPath = getOutputPath(file, { + inputDir: INPUT_DIR, + outputDir: OUTPUT_DIR, + }) + const output = await transformFile(file, { + sourceFileName: path.relative(path.dirname(outputPath), file), + sourceMaps: "inline", + module: { + type: "commonjs", + }, + jsc: { + parser: { + syntax: "typescript", + decorators: true, + }, + transform: { + decoratorMetadata: true, + }, + }, + }) + await writeToOut(file, output.code, { + inputDir: INPUT_DIR, + outputDir: OUTPUT_DIR, + targetExtension: ".js", + }) + } else if (!IGNORE_EXTENSIONS.some((ext) => file.endsWith(ext))) { + // Copy non-ts files + await copyToOut(file, { inputDir: INPUT_DIR, outputDir: OUTPUT_DIR }) + } +} + +export default async function ({ directory }: BuildArgs) { + const started = Date.now() + + const { configModule, error } = getConfigFile( + directory, + "medusa-config" + ) + + if (error) { + console.log(`Failed to load medusa-config.js`) + process.exit(1) + } + + const input = path.join(directory, INPUT_DIR) + const dist = path.join(directory, OUTPUT_DIR) + + await clean(dist) + + const files = await findFiles(input) + + await Promise.all(files.map(medusaTransform)) + + const adminOptions = { + disable: false, + path: "/app" as const, + outDir: "./build", + ...configModule.admin, + } + + if (!adminOptions.disable) { + try { + const { build: buildProductionBuild } = await import( + "@medusajs/admin-sdk" + ) + + await buildProductionBuild(adminOptions) + } catch (error) { + console.log("Failed to build admin") + } + } + + const time = Date.now() - started + + console.log(`Build completed in ${time}ms`) +} diff --git a/packages/medusa/src/loaders/admin.ts b/packages/medusa/src/loaders/admin.ts new file mode 100644 index 0000000000..e4eb3ec5c0 --- /dev/null +++ b/packages/medusa/src/loaders/admin.ts @@ -0,0 +1,51 @@ +import { AdminOptions, ConfigModule } from "@medusajs/types" +import { Express } from "express" + +type Options = { + app: Express + configModule: ConfigModule +} + +type IntializedOptions = Required< + Pick +> & + AdminOptions + +export default async function adminLoader({ app, configModule }: Options) { + const { admin } = configModule + + const adminOptions: IntializedOptions = { + disable: false, + path: "/app", + outDir: "./build", + ...admin, + } + + if (admin?.disable) { + return app + } + + if (process.env.COMMAND_INITIATED_BY === "develop") { + return initDevelopmentServer(app, adminOptions) + } + + return serveProductionBuild(app, adminOptions) +} + +async function initDevelopmentServer(app: Express, options: IntializedOptions) { + const { develop } = await import("@medusajs/admin-sdk") + + const adminMiddleware = await develop(options) + app.use(options.path, adminMiddleware) + return app +} + +async function serveProductionBuild(app: Express, options: IntializedOptions) { + const { serve } = await import("@medusajs/admin-sdk") + + const adminRoute = await serve(options) + + app.use(options.path, adminRoute) + + return app +} diff --git a/packages/medusa/src/loaders/config.ts b/packages/medusa/src/loaders/config.ts index ea39deae22..b1cf60e988 100644 --- a/packages/medusa/src/loaders/config.ts +++ b/packages/medusa/src/loaders/config.ts @@ -77,6 +77,7 @@ export default (rootDirectory: string): ConfigModule => { ...configModule?.projectConfig, worker_mode, }, + admin: configModule?.admin ?? {}, modules: configModule.modules ?? {}, featureFlags: configModule?.featureFlags ?? {}, plugins: configModule?.plugins ?? [], diff --git a/packages/medusa/src/loaders/index.ts b/packages/medusa/src/loaders/index.ts index 30a61501f4..4321fc3241 100644 --- a/packages/medusa/src/loaders/index.ts +++ b/packages/medusa/src/loaders/index.ts @@ -7,6 +7,7 @@ import { createMedusaContainer } from "medusa-core-utils" import requestIp from "request-ip" import { v4 } from "uuid" import { MedusaContainer } from "../types/global" +import adminLoader from "./admin" import apiLoader from "./api" import loadConfig from "./config" import expressLoader from "./express" @@ -54,6 +55,8 @@ async function loadEntrypoints( next() }) + await adminLoader({ app: expressApp, configModule }) + // subscribersLoader({ container }) await apiLoader({ diff --git a/yarn.lock b/yarn.lock index 67bd6eafe6..26c2bee234 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3265,6 +3265,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/aix-ppc64@npm:0.20.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm64@npm:0.18.20" @@ -3279,6 +3286,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm64@npm:0.20.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm@npm:0.18.20" @@ -3293,6 +3307,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm@npm:0.20.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-x64@npm:0.18.20" @@ -3307,6 +3328,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-x64@npm:0.20.2" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-arm64@npm:0.18.20" @@ -3321,6 +3349,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-arm64@npm:0.20.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-x64@npm:0.18.20" @@ -3335,6 +3370,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-x64@npm:0.20.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-arm64@npm:0.18.20" @@ -3349,6 +3391,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-arm64@npm:0.20.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-x64@npm:0.18.20" @@ -3363,6 +3412,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-x64@npm:0.20.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm64@npm:0.18.20" @@ -3377,6 +3433,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm64@npm:0.20.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm@npm:0.18.20" @@ -3391,6 +3454,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm@npm:0.20.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ia32@npm:0.18.20" @@ -3405,6 +3475,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ia32@npm:0.20.2" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-loong64@npm:0.18.20" @@ -3419,6 +3496,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-loong64@npm:0.20.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-mips64el@npm:0.18.20" @@ -3433,6 +3517,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-mips64el@npm:0.20.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ppc64@npm:0.18.20" @@ -3447,6 +3538,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ppc64@npm:0.20.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-riscv64@npm:0.18.20" @@ -3461,6 +3559,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-riscv64@npm:0.20.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-s390x@npm:0.18.20" @@ -3475,6 +3580,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-s390x@npm:0.20.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-x64@npm:0.18.20" @@ -3489,6 +3601,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-x64@npm:0.20.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/netbsd-x64@npm:0.18.20" @@ -3503,6 +3622,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/netbsd-x64@npm:0.20.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/openbsd-x64@npm:0.18.20" @@ -3517,6 +3643,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/openbsd-x64@npm:0.20.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/sunos-x64@npm:0.18.20" @@ -3531,6 +3664,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/sunos-x64@npm:0.20.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-arm64@npm:0.18.20" @@ -3545,6 +3685,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-arm64@npm:0.20.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-ia32@npm:0.18.20" @@ -3559,6 +3706,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-ia32@npm:0.20.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-x64@npm:0.18.20" @@ -3573,6 +3727,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-x64@npm:0.20.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -4788,29 +4949,37 @@ __metadata: languageName: node linkType: hard -"@medusajs/admin-bundler@workspace:packages/admin-next/admin-bundler": +"@medusajs/admin-sdk@0.0.1, @medusajs/admin-sdk@workspace:packages/admin-next/admin-sdk": version: 0.0.0-use.local - resolution: "@medusajs/admin-bundler@workspace:packages/admin-next/admin-bundler" + resolution: "@medusajs/admin-sdk@workspace:packages/admin-next/admin-sdk" dependencies: - "@medusajs/ui-preset": ^1.1.3 - "@medusajs/vite-plugin-extension": "*" + "@medusajs/admin-vite-plugin": 0.0.1 + "@medusajs/dashboard": 0.0.1 + "@medusajs/types": ^1.11.16 + "@types/compression": ^1.7.5 + "@types/connect-history-api-fallback": ^1.5.4 "@vitejs/plugin-react": ^4.2.1 autoprefixer: ^10.4.16 commander: ^11.1.0 + compression: ^1.7.4 + connect-history-api-fallback: ^2.0.0 + copyfiles: ^2.4.1 deepmerge: ^4.3.1 + express: ^4.18.2 glob: ^7.1.6 postcss: ^8.4.32 - rimraf: 5.0.1 tailwindcss: ^3.3.6 tsup: ^8.0.1 typescript: ^5.3.3 - vite: 5.0.10 - bin: - medusa-admin: ./bin/medusa-admin.js + vite: ^5.2.11 + vite-plugin-node-polyfills: ^0.21.0 + peerDependencies: + express: ^4.18.2 + react-dom: ^18.0.0 languageName: unknown linkType: soft -"@medusajs/admin-shared@*, @medusajs/admin-shared@workspace:packages/admin-next/admin-shared": +"@medusajs/admin-shared@0.0.1, @medusajs/admin-shared@workspace:packages/admin-next/admin-shared": version: 0.0.0-use.local resolution: "@medusajs/admin-shared@workspace:packages/admin-next/admin-shared" dependencies: @@ -4818,6 +4987,27 @@ __metadata: languageName: unknown linkType: soft +"@medusajs/admin-vite-plugin@0.0.1, @medusajs/admin-vite-plugin@workspace:packages/admin-next/admin-vite-plugin": + version: 0.0.0-use.local + resolution: "@medusajs/admin-vite-plugin@workspace:packages/admin-next/admin-vite-plugin" + dependencies: + "@babel/parser": 7.23.5 + "@babel/traverse": 7.23.5 + "@babel/types": 7.22.5 + "@medusajs/admin-shared": 0.0.1 + "@types/babel__traverse": 7.20.5 + "@types/node": ^20.10.4 + chokidar: 3.5.3 + fdir: 6.1.1 + magic-string: 0.30.5 + tsup: 8.0.1 + typescript: 5.3.3 + vite: ^5.2.11 + peerDependencies: + vite: ^5.0.0 + languageName: unknown + linkType: soft + "@medusajs/api-key@workspace:^, @medusajs/api-key@workspace:packages/modules/api-key": version: 0.0.0-use.local resolution: "@medusajs/api-key@workspace:packages/modules/api-key" @@ -5005,7 +5195,7 @@ __metadata: languageName: unknown linkType: soft -"@medusajs/dashboard@workspace:packages/admin-next/dashboard": +"@medusajs/dashboard@0.0.1, @medusajs/dashboard@workspace:packages/admin-next/dashboard": version: 0.0.0-use.local resolution: "@medusajs/dashboard@workspace:packages/admin-next/dashboard" dependencies: @@ -5013,12 +5203,11 @@ __metadata: "@dnd-kit/core": ^6.1.0 "@dnd-kit/sortable": ^8.0.0 "@hookform/resolvers": 3.3.2 - "@medusajs/icons": "workspace:^" - "@medusajs/medusa": "workspace:^" - "@medusajs/types": "workspace:^" - "@medusajs/ui": "workspace:^" - "@medusajs/ui-preset": "workspace:^" - "@medusajs/vite-plugin-extension": "workspace:^" + "@medusajs/admin-vite-plugin": 0.0.1 + "@medusajs/icons": 1.2.1 + "@medusajs/types": 1.11.16 + "@medusajs/ui": 3.0.0 + "@medusajs/ui-preset": 1.1.3 "@radix-ui/react-collapsible": 1.0.3 "@radix-ui/react-hover-card": ^1.0.7 "@tanstack/react-query": ^5.28.14 @@ -5051,9 +5240,10 @@ __metadata: react-resizable-panels: ^2.0.16 react-router-dom: 6.20.1 tailwindcss: ^3.4.1 + tsup: ^8.0.2 typescript: 5.2.2 - vite: 5.0.10 - zod: 3.22.4 + vite: ^5.2.11 + zod: ^3.22.4 languageName: unknown linkType: soft @@ -5190,7 +5380,7 @@ __metadata: languageName: unknown linkType: soft -"@medusajs/icons@^1.2.1, @medusajs/icons@workspace:^, @medusajs/icons@workspace:packages/design-system/icons": +"@medusajs/icons@1.2.1, @medusajs/icons@^1.2.1, @medusajs/icons@workspace:packages/design-system/icons": version: 0.0.0-use.local resolution: "@medusajs/icons@workspace:packages/design-system/icons" dependencies: @@ -5370,10 +5560,11 @@ __metadata: languageName: unknown linkType: soft -"@medusajs/medusa@^1.20.3, @medusajs/medusa@^1.20.4, @medusajs/medusa@workspace:*, @medusajs/medusa@workspace:^, @medusajs/medusa@workspace:packages/medusa": +"@medusajs/medusa@^1.20.3, @medusajs/medusa@^1.20.4, @medusajs/medusa@workspace:*, @medusajs/medusa@workspace:packages/medusa": version: 0.0.0-use.local resolution: "@medusajs/medusa@workspace:packages/medusa" dependencies: + "@medusajs/admin-sdk": 0.0.1 "@medusajs/core-flows": ^0.0.9 "@medusajs/link-modules": ^0.2.11 "@medusajs/medusa-cli": ^1.3.22 @@ -5389,7 +5580,6 @@ __metadata: "@types/jsonwebtoken": ^8.5.9 "@types/lodash": ^4.14.191 "@types/multer": ^1.4.7 - "@types/papaparse": ^5.3.7 awilix: ^8.0.0 body-parser: ^1.19.0 boxen: ^5.0.1 @@ -5891,7 +6081,7 @@ __metadata: languageName: unknown linkType: soft -"@medusajs/types@^1.11.12, @medusajs/types@^1.11.14, @medusajs/types@^1.11.15, @medusajs/types@^1.11.16, @medusajs/types@^1.11.6, @medusajs/types@workspace:^, @medusajs/types@workspace:packages/core/types": +"@medusajs/types@1.11.16, @medusajs/types@^1.11.12, @medusajs/types@^1.11.14, @medusajs/types@^1.11.15, @medusajs/types@^1.11.16, @medusajs/types@^1.11.6, @medusajs/types@workspace:^, @medusajs/types@workspace:packages/core/types": version: 0.0.0-use.local resolution: "@medusajs/types@workspace:packages/core/types" dependencies: @@ -5902,11 +6092,12 @@ __metadata: rimraf: ^5.0.1 typeorm: ^0.3.16 typescript: ^5.1.6 + vite: ^5.2.11 winston: ^3.8.2 languageName: unknown linkType: soft -"@medusajs/ui-preset@^1.1.3, @medusajs/ui-preset@workspace:^, @medusajs/ui-preset@workspace:packages/design-system/ui-preset": +"@medusajs/ui-preset@1.1.3, @medusajs/ui-preset@^1.1.3, @medusajs/ui-preset@workspace:packages/design-system/ui-preset": version: 0.0.0-use.local resolution: "@medusajs/ui-preset@workspace:packages/design-system/ui-preset" dependencies: @@ -5921,7 +6112,7 @@ __metadata: languageName: unknown linkType: soft -"@medusajs/ui@workspace:^, @medusajs/ui@workspace:packages/design-system/ui": +"@medusajs/ui@3.0.0, @medusajs/ui@workspace:packages/design-system/ui": version: 0.0.0-use.local resolution: "@medusajs/ui@workspace:packages/design-system/ui" dependencies: @@ -6046,27 +6237,6 @@ __metadata: languageName: unknown linkType: soft -"@medusajs/vite-plugin-extension@*, @medusajs/vite-plugin-extension@workspace:^, @medusajs/vite-plugin-extension@workspace:packages/admin-next/vite-plugin-extension": - version: 0.0.0-use.local - resolution: "@medusajs/vite-plugin-extension@workspace:packages/admin-next/vite-plugin-extension" - dependencies: - "@babel/parser": 7.23.5 - "@babel/traverse": 7.23.5 - "@babel/types": 7.22.5 - "@medusajs/admin-shared": "*" - "@types/babel__traverse": 7.20.5 - "@types/node": ^20.10.4 - chokidar: 3.5.3 - fdir: 6.1.1 - magic-string: 0.30.5 - tsup: 8.0.1 - typescript: 5.3.3 - vite: 5.0.10 - peerDependencies: - vite: ^5.0.0 - languageName: unknown - linkType: soft - "@medusajs/workflow-engine-inmemory@workspace:*, @medusajs/workflow-engine-inmemory@workspace:packages/modules/workflow-engine-inmemory": version: 0.0.0-use.local resolution: "@medusajs/workflow-engine-inmemory@workspace:packages/modules/workflow-engine-inmemory" @@ -8445,6 +8615,22 @@ __metadata: languageName: node linkType: hard +"@rollup/plugin-inject@npm:^5.0.5": + version: 5.0.5 + resolution: "@rollup/plugin-inject@npm:5.0.5" + dependencies: + "@rollup/pluginutils": ^5.0.1 + estree-walker: ^2.0.2 + magic-string: ^0.30.3 + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 22d10cf44fa56a6683d5ac4df24a9003379b3dcaae9897f5c30c844afc2ebca83cfaa5557f13a1399b1c8a0d312c3217bcacd508b7ebc4b2cbee401bd1ec8be2 + languageName: node + linkType: hard + "@rollup/plugin-json@npm:^4.1.0": version: 4.1.0 resolution: "@rollup/plugin-json@npm:4.1.0" @@ -10859,6 +11045,15 @@ __metadata: languageName: node linkType: hard +"@types/compression@npm:^1.7.5": + version: 1.7.5 + resolution: "@types/compression@npm:1.7.5" + dependencies: + "@types/express": "*" + checksum: 3818f3d10cede38a835b40b80c341eae162aef1691f2e8f81178a77dbc109f04234cf760b6066eaa06ecbb1da143433c00db2fd9999198b76cd5a193e1d09675 + languageName: node + linkType: hard + "@types/configstore@npm:^6.0.0": version: 6.0.2 resolution: "@types/configstore@npm:6.0.2" @@ -10866,6 +11061,16 @@ __metadata: languageName: node linkType: hard +"@types/connect-history-api-fallback@npm:^1.5.4": + version: 1.5.4 + resolution: "@types/connect-history-api-fallback@npm:1.5.4" + dependencies: + "@types/express-serve-static-core": "*" + "@types/node": "*" + checksum: 1b4035b627dcd714b05a22557f942e24a57ca48e7377dde0d2f86313fe685bc0a6566512a73257a55b5665b96c3041fb29228ac93331d8133011716215de8244 + languageName: node + linkType: hard + "@types/connect@npm:*": version: 3.4.38 resolution: "@types/connect@npm:3.4.38" @@ -10947,7 +11152,7 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:^4.17.33": +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33": version: 4.19.0 resolution: "@types/express-serve-static-core@npm:4.19.0" dependencies: @@ -11298,15 +11503,6 @@ __metadata: languageName: node linkType: hard -"@types/papaparse@npm:^5.3.7": - version: 5.3.14 - resolution: "@types/papaparse@npm:5.3.14" - dependencies: - "@types/node": "*" - checksum: feb4d215903b67442feaa9836a6a5771e78dc6a9da24781e399c6f891622fa82245cd783ab2613c5be43e4a2d6a94da52325538e4485af258166864576ecd0d8 - languageName: node - linkType: hard - "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -12701,6 +12897,17 @@ __metadata: languageName: node linkType: hard +"asn1.js@npm:^4.10.1": + version: 4.10.1 + resolution: "asn1.js@npm:4.10.1" + dependencies: + bn.js: ^4.0.0 + inherits: ^2.0.1 + minimalistic-assert: ^1.0.0 + checksum: afa7f3ab9e31566c80175a75b182e5dba50589dcc738aa485be42bdd787e2a07246a4b034d481861123cbe646a7656f318f4f1cad2e9e5e808a210d5d6feaa88 + languageName: node + linkType: hard + "asn1@npm:~0.2.3": version: 0.2.6 resolution: "asn1@npm:0.2.6" @@ -12717,7 +12924,7 @@ __metadata: languageName: node linkType: hard -"assert@npm:^2.1.0": +"assert@npm:^2.0.0, assert@npm:^2.1.0": version: 2.1.0 resolution: "assert@npm:2.1.0" dependencies: @@ -13356,6 +13563,20 @@ __metadata: languageName: node linkType: hard +"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": + version: 4.12.0 + resolution: "bn.js@npm:4.12.0" + checksum: 9736aaa317421b6b3ed038ff3d4491935a01419ac2d83ddcfebc5717385295fcfcf0c57311d90fe49926d0abbd7a9dbefdd8861e6129939177f7e67ebc645b21 + languageName: node + linkType: hard + +"bn.js@npm:^5.0.0, bn.js@npm:^5.2.1": + version: 5.2.1 + resolution: "bn.js@npm:5.2.1" + checksum: bed3d8bd34ec89dbcf9f20f88bd7d4a49c160fda3b561c7bb227501f974d3e435a48fb9b61bc3de304acab9215a3bda0803f7017ffb4d0016a0c3a740a283caa + languageName: node + linkType: hard + "body-parser@npm:1.19.0": version: 1.19.0 resolution: "body-parser@npm:1.19.0" @@ -13488,6 +13709,13 @@ __metadata: languageName: node linkType: hard +"brorand@npm:^1.0.1, brorand@npm:^1.1.0": + version: 1.1.0 + resolution: "brorand@npm:1.1.0" + checksum: 6f366d7c4990f82c366e3878492ba9a372a73163c09871e80d82fb4ae0d23f9f8924cb8a662330308206e6b3b76ba1d528b4601c9ef73c2166b440b2ea3b7571 + languageName: node + linkType: hard + "brotli-size@npm:^4.0.0": version: 4.0.0 resolution: "brotli-size@npm:4.0.0" @@ -13520,6 +13748,80 @@ __metadata: languageName: node linkType: hard +"browser-resolve@npm:^2.0.0": + version: 2.0.0 + resolution: "browser-resolve@npm:2.0.0" + dependencies: + resolve: ^1.17.0 + checksum: 06c43adf3cb1939825ab9a4ac355b23272820ee421a20d04f62e0dabd9ea305e497b97f3ac027f87d53c366483aafe8673bbe1aaa5e41cd69eeafa65ac5fda6e + languageName: node + linkType: hard + +"browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": + version: 1.2.0 + resolution: "browserify-aes@npm:1.2.0" + dependencies: + buffer-xor: ^1.0.3 + cipher-base: ^1.0.0 + create-hash: ^1.1.0 + evp_bytestokey: ^1.0.3 + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: 967f2ae60d610b7b252a4cbb55a7a3331c78293c94b4dd9c264d384ca93354c089b3af9c0dd023534efdc74ffbc82510f7ad4399cf82bc37bc07052eea485f18 + languageName: node + linkType: hard + +"browserify-cipher@npm:^1.0.0": + version: 1.0.1 + resolution: "browserify-cipher@npm:1.0.1" + dependencies: + browserify-aes: ^1.0.4 + browserify-des: ^1.0.0 + evp_bytestokey: ^1.0.0 + checksum: aa256dcb42bc53a67168bbc94ab85d243b0a3b56109dee3b51230b7d010d9b78985ffc1fb36e145c6e4db151f888076c1cfc207baf1525d3e375cbe8187fe27d + languageName: node + linkType: hard + +"browserify-des@npm:^1.0.0": + version: 1.0.2 + resolution: "browserify-des@npm:1.0.2" + dependencies: + cipher-base: ^1.0.1 + des.js: ^1.0.0 + inherits: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: 943eb5d4045eff80a6cde5be4e5fbb1f2d5002126b5a4789c3c1aae3cdddb1eb92b00fb92277f512288e5c6af330730b1dbabcf7ce0923e749e151fcee5a074d + languageName: node + linkType: hard + +"browserify-rsa@npm:^4.0.0, browserify-rsa@npm:^4.1.0": + version: 4.1.0 + resolution: "browserify-rsa@npm:4.1.0" + dependencies: + bn.js: ^5.0.0 + randombytes: ^2.0.1 + checksum: fb2b5a8279d8a567a28d8ee03fb62e448428a906bab5c3dc9e9c3253ace551b5ea271db15e566ac78f1b1d71b243559031446604168b9235c351a32cae99d02a + languageName: node + linkType: hard + +"browserify-sign@npm:^4.0.0": + version: 4.2.3 + resolution: "browserify-sign@npm:4.2.3" + dependencies: + bn.js: ^5.2.1 + browserify-rsa: ^4.1.0 + create-hash: ^1.2.0 + create-hmac: ^1.1.7 + elliptic: ^6.5.5 + hash-base: ~3.0 + inherits: ^2.0.4 + parse-asn1: ^5.1.7 + readable-stream: ^2.3.8 + safe-buffer: ^5.2.1 + checksum: 30c0eba3f5970a20866a4d3fbba2c5bd1928cd24f47faf995f913f1499214c6f3be14bb4d6ec1ab5c6cafb1eca9cb76ba1c2e1c04ed018370634d4e659c77216 + languageName: node + linkType: hard + "browserify-zlib@npm:^0.1.4": version: 0.1.4 resolution: "browserify-zlib@npm:0.1.4" @@ -13529,6 +13831,15 @@ __metadata: languageName: node linkType: hard +"browserify-zlib@npm:^0.2.0": + version: 0.2.0 + resolution: "browserify-zlib@npm:0.2.0" + dependencies: + pako: ~1.0.5 + checksum: 9ab10b6dc732c6c5ec8ebcbe5cb7fe1467f97402c9b2140113f47b5f187b9438f93a8e065d8baf8b929323c18324fbf1105af479ee86d9d36cab7d7ef3424ad9 + languageName: node + linkType: hard + "browserslist-generator@npm:^2.1.0": version: 2.1.0 resolution: "browserslist-generator@npm:2.1.0" @@ -13607,7 +13918,14 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.5.0, buffer@npm:^5.6.0": +"buffer-xor@npm:^1.0.3": + version: 1.0.3 + resolution: "buffer-xor@npm:1.0.3" + checksum: fd269d0e0bf71ecac3146187cfc79edc9dbb054e2ee69b4d97dfb857c6d997c33de391696d04bdd669272751fa48e7872a22f3a6c7b07d6c0bc31dbe02a4075c + languageName: node + linkType: hard + +"buffer@npm:^5.5.0, buffer@npm:^5.6.0, buffer@npm:^5.7.1": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -13634,6 +13952,13 @@ __metadata: languageName: node linkType: hard +"builtin-status-codes@npm:^3.0.0": + version: 3.0.0 + resolution: "builtin-status-codes@npm:3.0.0" + checksum: c37bbba11a34c4431e56bd681b175512e99147defbe2358318d8152b3a01df7bf25e0305873947e5b350073d5ef41a364a22b37e48f1fb6d2fe6d5286a0f348c + languageName: node + linkType: hard + "bullmq@npm:^5.4.2": version: 5.7.8 resolution: "bullmq@npm:5.7.8" @@ -14077,6 +14402,16 @@ __metadata: languageName: node linkType: hard +"cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": + version: 1.0.4 + resolution: "cipher-base@npm:1.0.4" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: d8d005f8b64d8a77b3d3ce531301ae7b45902c9cab4ec8b66bdbd2bf2a1d9fceb9a2133c293eb3c060b2d964da0f14c47fb740366081338aa3795dd1faa8984b + languageName: node + linkType: hard + "citty@npm:^0.1.6": version: 0.1.6 resolution: "citty@npm:0.1.6" @@ -14697,6 +15032,13 @@ __metadata: languageName: node linkType: hard +"connect-history-api-fallback@npm:^2.0.0": + version: 2.0.0 + resolution: "connect-history-api-fallback@npm:2.0.0" + checksum: 90fa8b16ab76e9531646cc70b010b1dbd078153730c510d3142f6cf07479ae8a812c5a3c0e40a28528dd1681a62395d0cfdef67da9e914c4772ac85d69a3ed87 + languageName: node + linkType: hard + "connect-redis@npm:^5.0.0": version: 5.2.0 resolution: "connect-redis@npm:5.2.0" @@ -14711,6 +15053,20 @@ __metadata: languageName: node linkType: hard +"console-browserify@npm:^1.1.0": + version: 1.2.0 + resolution: "console-browserify@npm:1.2.0" + checksum: 89b99a53b7d6cee54e1e64fa6b1f7ac24b844b4019c5d39db298637e55c1f4ffa5c165457ad984864de1379df2c8e1886cbbdac85d9dbb6876a9f26c3106f226 + languageName: node + linkType: hard + +"constants-browserify@npm:^1.0.0": + version: 1.0.0 + resolution: "constants-browserify@npm:1.0.0" + checksum: ab49b1d59a433ed77c964d90d19e08b2f77213fb823da4729c0baead55e3c597f8f97ebccfdfc47bd896d43854a117d114c849a6f659d9986420e97da0f83ac5 + languageName: node + linkType: hard + "content-disposition@npm:0.5.3": version: 0.5.3 resolution: "content-disposition@npm:0.5.3" @@ -14828,6 +15184,24 @@ __metadata: languageName: node linkType: hard +"copyfiles@npm:^2.4.1": + version: 2.4.1 + resolution: "copyfiles@npm:2.4.1" + dependencies: + glob: ^7.0.5 + minimatch: ^3.0.3 + mkdirp: ^1.0.4 + noms: 0.0.0 + through2: ^2.0.1 + untildify: ^4.0.0 + yargs: ^16.1.0 + bin: + copyfiles: copyfiles + copyup: copyfiles + checksum: e65cd055ec9acc14997b0ace83973d73f8d9c68167cbf4293c40b52d100af09a8c8da329042d52dc33422c0a8cbf74c6efb25e9ae088667721653659bd67bf57 + languageName: node + linkType: hard + "core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.36.1, core-js-compat@npm:^3.6.2": version: 3.37.0 resolution: "core-js-compat@npm:3.37.0" @@ -14898,6 +15272,43 @@ __metadata: languageName: node linkType: hard +"create-ecdh@npm:^4.0.0": + version: 4.0.4 + resolution: "create-ecdh@npm:4.0.4" + dependencies: + bn.js: ^4.1.0 + elliptic: ^6.5.3 + checksum: 77b11a51360fec9c3bce7a76288fc0deba4b9c838d5fb354b3e40c59194d23d66efe6355fd4b81df7580da0661e1334a235a2a5c040b7569ba97db428d466e7f + languageName: node + linkType: hard + +"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": + version: 1.2.0 + resolution: "create-hash@npm:1.2.0" + dependencies: + cipher-base: ^1.0.1 + inherits: ^2.0.1 + md5.js: ^1.3.4 + ripemd160: ^2.0.1 + sha.js: ^2.4.0 + checksum: d402e60e65e70e5083cb57af96d89567954d0669e90550d7cec58b56d49c4b193d35c43cec8338bc72358198b8cbf2f0cac14775b651e99238e1cf411490f915 + languageName: node + linkType: hard + +"create-hmac@npm:^1.1.0, create-hmac@npm:^1.1.4, create-hmac@npm:^1.1.7": + version: 1.1.7 + resolution: "create-hmac@npm:1.1.7" + dependencies: + cipher-base: ^1.0.3 + create-hash: ^1.1.0 + inherits: ^2.0.1 + ripemd160: ^2.0.0 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: 24332bab51011652a9a0a6d160eed1e8caa091b802335324ae056b0dcb5acbc9fcf173cf10d128eba8548c3ce98dfa4eadaa01bd02f44a34414baee26b651835 + languageName: node + linkType: hard + "create-jest@npm:^29.7.0": version: 29.7.0 resolution: "create-jest@npm:29.7.0" @@ -14960,7 +15371,7 @@ __metadata: languageName: unknown linkType: soft -"create-require@npm:^1.1.0": +"create-require@npm:^1.1.0, create-require@npm:^1.1.1": version: 1.1.1 resolution: "create-require@npm:1.1.1" checksum: 157cbc59b2430ae9a90034a5f3a1b398b6738bf510f713edc4d4e45e169bc514d3d99dd34d8d01ca7ae7830b5b8b537e46ae8f3c8f932371b0875c0151d7ec91 @@ -15062,6 +15473,25 @@ __metadata: languageName: node linkType: hard +"crypto-browserify@npm:^3.11.0": + version: 3.12.0 + resolution: "crypto-browserify@npm:3.12.0" + dependencies: + browserify-cipher: ^1.0.0 + browserify-sign: ^4.0.0 + create-ecdh: ^4.0.0 + create-hash: ^1.1.0 + create-hmac: ^1.1.0 + diffie-hellman: ^5.0.0 + inherits: ^2.0.1 + pbkdf2: ^3.0.3 + public-encrypt: ^4.0.0 + randombytes: ^2.0.0 + randomfill: ^1.0.3 + checksum: 0c20198886576050a6aa5ba6ae42f2b82778bfba1753d80c5e7a090836890dc372bdc780986b2568b4fb8ed2a91c958e61db1f0b6b1cc96af4bd03ffc298ba92 + languageName: node + linkType: hard + "crypto-random-string@npm:^2.0.0": version: 2.0.0 resolution: "crypto-random-string@npm:2.0.0" @@ -15825,6 +16255,16 @@ __metadata: languageName: node linkType: hard +"des.js@npm:^1.0.0": + version: 1.1.0 + resolution: "des.js@npm:1.1.0" + dependencies: + inherits: ^2.0.1 + minimalistic-assert: ^1.0.0 + checksum: 671354943ad67493e49eb4c555480ab153edd7cee3a51c658082fcde539d2690ed2a4a0b5d1f401f9cde822edf3939a6afb2585f32c091f2d3a1b1665cd45236 + languageName: node + linkType: hard + "destroy@npm:1.2.0": version: 1.2.0 resolution: "destroy@npm:1.2.0" @@ -15924,6 +16364,17 @@ __metadata: languageName: node linkType: hard +"diffie-hellman@npm:^5.0.0": + version: 5.0.3 + resolution: "diffie-hellman@npm:5.0.3" + dependencies: + bn.js: ^4.1.0 + miller-rabin: ^4.0.0 + randombytes: ^2.0.0 + checksum: ce53ccafa9ca544b7fc29b08a626e23a9b6562efc2a98559a0c97b4718937cebaa9b5d7d0a05032cc9c1435e9b3c1532b9e9bf2e0ede868525922807ad6e1ecf + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -15994,6 +16445,13 @@ __metadata: languageName: node linkType: hard +"domain-browser@npm:^4.22.0": + version: 4.23.0 + resolution: "domain-browser@npm:4.23.0" + checksum: dfcc6ba070a2c968a4d922e7d99ef440d1076812af0d983404aadf64729f746bb4a0ad2c5e73ccd5d9cf41bc79037f2a1e4a915bdf33d07e0d77f487b635b5b2 + languageName: node + linkType: hard + "domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -16232,6 +16690,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:^6.5.3, elliptic@npm:^6.5.5": + version: 6.5.5 + resolution: "elliptic@npm:6.5.5" + dependencies: + bn.js: ^4.11.9 + brorand: ^1.1.0 + hash.js: ^1.0.0 + hmac-drbg: ^1.0.1 + inherits: ^2.0.4 + minimalistic-assert: ^1.0.1 + minimalistic-crypto-utils: ^1.0.1 + checksum: 3e591e93783a1b66f234ebf5bd3a8a9a8e063a75073a35a671e03e3b25253b6e33ac121f7efe9b8808890fffb17b40596cc19d01e6e8d1fa13b9a56ff65597c8 + languageName: node + linkType: hard + "emittery@npm:^0.13.0, emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -16682,7 +17155,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.2, esbuild@npm:^0.19.3": +"esbuild@npm:^0.19.2": version: 0.19.12 resolution: "esbuild@npm:0.19.12" dependencies: @@ -16762,6 +17235,86 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.20.1": + version: 0.20.2 + resolution: "esbuild@npm:0.20.2" + dependencies: + "@esbuild/aix-ppc64": 0.20.2 + "@esbuild/android-arm": 0.20.2 + "@esbuild/android-arm64": 0.20.2 + "@esbuild/android-x64": 0.20.2 + "@esbuild/darwin-arm64": 0.20.2 + "@esbuild/darwin-x64": 0.20.2 + "@esbuild/freebsd-arm64": 0.20.2 + "@esbuild/freebsd-x64": 0.20.2 + "@esbuild/linux-arm": 0.20.2 + "@esbuild/linux-arm64": 0.20.2 + "@esbuild/linux-ia32": 0.20.2 + "@esbuild/linux-loong64": 0.20.2 + "@esbuild/linux-mips64el": 0.20.2 + "@esbuild/linux-ppc64": 0.20.2 + "@esbuild/linux-riscv64": 0.20.2 + "@esbuild/linux-s390x": 0.20.2 + "@esbuild/linux-x64": 0.20.2 + "@esbuild/netbsd-x64": 0.20.2 + "@esbuild/openbsd-x64": 0.20.2 + "@esbuild/sunos-x64": 0.20.2 + "@esbuild/win32-arm64": 0.20.2 + "@esbuild/win32-ia32": 0.20.2 + "@esbuild/win32-x64": 0.20.2 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 66398f9fb2c65e456a3e649747b39af8a001e47963b25e86d9c09d2a48d61aa641b27da0ce5cad63df95ad246105e1d83e7fee0e1e22a0663def73b1c5101112 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.1.2": version: 3.1.2 resolution: "escalade@npm:3.1.2" @@ -17226,6 +17779,24 @@ __metadata: languageName: node linkType: hard +"events@npm:^3.0.0": + version: 3.3.0 + resolution: "events@npm:3.3.0" + checksum: d6b6f2adbccbcda74ddbab52ed07db727ef52e31a61ed26db9feb7dc62af7fc8e060defa65e5f8af9449b86b52cc1a1f6a79f2eafcf4e62add2b7a1fa4a432f6 + languageName: node + linkType: hard + +"evp_bytestokey@npm:^1.0.0, evp_bytestokey@npm:^1.0.3": + version: 1.0.3 + resolution: "evp_bytestokey@npm:1.0.3" + dependencies: + md5.js: ^1.3.4 + node-gyp: latest + safe-buffer: ^5.1.1 + checksum: 77fbe2d94a902a80e9b8f5a73dcd695d9c14899c5e82967a61b1fc6cbbb28c46552d9b127cff47c45fcf684748bdbcfa0a50410349109de87ceb4b199ef6ee99 + languageName: node + linkType: hard + "exec-sh@npm:^0.3.2": version: 0.3.6 resolution: "exec-sh@npm:0.3.6" @@ -18504,7 +19075,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.2.5, glob@npm:^10.3.10, glob@npm:^10.3.7": +"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": version: 10.3.12 resolution: "glob@npm:10.3.12" dependencies: @@ -18532,7 +19103,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.0.0, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0, glob@npm:~7.2.0": +"glob@npm:^7.0.0, glob@npm:^7.0.5, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0, glob@npm:~7.2.0": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -18891,6 +19462,37 @@ __metadata: languageName: node linkType: hard +"hash-base@npm:^3.0.0": + version: 3.1.0 + resolution: "hash-base@npm:3.1.0" + dependencies: + inherits: ^2.0.4 + readable-stream: ^3.6.0 + safe-buffer: ^5.2.0 + checksum: 663eabcf4173326fbb65a1918a509045590a26cc7e0964b754eef248d281305c6ec9f6b31cb508d02ffca383ab50028180ce5aefe013e942b44a903ac8dc80d0 + languageName: node + linkType: hard + +"hash-base@npm:~3.0": + version: 3.0.4 + resolution: "hash-base@npm:3.0.4" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: a13357dccb3827f0bb0b56bf928da85c428dc8670f6e4a1c7265e4f1653ce02d69030b40fd01b0f1d218a995a066eea279cded9cec72d207b593bcdfe309c2f0 + languageName: node + linkType: hard + +"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": + version: 1.1.7 + resolution: "hash.js@npm:1.1.7" + dependencies: + inherits: ^2.0.3 + minimalistic-assert: ^1.0.1 + checksum: 41ada59494eac5332cfc1ce6b7ebdd7b88a3864a6d6b08a3ea8ef261332ed60f37f10877e0c825aaa4bddebf164fbffa618286aeeec5296675e2671cbfa746c4 + languageName: node + linkType: hard + "hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -18914,6 +19516,17 @@ __metadata: languageName: node linkType: hard +"hmac-drbg@npm:^1.0.1": + version: 1.0.1 + resolution: "hmac-drbg@npm:1.0.1" + dependencies: + hash.js: ^1.0.3 + minimalistic-assert: ^1.0.0 + minimalistic-crypto-utils: ^1.0.1 + checksum: f3d9ba31b40257a573f162176ac5930109816036c59a09f901eb2ffd7e5e705c6832bedfff507957125f2086a0ab8f853c0df225642a88bf1fcaea945f20600d + languageName: node + linkType: hard + "homedir-polyfill@npm:^1.0.1": version: 1.0.3 resolution: "homedir-polyfill@npm:1.0.3" @@ -19115,6 +19728,13 @@ __metadata: languageName: node linkType: hard +"https-browserify@npm:^1.0.0": + version: 1.0.0 + resolution: "https-browserify@npm:1.0.0" + checksum: e17b6943bc24ea9b9a7da5714645d808670af75a425f29baffc3284962626efdc1eb3aa9bbffaa6e64028a6ad98af5b09fabcb454a8f918fb686abfdc9e9b8ae + languageName: node + linkType: hard + "https-proxy-agent@npm:^4.0.0": version: 4.0.0 resolution: "https-proxy-agent@npm:4.0.0" @@ -19370,7 +19990,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -20293,6 +20913,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:0.0.1": + version: 0.0.1 + resolution: "isarray@npm:0.0.1" + checksum: ed1e62da617f71fe348907c71743b5ed550448b455f8d269f89a7c7ddb8ae6e962de3dab6a74a237b06f5eb7f6ece7a45ada8ce96d87fe972926530f91ae3311 + languageName: node + linkType: hard + "isarray@npm:1.0.0, isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" @@ -20344,6 +20971,13 @@ __metadata: languageName: node linkType: hard +"isomorphic-timers-promises@npm:^1.0.1": + version: 1.0.1 + resolution: "isomorphic-timers-promises@npm:1.0.1" + checksum: 3b4761d0012ebe6b6382246079fc667f3513f36fe4042638f2bfb7db1557e4f1acd33a9c9907706c04270890ec6434120f132f3f300161a42a7dd8628926c8a4 + languageName: node + linkType: hard + "isstream@npm:~0.1.2": version: 0.1.2 resolution: "isstream@npm:0.1.2" @@ -23335,6 +23969,17 @@ __metadata: languageName: node linkType: hard +"md5.js@npm:^1.3.4": + version: 1.3.5 + resolution: "md5.js@npm:1.3.5" + dependencies: + hash-base: ^3.0.0 + inherits: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: b7bd75077f419c8e013fc4d4dada48be71882e37d69a44af65a2f2804b91e253441eb43a0614423a1c91bb830b8140b0dc906bc797245e2e275759584f4efcc5 + languageName: node + linkType: hard + "mdast-util-definitions@npm:^4.0.0": version: 4.0.0 resolution: "mdast-util-definitions@npm:4.0.0" @@ -23668,6 +24313,18 @@ __metadata: languageName: node linkType: hard +"miller-rabin@npm:^4.0.0": + version: 4.0.1 + resolution: "miller-rabin@npm:4.0.1" + dependencies: + bn.js: ^4.0.0 + brorand: ^1.0.1 + bin: + miller-rabin: bin/miller-rabin + checksum: 26b2b96f6e49dbcff7faebb78708ed2f5f9ae27ac8cbbf1d7c08f83cf39bed3d418c0c11034dce997da70d135cc0ff6f3a4c15dc452f8e114c11986388a64346 + languageName: node + linkType: hard + "mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": version: 1.52.0 resolution: "mime-db@npm:1.52.0" @@ -23764,7 +24421,21 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:2 || 3, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-assert@npm:1.0.1" + checksum: 96730e5601cd31457f81a296f521eb56036e6f69133c0b18c13fe941109d53ad23a4204d946a0d638d7f3099482a0cec8c9bb6d642604612ce43ee536be3dddd + languageName: node + linkType: hard + +"minimalistic-crypto-utils@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-crypto-utils@npm:1.0.1" + checksum: 790ecec8c5c73973a4fbf2c663d911033e8494d5fb0960a4500634766ab05d6107d20af896ca2132e7031741f19888154d44b2408ada0852446705441383e9f8 + languageName: node + linkType: hard + +"minimatch@npm:2 || 3, minimatch@npm:^3.0.2, minimatch@npm:^3.0.3, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -23957,7 +24628,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:1.x, mkdirp@npm:^1.0.3": +"mkdirp@npm:1.x, mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -24513,6 +25184,41 @@ __metadata: languageName: node linkType: hard +"node-stdlib-browser@npm:^1.2.0": + version: 1.2.0 + resolution: "node-stdlib-browser@npm:1.2.0" + dependencies: + assert: ^2.0.0 + browser-resolve: ^2.0.0 + browserify-zlib: ^0.2.0 + buffer: ^5.7.1 + console-browserify: ^1.1.0 + constants-browserify: ^1.0.0 + create-require: ^1.1.1 + crypto-browserify: ^3.11.0 + domain-browser: ^4.22.0 + events: ^3.0.0 + https-browserify: ^1.0.0 + isomorphic-timers-promises: ^1.0.1 + os-browserify: ^0.3.0 + path-browserify: ^1.0.1 + pkg-dir: ^5.0.0 + process: ^0.11.10 + punycode: ^1.4.1 + querystring-es3: ^0.2.1 + readable-stream: ^3.6.0 + stream-browserify: ^3.0.0 + stream-http: ^3.2.0 + string_decoder: ^1.0.0 + timers-browserify: ^2.0.4 + tty-browserify: 0.0.1 + url: ^0.11.0 + util: ^0.12.4 + vm-browserify: ^1.0.1 + checksum: 4da239ebabcba68e09b2620aaae02dd589045b101441beb90988bc60f1af3d286e9fab0c334503eaf74986e583923e7648a8fa081edc4981e4d738636773f32e + languageName: node + linkType: hard + "nodemon@npm:^2.0.20": version: 2.0.22 resolution: "nodemon@npm:2.0.22" @@ -24533,6 +25239,16 @@ __metadata: languageName: node linkType: hard +"noms@npm:0.0.0": + version: 0.0.0 + resolution: "noms@npm:0.0.0" + dependencies: + inherits: ^2.0.1 + readable-stream: ~1.0.31 + checksum: 7790dbbef45c593b5444b361cb9cde3260244ab66aaa199c0728d334525eb69df96231115cff260b71b92fc7a6915a642aa22f2f8448696d8dd6e7d7cebfccce + languageName: node + linkType: hard + "nopt@npm:^7.0.0": version: 7.2.1 resolution: "nopt@npm:7.2.1" @@ -25068,6 +25784,13 @@ __metadata: languageName: node linkType: hard +"os-browserify@npm:^0.3.0": + version: 0.3.0 + resolution: "os-browserify@npm:0.3.0" + checksum: 6ff32cb1efe2bc6930ad0fd4c50e30c38010aee909eba8d65be60af55efd6cbb48f0287e3649b4e3f3a63dce5a667b23c187c4293a75e557f0d5489d735bcf52 + languageName: node + linkType: hard + "os-tmpdir@npm:~1.0.2": version: 1.0.2 resolution: "os-tmpdir@npm:1.0.2" @@ -25236,6 +25959,13 @@ __metadata: languageName: node linkType: hard +"pako@npm:~1.0.5": + version: 1.0.11 + resolution: "pako@npm:1.0.11" + checksum: 86dd99d8b34c3930345b8bbeb5e1cd8a05f608eeb40967b293f72fe469d0e9c88b783a8777e4cc7dc7c91ce54c5e93d88ff4b4f060e6ff18408fd21030d9ffbe + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -25252,6 +25982,20 @@ __metadata: languageName: node linkType: hard +"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.7": + version: 5.1.7 + resolution: "parse-asn1@npm:5.1.7" + dependencies: + asn1.js: ^4.10.1 + browserify-aes: ^1.2.0 + evp_bytestokey: ^1.0.3 + hash-base: ~3.0 + pbkdf2: ^3.1.2 + safe-buffer: ^5.2.1 + checksum: 05eb5937405c904eb5a7f3633bab1acc11f4ae3478a07ef5c6d81ce88c3c0e505ff51f9c7b935ebc1265c868343793698fc91025755a895d0276f620f95e8a82 + languageName: node + linkType: hard + "parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" @@ -25507,6 +26251,19 @@ __metadata: languageName: node linkType: hard +"pbkdf2@npm:^3.0.3, pbkdf2@npm:^3.1.2": + version: 3.1.2 + resolution: "pbkdf2@npm:3.1.2" + dependencies: + create-hash: ^1.1.2 + create-hmac: ^1.1.4 + ripemd160: ^2.0.1 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: 5a30374e87d33fa080a92734d778cf172542cc7e41b96198c4c88763997b62d7850de3fbda5c3111ddf79805ee7c1da7046881c90ac4920b5e324204518b05fd + languageName: node + linkType: hard + "peek-stream@npm:^1.1.0": version: 1.1.3 resolution: "peek-stream@npm:1.1.3" @@ -26696,6 +27453,20 @@ __metadata: languageName: node linkType: hard +"public-encrypt@npm:^4.0.0": + version: 4.0.3 + resolution: "public-encrypt@npm:4.0.3" + dependencies: + bn.js: ^4.1.0 + browserify-rsa: ^4.0.0 + create-hash: ^1.1.0 + parse-asn1: ^5.0.0 + randombytes: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: 6c2cc19fbb554449e47f2175065d6b32f828f9b3badbee4c76585ac28ae8641aafb9bb107afc430c33c5edd6b05dbe318df4f7d6d7712b1093407b11c4280700 + languageName: node + linkType: hard + "pump@npm:^2.0.0": version: 2.0.1 resolution: "pump@npm:2.0.1" @@ -26807,6 +27578,13 @@ __metadata: languageName: node linkType: hard +"querystring-es3@npm:^0.2.1": + version: 0.2.1 + resolution: "querystring-es3@npm:0.2.1" + checksum: 476938c1adb45c141f024fccd2ffd919a3746e79ed444d00e670aad68532977b793889648980e7ca7ff5ffc7bfece623118d0fbadcaf217495eeb7059ae51580 + languageName: node + linkType: hard + "querystringify@npm:^2.1.1": version: 2.2.0 resolution: "querystringify@npm:2.2.0" @@ -26874,7 +27652,7 @@ __metadata: languageName: node linkType: hard -"randombytes@npm:^2.1.0": +"randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" dependencies: @@ -26883,6 +27661,16 @@ __metadata: languageName: node linkType: hard +"randomfill@npm:^1.0.3": + version: 1.0.4 + resolution: "randomfill@npm:1.0.4" + dependencies: + randombytes: ^2.0.5 + safe-buffer: ^5.1.0 + checksum: 11aeed35515872e8f8a2edec306734e6b74c39c46653607f03c68385ab8030e2adcc4215f76b5e4598e028c4750d820afd5c65202527d831d2a5f207fe2bc87c + languageName: node + linkType: hard + "range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" @@ -27274,7 +28062,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.2, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.5, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.2, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.5, readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -27289,7 +28077,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -27300,6 +28088,18 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:~1.0.31": + version: 1.0.34 + resolution: "readable-stream@npm:1.0.34" + dependencies: + core-util-is: ~1.0.0 + inherits: ~2.0.1 + isarray: 0.0.1 + string_decoder: ~0.10.x + checksum: 02272551396ed8930ddee1a088bdf0379f0f7cc47ac49ed8804e998076cb7daec9fbd2b1fd9c0490ec72e56e8bb3651abeb8080492b8e0a9c3f2158330908ed6 + languageName: node + linkType: hard + "readdirp@npm:^2.2.1": version: 2.2.1 resolution: "readdirp@npm:2.2.1" @@ -27965,17 +28765,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:5.0.1": - version: 5.0.1 - resolution: "rimraf@npm:5.0.1" - dependencies: - glob: ^10.2.5 - bin: - rimraf: dist/cjs/src/bin.js - checksum: 9e6062c0aea96f384dd937e6bb06b624c881de2eee79a83d3068193183d44eb9b1f3f68a27a54b9ca8cce56bf34c2951ff4239b093b970e0501a091907031f52 - languageName: node - linkType: hard - "rimraf@npm:^2.6.1": version: 2.7.1 resolution: "rimraf@npm:2.7.1" @@ -28031,6 +28820,16 @@ __metadata: languageName: node linkType: hard +"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": + version: 2.0.2 + resolution: "ripemd160@npm:2.0.2" + dependencies: + hash-base: ^3.0.0 + inherits: ^2.0.1 + checksum: f6f0df78817e78287c766687aed4d5accbebc308a8e7e673fb085b9977473c1f139f0c5335d353f172a915bb288098430755d2ad3c4f30612f4dd0c901cd2c3a + languageName: node + linkType: hard + "rollup-plugin-bundle-size@npm:^1.0.3": version: 1.0.3 resolution: "rollup-plugin-bundle-size@npm:1.0.3" @@ -28242,7 +29041,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.0.2, rollup@npm:^4.2.0": +"rollup@npm:^4.0.2, rollup@npm:^4.13.0": version: 4.17.2 resolution: "rollup@npm:4.17.2" dependencies: @@ -28440,7 +29239,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.2, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 @@ -28778,6 +29577,13 @@ __metadata: languageName: node linkType: hard +"setimmediate@npm:^1.0.4": + version: 1.0.5 + resolution: "setimmediate@npm:1.0.5" + checksum: 5bae81bfdbfbd0ce992893286d49c9693c82b1bcc00dcaaf3a09c8f428fdeacf4190c013598b81875dfac2b08a572422db7df779a99332d0fce186d15a3e4d49 + languageName: node + linkType: hard + "setprototypeof@npm:1.1.1": version: 1.1.1 resolution: "setprototypeof@npm:1.1.1" @@ -28792,7 +29598,7 @@ __metadata: languageName: node linkType: hard -"sha.js@npm:^2.4.11": +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": version: 2.4.11 resolution: "sha.js@npm:2.4.11" dependencies: @@ -29539,6 +30345,28 @@ __metadata: languageName: node linkType: hard +"stream-browserify@npm:^3.0.0": + version: 3.0.0 + resolution: "stream-browserify@npm:3.0.0" + dependencies: + inherits: ~2.0.4 + readable-stream: ^3.5.0 + checksum: ec3b975a4e0aa4b3dc5e70ffae3fc8fd29ac725353a14e72f213dff477b00330140ad014b163a8cbb9922dfe90803f81a5ea2b269e1bbfd8bd71511b88f889ad + languageName: node + linkType: hard + +"stream-http@npm:^3.2.0": + version: 3.2.0 + resolution: "stream-http@npm:3.2.0" + dependencies: + builtin-status-codes: ^3.0.0 + inherits: ^2.0.4 + readable-stream: ^3.6.0 + xtend: ^4.0.2 + checksum: f128fb8076d60cd548f229554b6a1a70c08a04b7b2afd4dbe7811d20f27f7d4112562eb8bce86d72a8691df3b50573228afcf1271e55e81f981536c67498bc41 + languageName: node + linkType: hard + "stream-shift@npm:^1.0.0": version: 1.0.3 resolution: "stream-shift@npm:1.0.3" @@ -29679,7 +30507,7 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.1.1": +"string_decoder@npm:^1.0.0, string_decoder@npm:^1.1.1": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" dependencies: @@ -29688,6 +30516,13 @@ __metadata: languageName: node linkType: hard +"string_decoder@npm:~0.10.x": + version: 0.10.31 + resolution: "string_decoder@npm:0.10.31" + checksum: 1c628d78f974aa7539c496029f48e7019acc32487fc695464f9d6bdfec98edd7d933a06b3216bc2016918f6e75074c611d84430a53cb0e43071597d6c1ac5e25 + languageName: node + linkType: hard + "string_decoder@npm:~1.1.1": version: 1.1.1 resolution: "string_decoder@npm:1.1.1" @@ -30304,7 +31139,7 @@ __metadata: languageName: node linkType: hard -"through2@npm:^2.0.3": +"through2@npm:^2.0.1, through2@npm:^2.0.3": version: 2.0.5 resolution: "through2@npm:2.0.5" dependencies: @@ -30328,6 +31163,15 @@ __metadata: languageName: node linkType: hard +"timers-browserify@npm:^2.0.4": + version: 2.0.12 + resolution: "timers-browserify@npm:2.0.12" + dependencies: + setimmediate: ^1.0.4 + checksum: 98e84db1a685bc8827c117a8bc62aac811ad56a995d07938fc7ed8cdc5bf3777bfe2d4e5da868847194e771aac3749a20f6cdd22091300fe889a76fe214a4641 + languageName: node + linkType: hard + "tiny-glob@npm:^0.2.8": version: 0.2.9 resolution: "tiny-glob@npm:0.2.9" @@ -30915,7 +31759,7 @@ __metadata: languageName: node linkType: hard -"tsup@npm:^8.0.1": +"tsup@npm:^8.0.1, tsup@npm:^8.0.2": version: 8.0.2 resolution: "tsup@npm:8.0.2" dependencies: @@ -30965,6 +31809,13 @@ __metadata: languageName: node linkType: hard +"tty-browserify@npm:0.0.1": + version: 0.0.1 + resolution: "tty-browserify@npm:0.0.1" + checksum: 5e34883388eb5f556234dae75b08e069b9e62de12bd6d87687f7817f5569430a6dfef550b51dbc961715ae0cd0eb5a059e6e3fc34dc127ea164aa0f9b5bb033d + languageName: node + linkType: hard + "tty-table@npm:^4.1.5": version: 4.2.3 resolution: "tty-table@npm:4.2.3" @@ -31734,6 +32585,16 @@ __metadata: languageName: node linkType: hard +"url@npm:^0.11.0": + version: 0.11.3 + resolution: "url@npm:0.11.3" + dependencies: + punycode: ^1.4.1 + qs: ^6.11.2 + checksum: 7546b878ee7927cfc62ca21dbe2dc395cf70e889c3488b2815bf2c63355cb3c7db555128176a01b0af6cccf265667b6fd0b4806de00cb71c143c53986c08c602 + languageName: node + linkType: hard + "use-callback-ref@npm:^1.3.0": version: 1.3.2 resolution: "use-callback-ref@npm:1.3.2" @@ -32027,6 +32888,18 @@ __metadata: languageName: node linkType: hard +"vite-plugin-node-polyfills@npm:^0.21.0": + version: 0.21.0 + resolution: "vite-plugin-node-polyfills@npm:0.21.0" + dependencies: + "@rollup/plugin-inject": ^5.0.5 + node-stdlib-browser: ^1.2.0 + peerDependencies: + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + checksum: 09095c1244dea0b9e2c78b9c44591c75048b6c12b65dd85e78edb3c1b7dd8222670f72e1849f70bbdb5a2a0e0b2b1c4deec7779cbe52664ba1f0fda1c19115f5 + languageName: node + linkType: hard + "vite-plugin-turbosnap@npm:^1.0.2": version: 1.0.3 resolution: "vite-plugin-turbosnap@npm:1.0.3" @@ -32034,46 +32907,6 @@ __metadata: languageName: node linkType: hard -"vite@npm:5.0.10": - version: 5.0.10 - resolution: "vite@npm:5.0.10" - dependencies: - esbuild: ^0.19.3 - fsevents: ~2.3.3 - postcss: ^8.4.32 - rollup: ^4.2.0 - peerDependencies: - "@types/node": ^18.0.0 || >=20.0.0 - less: "*" - lightningcss: ^1.21.0 - sass: "*" - stylus: "*" - sugarss: "*" - terser: ^5.4.0 - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - "@types/node": - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - bin: - vite: bin/vite.js - checksum: d666b2760d2a7ea1d0d35f67c042053e562144f80554be4e4dc58e607fd5f62193cd203d73ab2e315df66830d8b9d9a2e3509d0208bdef1b2e92e0a5c364df84 - languageName: node - linkType: hard - "vite@npm:^3.0.0 || ^4.0.0, vite@npm:^4.3.9": version: 4.5.3 resolution: "vite@npm:4.5.3" @@ -32114,6 +32947,46 @@ __metadata: languageName: node linkType: hard +"vite@npm:^5.2.11": + version: 5.2.11 + resolution: "vite@npm:5.2.11" + dependencies: + esbuild: ^0.20.1 + fsevents: ~2.3.3 + postcss: ^8.4.38 + rollup: ^4.13.0 + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 664b8d68e4f5152ae16bd2041af1bbaf11c43630ac461835bc31ff7d019913b33e465386e09f66dc1037d7aeefbb06939e0173787c063319bc2bd30c3b9ad8e4 + languageName: node + linkType: hard + "vitest@npm:^0.32.2": version: 0.32.4 resolution: "vitest@npm:0.32.4" @@ -32174,6 +33047,13 @@ __metadata: languageName: node linkType: hard +"vm-browserify@npm:^1.0.1": + version: 1.1.2 + resolution: "vm-browserify@npm:1.1.2" + checksum: 0cc1af6e0d880deb58bc974921320c187f9e0a94f25570fca6b1bd64e798ce454ab87dfd797551b1b0cc1849307421aae0193cedf5f06bdb5680476780ee344b + languageName: node + linkType: hard + "void-elements@npm:3.1.0": version: 3.1.0 resolution: "void-elements@npm:3.1.0" @@ -32860,7 +33740,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^16.0.0": +"yargs@npm:^16.0.0, yargs@npm:^16.1.0": version: 16.2.0 resolution: "yargs@npm:16.2.0" dependencies: @@ -32929,3 +33809,10 @@ __metadata: checksum: 7578ab283dac0eee66a0ad0fc4a7f28c43e6745aadb3a529f59a4b851aa10872b3890398b3160f257f4b6817b4ce643debdda4fb21a2c040adda7862cab0a587 languageName: node linkType: hard + +"zod@npm:^3.22.4": + version: 3.23.8 + resolution: "zod@npm:3.23.8" + checksum: 8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69 + languageName: node + linkType: hard