Restructure plugin API, implement basic minimal shell prototype
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 197b39f..0000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "name": "iris-server [wrangler]",
- "preLaunchTask": "iris-server/wrangler",
- "type": "node",
- "request": "attach",
- "port": 2501,
- "resolveSourceMapLocations": null,
- "attachExistingChildren": false,
- "autoAttachChildProcesses": false,
- "cwd": "${workspaceFolder}/packages/server"
- }
- ]
-}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 0a31d2c..fb273e4 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -4,42 +4,6 @@
"version": "2.0.0",
"tasks": [
{
- "label": "iris-server/wrangler",
- "type": "shell",
- "command": "npm start",
- "options": {
- "cwd": "${workspaceFolder}/packages/server"
- },
- "isBackground": true,
- "problemMatcher": {
- "owner": "wrangler",
- "source": "wrangler",
- "pattern": {
- "regexp": "\\b\\B",
- "file": 1,
- "line": 2,
- "column": 3,
- "message": 4
- },
- "background": {
- "activeOnStart": true,
- "beginsPattern": "15f8cd96-2ee2-4dcc-a757-5d8fc00ed307",
- "endsPattern": "\\[wrangler:info\\] Ready on"
- }
- },
- "group": {
- "kind": "build",
- "isDefault": true
- },
- "icon": {
- "id": "cloud"
- },
- "dependsOn": [
- "iris-sdk/tsc",
- "iris-plugins/tsc"
- ]
- },
- {
"label": "iris-webui/vite",
"type": "shell",
"command": "npm run start",
@@ -71,29 +35,6 @@
"id": "record"
},
"dependsOn": [
- "iris-sdk/tsc",
- "iris-plugins/tsc"
- ]
- },
- {
- "label": "iris-plugins/tsc",
- "type": "shell",
- "command": "npm start",
- "options": {
- "cwd": "${workspaceFolder}/packages/plugins"
- },
- "isBackground": true,
- "problemMatcher": {
- "base": "$tsc-watch"
- },
- "group": {
- "kind": "build",
- "isDefault": true
- },
- "icon": {
- "id": "library"
- },
- "dependsOn": [
"iris-sdk/tsc"
]
},
diff --git a/package.json b/package.json
index 1d0a62e..d6e5b0a 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,8 @@
"@react-router/remix-routes-option-adapter": "^7.7.0",
"@remix-run/v1-route-convention": "patch:@remix-run/v1-route-convention@npm%3A0.1.4#~/.yarn/patches/@remix-run-v1-route-convention-npm-0.1.4-d336e45418.patch",
"chroma-js": "^3.1.2",
+ "jose": "^6.0.12",
+ "lodash": "^4.17.21",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router": "^7.5.3"
@@ -34,13 +36,16 @@
"@react-router/dev": "^7.5.3",
"@tailwindcss/vite": "^4.1.4",
"@types/chroma-js": "^3.1.1",
+ "@types/lodash": "^4.17.20",
"@types/node": "^20",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"cross-env": "^7.0.3",
+ "npm-run-all": "^4.1.5",
"nx": "^21.2.4",
"rimraf": "^6.0.1",
"tailwindcss": "^4.1.4",
+ "tsc-alias": "^1.8.16",
"typescript": "^5.8.3",
"vite": "^6.3.3",
"vite-tsconfig-paths": "^5.1.4",
diff --git a/packages/plugins/.gitignore b/packages/plugins/.gitignore
deleted file mode 100644
index 206df3e..0000000
--- a/packages/plugins/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-lib
-node_modules
-*.tsbuildinfo
\ No newline at end of file
diff --git a/packages/plugins/package.json b/packages/plugins/package.json
deleted file mode 100644
index 3406ac4..0000000
--- a/packages/plugins/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "iris-plugins",
- "private": true,
- "license": "LGPL-2.1-only",
- "author": "jottocraft",
- "scripts": {
- "build": "tsc --build",
- "clean": "rimraf lib",
- "start": "tsc --build --watch",
- "validate": "tsc --noEmit"
- },
- "dependencies": {
- "@jottocraft/iris-sdk": "workspace:*"
- }
-}
diff --git a/packages/plugins/src/index.ts b/packages/plugins/src/index.ts
deleted file mode 100644
index 7f535b5..0000000
--- a/packages/plugins/src/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// Iris
-// Copyright (c) jottocraft 2025
-
-export const DUMMY_EXPORT = 1;
\ No newline at end of file
diff --git a/packages/plugins/tsconfig.json b/packages/plugins/tsconfig.json
deleted file mode 100644
index 599fdc0..0000000
--- a/packages/plugins/tsconfig.json
+++ /dev/null
@@ -1,113 +0,0 @@
-{
- "include": [
- "src"
- ],
- "compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "commonjs", /* Specify what module code is generated. */
- "rootDir": "src", /* Specify the root folder within your source files. */
- "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- "paths": { /* Specify a set of entries that re-map imports to additional lookup locations. */
- "~/*": ["./src/*"]
- },
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
- // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
- // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
- // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
- // "resolveJsonModule": true, /* Enable importing .json files. */
- // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
- // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- "outDir": "lib", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
-
- /* Interop Constraints */
- "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
- // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
- }
-}
\ No newline at end of file
diff --git a/packages/sdk/package.json b/packages/sdk/package.json
index 4303336..e77cbdc 100644
--- a/packages/sdk/package.json
+++ b/packages/sdk/package.json
@@ -18,9 +18,11 @@
"README.md"
],
"scripts": {
- "build": "tsc --build",
+ "build": "tsc --build && tsc-alias",
"clean": "rimraf lib",
- "start": "tsc --build --watch",
- "validate": "tsc --noEmit"
+ "start": "run-p dev:*",
+ "validate": "tsc --noEmit",
+ "dev:tsc": "tsc --build --watch",
+ "dev:tsc-alias": "tsc-alias --watch"
}
}
diff --git a/packages/sdk/src/conduit.ts b/packages/sdk/src/conduit.ts
new file mode 100644
index 0000000..ac735b2
--- /dev/null
+++ b/packages/sdk/src/conduit.ts
@@ -0,0 +1,218 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+export type IrisPluginConfigConduit = {
+ type: "conduit";
+ id: string;
+ baseUrl: string;
+};
+
+export type IrisPluginCtxConduit<PluginType extends IrisPluginConduit> = {
+ type: "conduit";
+ plugin: PluginType;
+ client: import("@jottocraft/yggdrasil").YggdrasilConduitApiClient<IrisPluginConduitConduitServerTypes<PluginType>>;
+};
+
+export type IrisPluginConduitConduitServerTypes<PluginType extends IrisPluginConduit> = {
+ client: {
+ plugin: () => Promise<PluginType>;
+ panels: {
+ [Property in keyof PluginType["panels"]]: (args: IrisPluginConduitPanelArgs<PluginType["panels"][Property]["requiredArgs"]>) => Promise<IrisPluginConduitPanelLayout<PluginType>>;
+ };
+ forms: {
+ [Property in keyof PluginType["forms"]]: (data: IrisPluginConduitFieldData<PluginType["forms"][Property]["data"]>) => Promise<string>;
+ };
+ };
+ apiCtx: {
+ jwt: string;
+ };
+ conduitCtx: {
+ jwt: string;
+ };
+};
+
+export type IrisPluginConduit = {
+ displayName: string;
+ icon: string;
+ panels: {
+ [id: string]: IrisPluginConduitPanel;
+ };
+ forms: {
+ [id: string]: IrisPluginConduitForm;
+ };
+ navigation: {
+ panel: IrisPluginConduitPanelRef<IrisPluginConduit>;
+ displayName: string;
+ icon?: string;
+ }[];
+};
+
+export type IrisPluginConduitPanel = {
+ requiredArgs: string[];
+};
+
+export type IrisPluginConduitPanelArgs<RequiredArgsType extends string[]> = {
+ [Property in RequiredArgsType[number]]: string;
+} & {
+ [arg: string]: string;
+};
+
+export type IrisPluginConduitForm = {
+ displayName: string;
+ icon?: string;
+ data?: IrisPluginConduitField;
+};
+
+export type IrisPluginConduitField = {
+ displayName?: string;
+ icon?: string;
+ helpText?: string;
+ optional?: boolean;
+} & ({
+ type: "string" | "number" | "date" | "datetime" | "boolean";
+} | {
+ type: "dropdown";
+ options: { label: string; icon?: string; value: string; }[];
+} | {
+ type: "array";
+ of: IrisPluginConduitField;
+} | {
+ type: "object";
+ struct: {
+ [key: string]: IrisPluginConduitField;
+ };
+});
+
+export type _IrisPluginConduitFieldDeepOptional<FieldSpec extends IrisPluginConduitField | undefined> = FieldSpec extends { type: "string" | "date" | "datetime" | "number" | "boolean" | "dropdown" } ? (
+ Omit<FieldSpec, "optional"> & { optional: true; }
+) : FieldSpec extends { type: "array" } ? (
+ Omit<FieldSpec, "of"> & { of: _IrisPluginConduitFieldDeepOptional<FieldSpec["of"]>; }
+) : FieldSpec extends { type: "object" } ? (
+ Omit<FieldSpec, "struct"> & {
+ struct: {
+ [Property in keyof FieldSpec["struct"]]: _IrisPluginConduitFieldDeepOptional<FieldSpec["struct"][Property]>;
+ };
+ }
+) : FieldSpec extends undefined ? (
+ undefined
+) : never;
+
+// https://github.com/microsoft/TypeScript/issues/12400#issuecomment-758523767
+
+export type _IrisUKeysOfType<T, SelectedType> = {
+ [key in keyof T]: SelectedType extends T[key] ? key : never
+}[keyof T];
+
+export type _IrisUOptional<T> = Partial<Pick<T, _IrisUKeysOfType<T, undefined>>>;
+
+export type _IrisURequired<T> = Omit<T, _IrisUKeysOfType<T, undefined>>;
+
+export type _IrisUOptionalUndefined<T> = _IrisUOptional<T> & _IrisURequired<T>;
+
+export type _IrisPluginConduitFieldDataCore<FieldSpec extends IrisPluginConduitField | undefined> = FieldSpec extends { type: "string" | "date" | "datetime" } ? (
+ string
+) : FieldSpec extends { type: "number" } ? (
+ number
+) : FieldSpec extends { type: "boolean" } ? (
+ boolean
+) : FieldSpec extends { type: "dropdown" } ? (
+ FieldSpec["options"][number]
+) : FieldSpec extends { type: "array" } ? (
+ IrisPluginConduitFieldData<FieldSpec["of"]>[]
+) : FieldSpec extends { type: "object" } ? (
+ _IrisUOptionalUndefined<{
+ [Property in keyof FieldSpec["struct"]]: IrisPluginConduitFieldData<FieldSpec["struct"][Property]>;
+ }>
+) : FieldSpec extends undefined ? (
+ undefined
+) : never;
+
+export type IrisPluginConduitFieldData<FieldSpec extends IrisPluginConduitField | undefined> = FieldSpec extends { optional: true; } ? (
+ _IrisPluginConduitFieldDataCore<FieldSpec> | undefined
+) : (
+ _IrisPluginConduitFieldDataCore<FieldSpec>
+ );
+
+export type IrisPluginConduitPanelLayout<PluginType extends IrisPluginConduit> = {
+ displayName: string;
+ icon?: string;
+ forms?: IrisPluginConduitFormRef<PluginType>[];
+ main?: IrisPluginConduitPanelLayoutField[];
+ sections?: IrisPluginConduitPanelLayoutSection<PluginType>[];
+};
+
+export type IrisPluginConduitPanelLayoutSection<PluginType extends IrisPluginConduit> = IrisPluginConduitPanelLayoutSectionProperties<PluginType> | IrisPluginConduitPanelLayoutSectionTable<PluginType> | IrisPluginConduitPanelLayoutSectionRef<PluginType>;
+
+export type IrisPluginConduitPanelLayoutSectionCommon = {
+ id: string;
+ displayName: string;
+ icon?: string;
+};
+
+export type IrisPluginConduitPanelLayoutSectionProperties<PluginType extends IrisPluginConduit> = IrisPluginConduitPanelLayoutSectionCommon & {
+ type: "properties";
+ properties: IrisPluginConduitPanelLayoutField[];
+};
+
+export type IrisPluginConduitPanelLayoutSectionTable<PluginType extends IrisPluginConduit> = IrisPluginConduitPanelLayoutSectionCommon & {
+ type: "table";
+ columns: {
+ key: string;
+ displayName: string;
+ icon?: string;
+ }[];
+ rows: {
+ vals: {
+ [key: string]: string;
+ };
+ links?: {
+ [key: string]: IrisPluginConduitPanelRef<PluginType>;
+ };
+ }[];
+ firstRow: number;
+ totalRows: number;
+};
+
+export type IrisPluginConduitPanelLayoutSectionRef<PluginType extends IrisPluginConduit> = IrisPluginConduitPanelLayoutSectionCommon & {
+ type: "ref";
+ panel: IrisPluginConduitPanelRef<PluginType>;
+};
+
+export type IrisPluginConduitPanelRef<PluginType extends IrisPluginConduit> = {
+ id: string;
+ args?: unknown;
+};
+
+export type IrisPluginConduitFormRef<PluginType extends IrisPluginConduit> = {
+ id: string;
+ data?: unknown;
+};
+
+export type IrisPluginConduitPanelLayoutField = {
+ displayName: string;
+ icon?: string;
+ value: string;
+};
+
+/**
+ * Helper utility for implementing an Iris Conduit server with strong type safety.
+ */
+export function createIrisConduitServerImpl<PluginType extends IrisPluginConduit>(): {
+ panelRef: <PanelId extends keyof PluginType["panels"]>(id: PanelId, args?: Partial<IrisPluginConduitPanelArgs<PluginType["panels"][PanelId]["requiredArgs"]>>) => IrisPluginConduitPanelRef<PluginType>;
+ formRef: <FormId extends keyof PluginType["forms"]>(id: FormId, args?: IrisPluginConduitFieldData<_IrisPluginConduitFieldDeepOptional<PluginType["forms"][FormId]["data"]>>) => IrisPluginConduitFormRef<PluginType>;
+} {
+ return {
+ panelRef(id, args) {
+ return {
+ id: id as string,
+ args
+ }
+ },
+ formRef(id, data) {
+ return {
+ id: id as string,
+ data
+ }
+ }
+ };
+}
\ No newline at end of file
diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts
index 7f535b5..1750cff 100644
--- a/packages/sdk/src/index.ts
+++ b/packages/sdk/src/index.ts
@@ -1,4 +1,5 @@
// Iris
// Copyright (c) jottocraft 2025
-export const DUMMY_EXPORT = 1;
\ No newline at end of file
+export * from "~/conduit";
+export * from "~/site";
\ No newline at end of file
diff --git a/packages/sdk/src/site.ts b/packages/sdk/src/site.ts
new file mode 100644
index 0000000..c545a3d
--- /dev/null
+++ b/packages/sdk/src/site.ts
@@ -0,0 +1,42 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import { IrisPluginConduit, IrisPluginConfigConduit, IrisPluginCtxConduit } from "~/conduit";
+
+export type IrisSiteConfig = {
+ brand: {
+ name: string;
+ logo?: {
+ dark: string;
+ light: string;
+ };
+ };
+ auth: IrisAuthConfig;
+ plugins: IrisPluginConfig[];
+};
+
+// Auth:
+
+export type IrisAuthConfig = IrisAuthConfigOidc;
+
+export type IrisAuthConfigOidc = {
+ type: "oidc";
+ method: "implicit";
+ iss: string;
+ authUrl: string;
+ clientId: string;
+ scope?: string;
+};
+
+export type IrisAuthCtx = {
+ jwt: string;
+ claims: import("jose").JWTPayload;
+};
+
+// Plugins:
+
+export type IrisPluginConfig = IrisPluginConfigConduit;
+
+export type IrisPluginCtx = {
+ [id: string]: IrisPluginCtxConduit<IrisPluginConduit>;
+};
\ No newline at end of file
diff --git a/packages/server/.gitignore b/packages/server/.gitignore
deleted file mode 100644
index 1b0d95d..0000000
--- a/packages/server/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-node_modules
-build
-.wrangler
-*.tsbuildinfo
\ No newline at end of file
diff --git a/packages/server/package.json b/packages/server/package.json
deleted file mode 100644
index 522b845..0000000
--- a/packages/server/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "iris-server",
- "private": true,
- "license": "LGPL-2.1-only",
- "author": "jottocraft",
- "scripts": {
- "build": "wrangler deploy --dry-run --outdir build",
- "clean": "rimraf build",
- "deploy": "wrangler deploy",
- "start": "wrangler dev --local --ip 127.0.0.1 --port 2500 --inspector-port 2501",
- "validate": "tsc --noEmit"
- },
- "dependencies": {
- "@jottocraft/iris-sdk": "workspace:*",
- "iris-plugins": "workspace:*"
- }
-}
diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts
deleted file mode 100644
index c1698e8..0000000
--- a/packages/server/src/index.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-// Iris
-// Copyright (c) jottocraft 2025
-
-import { YggdrasilRouter } from "@jottocraft/yggdrasil";
-
-import { IrisServer } from "~/server";
-
-export default {
- async fetch(request: Request, env: IrisServerEnv, ctx: ExecutionContext): Promise<Response> {
- return IrisServer.handleRequest(request, async (ygg) => {
- return new Response("Hello world!", { status: 200 });
- }, {
- ctx: {
- env,
- exec: ctx
- }
- }, {
- // TODO: Put these in environment variables
- baseURL: "https://iris.hq.jottocraft.com/api",
- debug: true,
- generateHtmlStatusPage: async (ygg, e) => {
- return new Response([
- "Error " + e.status,
- e.statusCode,
- e.statusMessage,
- "",
- "",
- "",
- "",
- "Iris",
- "Copyright (c) jottocraft 2025"
- ].join("\n"), {
- status: 200
- });
- }
- });
- }
-}
\ No newline at end of file
diff --git a/packages/server/src/iris-server.d.ts b/packages/server/src/iris-server.d.ts
deleted file mode 100644
index 2e859ba..0000000
--- a/packages/server/src/iris-server.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-// Iris
-// Copyright (c) jottocraft 2025
-
-declare type IrisServerEnv = {
-
-};
-
-declare type IrisServerContext = {
- env: IrisServerEnv;
- exec: ExecutionContext;
-};
-
-declare type IrisServerAppTypes = {
- ctx: IrisServerContext;
-};
\ No newline at end of file
diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts
deleted file mode 100644
index f52d620..0000000
--- a/packages/server/src/server.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// Iris
-// Copyright (c) jottocraft 2025
-
-import { YggdrasilServer } from "@jottocraft/yggdrasil";
-
-export const IrisServer = new YggdrasilServer<IrisServerAppTypes>();
\ No newline at end of file
diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json
deleted file mode 100644
index 141ac4e..0000000
--- a/packages/server/tsconfig.json
+++ /dev/null
@@ -1,107 +0,0 @@
-{
- "include": [
- "src"
- ],
- "compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
- /* Language and Environment */
- "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- "lib": [
- "ESNext"
- ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "react-jsx", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
- /* Modules */
- // "module": "commonjs", /* Specify what module code is generated. */
- "rootDir": "src",
- "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- "paths": {
- "~/*": [
- "./src/*"
- ]
- },
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- "types": [
- "node",
- "@cloudflare/workers-types"
- ], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- "resolveJsonModule": true, /* Enable importing .json files. */
- // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
- /* JavaScript Support */
- "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
- /* Emit */
- "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- // "outDir": "./", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
- /* Type Checking */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- "noUnusedLocals": false, /* Enable error reporting when local variables aren't read. */
- "noUnusedParameters": false, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
- /* Completeness */
- "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
- }
-}
\ No newline at end of file
diff --git a/packages/server/wrangler.toml b/packages/server/wrangler.toml
deleted file mode 100644
index 32dbdf4..0000000
--- a/packages/server/wrangler.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-name = "iris-server"
-main = "src/index.ts"
-compatibility_date = "2025-07-12"
-compatibility_flags = [ "nodejs_compat" ]
-
-account_id = "17174d3fc7098a664b04fb3c4c4ec65c"
-workers_dev = false
\ No newline at end of file
diff --git a/packages/webui/.gitignore b/packages/webui/.gitignore
index 36cd0db..7bd7f37 100644
--- a/packages/webui/.gitignore
+++ b/packages/webui/.gitignore
@@ -11,3 +11,4 @@
.wrangler
.dev.vars*
+src/IRIS_SITE.ts
\ No newline at end of file
diff --git a/packages/webui/package.json b/packages/webui/package.json
index b7f06b6..74f6b9e 100644
--- a/packages/webui/package.json
+++ b/packages/webui/package.json
@@ -13,7 +13,6 @@
"validate": "tsc --noEmit"
},
"dependencies": {
- "@jottocraft/iris-sdk": "workspace:*",
- "iris-plugins": "workspace:*"
+ "@jottocraft/iris-sdk": "workspace:*"
}
}
diff --git a/packages/webui/src/app/components/Form/Field.tsx b/packages/webui/src/app/components/Form/Field.tsx
new file mode 100644
index 0000000..122654c
--- /dev/null
+++ b/packages/webui/src/app/components/Form/Field.tsx
@@ -0,0 +1,162 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import { Button, Dropdown, DropdownItem, Icon, Switch, TextInput } from "@ffxp/react-dom";
+import type { IrisPluginConduitField } from "@jottocraft/iris-sdk";
+
+export function createDefaultFieldData(spec: IrisPluginConduitField, refData?: any, forceRequired?: boolean) {
+ if (spec.optional && !forceRequired) return undefined;
+
+ if (spec.type === "string") {
+ return refData ?? "";
+ } else if (spec.type === "number") {
+ return refData ?? 0;
+ } else if (spec.type === "date") {
+ return refData ?? new Date().toISOString().split("T")[0];
+ } else if (spec.type === "datetime") {
+ return refData ?? new Date().toISOString();
+ } else if (spec.type === "boolean") {
+ return refData ?? false;
+ } else if (spec.type === "dropdown") {
+ return refData ?? spec.options[0].value;
+ } else if (spec.type === "array") {
+ return refData ? refData.map((refItem: any) => createDefaultFieldData(spec.of, refItem)) : [];
+ } else if (spec.type === "object") {
+ const defaultData: any = {};
+ for (const key in spec.struct) {
+ defaultData[key] = createDefaultFieldData(spec.struct[key], refData ? refData[key] : undefined);
+ }
+ return defaultData;
+ }
+}
+
+export default function Field({ path, data, refData, spec, patchFormData, controls }: { path: string; data: any; refData: any; spec: IrisPluginConduitField; patchFormData: (path: string, value: unknown) => void; controls?: React.ReactNode; }) {
+ let fieldInput: React.ReactNode = null;
+
+ if ((refData !== undefined) && (spec.type !== "object")) return null;
+
+ if (data === undefined) {
+ fieldInput = (
+ <Button onClick={() => patchFormData(path, createDefaultFieldData(spec, undefined, true))} iconLeading="add">Set value</Button>
+ );
+ } else if ((spec.type === "string") || (spec.type === "number") || (spec.type === "date") || (spec.type === "datetime")) {
+ fieldInput = (
+ <TextInput
+ onChange={e => {
+ if (spec.type === "string") {
+ patchFormData(path, e.target.value);
+ } else if (spec.type === "number") {
+ patchFormData(path, Number(e.target.value));
+ } else if (spec.type === "date") {
+ patchFormData(path, e.target.value);
+ } else if (spec.type === "datetime") {
+ patchFormData(path, e.target.value + "Z");
+ }
+ }}
+ value={spec.type === "datetime" ? new Date(data).toISOString().split(":").slice(0, -1).join(":") : data}
+ type={spec.type === "string" ? (
+ "text"
+ ) : spec.type === "number" ? (
+ "number"
+ ) : spec.type === "date" ? (
+ "date"
+ ) : spec.type === "datetime" ? (
+ "datetime-local"
+ ) : undefined}
+ />
+ );
+ } else if (spec.type === "boolean") {
+ fieldInput = (
+ <Switch onClick={() => patchFormData(path, !data)} active={data} />
+ );
+ } else if (spec.type === "dropdown") {
+ const selectedOption = spec.options.find(option => option.value === data)!;
+ fieldInput = (
+ <Dropdown menu={(
+ <>
+ {spec.options.map(option => (
+ <DropdownItem onClick={() => patchFormData(path, option.value)} icon={option.icon}>{option.label}</DropdownItem>
+ ))}
+ </>
+ )}>
+ <Button variant="outline" iconLeading={selectedOption.icon} iconTrailing="arrow_drop_down">{selectedOption.label}</Button>
+ </Dropdown>
+ );
+ } else if (spec.type === "array") {
+ fieldInput = (
+ <div className="space-y-6 border border-ui-20 p-4 roundness-xl">
+ {data.map((value: any, i: number) => {
+ return (
+ <Field controls={(
+ <div className="space-x-2">
+ <Button onClick={() => {
+ if (i === 0) return;
+ const newValue = [...data];
+ newValue.splice(i, 1);
+ newValue.splice(i - 1, 0, value);
+ patchFormData(path, newValue);
+ }} iconLeading="arrow_upward" size="small" />
+ <Button onClick={() => {
+ if (i === (data.length - 1)) return;
+ const newValue = [...data];
+ newValue.splice(i, 1);
+ newValue.splice(i + 1, 0, value);
+ patchFormData(path, newValue);
+ }} iconLeading="arrow_downward" size="small" />
+ <Button onClick={() => {
+ const newValue = [...data];
+ newValue.splice(i, 1);
+ patchFormData(path, newValue);
+ }} iconLeading="delete" size="small" />
+ </div>
+ )} path={`${path}[${i}]`} data={value} refData={refData !== undefined ? refData[i] : undefined} spec={spec.of} patchFormData={patchFormData} />
+ );
+ })}
+ <Button iconLeading="add" onClick={() => patchFormData(path, [...data, createDefaultFieldData(spec.of)])}>Add item</Button>
+ </div>
+ );
+ } else if (spec.type === "object") {
+ fieldInput = (
+ <div className="space-y-6 border border-ui-20 p-4 roundness-xl">
+ {Object.keys(spec.struct).map(key => {
+ return (
+ <Field path={`${path}.${key}`} data={data[key]} refData={refData !== undefined ? refData[key] : undefined} spec={spec.struct[key]} patchFormData={patchFormData} />
+ );
+ })}
+ </div>
+ );
+ } else {
+ fieldInput = (
+ <div>
+ <p>Unrecognized field type {spec.type}</p>
+ </div>
+ );
+ }
+
+ return (
+ <div className="space-y-2">
+ {spec.icon || spec.displayName || spec.optional || controls ? (
+ <div className="flex flex-row items-center justify-between">
+ <div className="flex flex-row items-center space-x-2">
+ {spec.icon ? <Icon className="text-lg">{spec.icon}</Icon> : null}
+ {spec.displayName ? <div>{spec.displayName}</div> : null}
+ </div>
+ <div className="flex flex-row items-center space-x-8">
+ {spec.optional && (data !== undefined) ? (
+ <Button onClick={() => patchFormData(path, undefined)} iconLeading="delete" size="small">Clear value</Button>
+ ) : spec.optional ? (
+ <div className="text-xs px-2 py-1 bg-ui-10 roundness">
+ Optional
+ </div>
+ ) : null}
+ {controls}
+ </div>
+ </div>
+ ) : null}
+ {fieldInput}
+ {spec.helpText ? (
+ <div className="text-type-30 text-xs">{spec.helpText}</div>
+ ) : null}
+ </div>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/Form/index.tsx b/packages/webui/src/app/components/Form/index.tsx
new file mode 100644
index 0000000..b323de0
--- /dev/null
+++ b/packages/webui/src/app/components/Form/index.tsx
@@ -0,0 +1,81 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { IrisPluginConduitField } from "@jottocraft/iris-sdk";
+import { Button, Icon } from "@ffxp/react-dom";
+import { useCallback, useMemo, useState } from "react";
+import { createPortal } from "react-dom";
+import set from "lodash/set";
+import clone from "lodash/clone";
+
+import Field, { createDefaultFieldData } from "~/app/components/Form/Field";
+import { usePanelNavigation } from "~/app/data/panels";
+import { usePlugins } from "~/app/data/root";
+import { YggdrasilStatus } from "@jottocraft/yggdrasil";
+
+export default function Form({ ref, onFinished }: { ref: IrisWebuiFormRef; onFinished: () => void; }) {
+ const plugins = usePlugins()!;
+ const panelNavigation = usePanelNavigation() as IrisWebuiPanelNavigationCtxActive;
+ const form = plugins[panelNavigation.pluginId].plugin.forms[ref.id];
+
+ const defaultData = useMemo(() => form.data ? createDefaultFieldData(form.data, ref.data) : undefined, [form, ref]);
+
+ const [formData, setFormData] = useState<{ data: unknown; }>({
+ data: clone(defaultData)
+ });
+
+ const patchFormData = useCallback((path: string, value: unknown) => {
+ set(formData, path, value);
+
+ setFormData({
+ data: formData.data
+ });
+ }, [formData]);
+
+ const [formResult, setFormResult] = useState<YggdrasilStatus<unknown> | string | null>(null);
+ const submitForm = useCallback(() => {
+ (async () => {
+ try {
+ const data = await plugins[panelNavigation.pluginId].client().forms[ref.id](formData.data as any);
+ setFormResult(data);
+ } catch(e) {
+ if (!(e instanceof YggdrasilStatus)) throw e;
+ setFormResult(e);
+ }
+ })();
+ }, [panelNavigation, ref, formData]);
+
+ return createPortal((
+ <div className="w-full h-full py-10 absolute top-0 left-0 z-99 bg-black/90 flex items-center justify-center">
+ <div className="max-h-full overflow-auto w-2xl bg-ui-0 p-4 roundness-xl shadow-xl space-y-8">
+ <div className="flex flex-row items-center justify-between">
+ <div className="flex flex-row items-center text-xl space-x-2 font-medium">
+ {form.icon ? <Icon className="text-2xl">{form.icon}</Icon> : null}
+ <h1>{form.displayName}</h1>
+ </div>
+ <div>
+ <Button variant="borderless" onClick={() => onFinished()} iconLeading="close" size="small" />
+ </div>
+ </div>
+ {formResult ? (
+ <div>
+ <p>{formResult instanceof YggdrasilStatus ? formResult.statusCode : formResult}</p>
+ </div>
+ ) : (
+ <>
+ <div>
+ {form.data ? (
+ <Field path="data" data={formData.data} refData={ref.data} spec={form.data} patchFormData={patchFormData} />
+ ) : (
+ <p>This form doesn't take any input.</p>
+ )}
+ </div>
+ <div>
+ <Button onClick={submitForm} variant="primary">Submit</Button>
+ </div>
+ </>
+ )}
+ </div >
+ </div >
+ ), document.body);
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/Panel/index.tsx b/packages/webui/src/app/components/Panel/index.tsx
new file mode 100644
index 0000000..bafc717
--- /dev/null
+++ b/packages/webui/src/app/components/Panel/index.tsx
@@ -0,0 +1,82 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import { Button, Icon } from "@ffxp/react-dom";
+import type { IrisPluginConduit, IrisPluginConduitPanelArgs, IrisPluginConduitPanelLayout } from "@jottocraft/iris-sdk";
+import { useEffect, useState } from "react";
+import { useSearchParams } from "react-router";
+
+import { usePlugins } from "~/app/data/root";
+import PanelSection from "~/app/components/PanelSection";
+import { usePanelNavigation } from "~/app/data/panels";
+import Form from "~/app/components/Form";
+
+export default function Panel() {
+ const panelNavigation = usePanelNavigation()!;
+ const plugins = usePlugins()!;
+ const [activeForm, setActiveForm] = useState<IrisWebuiFormRef | null>(null);
+
+ if (!panelNavigation.activeRef) {
+ return (
+ <p>Please select a panel to open from the sidebar.</p>
+ );
+ }
+
+ if (!panelNavigation.layout) {
+ return (
+ <p>Loading panel {panelNavigation.activeRef.id}...</p>
+ );
+ }
+
+ const plugin = plugins[panelNavigation.pluginId];
+ const layout = panelNavigation.layout;
+
+ return (
+ <>
+ {activeForm ? (
+ <Form ref={activeForm} onFinished={() => setActiveForm(null)} />
+ ) : null}
+ <div className="space-y-8">
+ <div className="flex flex-row items-center space-x-3 text-4xl font-semibold">
+ {layout.icon ? <Icon>{layout.icon}</Icon> : null}
+ <h1>{layout.displayName}</h1>
+ </div>
+ {layout.forms ? (
+ <div>
+ {layout.forms?.map((ref) => {
+ const form = plugin.plugin.forms[ref.id];
+
+ return (
+ <div className="inline-block m-1">
+ <Button onClick={() => setActiveForm(ref)} iconLeading={form.icon}>{form.displayName}</Button>
+ </div>
+ );
+ })}
+ </div>
+ ) : null}
+ {layout.main ? (
+ <div>
+ {layout.main.map(item => (
+ <div className="inline-block space-y-2 m-1 p-4 bg-ui-5 roundness-xl">
+ <div className="flex flex-row items-center space-x-2 text-xl font-medium">
+ {item.icon ? <Icon>{item.icon}</Icon> : null}
+ <div>{item.displayName}</div>
+ </div>
+ <div>
+ <div>{item.value}</div>
+ </div>
+ </div>
+ ))}
+ </div>
+ ) : null}
+ {layout.sections ? (
+ <div>
+ {layout.sections.map(section => (
+ <PanelSection section={section} />
+ ))}
+ </div>
+ ) : null}
+ </div>
+ </>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/PanelBreadcrumbs.tsx b/packages/webui/src/app/components/PanelBreadcrumbs.tsx
new file mode 100644
index 0000000..1e824a2
--- /dev/null
+++ b/packages/webui/src/app/components/PanelBreadcrumbs.tsx
@@ -0,0 +1,38 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import { Button, Icon, Link } from "@ffxp/react-dom";
+import { Link as RouterLink } from "react-router";
+import { panelRefHref, usePanelNavigation } from "~/app/data/panels";
+
+export default function PanelBreadcrumbs() {
+ const panelNavigation = usePanelNavigation()!;
+
+ if (!panelNavigation.activeRef) return;
+
+ return (
+ <div className="flex-grow flex flex-row items-center border-ui-20 border-2 roundness-lg p-1">
+ <div className="mr-4 space-x-1">
+ <Button onClick={() => panelNavigation.back()} iconLeading="arrow_back" size="small" />
+ <Button onClick={() => panelNavigation.refreshLayout()} iconLeading="refresh" size="small" />
+ </div>
+ {panelNavigation.breadcrumbs.map((breadcrumb, i) => (
+ <div className="flex flex-row items-center space-x-1 text-sm text-type-20">
+ {breadcrumb.icon ? <Icon className="text-base">{breadcrumb.icon}</Icon> : null}
+ <div>
+ <RouterLink to={panelRefHref(panelNavigation.pluginId, breadcrumb.ref)} onClick={(e) => panelNavigation.goToBreadcrumb(i, e)}>
+ <Link>{breadcrumb.displayName}</Link>
+ </RouterLink>
+ </div>
+ <Icon className="text-xl mx-1">keyboard_arrow_right</Icon>
+ </div>
+ ))}
+ {panelNavigation.layout ? (
+ <div className="flex flex-row items-center space-x-1 text-base text-type-0 mr-2">
+ {panelNavigation.layout.icon ? <Icon className="text-lg">{panelNavigation.layout.icon}</Icon> : null}
+ <div className="font-medium">{panelNavigation.layout.displayName}</div>
+ </div>
+ ) : null}
+ </div>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/PanelNavigator.tsx b/packages/webui/src/app/components/PanelNavigator.tsx
new file mode 100644
index 0000000..16bcb25
--- /dev/null
+++ b/packages/webui/src/app/components/PanelNavigator.tsx
@@ -0,0 +1,94 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { IrisPluginConduit, IrisPluginConduitPanelLayout } from "@jottocraft/iris-sdk";
+import { useCallback, useEffect, useState } from "react";
+import { useNavigate } from "react-router";
+
+import { panelNavigationCtx, panelRefHref } from "~/app/data/panels";
+import { usePlugins } from "~/app/data/root";
+
+export default function PanelNavigator({ children }: { children?: React.ReactNode; }) {
+ const routerNavigate = useNavigate();
+ const plugins = usePlugins()!;
+
+ const [pluginId, setPluginId] = useState<string | null>(null);
+ const [activeRef, setActiveRef] = useState<IrisWebuiPanelRef | null>(null);
+ const [layout, setLayout] = useState<IrisPluginConduitPanelLayout<IrisPluginConduit> | null>(null);
+ const [breadcrumbs, setBreadcrumbs] = useState<IrisWebuiPanelBreadcrumb[]>([]);
+
+ useEffect(() => {
+ if (!activeRef) return;
+ routerNavigate(panelRefHref(pluginId!, activeRef));
+ }, [pluginId, activeRef, routerNavigate]);
+
+ const fetchLayout = useCallback(() => {
+ (async () => {
+ const data = await plugins[pluginId!].client().panels[activeRef!.id]((activeRef!.args ?? {}) as { [key: string]: string; });
+ setLayout(data);
+ })();
+ }, [plugins, pluginId, activeRef]);
+
+ useEffect(() => {
+ if (!activeRef) return;
+
+ fetchLayout();
+ }, [activeRef, fetchLayout]);
+
+ const navigate = useCallback((ref: IrisWebuiPanelRef, e?: React.MouseEvent) => {
+ e?.preventDefault();
+
+ setBreadcrumbs([...breadcrumbs, {
+ displayName: layout?.displayName ?? activeRef!.id,
+ icon: layout?.icon ?? undefined,
+ ref: activeRef!
+ }]);
+ setActiveRef(ref);
+ }, [activeRef, layout, breadcrumbs]);
+
+ const back = useCallback((e?: React.MouseEvent) => {
+ e?.preventDefault();
+ if (!breadcrumbs.length) return;
+
+ setActiveRef(breadcrumbs[breadcrumbs.length - 1].ref);
+ setBreadcrumbs(breadcrumbs.slice(0, -1));
+ }, [breadcrumbs]);
+
+ const goToBreadcrumb = useCallback((index: number, e?: React.MouseEvent) => {
+ e?.preventDefault();
+ if (!breadcrumbs.length) return;
+
+ setActiveRef(breadcrumbs[index].ref);
+ setBreadcrumbs(breadcrumbs.slice(0, index));
+ }, [breadcrumbs]);
+
+ const startNavigation = useCallback((pluginId: string, ref: IrisWebuiPanelRef, e?: React.MouseEvent) => {
+ setPluginId(pluginId);
+ setActiveRef(ref);
+ setBreadcrumbs([]);
+ }, []);
+
+ const refreshLayout = useCallback(() => {
+ setLayout(null);
+ fetchLayout();
+ }, [fetchLayout]);
+
+ return (
+ <panelNavigationCtx.Provider value={activeRef ? {
+ activeRef,
+ layout,
+ pluginId: pluginId!,
+ breadcrumbs,
+ navigate,
+ back,
+ goToBreadcrumb,
+ startNavigation,
+ refreshLayout
+ } : {
+ activeRef,
+ startNavigation
+ }}>
+ {children}
+ </panelNavigationCtx.Provider>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/PanelSection/PanelSectionProperties.tsx b/packages/webui/src/app/components/PanelSection/PanelSectionProperties.tsx
new file mode 100644
index 0000000..1668d1c
--- /dev/null
+++ b/packages/webui/src/app/components/PanelSection/PanelSectionProperties.tsx
@@ -0,0 +1,10 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { IrisPluginConduit, IrisPluginConduitPanelLayoutSectionProperties } from "@jottocraft/iris-sdk";
+
+export default function PanelSectionProperties({ section }: { section: IrisPluginConduitPanelLayoutSectionProperties<IrisPluginConduit>; }) {
+ return (
+ <p>TODO</p>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/PanelSection/PanelSectionRef.tsx b/packages/webui/src/app/components/PanelSection/PanelSectionRef.tsx
new file mode 100644
index 0000000..c889178
--- /dev/null
+++ b/packages/webui/src/app/components/PanelSection/PanelSectionRef.tsx
@@ -0,0 +1,10 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { IrisPluginConduit, IrisPluginConduitPanelLayoutSectionRef } from "@jottocraft/iris-sdk";
+
+export default function PanelSectionRef({ section }: { section: IrisPluginConduitPanelLayoutSectionRef<IrisPluginConduit>; }) {
+ return (
+ <p>TODO</p>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/PanelSection/PanelSectionTable.tsx b/packages/webui/src/app/components/PanelSection/PanelSectionTable.tsx
new file mode 100644
index 0000000..26229e4
--- /dev/null
+++ b/packages/webui/src/app/components/PanelSection/PanelSectionTable.tsx
@@ -0,0 +1,46 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { IrisPluginConduit, IrisPluginConduitPanelLayoutSectionTable } from "@jottocraft/iris-sdk";
+import { Link, useParams } from "react-router";
+
+import { panelRefHref, usePanelNavigation } from "~/app/data/panels";
+
+export default function PanelSectionTable({ section }: { section: IrisPluginConduitPanelLayoutSectionTable<IrisPluginConduit>; }) {
+ const params = useParams();
+ const panelNavigation = usePanelNavigation() as IrisWebuiPanelNavigationCtxActive;
+
+ return (
+ <div>
+ <table>
+ <thead>
+ <tr>
+ {section.columns.map(column => (
+ <th>
+ {column.displayName}
+ </th>
+ ))}
+ </tr>
+ </thead>
+ <tbody>
+ {section.rows.map(row => (
+ <tr>
+ {section.columns.map(column => {
+ const link = row.links?.[column.key];
+ return (
+ <td>
+ {link ? (
+ <Link to={panelRefHref(panelNavigation.pluginId, link)} onClick={(e) => panelNavigation.navigate(link, e)}>{row.vals[column.key] ?? null}</Link>
+ ) : (
+ row.vals[column.key] ?? null
+ )}
+ </td>
+ );
+ })}
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/PanelSection/index.tsx b/packages/webui/src/app/components/PanelSection/index.tsx
new file mode 100644
index 0000000..af483f0
--- /dev/null
+++ b/packages/webui/src/app/components/PanelSection/index.tsx
@@ -0,0 +1,26 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { IrisPluginConduit, IrisPluginConduitPanelLayoutSection } from "@jottocraft/iris-sdk";
+
+import PanelSectionProperties from "~/app/components/PanelSection/PanelSectionProperties";
+import PanelSectionTable from "~/app/components/PanelSection/PanelSectionTable";
+import PanelSectionRef from "~/app/components/PanelSection/PanelSectionRef";
+
+export default function PanelSection({ section }: { section: IrisPluginConduitPanelLayoutSection<IrisPluginConduit>; }) {
+ if (section.type === "properties") {
+ return (
+ <PanelSectionProperties section={section} />
+ );
+ } else if (section.type === "table") {
+ return (
+ <PanelSectionTable section={section} />
+ );
+ } else if (section.type === "ref") {
+ return (
+ <PanelSectionRef section={section} />
+ );
+ } else {
+ throw new Error("Unrecognized panel layout section type " + (section as any).type);
+ }
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/components/Shell.tsx b/packages/webui/src/app/components/Shell.tsx
new file mode 100644
index 0000000..62267db
--- /dev/null
+++ b/packages/webui/src/app/components/Shell.tsx
@@ -0,0 +1,111 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import { Button, NavbarLayout, NavbarTitle, SidebarHeader, SidebarItem, SidebarItemGroup, SidebarItems, SidebarLayout, SidebarTitle, useThemeEngine } from "@ffxp/react-dom";
+import { useEffect } from "react";
+import { Link, Outlet, useLocation, useParams, useSearchParams } from "react-router";
+
+import IRIS_SITE from "~/IRIS_SITE";
+import { useAuth, usePlugins } from "~/app/data/root";
+import { isAtPanel, panelRefHref, usePanelNavigation } from "~/app/data/panels";
+import PanelNavigator from "~/app/components/PanelNavigator";
+import PanelBreadcrumbs from "~/app/components/PanelBreadcrumbs";
+
+function ShellLayout({ children }: { children?: React.ReactNode; }) {
+ const theme = useThemeEngine();
+ const plugins = usePlugins()!;
+ const auth = useAuth();
+ const panelNavigation = usePanelNavigation()!;
+ const routerParams = useParams();
+ const [searchParams] = useSearchParams();
+
+ useEffect(() => {
+ if (!panelNavigation.activeRef && (routerParams.pluginId && routerParams.panelId)) {
+ const args: { [key: string]: string } = {};
+ for (const [k, v] of searchParams.entries()) args[k] = v;
+
+ panelNavigation.startNavigation(routerParams.pluginId, {
+ id: routerParams.panelId,
+ args
+ });
+ }
+ }, [routerParams, searchParams, panelNavigation]);
+
+ return (
+ <NavbarLayout left={(
+ <div className="flex-grow flex flex-row items-center space-x-8">
+ <Link to="/">
+ <NavbarTitle logo="/webui/assets/favicon.png">
+ Iris
+ </NavbarTitle>
+ </Link>
+ <PanelBreadcrumbs />
+ </div>
+ )}
+ right={(
+ <>
+ <Button onClick={() => {
+ if (window.confirm("Do you want to sign out?")) {
+ window.localStorage.removeItem("jwt");
+ window.location.reload();
+ }
+ }}>
+ Signed in as {auth?.claims.email as string}
+ </Button>
+ </>
+ )}>
+ <SidebarLayout sidebar={(
+ <>
+ <SidebarHeader>
+ {IRIS_SITE.brand.logo ? (
+ <img className="w-full h-10 object-contain" src={theme.config.colors.dark ? IRIS_SITE.brand.logo.light : IRIS_SITE.brand.logo.dark} />
+ ) : (
+ <SidebarTitle>{IRIS_SITE.brand.name}</SidebarTitle>
+ )}
+ </SidebarHeader>
+ <SidebarItems>
+ {IRIS_SITE.plugins.map(({ id }) => {
+ const plugin = plugins[id];
+ return (
+ <SidebarItemGroup title={plugin.plugin.displayName} icon={plugin.plugin.icon}>
+ {plugin.plugin.navigation.map(item => (
+ <Link to={panelRefHref(id, item.panel)} onClick={e => panelNavigation.startNavigation(id, item.panel, e)}>
+ <SidebarItem active={(panelNavigation.activeRef && (panelNavigation.pluginId === id)) ? isAtPanel(panelNavigation.breadcrumbs[0]?.ref ?? panelNavigation.activeRef, item.panel) : false} icon={item.icon}>{item.displayName}</SidebarItem>
+ </Link>
+ ))}
+ </SidebarItemGroup>
+ );
+ })}
+ </SidebarItems>
+ </>
+ )}>
+ {children}
+ </SidebarLayout>
+ </NavbarLayout>
+ );
+}
+
+export default function Shell({ children }: { children?: React.ReactNode; }) {
+ const location = useLocation();
+ const plugins = usePlugins();
+
+ if (location.pathname === "/login") {
+ return (
+ <Outlet />
+ );
+ }
+
+ if (!plugins) {
+ return (
+ <p>Loading plugins...</p>
+ );
+ }
+
+ return (
+ <PanelNavigator>
+ <ShellLayout>
+ {children}
+ </ShellLayout>
+ </PanelNavigator>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/data/panels.ts b/packages/webui/src/app/data/panels.ts
new file mode 100644
index 0000000..26e99f0
--- /dev/null
+++ b/packages/webui/src/app/data/panels.ts
@@ -0,0 +1,28 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import { createContext, useContext } from "react";
+import isEqual from "lodash/isEqual";
+
+export const panelNavigationCtx = createContext<IrisWebuiPanelNavigationCtx | null>(null);
+export function usePanelNavigation() {
+ return useContext(panelNavigationCtx);
+}
+
+export function panelRefHref(pluginId: string, ref: IrisWebuiPanelRef) {
+ let linkHref: string = `/p/${pluginId}/${ref.id}`;
+ if (ref.args) {
+ const linkParams = new URLSearchParams();
+ for (const arg in ref.args) {
+ if (ref.args[arg]) linkParams.set(arg, ref.args[arg]);
+ }
+ linkHref = linkHref + "?" + linkParams.toString();
+ }
+
+ return linkHref;
+}
+
+export function isAtPanel(activeRef: IrisWebuiPanelRef, desiredRef: IrisWebuiPanelRef) {
+ if (activeRef.id !== desiredRef.id) return false;
+ return isEqual(activeRef.args ?? {}, desiredRef.args ?? {});
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/data/root.ts b/packages/webui/src/app/data/root.ts
new file mode 100644
index 0000000..0697087
--- /dev/null
+++ b/packages/webui/src/app/data/root.ts
@@ -0,0 +1,15 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { IrisAuthCtx, IrisPluginCtx } from "@jottocraft/iris-sdk";
+import { createContext, useContext } from "react";
+
+export const pluginContext = createContext<IrisPluginCtx | null>(null);
+export function usePlugins() {
+ return useContext(pluginContext);
+}
+
+export const authContext = createContext<IrisAuthCtx | null>(null);
+export function useAuth() {
+ return useContext(authContext);
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/root.tsx b/packages/webui/src/app/root.tsx
index abab211..c96602f 100644
--- a/packages/webui/src/app/root.tsx
+++ b/packages/webui/src/app/root.tsx
@@ -2,6 +2,9 @@
// Copyright (c) jottocraft 2025
import { BodyWrapper, Container, HeadWrapper, HTMLWrapper, Link, Root, ThemeEngine } from "@ffxp/react-dom";
+import type { IrisAuthCtx, IrisPluginConduit, IrisPluginConduitConduitServerTypes, IrisPluginCtx } from "@jottocraft/iris-sdk";
+import { createConduitClientSideClient } from "@jottocraft/yggdrasil";
+import { useEffect, useState } from "react";
import {
isRouteErrorResponse,
Links,
@@ -9,12 +12,88 @@
Scripts,
ScrollRestoration,
useLoaderData,
+ useLocation,
type LoaderFunction,
} from "react-router";
import "~/app/app.css";
+import Shell from "~/app/components/Shell";
+import { authContext, pluginContext } from "~/app/data/root";
+import IRIS_SITE from "~/IRIS_SITE";
export default function App() {
+ const location = useLocation();
+
+ const [auth, setAuth] = useState<IrisAuthCtx | null>(null);
+ useEffect(() => {
+ if (location.pathname === "/login") {
+ return;
+ }
+
+ if (!auth) {
+ let jwt = window.localStorage.getItem("jwt");
+ if (jwt) {
+ const jwtData = JSON.parse(atob(jwt.split(".")[1]));
+ if (!jwtData.exp || (new Date().getTime() > (jwtData.exp * 1000))) {
+ jwt = null;
+ } else {
+ setAuth({
+ jwt,
+ claims: jwtData
+ });
+ }
+ }
+
+ if (!jwt) {
+ const redirectUrl = new URL(window.location.origin);
+ redirectUrl.pathname = "/webui/login";
+
+ const nonce = crypto.randomUUID();
+ window.localStorage.setItem("nonce", JSON.stringify({
+ nonce,
+ // Expires in 30 minutes
+ useBefore: new Date().getTime() + 30 * 60 * 1000
+ } satisfies IrisWebuiNonceStorage));
+
+ const authUrl = new URL(IRIS_SITE.auth.authUrl);
+ authUrl.searchParams.set("client_id", IRIS_SITE.auth.clientId);
+ authUrl.searchParams.set("redirect_uri", redirectUrl.href);
+ authUrl.searchParams.set("response_type", "id_token");
+ authUrl.searchParams.set("scope", IRIS_SITE.auth.scope ?? "openid email profile");
+ authUrl.searchParams.set("nonce", nonce);
+ window.location.href = authUrl.href;
+ }
+ }
+ }, [auth, location.pathname]);
+
+ const [plugins, setPlugins] = useState<null | IrisPluginCtx>(null);
+ useEffect(() => {
+ if (!auth) return;
+
+ const plugins: IrisPluginCtx = {};
+ Promise.all(IRIS_SITE.plugins.map(async (sitePlugin) => {
+ if (sitePlugin.type === "conduit") {
+ const client = createConduitClientSideClient<IrisPluginConduitConduitServerTypes<IrisPluginConduit>>({
+ jwt: auth.jwt
+ }, {
+ baseURL: sitePlugin.baseUrl
+ });
+
+ const plugin = await client().plugin();
+
+ plugins[sitePlugin.id] = {
+ type: "conduit",
+ plugin,
+ client
+ };
+ } else {
+ throw new Error("Unexpected plugin type " + sitePlugin.type);
+ }
+ })).then(() => {
+ setPlugins(plugins);
+ }).catch(e => { throw e; });
+ }, [auth]);
+
return (
<Root>
<ThemeEngine plugins={[
@@ -53,7 +132,13 @@
<Links />
</HeadWrapper>
<BodyWrapper>
- <Outlet />
+ <authContext.Provider value={auth}>
+ <pluginContext.Provider value={plugins}>
+ <Shell>
+ <Outlet />
+ </Shell>
+ </pluginContext.Provider>
+ </authContext.Provider>
<ScrollRestoration />
<Scripts />
</BodyWrapper>
diff --git a/packages/webui/src/app/routes/login.tsx b/packages/webui/src/app/routes/login.tsx
new file mode 100644
index 0000000..f63ce03
--- /dev/null
+++ b/packages/webui/src/app/routes/login.tsx
@@ -0,0 +1,68 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import type { JWTPayload } from "jose";
+import { useEffect, useState } from "react";
+
+import IRIS_SITE from "~/IRIS_SITE";
+
+export default function Login() {
+ const [error, setError] = useState<null | string>(null);
+ useEffect(() => {
+ const nonce = window.localStorage.getItem("nonce");
+ if (!nonce) {
+ setError("Missing auth state");
+ return;
+ }
+
+ const nonceData = JSON.parse(nonce) as IrisWebuiNonceStorage;
+ if (new Date().getTime() > nonceData.useBefore) {
+ setError("Auth state has expired");
+ return;
+ }
+
+ if (!window.location.hash.slice(1)) {
+ setError("Missing auth parameters");
+ return;
+ }
+
+ const hashParams = new URLSearchParams(window.location.hash.slice(1));
+ const jwt = hashParams.get("id_token");
+ if (!jwt) {
+ setError("Missing required id_token parameter");
+ return;
+ }
+
+ const jwtData = JSON.parse(atob(jwt.split(".")[1])) as JWTPayload;
+ if ((jwtData.aud !== IRIS_SITE.auth.clientId) ||
+ (jwtData.iss !== IRIS_SITE.auth.iss) ||
+ !jwtData.nbf ||
+ ((jwtData.nbf * 1000) > new Date().getTime()) ||
+ !jwtData.exp ||
+ ((jwtData.exp * 1000) < new Date().getTime()) ||
+ (jwtData.nonce !== nonceData.nonce)) {
+ setError("Invalid or expired id_token");
+ return;
+ }
+
+ const webuiUrl = new URL(window.location.origin);
+ webuiUrl.pathname = "/webui";
+
+ window.localStorage.removeItem("nonce");
+ window.localStorage.setItem("jwt", jwt);
+ window.location.href = webuiUrl.href;
+ }, []);
+
+ return (
+ <div>
+ {error ? (
+ <div>
+ <h1>Authentication error</h1>
+ <p>{error}</p>
+ </div>
+ ) : (
+ <p>Signing in...</p>
+ )}
+ </div>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/routes/p/$.tsx b/packages/webui/src/app/routes/p/$.tsx
new file mode 100644
index 0000000..1837210
--- /dev/null
+++ b/packages/webui/src/app/routes/p/$.tsx
@@ -0,0 +1,10 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+export default function Home() {
+ return (
+ <div>
+ <p>Hello plugin!</p>
+ </div>
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/app/routes/p/$pluginId/$panelId.tsx b/packages/webui/src/app/routes/p/$pluginId/$panelId.tsx
new file mode 100644
index 0000000..76e2f75
--- /dev/null
+++ b/packages/webui/src/app/routes/p/$pluginId/$panelId.tsx
@@ -0,0 +1,15 @@
+// Iris
+// Copyright (c) jottocraft 2025
+
+import { useState } from "react";
+import { useParams } from "react-router";
+
+import Panel from "~/app/components/Panel";
+
+export default function PanelRoute() {
+ return (
+ <div className="py-12">
+ <Panel />
+ </div >
+ );
+}
\ No newline at end of file
diff --git a/packages/webui/src/webui.d.ts b/packages/webui/src/webui.d.ts
index dc05a7e..869b1fc 100644
--- a/packages/webui/src/webui.d.ts
+++ b/packages/webui/src/webui.d.ts
@@ -1,2 +1,42 @@
// Iris
-// Copyright (c) jottocraft 2025
\ No newline at end of file
+// Copyright (c) jottocraft 2025
+
+declare type IrisWebuiConfig = {
+ origin: string;
+ site: import("@jottocraft/iris-sdk").IrisSiteConfig;
+};
+
+declare type IrisWebuiNonceStorage = {
+ nonce: string;
+ useBefore: number;
+};
+
+declare type IrisWebuiPanelRef = import("@jottocraft/iris-sdk").IrisPluginConduitPanelRef<import("@jottocraft/iris-sdk").IrisPluginConduit>;
+declare type IrisWebuiFormRef = import("@jottocraft/iris-sdk").IrisPluginConduitFormRef<import("@jottocraft/iris-sdk").IrisPluginConduit>;
+
+declare type IrisWebuiPanelNavigationCtx = IrisWebuiPanelNavigationCtxActive | IrisWebuiPanelNavigationCtxInactive;
+
+declare type IrisWebuiPanelNavigationCtxCommon = {
+ startNavigation: (pluginId: string, ref: IrisWebuiPanelRef, e?: React.MouseEvent) => void;
+};
+
+declare type IrisWebuiPanelNavigationCtxActive = IrisWebuiPanelNavigationCtxCommon & {
+ activeRef: IrisWebuiPanelRef;
+ layout: null | import("@jottocraft/iris-sdk").IrisPluginConduitPanelLayout<import("@jottocraft/iris-sdk").IrisPluginConduit>;
+ pluginId: string;
+ breadcrumbs: IrisWebuiPanelBreadcrumb[];
+ navigate: (ref: IrisWebuiPanelRef, e?: React.MouseEvent) => void;
+ back: (e?: React.MouseEvent) => void;
+ goToBreadcrumb: (index: number, e?: React.MouseEvent) => void;
+ refreshLayout: () => void;
+};
+
+declare type IrisWebuiPanelNavigationCtxInactive = IrisWebuiPanelNavigationCtxCommon & {
+ activeRef: null;
+};
+
+declare type IrisWebuiPanelBreadcrumb = {
+ displayName: string;
+ icon?: string;
+ ref: IrisWebuiPanelRef;
+};
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 5da2495..4e04f2d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1157,6 +1157,33 @@
languageName: node
linkType: hard
+"@nodelib/fs.scandir@npm:2.1.5":
+ version: 2.1.5
+ resolution: "@nodelib/fs.scandir@npm:2.1.5"
+ dependencies:
+ "@nodelib/fs.stat": "npm:2.0.5"
+ run-parallel: "npm:^1.1.9"
+ checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb
+ languageName: node
+ linkType: hard
+
+"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2":
+ version: 2.0.5
+ resolution: "@nodelib/fs.stat@npm:2.0.5"
+ checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d
+ languageName: node
+ linkType: hard
+
+"@nodelib/fs.walk@npm:^1.2.3":
+ version: 1.2.8
+ resolution: "@nodelib/fs.walk@npm:1.2.8"
+ dependencies:
+ "@nodelib/fs.scandir": "npm:2.1.5"
+ fastq: "npm:^1.6.0"
+ checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1
+ languageName: node
+ linkType: hard
+
"@npmcli/agent@npm:^3.0.0":
version: 3.0.0
resolution: "@npmcli/agent@npm:3.0.0"
@@ -1782,6 +1809,13 @@
languageName: node
linkType: hard
+"@types/lodash@npm:^4.17.20":
+ version: 4.17.20
+ resolution: "@types/lodash@npm:4.17.20"
+ checksum: 10c0/98cdd0faae22cbb8079a01a3bb65aa8f8c41143367486c1cbf5adc83f16c9272a2a5d2c1f541f61d0d73da543c16ee1d21cf2ef86cb93cd0cc0ac3bced6dd88f
+ languageName: node
+ linkType: hard
+
"@types/node@npm:^20":
version: 20.19.9
resolution: "@types/node@npm:20.19.9"
@@ -1888,6 +1922,15 @@
languageName: node
linkType: hard
+"ansi-styles@npm:^3.2.1":
+ version: 3.2.1
+ resolution: "ansi-styles@npm:3.2.1"
+ dependencies:
+ color-convert: "npm:^1.9.0"
+ checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b
+ languageName: node
+ linkType: hard
+
"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0":
version: 4.3.0
resolution: "ansi-styles@npm:4.3.0"
@@ -1911,6 +1954,16 @@
languageName: node
linkType: hard
+"anymatch@npm:~3.1.2":
+ version: 3.1.3
+ resolution: "anymatch@npm:3.1.3"
+ dependencies:
+ normalize-path: "npm:^3.0.0"
+ picomatch: "npm:^2.0.4"
+ checksum: 10c0/57b06ae984bc32a0d22592c87384cd88fe4511b1dd7581497831c56d41939c8a001b28e7b853e1450f2bf61992dfcaa8ae2d0d161a0a90c4fb631ef07098fbac
+ languageName: node
+ linkType: hard
+
"arg@npm:^5.0.1":
version: 5.0.2
resolution: "arg@npm:5.0.2"
@@ -1934,6 +1987,45 @@
languageName: node
linkType: hard
+"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "array-buffer-byte-length@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ is-array-buffer: "npm:^3.0.5"
+ checksum: 10c0/74e1d2d996941c7a1badda9cabb7caab8c449db9086407cad8a1b71d2604cc8abf105db8ca4e02c04579ec58b7be40279ddb09aea4784832984485499f48432d
+ languageName: node
+ linkType: hard
+
+"array-union@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "array-union@npm:2.1.0"
+ checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962
+ languageName: node
+ linkType: hard
+
+"arraybuffer.prototype.slice@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "arraybuffer.prototype.slice@npm:1.0.4"
+ dependencies:
+ array-buffer-byte-length: "npm:^1.0.1"
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.5"
+ es-errors: "npm:^1.3.0"
+ get-intrinsic: "npm:^1.2.6"
+ is-array-buffer: "npm:^3.0.4"
+ checksum: 10c0/2f2459caa06ae0f7f615003f9104b01f6435cc803e11bd2a655107d52a1781dc040532dc44d93026b694cc18793993246237423e13a5337e86b43ed604932c06
+ languageName: node
+ linkType: hard
+
+"async-function@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "async-function@npm:1.0.0"
+ checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73
+ languageName: node
+ linkType: hard
+
"asynckit@npm:^0.4.0":
version: 0.4.0
resolution: "asynckit@npm:0.4.0"
@@ -1941,6 +2033,15 @@
languageName: node
linkType: hard
+"available-typed-arrays@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "available-typed-arrays@npm:1.0.7"
+ dependencies:
+ possible-typed-array-names: "npm:^1.0.0"
+ checksum: 10c0/d07226ef4f87daa01bd0fe80f8f310982e345f372926da2e5296aecc25c41cab440916bbaa4c5e1034b453af3392f67df5961124e4b586df1e99793a1374bdb2
+ languageName: node
+ linkType: hard
+
"axios@npm:^1.8.3":
version: 1.10.0
resolution: "axios@npm:1.10.0"
@@ -1978,6 +2079,13 @@
languageName: node
linkType: hard
+"binary-extensions@npm:^2.0.0":
+ version: 2.3.0
+ resolution: "binary-extensions@npm:2.3.0"
+ checksum: 10c0/75a59cafc10fb12a11d510e77110c6c7ae3f4ca22463d52487709ca7f18f69d886aa387557cc9864fbdb10153d0bdb4caacabf11541f55e89ed6e18d12ece2b5
+ languageName: node
+ linkType: hard
+
"bl@npm:^4.0.3":
version: 4.1.0
resolution: "bl@npm:4.1.0"
@@ -1996,6 +2104,16 @@
languageName: node
linkType: hard
+"brace-expansion@npm:^1.1.7":
+ version: 1.1.12
+ resolution: "brace-expansion@npm:1.1.12"
+ dependencies:
+ balanced-match: "npm:^1.0.0"
+ concat-map: "npm:0.0.1"
+ checksum: 10c0/975fecac2bb7758c062c20d0b3b6288c7cc895219ee25f0a64a9de662dbac981ff0b6e89909c3897c1f84fa353113a721923afdec5f8b2350255b097f12b1f73
+ languageName: node
+ linkType: hard
+
"brace-expansion@npm:^2.0.1":
version: 2.0.2
resolution: "brace-expansion@npm:2.0.2"
@@ -2005,6 +2123,15 @@
languageName: node
linkType: hard
+"braces@npm:^3.0.3, braces@npm:~3.0.2":
+ version: 3.0.3
+ resolution: "braces@npm:3.0.3"
+ dependencies:
+ fill-range: "npm:^7.1.1"
+ checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04
+ languageName: node
+ linkType: hard
+
"browserslist@npm:^4.24.0":
version: 4.25.1
resolution: "browserslist@npm:4.25.1"
@@ -2056,7 +2183,7 @@
languageName: node
linkType: hard
-"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2":
+"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2":
version: 1.0.2
resolution: "call-bind-apply-helpers@npm:1.0.2"
dependencies:
@@ -2066,6 +2193,28 @@
languageName: node
linkType: hard
+"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8":
+ version: 1.0.8
+ resolution: "call-bind@npm:1.0.8"
+ dependencies:
+ call-bind-apply-helpers: "npm:^1.0.0"
+ es-define-property: "npm:^1.0.0"
+ get-intrinsic: "npm:^1.2.4"
+ set-function-length: "npm:^1.2.2"
+ checksum: 10c0/a13819be0681d915144467741b69875ae5f4eba8961eb0bf322aab63ec87f8250eb6d6b0dcbb2e1349876412a56129ca338592b3829ef4343527f5f18a0752d4
+ languageName: node
+ linkType: hard
+
+"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "call-bound@npm:1.0.4"
+ dependencies:
+ call-bind-apply-helpers: "npm:^1.0.2"
+ get-intrinsic: "npm:^1.3.0"
+ checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644
+ languageName: node
+ linkType: hard
+
"caniuse-lite@npm:^1.0.30001726":
version: 1.0.30001727
resolution: "caniuse-lite@npm:1.0.30001727"
@@ -2073,6 +2222,17 @@
languageName: node
linkType: hard
+"chalk@npm:^2.4.1":
+ version: 2.4.2
+ resolution: "chalk@npm:2.4.2"
+ dependencies:
+ ansi-styles: "npm:^3.2.1"
+ escape-string-regexp: "npm:^1.0.5"
+ supports-color: "npm:^5.3.0"
+ checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073
+ languageName: node
+ linkType: hard
+
"chalk@npm:^4.1.0, chalk@npm:^4.1.2":
version: 4.1.2
resolution: "chalk@npm:4.1.2"
@@ -2083,6 +2243,25 @@
languageName: node
linkType: hard
+"chokidar@npm:^3.5.3":
+ version: 3.6.0
+ resolution: "chokidar@npm:3.6.0"
+ dependencies:
+ anymatch: "npm:~3.1.2"
+ braces: "npm:~3.0.2"
+ fsevents: "npm:~2.3.2"
+ glob-parent: "npm:~5.1.2"
+ is-binary-path: "npm:~2.1.0"
+ is-glob: "npm:~4.0.1"
+ normalize-path: "npm:~3.0.0"
+ readdirp: "npm:~3.6.0"
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ checksum: 10c0/8361dcd013f2ddbe260eacb1f3cb2f2c6f2b0ad118708a343a5ed8158941a39cb8fb1d272e0f389712e74ee90ce8ba864eece9e0e62b9705cb468a2f6d917462
+ languageName: node
+ linkType: hard
+
"chokidar@npm:^4.0.0":
version: 4.0.3
resolution: "chokidar@npm:4.0.3"
@@ -2161,6 +2340,15 @@
languageName: node
linkType: hard
+"color-convert@npm:^1.9.0":
+ version: 1.9.3
+ resolution: "color-convert@npm:1.9.3"
+ dependencies:
+ color-name: "npm:1.1.3"
+ checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c
+ languageName: node
+ linkType: hard
+
"color-convert@npm:^2.0.1":
version: 2.0.1
resolution: "color-convert@npm:2.0.1"
@@ -2170,6 +2358,13 @@
languageName: node
linkType: hard
+"color-name@npm:1.1.3":
+ version: 1.1.3
+ resolution: "color-name@npm:1.1.3"
+ checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6
+ languageName: node
+ linkType: hard
+
"color-name@npm:^1.0.0, color-name@npm:~1.1.4":
version: 1.1.4
resolution: "color-name@npm:1.1.4"
@@ -2206,6 +2401,20 @@
languageName: node
linkType: hard
+"commander@npm:^9.0.0":
+ version: 9.5.0
+ resolution: "commander@npm:9.5.0"
+ checksum: 10c0/5f7784fbda2aaec39e89eb46f06a999e00224b3763dc65976e05929ec486e174fe9aac2655f03ba6a5e83875bd173be5283dc19309b7c65954701c02025b3c1d
+ languageName: node
+ linkType: hard
+
+"concat-map@npm:0.0.1":
+ version: 0.0.1
+ resolution: "concat-map@npm:0.0.1"
+ checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f
+ languageName: node
+ linkType: hard
+
"convert-source-map@npm:^2.0.0":
version: 2.0.0
resolution: "convert-source-map@npm:2.0.0"
@@ -2232,6 +2441,19 @@
languageName: node
linkType: hard
+"cross-spawn@npm:^6.0.5":
+ version: 6.0.6
+ resolution: "cross-spawn@npm:6.0.6"
+ dependencies:
+ nice-try: "npm:^1.0.4"
+ path-key: "npm:^2.0.1"
+ semver: "npm:^5.5.0"
+ shebang-command: "npm:^1.2.0"
+ which: "npm:^1.2.9"
+ checksum: 10c0/bf61fb890e8635102ea9bce050515cf915ff6a50ccaa0b37a17dc82fded0fb3ed7af5478b9367b86baee19127ad86af4be51d209f64fd6638c0862dca185fe1d
+ languageName: node
+ linkType: hard
+
"cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.6":
version: 7.0.6
resolution: "cross-spawn@npm:7.0.6"
@@ -2250,6 +2472,39 @@
languageName: node
linkType: hard
+"data-view-buffer@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "data-view-buffer@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ is-data-view: "npm:^1.0.2"
+ checksum: 10c0/7986d40fc7979e9e6241f85db8d17060dd9a71bd53c894fa29d126061715e322a4cd47a00b0b8c710394854183d4120462b980b8554012acc1c0fa49df7ad38c
+ languageName: node
+ linkType: hard
+
+"data-view-byte-length@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "data-view-byte-length@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ is-data-view: "npm:^1.0.2"
+ checksum: 10c0/f8a4534b5c69384d95ac18137d381f18a5cfae1f0fc1df0ef6feef51ef0d568606d970b69e02ea186c6c0f0eac77fe4e6ad96fec2569cc86c3afcc7475068c55
+ languageName: node
+ linkType: hard
+
+"data-view-byte-offset@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "data-view-byte-offset@npm:1.0.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ es-errors: "npm:^1.3.0"
+ is-data-view: "npm:^1.0.1"
+ checksum: 10c0/fa7aa40078025b7810dcffc16df02c480573b7b53ef1205aa6a61533011005c1890e5ba17018c692ce7c900212b547262d33279fde801ad9843edc0863bf78c4
+ languageName: node
+ linkType: hard
+
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.4, debug@npm:^4.4.1":
version: 4.4.1
resolution: "debug@npm:4.4.1"
@@ -2283,6 +2538,17 @@
languageName: node
linkType: hard
+"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4":
+ version: 1.1.4
+ resolution: "define-data-property@npm:1.1.4"
+ dependencies:
+ es-define-property: "npm:^1.0.0"
+ es-errors: "npm:^1.3.0"
+ gopd: "npm:^1.0.1"
+ checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37
+ languageName: node
+ linkType: hard
+
"define-lazy-prop@npm:^2.0.0":
version: 2.0.0
resolution: "define-lazy-prop@npm:2.0.0"
@@ -2290,6 +2556,17 @@
languageName: node
linkType: hard
+"define-properties@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "define-properties@npm:1.2.1"
+ dependencies:
+ define-data-property: "npm:^1.0.1"
+ has-property-descriptors: "npm:^1.0.0"
+ object-keys: "npm:^1.1.1"
+ checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3
+ languageName: node
+ linkType: hard
+
"defu@npm:^6.1.4":
version: 6.1.4
resolution: "defu@npm:6.1.4"
@@ -2311,6 +2588,15 @@
languageName: node
linkType: hard
+"dir-glob@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "dir-glob@npm:3.0.1"
+ dependencies:
+ path-type: "npm:^4.0.0"
+ checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c
+ languageName: node
+ linkType: hard
+
"dotenv-expand@npm:~11.0.6":
version: 11.0.7
resolution: "dotenv-expand@npm:11.0.7"
@@ -2334,7 +2620,7 @@
languageName: node
linkType: hard
-"dunder-proto@npm:^1.0.1":
+"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
version: 1.0.1
resolution: "dunder-proto@npm:1.0.1"
dependencies:
@@ -2424,6 +2710,15 @@
languageName: node
linkType: hard
+"error-ex@npm:^1.3.1":
+ version: 1.3.2
+ resolution: "error-ex@npm:1.3.2"
+ dependencies:
+ is-arrayish: "npm:^0.2.1"
+ checksum: 10c0/ba827f89369b4c93382cfca5a264d059dfefdaa56ecc5e338ffa58a6471f5ed93b71a20add1d52290a4873d92381174382658c885ac1a2305f7baca363ce9cce
+ languageName: node
+ linkType: hard
+
"error-stack-parser-es@npm:^1.0.5":
version: 1.0.5
resolution: "error-stack-parser-es@npm:1.0.5"
@@ -2431,7 +2726,69 @@
languageName: node
linkType: hard
-"es-define-property@npm:^1.0.1":
+"es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.9":
+ version: 1.24.0
+ resolution: "es-abstract@npm:1.24.0"
+ dependencies:
+ array-buffer-byte-length: "npm:^1.0.2"
+ arraybuffer.prototype.slice: "npm:^1.0.4"
+ available-typed-arrays: "npm:^1.0.7"
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.4"
+ data-view-buffer: "npm:^1.0.2"
+ data-view-byte-length: "npm:^1.0.2"
+ data-view-byte-offset: "npm:^1.0.1"
+ es-define-property: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.1.1"
+ es-set-tostringtag: "npm:^2.1.0"
+ es-to-primitive: "npm:^1.3.0"
+ function.prototype.name: "npm:^1.1.8"
+ get-intrinsic: "npm:^1.3.0"
+ get-proto: "npm:^1.0.1"
+ get-symbol-description: "npm:^1.1.0"
+ globalthis: "npm:^1.0.4"
+ gopd: "npm:^1.2.0"
+ has-property-descriptors: "npm:^1.0.2"
+ has-proto: "npm:^1.2.0"
+ has-symbols: "npm:^1.1.0"
+ hasown: "npm:^2.0.2"
+ internal-slot: "npm:^1.1.0"
+ is-array-buffer: "npm:^3.0.5"
+ is-callable: "npm:^1.2.7"
+ is-data-view: "npm:^1.0.2"
+ is-negative-zero: "npm:^2.0.3"
+ is-regex: "npm:^1.2.1"
+ is-set: "npm:^2.0.3"
+ is-shared-array-buffer: "npm:^1.0.4"
+ is-string: "npm:^1.1.1"
+ is-typed-array: "npm:^1.1.15"
+ is-weakref: "npm:^1.1.1"
+ math-intrinsics: "npm:^1.1.0"
+ object-inspect: "npm:^1.13.4"
+ object-keys: "npm:^1.1.1"
+ object.assign: "npm:^4.1.7"
+ own-keys: "npm:^1.0.1"
+ regexp.prototype.flags: "npm:^1.5.4"
+ safe-array-concat: "npm:^1.1.3"
+ safe-push-apply: "npm:^1.0.0"
+ safe-regex-test: "npm:^1.1.0"
+ set-proto: "npm:^1.0.0"
+ stop-iteration-iterator: "npm:^1.1.0"
+ string.prototype.trim: "npm:^1.2.10"
+ string.prototype.trimend: "npm:^1.0.9"
+ string.prototype.trimstart: "npm:^1.0.8"
+ typed-array-buffer: "npm:^1.0.3"
+ typed-array-byte-length: "npm:^1.0.3"
+ typed-array-byte-offset: "npm:^1.0.4"
+ typed-array-length: "npm:^1.0.7"
+ unbox-primitive: "npm:^1.1.0"
+ which-typed-array: "npm:^1.1.19"
+ checksum: 10c0/b256e897be32df5d382786ce8cce29a1dd8c97efbab77a26609bd70f2ed29fbcfc7a31758cb07488d532e7ccccdfca76c1118f2afe5a424cdc05ca007867c318
+ languageName: node
+ linkType: hard
+
+"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1":
version: 1.0.1
resolution: "es-define-property@npm:1.0.1"
checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c
@@ -2473,6 +2830,17 @@
languageName: node
linkType: hard
+"es-to-primitive@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "es-to-primitive@npm:1.3.0"
+ dependencies:
+ is-callable: "npm:^1.2.7"
+ is-date-object: "npm:^1.0.5"
+ is-symbol: "npm:^1.0.4"
+ checksum: 10c0/c7e87467abb0b438639baa8139f701a06537d2b9bc758f23e8622c3b42fd0fdb5bde0f535686119e446dd9d5e4c0f238af4e14960f4771877cf818d023f6730b
+ languageName: node
+ linkType: hard
+
"esbuild@npm:0.25.4":
version: 0.25.4
resolution: "esbuild@npm:0.25.4"
@@ -2693,6 +3061,28 @@
languageName: node
linkType: hard
+"fast-glob@npm:^3.2.9":
+ version: 3.3.3
+ resolution: "fast-glob@npm:3.3.3"
+ dependencies:
+ "@nodelib/fs.stat": "npm:^2.0.2"
+ "@nodelib/fs.walk": "npm:^1.2.3"
+ glob-parent: "npm:^5.1.2"
+ merge2: "npm:^1.3.0"
+ micromatch: "npm:^4.0.8"
+ checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe
+ languageName: node
+ linkType: hard
+
+"fastq@npm:^1.6.0":
+ version: 1.19.1
+ resolution: "fastq@npm:1.19.1"
+ dependencies:
+ reusify: "npm:^1.0.4"
+ checksum: 10c0/ebc6e50ac7048daaeb8e64522a1ea7a26e92b3cee5cd1c7f2316cdca81ba543aa40a136b53891446ea5c3a67ec215fbaca87ad405f102dd97012f62916905630
+ languageName: node
+ linkType: hard
+
"fdir@npm:^6.4.4, fdir@npm:^6.4.6":
version: 6.4.6
resolution: "fdir@npm:6.4.6"
@@ -2714,6 +3104,15 @@
languageName: node
linkType: hard
+"fill-range@npm:^7.1.1":
+ version: 7.1.1
+ resolution: "fill-range@npm:7.1.1"
+ dependencies:
+ to-regex-range: "npm:^5.0.1"
+ checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018
+ languageName: node
+ linkType: hard
+
"flat@npm:^5.0.2":
version: 5.0.2
resolution: "flat@npm:5.0.2"
@@ -2733,6 +3132,15 @@
languageName: node
linkType: hard
+"for-each@npm:^0.3.3, for-each@npm:^0.3.5":
+ version: 0.3.5
+ resolution: "for-each@npm:0.3.5"
+ dependencies:
+ is-callable: "npm:^1.2.7"
+ checksum: 10c0/0e0b50f6a843a282637d43674d1fb278dda1dd85f4f99b640024cfb10b85058aac0cc781bf689d5fe50b4b7f638e91e548560723a4e76e04fe96ae35ef039cee
+ languageName: node
+ linkType: hard
+
"foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1":
version: 3.3.1
resolution: "foreground-child@npm:3.3.1"
@@ -2807,6 +3215,27 @@
languageName: node
linkType: hard
+"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8":
+ version: 1.1.8
+ resolution: "function.prototype.name@npm:1.1.8"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.3"
+ define-properties: "npm:^1.2.1"
+ functions-have-names: "npm:^1.2.3"
+ hasown: "npm:^2.0.2"
+ is-callable: "npm:^1.2.7"
+ checksum: 10c0/e920a2ab52663005f3cbe7ee3373e3c71c1fb5558b0b0548648cdf3e51961085032458e26c71ff1a8c8c20e7ee7caeb03d43a5d1fa8610c459333323a2e71253
+ languageName: node
+ linkType: hard
+
+"functions-have-names@npm:^1.2.3":
+ version: 1.2.3
+ resolution: "functions-have-names@npm:1.2.3"
+ checksum: 10c0/33e77fd29bddc2d9bb78ab3eb854c165909201f88c75faa8272e35899e2d35a8a642a15e7420ef945e1f64a9670d6aa3ec744106b2aa42be68ca5114025954ca
+ languageName: node
+ linkType: hard
+
"gensync@npm:^1.0.0-beta.2":
version: 1.0.0-beta.2
resolution: "gensync@npm:1.0.0-beta.2"
@@ -2821,7 +3250,7 @@
languageName: node
linkType: hard
-"get-intrinsic@npm:^1.2.6":
+"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0":
version: 1.3.0
resolution: "get-intrinsic@npm:1.3.0"
dependencies:
@@ -2839,7 +3268,7 @@
languageName: node
linkType: hard
-"get-proto@npm:^1.0.1":
+"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1":
version: 1.0.1
resolution: "get-proto@npm:1.0.1"
dependencies:
@@ -2849,6 +3278,35 @@
languageName: node
linkType: hard
+"get-symbol-description@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "get-symbol-description@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ get-intrinsic: "npm:^1.2.6"
+ checksum: 10c0/d6a7d6afca375779a4b307738c9e80dbf7afc0bdbe5948768d54ab9653c865523d8920e670991a925936eb524b7cb6a6361d199a760b21d0ca7620194455aa4b
+ languageName: node
+ linkType: hard
+
+"get-tsconfig@npm:^4.10.0":
+ version: 4.10.1
+ resolution: "get-tsconfig@npm:4.10.1"
+ dependencies:
+ resolve-pkg-maps: "npm:^1.0.0"
+ checksum: 10c0/7f8e3dabc6a49b747920a800fb88e1952fef871cdf51b79e98db48275a5de6cdaf499c55ee67df5fa6fe7ce65f0063e26de0f2e53049b408c585aa74d39ffa21
+ languageName: node
+ linkType: hard
+
+"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
+ version: 5.1.2
+ resolution: "glob-parent@npm:5.1.2"
+ dependencies:
+ is-glob: "npm:^4.0.1"
+ checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee
+ languageName: node
+ linkType: hard
+
"glob-to-regexp@npm:0.4.1":
version: 0.4.1
resolution: "glob-to-regexp@npm:0.4.1"
@@ -2888,6 +3346,30 @@
languageName: node
linkType: hard
+"globalthis@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "globalthis@npm:1.0.4"
+ dependencies:
+ define-properties: "npm:^1.2.1"
+ gopd: "npm:^1.0.1"
+ checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846
+ languageName: node
+ linkType: hard
+
+"globby@npm:^11.0.4":
+ version: 11.1.0
+ resolution: "globby@npm:11.1.0"
+ dependencies:
+ array-union: "npm:^2.1.0"
+ dir-glob: "npm:^3.0.1"
+ fast-glob: "npm:^3.2.9"
+ ignore: "npm:^5.2.0"
+ merge2: "npm:^1.4.1"
+ slash: "npm:^3.0.0"
+ checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189
+ languageName: node
+ linkType: hard
+
"globrex@npm:^0.1.2":
version: 0.1.2
resolution: "globrex@npm:0.1.2"
@@ -2895,20 +3377,34 @@
languageName: node
linkType: hard
-"gopd@npm:^1.2.0":
+"gopd@npm:^1.0.1, gopd@npm:^1.2.0":
version: 1.2.0
resolution: "gopd@npm:1.2.0"
checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead
languageName: node
linkType: hard
-"graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6":
+"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6":
version: 4.2.11
resolution: "graceful-fs@npm:4.2.11"
checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
languageName: node
linkType: hard
+"has-bigints@npm:^1.0.2":
+ version: 1.1.0
+ resolution: "has-bigints@npm:1.1.0"
+ checksum: 10c0/2de0cdc4a1ccf7a1e75ffede1876994525ac03cc6f5ae7392d3415dd475cd9eee5bceec63669ab61aa997ff6cceebb50ef75561c7002bed8988de2b9d1b40788
+ languageName: node
+ linkType: hard
+
+"has-flag@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "has-flag@npm:3.0.0"
+ checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473
+ languageName: node
+ linkType: hard
+
"has-flag@npm:^4.0.0":
version: 4.0.0
resolution: "has-flag@npm:4.0.0"
@@ -2916,6 +3412,24 @@
languageName: node
linkType: hard
+"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "has-property-descriptors@npm:1.0.2"
+ dependencies:
+ es-define-property: "npm:^1.0.0"
+ checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236
+ languageName: node
+ linkType: hard
+
+"has-proto@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "has-proto@npm:1.2.0"
+ dependencies:
+ dunder-proto: "npm:^1.0.0"
+ checksum: 10c0/46538dddab297ec2f43923c3d35237df45d8c55a6fc1067031e04c13ed8a9a8f94954460632fd4da84c31a1721eefee16d901cbb1ae9602bab93bb6e08f93b95
+ languageName: node
+ linkType: hard
+
"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0":
version: 1.1.0
resolution: "has-symbols@npm:1.1.0"
@@ -2941,6 +3455,13 @@
languageName: node
linkType: hard
+"hosted-git-info@npm:^2.1.4":
+ version: 2.8.9
+ resolution: "hosted-git-info@npm:2.8.9"
+ checksum: 10c0/317cbc6b1bbbe23c2a40ae23f3dafe9fa349ce42a89a36f930e3f9c0530c179a3882d2ef1e4141a4c3674d6faaea862138ec55b43ad6f75e387fda2483a13c70
+ languageName: node
+ linkType: hard
+
"hosted-git-info@npm:^6.0.0, hosted-git-info@npm:^6.1.1":
version: 6.1.3
resolution: "hosted-git-info@npm:6.1.3"
@@ -2993,7 +3514,7 @@
languageName: node
linkType: hard
-"ignore@npm:^5.0.4":
+"ignore@npm:^5.0.4, ignore@npm:^5.2.0":
version: 5.3.2
resolution: "ignore@npm:5.3.2"
checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337
@@ -3014,6 +3535,17 @@
languageName: node
linkType: hard
+"internal-slot@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "internal-slot@npm:1.1.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ hasown: "npm:^2.0.2"
+ side-channel: "npm:^1.1.0"
+ checksum: 10c0/03966f5e259b009a9bf1a78d60da920df198af4318ec004f57b8aef1dd3fe377fbc8cce63a96e8c810010302654de89f9e19de1cd8ad0061d15be28a695465c7
+ languageName: node
+ linkType: hard
+
"ip-address@npm:^9.0.5":
version: 9.0.5
resolution: "ip-address@npm:9.0.5"
@@ -3024,29 +3556,11 @@
languageName: node
linkType: hard
-"iris-plugins@workspace:*, iris-plugins@workspace:packages/plugins":
- version: 0.0.0-use.local
- resolution: "iris-plugins@workspace:packages/plugins"
- dependencies:
- "@jottocraft/iris-sdk": "workspace:*"
- languageName: unknown
- linkType: soft
-
-"iris-server@workspace:packages/server":
- version: 0.0.0-use.local
- resolution: "iris-server@workspace:packages/server"
- dependencies:
- "@jottocraft/iris-sdk": "workspace:*"
- iris-plugins: "workspace:*"
- languageName: unknown
- linkType: soft
-
"iris-webui@workspace:packages/webui":
version: 0.0.0-use.local
resolution: "iris-webui@workspace:packages/webui"
dependencies:
"@jottocraft/iris-sdk": "workspace:*"
- iris-plugins: "workspace:*"
languageName: unknown
linkType: soft
@@ -3067,17 +3581,22 @@
"@remix-run/v1-route-convention": "patch:@remix-run/v1-route-convention@npm%3A0.1.4#~/.yarn/patches/@remix-run-v1-route-convention-npm-0.1.4-d336e45418.patch"
"@tailwindcss/vite": "npm:^4.1.4"
"@types/chroma-js": "npm:^3.1.1"
+ "@types/lodash": "npm:^4.17.20"
"@types/node": "npm:^20"
"@types/react": "npm:^19.1.2"
"@types/react-dom": "npm:^19.1.2"
chroma-js: "npm:^3.1.2"
cross-env: "npm:^7.0.3"
+ jose: "npm:^6.0.12"
+ lodash: "npm:^4.17.21"
+ npm-run-all: "npm:^4.1.5"
nx: "npm:^21.2.4"
react: "npm:^19.1.0"
react-dom: "npm:^19.1.0"
react-router: "npm:^7.5.3"
rimraf: "npm:^6.0.1"
tailwindcss: "npm:^4.1.4"
+ tsc-alias: "npm:^1.8.16"
typescript: "npm:^5.8.3"
vite: "npm:^6.3.3"
vite-tsconfig-paths: "npm:^5.1.4"
@@ -3085,6 +3604,24 @@
languageName: unknown
linkType: soft
+"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5":
+ version: 3.0.5
+ resolution: "is-array-buffer@npm:3.0.5"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.3"
+ get-intrinsic: "npm:^1.2.6"
+ checksum: 10c0/c5c9f25606e86dbb12e756694afbbff64bc8b348d1bc989324c037e1068695131930199d6ad381952715dad3a9569333817f0b1a72ce5af7f883ce802e49c83d
+ languageName: node
+ linkType: hard
+
+"is-arrayish@npm:^0.2.1":
+ version: 0.2.1
+ resolution: "is-arrayish@npm:0.2.1"
+ checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729
+ languageName: node
+ linkType: hard
+
"is-arrayish@npm:^0.3.1":
version: 0.3.2
resolution: "is-arrayish@npm:0.3.2"
@@ -3092,7 +3629,55 @@
languageName: node
linkType: hard
-"is-core-module@npm:^2.8.1":
+"is-async-function@npm:^2.0.0":
+ version: 2.1.1
+ resolution: "is-async-function@npm:2.1.1"
+ dependencies:
+ async-function: "npm:^1.0.0"
+ call-bound: "npm:^1.0.3"
+ get-proto: "npm:^1.0.1"
+ has-tostringtag: "npm:^1.0.2"
+ safe-regex-test: "npm:^1.1.0"
+ checksum: 10c0/d70c236a5e82de6fc4d44368ffd0c2fee2b088b893511ce21e679da275a5ecc6015ff59a7d7e1bdd7ca39f71a8dbdd253cf8cce5c6b3c91cdd5b42b5ce677298
+ languageName: node
+ linkType: hard
+
+"is-bigint@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "is-bigint@npm:1.1.0"
+ dependencies:
+ has-bigints: "npm:^1.0.2"
+ checksum: 10c0/f4f4b905ceb195be90a6ea7f34323bf1c18e3793f18922e3e9a73c684c29eeeeff5175605c3a3a74cc38185fe27758f07efba3dbae812e5c5afbc0d2316b40e4
+ languageName: node
+ linkType: hard
+
+"is-binary-path@npm:~2.1.0":
+ version: 2.1.0
+ resolution: "is-binary-path@npm:2.1.0"
+ dependencies:
+ binary-extensions: "npm:^2.0.0"
+ checksum: 10c0/a16eaee59ae2b315ba36fad5c5dcaf8e49c3e27318f8ab8fa3cdb8772bf559c8d1ba750a589c2ccb096113bb64497084361a25960899cb6172a6925ab6123d38
+ languageName: node
+ linkType: hard
+
+"is-boolean-object@npm:^1.2.1":
+ version: 1.2.2
+ resolution: "is-boolean-object@npm:1.2.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/36ff6baf6bd18b3130186990026f5a95c709345c39cd368468e6c1b6ab52201e9fd26d8e1f4c066357b4938b0f0401e1a5000e08257787c1a02f3a719457001e
+ languageName: node
+ linkType: hard
+
+"is-callable@npm:^1.2.7":
+ version: 1.2.7
+ resolution: "is-callable@npm:1.2.7"
+ checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f
+ languageName: node
+ linkType: hard
+
+"is-core-module@npm:^2.16.0, is-core-module@npm:^2.8.1":
version: 2.16.1
resolution: "is-core-module@npm:2.16.1"
dependencies:
@@ -3101,6 +3686,27 @@
languageName: node
linkType: hard
+"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "is-data-view@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ get-intrinsic: "npm:^1.2.6"
+ is-typed-array: "npm:^1.1.13"
+ checksum: 10c0/ef3548a99d7e7f1370ce21006baca6d40c73e9f15c941f89f0049c79714c873d03b02dae1c64b3f861f55163ecc16da06506c5b8a1d4f16650b3d9351c380153
+ languageName: node
+ linkType: hard
+
+"is-date-object@npm:^1.0.5, is-date-object@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "is-date-object@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/1a4d199c8e9e9cac5128d32e6626fa7805175af9df015620ac0d5d45854ccf348ba494679d872d37301032e35a54fc7978fba1687e8721b2139aea7870cafa2f
+ languageName: node
+ linkType: hard
+
"is-docker@npm:^2.0.0, is-docker@npm:^2.1.1":
version: 2.2.1
resolution: "is-docker@npm:2.2.1"
@@ -3110,6 +3716,22 @@
languageName: node
linkType: hard
+"is-extglob@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "is-extglob@npm:2.1.1"
+ checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912
+ languageName: node
+ linkType: hard
+
+"is-finalizationregistry@npm:^1.1.0":
+ version: 1.1.1
+ resolution: "is-finalizationregistry@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ checksum: 10c0/818dff679b64f19e228a8205a1e2d09989a98e98def3a817f889208cfcbf918d321b251aadf2c05918194803ebd2eb01b14fc9d0b2bea53d984f4137bfca5e97
+ languageName: node
+ linkType: hard
+
"is-fullwidth-code-point@npm:^3.0.0":
version: 3.0.0
resolution: "is-fullwidth-code-point@npm:3.0.0"
@@ -3117,6 +3739,27 @@
languageName: node
linkType: hard
+"is-generator-function@npm:^1.0.10":
+ version: 1.1.0
+ resolution: "is-generator-function@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ get-proto: "npm:^1.0.0"
+ has-tostringtag: "npm:^1.0.2"
+ safe-regex-test: "npm:^1.1.0"
+ checksum: 10c0/fdfa96c8087bf36fc4cd514b474ba2ff404219a4dd4cfa6cf5426404a1eed259bdcdb98f082a71029a48d01f27733e3436ecc6690129a7ec09cb0434bee03a2a
+ languageName: node
+ linkType: hard
+
+"is-glob@npm:^4.0.1, is-glob@npm:~4.0.1":
+ version: 4.0.3
+ resolution: "is-glob@npm:4.0.3"
+ dependencies:
+ is-extglob: "npm:^2.1.1"
+ checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a
+ languageName: node
+ linkType: hard
+
"is-interactive@npm:^1.0.0":
version: 1.0.0
resolution: "is-interactive@npm:1.0.0"
@@ -3124,6 +3767,95 @@
languageName: node
linkType: hard
+"is-map@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "is-map@npm:2.0.3"
+ checksum: 10c0/2c4d431b74e00fdda7162cd8e4b763d6f6f217edf97d4f8538b94b8702b150610e2c64961340015fe8df5b1fcee33ccd2e9b62619c4a8a3a155f8de6d6d355fc
+ languageName: node
+ linkType: hard
+
+"is-negative-zero@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "is-negative-zero@npm:2.0.3"
+ checksum: 10c0/bcdcf6b8b9714063ffcfa9929c575ac69bfdabb8f4574ff557dfc086df2836cf07e3906f5bbc4f2a5c12f8f3ba56af640c843cdfc74da8caed86c7c7d66fd08e
+ languageName: node
+ linkType: hard
+
+"is-number-object@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-number-object@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/97b451b41f25135ff021d85c436ff0100d84a039bb87ffd799cbcdbea81ef30c464ced38258cdd34f080be08fc3b076ca1f472086286d2aa43521d6ec6a79f53
+ languageName: node
+ linkType: hard
+
+"is-number@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "is-number@npm:7.0.0"
+ checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811
+ languageName: node
+ linkType: hard
+
+"is-regex@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "is-regex@npm:1.2.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ gopd: "npm:^1.2.0"
+ has-tostringtag: "npm:^1.0.2"
+ hasown: "npm:^2.0.2"
+ checksum: 10c0/1d3715d2b7889932349241680032e85d0b492cfcb045acb75ffc2c3085e8d561184f1f7e84b6f8321935b4aea39bc9c6ba74ed595b57ce4881a51dfdbc214e04
+ languageName: node
+ linkType: hard
+
+"is-set@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "is-set@npm:2.0.3"
+ checksum: 10c0/f73732e13f099b2dc879c2a12341cfc22ccaca8dd504e6edae26484bd5707a35d503fba5b4daad530a9b088ced1ae6c9d8200fd92e09b428fe14ea79ce8080b7
+ languageName: node
+ linkType: hard
+
+"is-shared-array-buffer@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "is-shared-array-buffer@npm:1.0.4"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ checksum: 10c0/65158c2feb41ff1edd6bbd6fd8403a69861cf273ff36077982b5d4d68e1d59278c71691216a4a64632bd76d4792d4d1d2553901b6666d84ade13bba5ea7bc7db
+ languageName: node
+ linkType: hard
+
+"is-string@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-string@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/2f518b4e47886bb81567faba6ffd0d8a8333cf84336e2e78bf160693972e32ad00fe84b0926491cc598dee576fdc55642c92e62d0cbe96bf36f643b6f956f94d
+ languageName: node
+ linkType: hard
+
+"is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-symbol@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ has-symbols: "npm:^1.1.0"
+ safe-regex-test: "npm:^1.1.0"
+ checksum: 10c0/f08f3e255c12442e833f75a9e2b84b2d4882fdfd920513cf2a4a2324f0a5b076c8fd913778e3ea5d258d5183e9d92c0cd20e04b03ab3df05316b049b2670af1e
+ languageName: node
+ linkType: hard
+
+"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15":
+ version: 1.1.15
+ resolution: "is-typed-array@npm:1.1.15"
+ dependencies:
+ which-typed-array: "npm:^1.1.16"
+ checksum: 10c0/415511da3669e36e002820584e264997ffe277ff136643a3126cc949197e6ca3334d0f12d084e83b1994af2e9c8141275c741cf2b7da5a2ff62dd0cac26f76c4
+ languageName: node
+ linkType: hard
+
"is-unicode-supported@npm:^0.1.0":
version: 0.1.0
resolution: "is-unicode-supported@npm:0.1.0"
@@ -3131,6 +3863,32 @@
languageName: node
linkType: hard
+"is-weakmap@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "is-weakmap@npm:2.0.2"
+ checksum: 10c0/443c35bb86d5e6cc5929cd9c75a4024bb0fff9586ed50b092f94e700b89c43a33b186b76dbc6d54f3d3d09ece689ab38dcdc1af6a482cbe79c0f2da0a17f1299
+ languageName: node
+ linkType: hard
+
+"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-weakref@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ checksum: 10c0/8e0a9c07b0c780949a100e2cab2b5560a48ecd4c61726923c1a9b77b6ab0aa0046c9e7fb2206042296817045376dee2c8ab1dabe08c7c3dfbf195b01275a085b
+ languageName: node
+ linkType: hard
+
+"is-weakset@npm:^2.0.3":
+ version: 2.0.4
+ resolution: "is-weakset@npm:2.0.4"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ get-intrinsic: "npm:^1.2.6"
+ checksum: 10c0/6491eba08acb8dc9532da23cb226b7d0192ede0b88f16199e592e4769db0a077119c1f5d2283d1e0d16d739115f70046e887e477eb0e66cd90e1bb29f28ba647
+ languageName: node
+ linkType: hard
+
"is-wsl@npm:^2.2.0":
version: 2.2.0
resolution: "is-wsl@npm:2.2.0"
@@ -3140,6 +3898,13 @@
languageName: node
linkType: hard
+"isarray@npm:^2.0.5":
+ version: 2.0.5
+ resolution: "isarray@npm:2.0.5"
+ checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd
+ languageName: node
+ linkType: hard
+
"isbot@npm:^5.1.11":
version: 5.1.28
resolution: "isbot@npm:5.1.28"
@@ -3204,6 +3969,13 @@
languageName: node
linkType: hard
+"jose@npm:^6.0.12":
+ version: 6.0.12
+ resolution: "jose@npm:6.0.12"
+ checksum: 10c0/e5ca51b078b2443f6ca671e14d72e0ffd21b760dac0d77cabd7af649a127376ec90665c8b25f34dd88bb31094915ee662daf76e0b33a025d28dbc2bc17413dec
+ languageName: node
+ linkType: hard
+
"js-tokens@npm:^4.0.0":
version: 4.0.0
resolution: "js-tokens@npm:4.0.0"
@@ -3248,6 +4020,13 @@
languageName: node
linkType: hard
+"json-parse-better-errors@npm:^1.0.1":
+ version: 1.0.2
+ resolution: "json-parse-better-errors@npm:1.0.2"
+ checksum: 10c0/2f1287a7c833e397c9ddd361a78638e828fc523038bb3441fd4fc144cfd2c6cd4963ffb9e207e648cf7b692600f1e1e524e965c32df5152120910e4903a47dcb
+ languageName: node
+ linkType: hard
+
"json-parse-even-better-errors@npm:^3.0.0":
version: 3.0.2
resolution: "json-parse-even-better-errors@npm:3.0.2"
@@ -3395,6 +4174,18 @@
languageName: node
linkType: hard
+"load-json-file@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "load-json-file@npm:4.0.0"
+ dependencies:
+ graceful-fs: "npm:^4.1.2"
+ parse-json: "npm:^4.0.0"
+ pify: "npm:^3.0.0"
+ strip-bom: "npm:^3.0.0"
+ checksum: 10c0/6b48f6a0256bdfcc8970be2c57f68f10acb2ee7e63709b386b2febb6ad3c86198f840889cdbe71d28f741cbaa2f23a7771206b138cd1bdd159564511ca37c1d5
+ languageName: node
+ linkType: hard
+
"lodash@npm:^4.17.21":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
@@ -3477,6 +4268,30 @@
languageName: node
linkType: hard
+"memorystream@npm:^0.3.1":
+ version: 0.3.1
+ resolution: "memorystream@npm:0.3.1"
+ checksum: 10c0/4bd164657711d9747ff5edb0508b2944414da3464b7fe21ac5c67cf35bba975c4b446a0124bd0f9a8be54cfc18faf92e92bd77563a20328b1ccf2ff04e9f39b9
+ languageName: node
+ linkType: hard
+
+"merge2@npm:^1.3.0, merge2@npm:^1.4.1":
+ version: 1.4.1
+ resolution: "merge2@npm:1.4.1"
+ checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb
+ languageName: node
+ linkType: hard
+
+"micromatch@npm:^4.0.8":
+ version: 4.0.8
+ resolution: "micromatch@npm:4.0.8"
+ dependencies:
+ braces: "npm:^3.0.3"
+ picomatch: "npm:^2.3.1"
+ checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8
+ languageName: node
+ linkType: hard
+
"mime-db@npm:1.52.0":
version: 1.52.0
resolution: "mime-db@npm:1.52.0"
@@ -3549,6 +4364,15 @@
languageName: node
linkType: hard
+"minimatch@npm:^3.0.4":
+ version: 3.1.2
+ resolution: "minimatch@npm:3.1.2"
+ dependencies:
+ brace-expansion: "npm:^1.1.7"
+ checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311
+ languageName: node
+ linkType: hard
+
"minimatch@npm:^7.4.3":
version: 7.4.6
resolution: "minimatch@npm:7.4.6"
@@ -3666,6 +4490,13 @@
languageName: node
linkType: hard
+"mylas@npm:^2.1.9":
+ version: 2.1.13
+ resolution: "mylas@npm:2.1.13"
+ checksum: 10c0/093dfaf88f444d9da956c68a61ddcfe05ab9411c0024b0c7f4d721639ba7d311ea8f9c052ce617344e67d40982f67614cd634b525b923048bf9a191234968c9c
+ languageName: node
+ linkType: hard
+
"nanoid@npm:^3.3.11":
version: 3.3.11
resolution: "nanoid@npm:3.3.11"
@@ -3682,6 +4513,13 @@
languageName: node
linkType: hard
+"nice-try@npm:^1.0.4":
+ version: 1.0.5
+ resolution: "nice-try@npm:1.0.5"
+ checksum: 10c0/95568c1b73e1d0d4069a3e3061a2102d854513d37bcfda73300015b7ba4868d3b27c198d1dbbd8ebdef4112fc2ed9e895d4a0f2e1cce0bd334f2a1346dc9205f
+ languageName: node
+ linkType: hard
+
"node-gyp@npm:latest":
version: 11.2.0
resolution: "node-gyp@npm:11.2.0"
@@ -3727,6 +4565,18 @@
languageName: node
linkType: hard
+"normalize-package-data@npm:^2.3.2":
+ version: 2.5.0
+ resolution: "normalize-package-data@npm:2.5.0"
+ dependencies:
+ hosted-git-info: "npm:^2.1.4"
+ resolve: "npm:^1.10.0"
+ semver: "npm:2 || 3 || 4 || 5"
+ validate-npm-package-license: "npm:^3.0.1"
+ checksum: 10c0/357cb1646deb42f8eb4c7d42c4edf0eec312f3628c2ef98501963cc4bbe7277021b2b1d977f982b2edce78f5a1014613ce9cf38085c3df2d76730481357ca504
+ languageName: node
+ linkType: hard
+
"normalize-package-data@npm:^5.0.0":
version: 5.0.0
resolution: "normalize-package-data@npm:5.0.0"
@@ -3739,6 +4589,13 @@
languageName: node
linkType: hard
+"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
+ version: 3.0.0
+ resolution: "normalize-path@npm:3.0.0"
+ checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046
+ languageName: node
+ linkType: hard
+
"npm-install-checks@npm:^6.0.0":
version: 6.3.0
resolution: "npm-install-checks@npm:6.3.0"
@@ -3779,6 +4636,27 @@
languageName: node
linkType: hard
+"npm-run-all@npm:^4.1.5":
+ version: 4.1.5
+ resolution: "npm-run-all@npm:4.1.5"
+ dependencies:
+ ansi-styles: "npm:^3.2.1"
+ chalk: "npm:^2.4.1"
+ cross-spawn: "npm:^6.0.5"
+ memorystream: "npm:^0.3.1"
+ minimatch: "npm:^3.0.4"
+ pidtree: "npm:^0.3.0"
+ read-pkg: "npm:^3.0.0"
+ shell-quote: "npm:^1.6.1"
+ string.prototype.padend: "npm:^3.0.0"
+ bin:
+ npm-run-all: bin/npm-run-all/index.js
+ run-p: bin/run-p/index.js
+ run-s: bin/run-s/index.js
+ checksum: 10c0/736ee39bd35454d3efaa4a2e53eba6c523e2e17fba21a18edcce6b221f5cab62000bef16bb6ae8aff9e615831e6b0eb25ab51d52d60e6fa6f4ea880e4c6d31f4
+ languageName: node
+ linkType: hard
+
"npm-run-path@npm:^4.0.1":
version: 4.0.1
resolution: "npm-run-path@npm:4.0.1"
@@ -3873,6 +4751,34 @@
languageName: node
linkType: hard
+"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4":
+ version: 1.13.4
+ resolution: "object-inspect@npm:1.13.4"
+ checksum: 10c0/d7f8711e803b96ea3191c745d6f8056ce1f2496e530e6a19a0e92d89b0fa3c76d910c31f0aa270432db6bd3b2f85500a376a83aaba849a8d518c8845b3211692
+ languageName: node
+ linkType: hard
+
+"object-keys@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "object-keys@npm:1.1.1"
+ checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d
+ languageName: node
+ linkType: hard
+
+"object.assign@npm:^4.1.7":
+ version: 4.1.7
+ resolution: "object.assign@npm:4.1.7"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.3"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.0.0"
+ has-symbols: "npm:^1.1.0"
+ object-keys: "npm:^1.1.1"
+ checksum: 10c0/3b2732bd860567ea2579d1567525168de925a8d852638612846bd8082b3a1602b7b89b67b09913cbb5b9bd6e95923b2ae73580baa9d99cb4e990564e8cbf5ddc
+ languageName: node
+ linkType: hard
+
"ohash@npm:^2.0.11":
version: 2.0.11
resolution: "ohash@npm:2.0.11"
@@ -3925,6 +4831,17 @@
languageName: node
linkType: hard
+"own-keys@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "own-keys@npm:1.0.1"
+ dependencies:
+ get-intrinsic: "npm:^1.2.6"
+ object-keys: "npm:^1.1.1"
+ safe-push-apply: "npm:^1.0.0"
+ checksum: 10c0/6dfeb3455bff92ec3f16a982d4e3e65676345f6902d9f5ded1d8265a6318d0200ce461956d6d1c70053c7fe9f9fe65e552faac03f8140d37ef0fdd108e67013a
+ languageName: node
+ linkType: hard
+
"p-map@npm:^7.0.2":
version: 7.0.3
resolution: "p-map@npm:7.0.3"
@@ -3939,6 +4856,23 @@
languageName: node
linkType: hard
+"parse-json@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "parse-json@npm:4.0.0"
+ dependencies:
+ error-ex: "npm:^1.3.1"
+ json-parse-better-errors: "npm:^1.0.1"
+ checksum: 10c0/8d80790b772ccb1bcea4e09e2697555e519d83d04a77c2b4237389b813f82898943a93ffff7d0d2406203bdd0c30dcf95b1661e3a53f83d0e417f053957bef32
+ languageName: node
+ linkType: hard
+
+"path-key@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "path-key@npm:2.0.1"
+ checksum: 10c0/dd2044f029a8e58ac31d2bf34c34b93c3095c1481942960e84dd2faa95bbb71b9b762a106aead0646695330936414b31ca0bd862bf488a937ad17c8c5d73b32b
+ languageName: node
+ linkType: hard
+
"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
version: 3.1.1
resolution: "path-key@npm:3.1.1"
@@ -3946,6 +4880,13 @@
languageName: node
linkType: hard
+"path-parse@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "path-parse@npm:1.0.7"
+ checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1
+ languageName: node
+ linkType: hard
+
"path-scurry@npm:^1.11.1":
version: 1.11.1
resolution: "path-scurry@npm:1.11.1"
@@ -3973,6 +4914,22 @@
languageName: node
linkType: hard
+"path-type@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "path-type@npm:3.0.0"
+ dependencies:
+ pify: "npm:^3.0.0"
+ checksum: 10c0/1332c632f1cac15790ebab8dd729b67ba04fc96f81647496feb1c2975d862d046f41e4b975dbd893048999b2cc90721f72924ad820acc58c78507ba7141a8e56
+ languageName: node
+ linkType: hard
+
+"path-type@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "path-type@npm:4.0.0"
+ checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c
+ languageName: node
+ linkType: hard
+
"pathe@npm:^1.1.2":
version: 1.1.2
resolution: "pathe@npm:1.1.2"
@@ -3994,6 +4951,13 @@
languageName: node
linkType: hard
+"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1":
+ version: 2.3.1
+ resolution: "picomatch@npm:2.3.1"
+ checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be
+ languageName: node
+ linkType: hard
+
"picomatch@npm:^4.0.2":
version: 4.0.3
resolution: "picomatch@npm:4.0.3"
@@ -4001,6 +4965,38 @@
languageName: node
linkType: hard
+"pidtree@npm:^0.3.0":
+ version: 0.3.1
+ resolution: "pidtree@npm:0.3.1"
+ bin:
+ pidtree: bin/pidtree.js
+ checksum: 10c0/cd69b0182f749f45ab48584e3442c48c5dc4512502c18d5b0147a33b042c41a4db4269b9ce2f7c48f11833ee5e79d81f5ebc6f7bf8372d4ea55726f60dc505a1
+ languageName: node
+ linkType: hard
+
+"pify@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "pify@npm:3.0.0"
+ checksum: 10c0/fead19ed9d801f1b1fcd0638a1ac53eabbb0945bf615f2f8806a8b646565a04a1b0e7ef115c951d225f042cca388fdc1cd3add46d10d1ed6951c20bd2998af10
+ languageName: node
+ linkType: hard
+
+"plimit-lit@npm:^1.2.6":
+ version: 1.6.1
+ resolution: "plimit-lit@npm:1.6.1"
+ dependencies:
+ queue-lit: "npm:^1.5.1"
+ checksum: 10c0/af5d351bb55afe1eaa84b27c2b329699e150e4cf70464f3d474f5eabe9bdb9f48ed378ada1498d3b893f68ee7da2423ba6d9a4d88b1429d3b0aea22afcf5292b
+ languageName: node
+ linkType: hard
+
+"possible-typed-array-names@npm:^1.0.0":
+ version: 1.1.0
+ resolution: "possible-typed-array-names@npm:1.1.0"
+ checksum: 10c0/c810983414142071da1d644662ce4caebce890203eb2bc7bf119f37f3fe5796226e117e6cca146b521921fa6531072674174a3325066ac66fce089a53e1e5196
+ languageName: node
+ linkType: hard
+
"postcss@npm:^8.5.3, postcss@npm:^8.5.6":
version: 8.5.6
resolution: "postcss@npm:8.5.6"
@@ -4070,6 +5066,20 @@
languageName: node
linkType: hard
+"queue-lit@npm:^1.5.1":
+ version: 1.5.2
+ resolution: "queue-lit@npm:1.5.2"
+ checksum: 10c0/8aa838b2c939aeaa6cd272b5b6b172379a3fa1d9193b2a3e687643c68c0efee3cd3493af4f1f8a11ff79b8207e4d00cc5d0b072f6e4bbeaaa27ee01f567ec4ac
+ languageName: node
+ linkType: hard
+
+"queue-microtask@npm:^1.2.2":
+ version: 1.2.3
+ resolution: "queue-microtask@npm:1.2.3"
+ checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102
+ languageName: node
+ linkType: hard
+
"react-dom@npm:^19.1.0":
version: 19.1.0
resolution: "react-dom@npm:19.1.0"
@@ -4118,6 +5128,17 @@
languageName: node
linkType: hard
+"read-pkg@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "read-pkg@npm:3.0.0"
+ dependencies:
+ load-json-file: "npm:^4.0.0"
+ normalize-package-data: "npm:^2.3.2"
+ path-type: "npm:^3.0.0"
+ checksum: 10c0/65acf2df89fbcd506b48b7ced56a255ba00adf7ecaa2db759c86cc58212f6fd80f1f0b7a85c848551a5d0685232e9b64f45c1fd5b48d85df2761a160767eeb93
+ languageName: node
+ linkType: hard
+
"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0":
version: 3.6.2
resolution: "readable-stream@npm:3.6.2"
@@ -4136,6 +5157,45 @@
languageName: node
linkType: hard
+"readdirp@npm:~3.6.0":
+ version: 3.6.0
+ resolution: "readdirp@npm:3.6.0"
+ dependencies:
+ picomatch: "npm:^2.2.1"
+ checksum: 10c0/6fa848cf63d1b82ab4e985f4cf72bd55b7dcfd8e0a376905804e48c3634b7e749170940ba77b32804d5fe93b3cc521aa95a8d7e7d725f830da6d93f3669ce66b
+ languageName: node
+ linkType: hard
+
+"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9":
+ version: 1.0.10
+ resolution: "reflect.getprototypeof@npm:1.0.10"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.9"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.0.0"
+ get-intrinsic: "npm:^1.2.7"
+ get-proto: "npm:^1.0.1"
+ which-builtin-type: "npm:^1.2.1"
+ checksum: 10c0/7facec28c8008876f8ab98e80b7b9cb4b1e9224353fd4756dda5f2a4ab0d30fa0a5074777c6df24e1e0af463a2697513b0a11e548d99cf52f21f7bc6ba48d3ac
+ languageName: node
+ linkType: hard
+
+"regexp.prototype.flags@npm:^1.5.4":
+ version: 1.5.4
+ resolution: "regexp.prototype.flags@npm:1.5.4"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-errors: "npm:^1.3.0"
+ get-proto: "npm:^1.0.1"
+ gopd: "npm:^1.2.0"
+ set-function-name: "npm:^2.0.2"
+ checksum: 10c0/83b88e6115b4af1c537f8dabf5c3744032cb875d63bc05c288b1b8c0ef37cbe55353f95d8ca817e8843806e3e150b118bc624e4279b24b4776b4198232735a77
+ languageName: node
+ linkType: hard
+
"require-directory@npm:^2.1.1":
version: 2.1.1
resolution: "require-directory@npm:2.1.1"
@@ -4143,6 +5203,13 @@
languageName: node
linkType: hard
+"resolve-pkg-maps@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "resolve-pkg-maps@npm:1.0.0"
+ checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab
+ languageName: node
+ linkType: hard
+
"resolve.exports@npm:2.0.3":
version: 2.0.3
resolution: "resolve.exports@npm:2.0.3"
@@ -4150,6 +5217,32 @@
languageName: node
linkType: hard
+"resolve@npm:^1.10.0":
+ version: 1.22.10
+ resolution: "resolve@npm:1.22.10"
+ dependencies:
+ is-core-module: "npm:^2.16.0"
+ path-parse: "npm:^1.0.7"
+ supports-preserve-symlinks-flag: "npm:^1.0.0"
+ bin:
+ resolve: bin/resolve
+ checksum: 10c0/8967e1f4e2cc40f79b7e080b4582b9a8c5ee36ffb46041dccb20e6461161adf69f843b43067b4a375de926a2cd669157e29a29578191def399dd5ef89a1b5203
+ languageName: node
+ linkType: hard
+
+"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin<compat/resolve>":
+ version: 1.22.10
+ resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin<compat/resolve>::version=1.22.10&hash=c3c19d"
+ dependencies:
+ is-core-module: "npm:^2.16.0"
+ path-parse: "npm:^1.0.7"
+ supports-preserve-symlinks-flag: "npm:^1.0.0"
+ bin:
+ resolve: bin/resolve
+ checksum: 10c0/52a4e505bbfc7925ac8f4cd91fd8c4e096b6a89728b9f46861d3b405ac9a1ccf4dcbf8befb4e89a2e11370dacd0160918163885cbc669369590f2f31f4c58939
+ languageName: node
+ linkType: hard
+
"restore-cursor@npm:^3.1.0":
version: 3.1.0
resolution: "restore-cursor@npm:3.1.0"
@@ -4167,6 +5260,13 @@
languageName: node
linkType: hard
+"reusify@npm:^1.0.4":
+ version: 1.1.0
+ resolution: "reusify@npm:1.1.0"
+ checksum: 10c0/4eff0d4a5f9383566c7d7ec437b671cc51b25963bd61bf127c3f3d3f68e44a026d99b8d2f1ad344afff8d278a8fe70a8ea092650a716d22287e8bef7126bb2fa
+ languageName: node
+ linkType: hard
+
"rimraf@npm:^6.0.1":
version: 6.0.1
resolution: "rimraf@npm:6.0.1"
@@ -4254,6 +5354,28 @@
languageName: node
linkType: hard
+"run-parallel@npm:^1.1.9":
+ version: 1.2.0
+ resolution: "run-parallel@npm:1.2.0"
+ dependencies:
+ queue-microtask: "npm:^1.2.2"
+ checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39
+ languageName: node
+ linkType: hard
+
+"safe-array-concat@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "safe-array-concat@npm:1.1.3"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.2"
+ get-intrinsic: "npm:^1.2.6"
+ has-symbols: "npm:^1.1.0"
+ isarray: "npm:^2.0.5"
+ checksum: 10c0/43c86ffdddc461fb17ff8a17c5324f392f4868f3c7dd2c6a5d9f5971713bc5fd755667212c80eab9567595f9a7509cc2f83e590ddaebd1bd19b780f9c79f9a8d
+ languageName: node
+ linkType: hard
+
"safe-buffer@npm:~5.2.0":
version: 5.2.1
resolution: "safe-buffer@npm:5.2.1"
@@ -4261,6 +5383,27 @@
languageName: node
linkType: hard
+"safe-push-apply@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "safe-push-apply@npm:1.0.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ isarray: "npm:^2.0.5"
+ checksum: 10c0/831f1c9aae7436429e7862c7e46f847dfe490afac20d0ee61bae06108dbf5c745a0de3568ada30ccdd3eeb0864ca8331b2eef703abd69bfea0745b21fd320750
+ languageName: node
+ linkType: hard
+
+"safe-regex-test@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "safe-regex-test@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ es-errors: "npm:^1.3.0"
+ is-regex: "npm:^1.2.1"
+ checksum: 10c0/f2c25281bbe5d39cddbbce7f86fca5ea9b3ce3354ea6cd7c81c31b006a5a9fff4286acc5450a3b9122c56c33eba69c56b9131ad751457b2b4a585825e6a10665
+ languageName: node
+ linkType: hard
+
"safer-buffer@npm:>= 2.1.2 < 3.0.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
@@ -4275,6 +5418,15 @@
languageName: node
linkType: hard
+"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0":
+ version: 5.7.2
+ resolution: "semver@npm:5.7.2"
+ bin:
+ semver: bin/semver
+ checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25
+ languageName: node
+ linkType: hard
+
"semver@npm:^6.3.1":
version: 6.3.1
resolution: "semver@npm:6.3.1"
@@ -4300,6 +5452,43 @@
languageName: node
linkType: hard
+"set-function-length@npm:^1.2.2":
+ version: 1.2.2
+ resolution: "set-function-length@npm:1.2.2"
+ dependencies:
+ define-data-property: "npm:^1.1.4"
+ es-errors: "npm:^1.3.0"
+ function-bind: "npm:^1.1.2"
+ get-intrinsic: "npm:^1.2.4"
+ gopd: "npm:^1.0.1"
+ has-property-descriptors: "npm:^1.0.2"
+ checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c
+ languageName: node
+ linkType: hard
+
+"set-function-name@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "set-function-name@npm:2.0.2"
+ dependencies:
+ define-data-property: "npm:^1.1.4"
+ es-errors: "npm:^1.3.0"
+ functions-have-names: "npm:^1.2.3"
+ has-property-descriptors: "npm:^1.0.2"
+ checksum: 10c0/fce59f90696c450a8523e754abb305e2b8c73586452619c2bad5f7bf38c7b6b4651895c9db895679c5bef9554339cf3ef1c329b66ece3eda7255785fbe299316
+ languageName: node
+ linkType: hard
+
+"set-proto@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "set-proto@npm:1.0.0"
+ dependencies:
+ dunder-proto: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/ca5c3ccbba479d07c30460e367e66337cec825560b11e8ba9c5ebe13a2a0d6021ae34eddf94ff3dfe17a3104dc1f191519cb6c48378b503e5c3f36393938776a
+ languageName: node
+ linkType: hard
+
"sharp@npm:^0.33.5":
version: 0.33.5
resolution: "sharp@npm:0.33.5"
@@ -4369,6 +5558,15 @@
languageName: node
linkType: hard
+"shebang-command@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "shebang-command@npm:1.2.0"
+ dependencies:
+ shebang-regex: "npm:^1.0.0"
+ checksum: 10c0/7b20dbf04112c456b7fc258622dafd566553184ac9b6938dd30b943b065b21dabd3776460df534cc02480db5e1b6aec44700d985153a3da46e7db7f9bd21326d
+ languageName: node
+ linkType: hard
+
"shebang-command@npm:^2.0.0":
version: 2.0.0
resolution: "shebang-command@npm:2.0.0"
@@ -4378,6 +5576,13 @@
languageName: node
linkType: hard
+"shebang-regex@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "shebang-regex@npm:1.0.0"
+ checksum: 10c0/9abc45dee35f554ae9453098a13fdc2f1730e525a5eb33c51f096cc31f6f10a4b38074c1ebf354ae7bffa7229506083844008dfc3bb7818228568c0b2dc1fff2
+ languageName: node
+ linkType: hard
+
"shebang-regex@npm:^3.0.0":
version: 3.0.0
resolution: "shebang-regex@npm:3.0.0"
@@ -4385,6 +5590,61 @@
languageName: node
linkType: hard
+"shell-quote@npm:^1.6.1":
+ version: 1.8.3
+ resolution: "shell-quote@npm:1.8.3"
+ checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd
+ languageName: node
+ linkType: hard
+
+"side-channel-list@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "side-channel-list@npm:1.0.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ object-inspect: "npm:^1.13.3"
+ checksum: 10c0/644f4ac893456c9490ff388bf78aea9d333d5e5bfc64cfb84be8f04bf31ddc111a8d4b83b85d7e7e8a7b845bc185a9ad02c052d20e086983cf59f0be517d9b3d
+ languageName: node
+ linkType: hard
+
+"side-channel-map@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "side-channel-map@npm:1.0.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ es-errors: "npm:^1.3.0"
+ get-intrinsic: "npm:^1.2.5"
+ object-inspect: "npm:^1.13.3"
+ checksum: 10c0/010584e6444dd8a20b85bc926d934424bd809e1a3af941cace229f7fdcb751aada0fb7164f60c2e22292b7fa3c0ff0bce237081fd4cdbc80de1dc68e95430672
+ languageName: node
+ linkType: hard
+
+"side-channel-weakmap@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "side-channel-weakmap@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ es-errors: "npm:^1.3.0"
+ get-intrinsic: "npm:^1.2.5"
+ object-inspect: "npm:^1.13.3"
+ side-channel-map: "npm:^1.0.1"
+ checksum: 10c0/71362709ac233e08807ccd980101c3e2d7efe849edc51455030327b059f6c4d292c237f94dc0685031dd11c07dd17a68afde235d6cf2102d949567f98ab58185
+ languageName: node
+ linkType: hard
+
+"side-channel@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "side-channel@npm:1.1.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ object-inspect: "npm:^1.13.3"
+ side-channel-list: "npm:^1.0.0"
+ side-channel-map: "npm:^1.0.1"
+ side-channel-weakmap: "npm:^1.0.2"
+ checksum: 10c0/cb20dad41eb032e6c24c0982e1e5a24963a28aa6122b4f05b3f3d6bf8ae7fd5474ef382c8f54a6a3ab86e0cac4d41a23bd64ede3970e5bfb50326ba02a7996e6
+ languageName: node
+ linkType: hard
+
"signal-exit@npm:^3.0.2":
version: 3.0.7
resolution: "signal-exit@npm:3.0.7"
@@ -4408,6 +5668,13 @@
languageName: node
linkType: hard
+"slash@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "slash@npm:3.0.0"
+ checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b
+ languageName: node
+ linkType: hard
+
"smart-buffer@npm:^4.2.0":
version: 4.2.0
resolution: "smart-buffer@npm:4.2.0"
@@ -4500,6 +5767,16 @@
languageName: node
linkType: hard
+"stop-iteration-iterator@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "stop-iteration-iterator@npm:1.1.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ internal-slot: "npm:^1.1.0"
+ checksum: 10c0/de4e45706bb4c0354a4b1122a2b8cc45a639e86206807ce0baf390ee9218d3ef181923fa4d2b67443367c491aa255c5fbaa64bb74648e3c5b48299928af86c09
+ languageName: node
+ linkType: hard
+
"stoppable@npm:1.1.0":
version: 1.1.0
resolution: "stoppable@npm:1.1.0"
@@ -4529,6 +5806,56 @@
languageName: node
linkType: hard
+"string.prototype.padend@npm:^3.0.0":
+ version: 3.1.6
+ resolution: "string.prototype.padend@npm:3.1.6"
+ dependencies:
+ call-bind: "npm:^1.0.7"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.2"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/8f2c8c1f3db1efcdc210668c80c87f2cea1253d6029ff296a172b5e13edc9adebeed4942d023de8d31f9b13b69f3f5d73de7141959b1f09817fba5f527e83be1
+ languageName: node
+ linkType: hard
+
+"string.prototype.trim@npm:^1.2.10":
+ version: 1.2.10
+ resolution: "string.prototype.trim@npm:1.2.10"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.2"
+ define-data-property: "npm:^1.1.4"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.5"
+ es-object-atoms: "npm:^1.0.0"
+ has-property-descriptors: "npm:^1.0.2"
+ checksum: 10c0/8a8854241c4b54a948e992eb7dd6b8b3a97185112deb0037a134f5ba57541d8248dd610c966311887b6c2fd1181a3877bffb14d873ce937a344535dabcc648f8
+ languageName: node
+ linkType: hard
+
+"string.prototype.trimend@npm:^1.0.9":
+ version: 1.0.9
+ resolution: "string.prototype.trimend@npm:1.0.9"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.2"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/59e1a70bf9414cb4c536a6e31bef5553c8ceb0cf44d8b4d0ed65c9653358d1c64dd0ec203b100df83d0413bbcde38b8c5d49e14bc4b86737d74adc593a0d35b6
+ languageName: node
+ linkType: hard
+
+"string.prototype.trimstart@npm:^1.0.8":
+ version: 1.0.8
+ resolution: "string.prototype.trimstart@npm:1.0.8"
+ dependencies:
+ call-bind: "npm:^1.0.7"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/d53af1899959e53c83b64a5fd120be93e067da740e7e75acb433849aa640782fb6c7d4cd5b84c954c84413745a3764df135a8afeb22908b86a835290788d8366
+ languageName: node
+ linkType: hard
+
"string_decoder@npm:^1.1.1":
version: 1.3.0
resolution: "string_decoder@npm:1.3.0"
@@ -4570,6 +5897,15 @@
languageName: node
linkType: hard
+"supports-color@npm:^5.3.0":
+ version: 5.5.0
+ resolution: "supports-color@npm:5.5.0"
+ dependencies:
+ has-flag: "npm:^3.0.0"
+ checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05
+ languageName: node
+ linkType: hard
+
"supports-color@npm:^7.1.0":
version: 7.2.0
resolution: "supports-color@npm:7.2.0"
@@ -4579,6 +5915,13 @@
languageName: node
linkType: hard
+"supports-preserve-symlinks-flag@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
+ checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39
+ languageName: node
+ linkType: hard
+
"tailwindcss@npm:4.1.11, tailwindcss@npm:^4.1.4":
version: 4.1.11
resolution: "tailwindcss@npm:4.1.11"
@@ -4637,6 +5980,15 @@
languageName: node
linkType: hard
+"to-regex-range@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "to-regex-range@npm:5.0.1"
+ dependencies:
+ is-number: "npm:^7.0.0"
+ checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892
+ languageName: node
+ linkType: hard
+
"tree-kill@npm:^1.2.2":
version: 1.2.2
resolution: "tree-kill@npm:1.2.2"
@@ -4646,6 +5998,23 @@
languageName: node
linkType: hard
+"tsc-alias@npm:^1.8.16":
+ version: 1.8.16
+ resolution: "tsc-alias@npm:1.8.16"
+ dependencies:
+ chokidar: "npm:^3.5.3"
+ commander: "npm:^9.0.0"
+ get-tsconfig: "npm:^4.10.0"
+ globby: "npm:^11.0.4"
+ mylas: "npm:^2.1.9"
+ normalize-path: "npm:^3.0.0"
+ plimit-lit: "npm:^1.2.6"
+ bin:
+ tsc-alias: dist/bin/index.js
+ checksum: 10c0/5775a6044bd5b6e94efdf1902493aa959270def65e7915edad78023fac7f42f25724842bd98f38a5d00e01f7395dca102a6615933bec3bdd887617d00419f66a
+ languageName: node
+ linkType: hard
+
"tsconfck@npm:^3.0.3":
version: 3.1.6
resolution: "tsconfck@npm:3.1.6"
@@ -4678,6 +6047,59 @@
languageName: node
linkType: hard
+"typed-array-buffer@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "typed-array-buffer@npm:1.0.3"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ is-typed-array: "npm:^1.1.14"
+ checksum: 10c0/1105071756eb248774bc71646bfe45b682efcad93b55532c6ffa4518969fb6241354e4aa62af679ae83899ec296d69ef88f1f3763657cdb3a4d29321f7b83079
+ languageName: node
+ linkType: hard
+
+"typed-array-byte-length@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "typed-array-byte-length@npm:1.0.3"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ for-each: "npm:^0.3.3"
+ gopd: "npm:^1.2.0"
+ has-proto: "npm:^1.2.0"
+ is-typed-array: "npm:^1.1.14"
+ checksum: 10c0/6ae083c6f0354f1fce18b90b243343b9982affd8d839c57bbd2c174a5d5dc71be9eb7019ffd12628a96a4815e7afa85d718d6f1e758615151d5f35df841ffb3e
+ languageName: node
+ linkType: hard
+
+"typed-array-byte-offset@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "typed-array-byte-offset@npm:1.0.4"
+ dependencies:
+ available-typed-arrays: "npm:^1.0.7"
+ call-bind: "npm:^1.0.8"
+ for-each: "npm:^0.3.3"
+ gopd: "npm:^1.2.0"
+ has-proto: "npm:^1.2.0"
+ is-typed-array: "npm:^1.1.15"
+ reflect.getprototypeof: "npm:^1.0.9"
+ checksum: 10c0/3d805b050c0c33b51719ee52de17c1cd8e6a571abdf0fffb110e45e8dd87a657e8b56eee94b776b13006d3d347a0c18a730b903cf05293ab6d92e99ff8f77e53
+ languageName: node
+ linkType: hard
+
+"typed-array-length@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "typed-array-length@npm:1.0.7"
+ dependencies:
+ call-bind: "npm:^1.0.7"
+ for-each: "npm:^0.3.3"
+ gopd: "npm:^1.0.1"
+ is-typed-array: "npm:^1.1.13"
+ possible-typed-array-names: "npm:^1.0.0"
+ reflect.getprototypeof: "npm:^1.0.6"
+ checksum: 10c0/e38f2ae3779584c138a2d8adfa8ecf749f494af3cd3cdafe4e688ce51418c7d2c5c88df1bd6be2bbea099c3f7cea58c02ca02ed438119e91f162a9de23f61295
+ languageName: node
+ linkType: hard
+
"typescript@npm:^5.8.3":
version: 5.8.3
resolution: "typescript@npm:5.8.3"
@@ -4705,6 +6127,18 @@
languageName: node
linkType: hard
+"unbox-primitive@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "unbox-primitive@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-bigints: "npm:^1.0.2"
+ has-symbols: "npm:^1.1.0"
+ which-boxed-primitive: "npm:^1.1.1"
+ checksum: 10c0/7dbd35ab02b0e05fe07136c72cb9355091242455473ec15057c11430129bab38b7b3624019b8778d02a881c13de44d63cd02d122ee782fb519e1de7775b5b982
+ languageName: node
+ linkType: hard
+
"undici-types@npm:~6.21.0":
version: 6.21.0
resolution: "undici-types@npm:6.21.0"
@@ -4783,7 +6217,7 @@
languageName: node
linkType: hard
-"validate-npm-package-license@npm:^3.0.4":
+"validate-npm-package-license@npm:^3.0.1, validate-npm-package-license@npm:^3.0.4":
version: 3.0.4
resolution: "validate-npm-package-license@npm:3.0.4"
dependencies:
@@ -4950,6 +6384,78 @@
languageName: node
linkType: hard
+"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "which-boxed-primitive@npm:1.1.1"
+ dependencies:
+ is-bigint: "npm:^1.1.0"
+ is-boolean-object: "npm:^1.2.1"
+ is-number-object: "npm:^1.1.1"
+ is-string: "npm:^1.1.1"
+ is-symbol: "npm:^1.1.1"
+ checksum: 10c0/aceea8ede3b08dede7dce168f3883323f7c62272b49801716e8332ff750e7ae59a511ae088840bc6874f16c1b7fd296c05c949b0e5b357bfe3c431b98c417abe
+ languageName: node
+ linkType: hard
+
+"which-builtin-type@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "which-builtin-type@npm:1.2.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ function.prototype.name: "npm:^1.1.6"
+ has-tostringtag: "npm:^1.0.2"
+ is-async-function: "npm:^2.0.0"
+ is-date-object: "npm:^1.1.0"
+ is-finalizationregistry: "npm:^1.1.0"
+ is-generator-function: "npm:^1.0.10"
+ is-regex: "npm:^1.2.1"
+ is-weakref: "npm:^1.0.2"
+ isarray: "npm:^2.0.5"
+ which-boxed-primitive: "npm:^1.1.0"
+ which-collection: "npm:^1.0.2"
+ which-typed-array: "npm:^1.1.16"
+ checksum: 10c0/8dcf323c45e5c27887800df42fbe0431d0b66b1163849bb7d46b5a730ad6a96ee8bfe827d078303f825537844ebf20c02459de41239a0a9805e2fcb3cae0d471
+ languageName: node
+ linkType: hard
+
+"which-collection@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "which-collection@npm:1.0.2"
+ dependencies:
+ is-map: "npm:^2.0.3"
+ is-set: "npm:^2.0.3"
+ is-weakmap: "npm:^2.0.2"
+ is-weakset: "npm:^2.0.3"
+ checksum: 10c0/3345fde20964525a04cdf7c4a96821f85f0cc198f1b2ecb4576e08096746d129eb133571998fe121c77782ac8f21cbd67745a3d35ce100d26d4e684c142ea1f2
+ languageName: node
+ linkType: hard
+
+"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19":
+ version: 1.1.19
+ resolution: "which-typed-array@npm:1.1.19"
+ dependencies:
+ available-typed-arrays: "npm:^1.0.7"
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.4"
+ for-each: "npm:^0.3.5"
+ get-proto: "npm:^1.0.1"
+ gopd: "npm:^1.2.0"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/702b5dc878addafe6c6300c3d0af5983b175c75fcb4f2a72dfc3dd38d93cf9e89581e4b29c854b16ea37e50a7d7fca5ae42ece5c273d8060dcd603b2404bbb3f
+ languageName: node
+ linkType: hard
+
+"which@npm:^1.2.9":
+ version: 1.3.1
+ resolution: "which@npm:1.3.1"
+ dependencies:
+ isexe: "npm:^2.0.0"
+ bin:
+ which: ./bin/which
+ checksum: 10c0/e945a8b6bbf6821aaaef7f6e0c309d4b615ef35699576d5489b4261da9539f70393c6b2ce700ee4321c18f914ebe5644bc4631b15466ffbaad37d83151f6af59
+ languageName: node
+ linkType: hard
+
"which@npm:^2.0.1":
version: 2.0.2
resolution: "which@npm:2.0.2"