diff --git a/package.json b/package.json
index 7d4cef8..6aa618a 100644
--- a/package.json
+++ b/package.json
@@ -16,5 +16,8 @@
"packages/lambda-layer/nodejs",
"packages/*"
]
+ },
+ "devDependencies": {
+ "prettier": "^3.3.3"
}
}
diff --git a/packages/api/serverless.yml b/packages/api/serverless.yml
index 10f8c97..f45b670 100644
--- a/packages/api/serverless.yml
+++ b/packages/api/serverless.yml
@@ -43,6 +43,7 @@ provider:
NODE_ENV: ${sls:stage}
TABLE_NAME: ${self:service}-${sls:stage}
CUSTOM_DOMAIN: ${param:CUSTOM_DOMAIN}
+ EDGE_ENDPOINT: !GetAtt HttpApi.ApiEndpoint
# S3_BUCKET: ${self:service}-${sls:stage}
# CLOUDFRONT_DOMAIN: !GetAtt UserMediaDistribution.DomainName
# USER_POOL_ID:
diff --git a/packages/api/src/functions/collector/handler.js b/packages/api/src/functions/collector/handler.js
index f179d53..c1544f1 100644
--- a/packages/api/src/functions/collector/handler.js
+++ b/packages/api/src/functions/collector/handler.js
@@ -7,46 +7,58 @@ export const app = async ({ body }) => {
if (span.type === "log") {
// save log span
- await put({
- ...span,
- pk: `transaction#${span.transactionId || span.transaction_id}`,
- sk: `log#${span.started}#${span.id}`,
- type: "log",
- });
+ await put(
+ {
+ ...span,
+ pk: `transaction#${span.transactionId || span.transaction_id}`,
+ sk: `log#${span.started}#${span.id}`,
+ type: "log",
+ },
+ true,
+ );
continue;
}
// save transaction span
- await put({
- ...span,
- pk: `transaction#${span.transactionId || span.transaction_id}`,
- sk: `span#${span.started || span.sending_time}#${span.id}`,
- type: "span",
- spanType: span.type,
- });
+ await put(
+ {
+ ...span,
+ pk: `transaction#${span.transactionId || span.transaction_id}`,
+ sk: `span#${span.started || span.sending_time}#${span.id}`,
+ type: "span",
+ spanType: span.type,
+ },
+ true,
+ );
if (span.type === "function" && span.ended) {
// save function invocation details
- await put({
- ...span,
- pk: `function#${span.name}`,
- sk: `invocation#${span.started}#${span.id}`,
- type: "invocation",
- });
+ await put(
+ {
+ ...span,
+ pk: `function#${span.name}`,
+ sk: `invocation#${span.started}#${span.id}`,
+ type: "invocation",
+ },
+ true,
+ );
// save function meta data
- await put({
- pk: `function#${span.name}`,
- sk: `function`,
- type: "function",
- lastInvocation: span.started,
- runtime: span.runtime,
- account: span.account,
- region: span.region,
- arn: span.invokedArn,
- memoryAllocation: span.memoryAllocation,
- timeout: span.maxFinishTime - span.started,
- });
+ await put(
+ {
+ pk: `function#${span.name}`,
+ sk: `function`,
+ type: "function",
+ lastInvocation: span.started,
+ runtime: span.runtime,
+ account: span.account,
+ region: span.region,
+ arn: span.invokedArn,
+ memoryAllocation: span.memoryAllocation,
+ timeout: span.maxFinishTime - span.started,
+ },
+ true,
+ );
}
}
};
diff --git a/packages/api/src/functions/media/upload/function.yml b/packages/api/src/functions/media/upload/function.yml
deleted file mode 100644
index 6433b5c..0000000
--- a/packages/api/src/functions/media/upload/function.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-media-upload:
- handler: src/functions/media/upload/handler.handler
- events:
- - httpApi:
- path: /media/upload
- method: get
- authorizer:
- name: WebAuthorizer
diff --git a/packages/api/src/functions/media/upload/handler.js b/packages/api/src/functions/media/upload/handler.js
deleted file mode 100644
index deaad15..0000000
--- a/packages/api/src/functions/media/upload/handler.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { middleware, auth } from "@includable/serverless-middleware";
-import { v4 as uuid } from "uuid";
-
-import { getSignedUrl, sanitizeFilename } from "../../../lib/media";
-
-const dependencies = () => ({
- getSignedUrl,
- uuid,
-});
-
-const defaultParams = {
- type: "avatar",
- filename: "image.jpg",
- contentType: "image/jpeg",
-};
-
-export const app = async (
- { query = {} },
- { currentUser, getSignedUrl, uuid },
-) => {
- const { filename, type, contentType } = { ...defaultParams, ...query };
- const safeFilename = sanitizeFilename(filename);
- const safeType = sanitizeFilename(type);
- const key = `${safeType}/${currentUser.id}/${uuid()}/${safeFilename}`;
-
- const uploadUrl = await getSignedUrl(key, contentType, {
- "x-upload-user": currentUser.id,
- "x-upload-category": safeType,
- "x-upload-filename": filename,
- });
-
- return {
- uploadUrl,
- publicUrl: `https://${process.env.CLOUDFRONT_DOMAIN}/${key}`,
- };
-};
-
-export const handler = middleware(app, [auth]).register(dependencies);
diff --git a/packages/api/src/functions/media/upload/test.js b/packages/api/src/functions/media/upload/test.js
deleted file mode 100644
index a914540..0000000
--- a/packages/api/src/functions/media/upload/test.js
+++ /dev/null
@@ -1,38 +0,0 @@
-const { app } = require("./handler");
-
-describe("media-upload", () => {
- it("can generate signed URL", async () => {
- const event = {
- query: {
- type: "custom-image",
- },
- };
- const getSignedUrl = jest.fn().mockReturnValue("https://example.com/");
- const dependencies = {
- getSignedUrl,
- uuid: jest.fn().mockReturnValue("133a1a65-dc63-48e5-9afd-40d17b228874"),
- currentUser: {
- id: "test123",
- },
- };
-
- process.env.CLOUDFRONT_DOMAIN = "test.com";
- const result = await app(event, dependencies);
-
- expect(result).toEqual({
- publicUrl:
- "https://test.com/custom-image/test123/133a1a65-dc63-48e5-9afd-40d17b228874/image.jpg",
- uploadUrl: "https://example.com/",
- });
- expect(getSignedUrl).toBeCalledTimes(1);
- expect(getSignedUrl).toBeCalledWith(
- "custom-image/test123/133a1a65-dc63-48e5-9afd-40d17b228874/image.jpg",
- "image/jpeg",
- {
- "x-upload-user": "test123",
- "x-upload-category": "custom-image",
- "x-upload-filename": "image.jpg",
- }
- );
- });
-});
diff --git a/packages/api/src/functions/preferences/get/function.yml b/packages/api/src/functions/preferences/get/function.yml
deleted file mode 100644
index 7cb513e..0000000
--- a/packages/api/src/functions/preferences/get/function.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-preferences-get:
- handler: src/functions/preferences/get/handler.handler
- events:
- - httpApi:
- path: /preferences
- method: get
- authorizer:
- name: WebAuthorizer
diff --git a/packages/api/src/functions/preferences/get/handler.js b/packages/api/src/functions/preferences/get/handler.js
deleted file mode 100644
index 5d649ee..0000000
--- a/packages/api/src/functions/preferences/get/handler.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { middleware, auth } from "@includable/serverless-middleware";
-
-import User from "../../../lib/entities/User";
-
-const dependencies = () => ({
- User,
-});
-
-export const app = async (event, { User, currentUser }) => {
- let { Item: result } = await User.get({ id: currentUser.id });
-
- return (result && result.preferences) || {};
-};
-
-export const handler = middleware(app, [auth]).register(dependencies);
diff --git a/packages/api/src/functions/preferences/get/test.js b/packages/api/src/functions/preferences/get/test.js
deleted file mode 100644
index 338ae82..0000000
--- a/packages/api/src/functions/preferences/get/test.js
+++ /dev/null
@@ -1,65 +0,0 @@
-const { app } = require("./handler");
-
-describe("preferences-get", () => {
- it("can get preferences if user exists and has preferences", async () => {
- const preferences = {
- myPreference: true,
- somethingElse: [123, "test", false, null],
- };
- const getHandler = jest.fn().mockResolvedValue({ Item: { preferences } });
- const dependencies = {
- User: {
- get: getHandler,
- },
- currentUser: {
- id: "test123",
- },
- };
-
- const result = await app({}, dependencies);
-
- expect(result).toEqual(preferences);
- expect(getHandler).toBeCalledTimes(1);
- expect(getHandler).toBeCalledWith({
- id: "test123",
- });
- });
- it("can get preferences if user exists and has no preferences", async () => {
- const getHandler = jest.fn().mockResolvedValue({ Item: {} });
- const dependencies = {
- User: {
- get: getHandler,
- },
- currentUser: {
- id: "test123",
- },
- };
-
- const result = await app({}, dependencies);
-
- expect(result).toEqual({});
- expect(getHandler).toBeCalledTimes(1);
- expect(getHandler).toBeCalledWith({
- id: "test123",
- });
- });
- it("can get preferences if user does not exist", async () => {
- const getHandler = jest.fn().mockResolvedValue({ Item: null });
- const dependencies = {
- User: {
- get: getHandler,
- },
- currentUser: {
- id: "test123",
- },
- };
-
- const result = await app({}, dependencies);
-
- expect(result).toEqual({});
- expect(getHandler).toBeCalledTimes(1);
- expect(getHandler).toBeCalledWith({
- id: "test123",
- });
- });
-});
diff --git a/packages/api/src/functions/preferences/update/function.yml b/packages/api/src/functions/preferences/update/function.yml
deleted file mode 100644
index cd873cb..0000000
--- a/packages/api/src/functions/preferences/update/function.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-preferences-update:
- handler: src/functions/preferences/update/handler.handler
- events:
- - httpApi:
- path: /preferences
- method: post
- authorizer:
- name: WebAuthorizer
diff --git a/packages/api/src/functions/preferences/update/handler.js b/packages/api/src/functions/preferences/update/handler.js
deleted file mode 100644
index 77b4abd..0000000
--- a/packages/api/src/functions/preferences/update/handler.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import Joi from "joi";
-import { middleware, auth } from "@includable/serverless-middleware";
-
-import User from "../../../lib/entities/User";
-
-const dependencies = () => ({
- User,
-});
-
-const schema = Joi.object().unknown(true);
-
-export const app = async ({ body }, { User, currentUser }) => {
- // Validate input
- const data = await schema.validateAsync(body);
-
- // Update db entry
- let res;
- try {
- // Note the $set: ... in here!
- res = await User.update(
- {
- id: currentUser.id,
- preferences: { $set: data },
- },
- {
- returnValues: "all_new",
- }
- );
- } catch (e) {
- // Means the user doesn't yet exist
- res = await User.update(
- {
- id: currentUser.id,
- preferences: { ...data },
- },
- {
- returnValues: "all_new",
- }
- );
- }
-
- // Output updated version
- return res.Attributes.preferences;
-};
-
-export const handler = middleware(app, [auth]).register(dependencies);
diff --git a/packages/api/src/functions/preferences/update/test.js b/packages/api/src/functions/preferences/update/test.js
deleted file mode 100644
index 9e89bb1..0000000
--- a/packages/api/src/functions/preferences/update/test.js
+++ /dev/null
@@ -1,103 +0,0 @@
-const { app } = require("./handler");
-
-describe("preferences-update", () => {
- it("can update if user exists", async () => {
- const event = {
- body: {
- myPreference: true,
- somethingElse: [123, "test", false, null],
- },
- };
- const updateHandler = jest
- .fn()
- .mockResolvedValue({ Attributes: { preferences: event.body } });
- const dependencies = {
- User: {
- update: updateHandler,
- },
- currentUser: {
- id: "test123",
- },
- };
-
- const result = await app(event, dependencies);
-
- expect(result).toEqual(event.body);
- expect(updateHandler).toBeCalledTimes(1);
- expect(updateHandler).toBeCalledWith(
- {
- id: "test123",
- preferences: { $set: event.body },
- },
- {
- returnValues: "all_new",
- }
- );
- });
- it("can update if user does not exist", async () => {
- const event = {
- body: {
- myPreference: true,
- somethingElse: [123, "test", false, null],
- },
- };
- const updateHandler = jest
- .fn()
- .mockRejectedValueOnce(new Error("Item not found."))
- .mockResolvedValue({ Attributes: { preferences: event.body } });
- const dependencies = {
- User: {
- update: updateHandler,
- },
- currentUser: {
- id: "test123",
- },
- };
-
- const result = await app(event, dependencies);
-
- expect(result).toEqual(event.body);
- expect(updateHandler).toBeCalledTimes(2);
- expect(updateHandler).toBeCalledWith(
- {
- id: "test123",
- preferences: { $set: event.body },
- },
- {
- returnValues: "all_new",
- }
- );
- expect(updateHandler).toBeCalledWith(
- {
- id: "test123",
- preferences: event.body,
- },
- {
- returnValues: "all_new",
- }
- );
- });
- it("rejects invalid body", async () => {
- const event = {
- body: "lalala",
- };
- const dependencies = {
- User: {
- update: jest.fn(),
- },
- currentUser: {
- id: "test123",
- },
- };
-
- expect.assertions(2);
-
- try {
- await app(event, dependencies);
- } catch (e) {
- expect(e.message).toEqual('"value" must be of type object');
- }
-
- expect(dependencies.User.update).not.toBeCalled();
- });
-});
diff --git a/packages/api/src/functions/users/get/function.yml b/packages/api/src/functions/users/get/function.yml
deleted file mode 100644
index a493e60..0000000
--- a/packages/api/src/functions/users/get/function.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-users-get:
- handler: src/functions/users/get/handler.handler
- events:
- - httpApi:
- path: /users/{userId}
- method: get
- authorizer:
- name: WebAuthorizer
- - httpApi:
- path: /me
- method: get
- authorizer:
- name: WebAuthorizer
diff --git a/packages/api/src/functions/users/get/handler.js b/packages/api/src/functions/users/get/handler.js
deleted file mode 100644
index b833f4c..0000000
--- a/packages/api/src/functions/users/get/handler.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import { middleware, auth } from "@includable/serverless-middleware";
-
-import User from "../../../lib/entities/User";
-import { createUser } from "../../../lib/userManagement";
-
-const dependencies = () => ({
- User,
- createUser,
-});
-
-export const app = async ({ userId }, { User, currentUser }) => {
- let { Item: result } = await User.get({ id: userId || currentUser.id });
- if (!result && (!userId || userId === currentUser.id)) {
- // Create profile for user if it doesn't exist
- // using data from Cognito
- result = await createUser(currentUser.id);
- }
-
- if (!result) {
- throw new Error("User not found.");
- }
-
- const publicWhitelist = ["id", "displayName", "name", "avatar", "bio"];
- if (result.id === currentUser.id) {
- return result;
- }
-
- return Object.fromEntries(
- Object.entries(result).filter(([key]) => publicWhitelist.includes(key))
- );
-};
-
-export const handler = middleware(app, [auth]).register(dependencies);
diff --git a/packages/api/src/functions/users/update/function.yml b/packages/api/src/functions/users/update/function.yml
deleted file mode 100644
index 2f2f519..0000000
--- a/packages/api/src/functions/users/update/function.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-users-update:
- handler: src/functions/users/update/handler.handler
- events:
- - httpApi:
- path: /users/{userId}
- method: post
- authorizer:
- name: WebAuthorizer
- - httpApi:
- path: /me
- method: post
- authorizer:
- name: WebAuthorizer
diff --git a/packages/api/src/functions/users/update/handler.js b/packages/api/src/functions/users/update/handler.js
deleted file mode 100644
index 68dae77..0000000
--- a/packages/api/src/functions/users/update/handler.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { middleware, auth } from "@includable/serverless-middleware";
-import Joi from "joi";
-
-import User from "../../../lib/entities/User";
-import { createUser, updateUserAttributes } from "../../../lib/userManagement";
-
-const dependencies = () => ({
- User,
- createUser,
-});
-
-const schema = Joi.object({
- displayName: Joi.string().min(3).max(60),
- name: Joi.string().min(3).max(120),
- email: Joi.string().email(),
- bio: Joi.string().max(500),
- avatar: Joi.string().uri({ scheme: ["https"] }),
-});
-
-export const app = async ({ userId, body }, { User, currentUser }) => {
- const id = userId || currentUser.id;
- if (id !== currentUser.id) {
- throw new Error("No permission to edit other users.");
- }
-
- // Validate input
- const input = await schema.validateAsync(body);
-
- // Update cognito
- const cognitoAllowedAttributesMap = {
- email: "email",
- name: "name",
- displayName: "nickname",
- avatar: "picture",
- };
- const cognitoAttributes = {};
- Object.entries(cognitoAllowedAttributesMap).forEach(
- ([attribute, cognitoName]) => {
- if (
- attribute in input &&
- input[attribute] &&
- input[attribute] !== currentUser[cognitoName]
- ) {
- cognitoAttributes[cognitoName] = input[attribute];
- }
- }
- );
- if (Object.keys(cognitoAttributes).length) {
- await updateUserAttributes(id, cognitoAttributes);
- }
-
- // Update db entry
- const { Attributes } = await User.update(
- { ...input, id },
- { returnValues: "all_new" }
- );
-
- // Output updated version
- return Attributes;
-};
-
-export const handler = middleware(app, [auth]).register(dependencies);
diff --git a/packages/api/src/infrastructure/storage/bucket.yml b/packages/api/src/infrastructure/storage/bucket.yml
deleted file mode 100644
index 3966c2c..0000000
--- a/packages/api/src/infrastructure/storage/bucket.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-Resources:
- UserMediaBucket:
- Type: AWS::S3::Bucket
- DeletionPolicy: Retain
- Properties:
- BucketName: ${self:service}-${sls:stage}
- AccelerateConfiguration:
- AccelerationStatus: Enabled
- WebsiteConfiguration:
- IndexDocument: default.png
- ErrorDocument: default.png
- OwnershipControls:
- Rules:
- - ObjectOwnership: BucketOwnerPreferred
- CorsConfiguration:
- CorsRules:
- - AllowedOrigins:
- - "*"
- AllowedHeaders:
- - "*"
- AllowedMethods:
- - GET
- - PUT
- - POST
- - DELETE
- - HEAD
- MaxAge: 3000
- UserMediaDistribution:
- Type: AWS::CloudFront::Distribution
- Properties:
- DistributionConfig:
- DefaultCacheBehavior:
- TargetOriginId: UserMediaBucket
- ViewerProtocolPolicy: allow-all
- Compress: true
- ForwardedValues:
- QueryString: true
- Cookies:
- Forward: none
- AllowedMethods:
- - GET
- - HEAD
- - OPTIONS
- Enabled: true
- Origins:
- - Id: UserMediaBucket
- DomainName: ${self:service}-${sls:stage}.s3-website-${self:provider.region}.amazonaws.com
- CustomOriginConfig:
- HTTPPort: 80
- HTTPSPort: 443
- OriginProtocolPolicy: http-only
diff --git a/packages/api/src/lib/events.js b/packages/api/src/lib/events.js
deleted file mode 100644
index 2aa5efc..0000000
--- a/packages/api/src/lib/events.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { EventBridge } from "@aws-sdk/client-eventbridge";
-
-const bridge = new EventBridge();
-
-const createEventEntry = (type, data = {}) => ({
- Source: process.env.SERVICE,
- DetailType: type,
- Detail: JSON.stringify({ data }),
-});
-
-export const sendEvent = async (type, data = {}) =>
- bridge.putEvents({ Entries: [createEventEntry(type, data)] });
diff --git a/packages/api/src/lib/media.js b/packages/api/src/lib/media.js
deleted file mode 100644
index 587fad2..0000000
--- a/packages/api/src/lib/media.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import { getSignedUrl as s3SignedUrl } from "@aws-sdk/s3-request-presigner";
-import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
-const client = new S3Client({ useAccelerateEndpoint: true });
-
-const illegalRe = /[\/?<>\\:*|"]/g;
-const controlRe = /[\x00-\x1f\x80-\x9f]/g;
-const reservedRe = /^\.+$/;
-const windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i;
-const windowsTrailingRe = /[. ]+$/;
-
-export const sanitizeFilename = (input) =>
- input
- .replace(illegalRe, "-")
- .replace(controlRe, "-")
- .replace(reservedRe, "-")
- .replace(windowsReservedRe, "-")
- .replace(windowsTrailingRe, "-")
- .replace(/ /g, "-");
-
-export async function getSignedUrl(key, contentType, metadata = {}) {
- const command = new PutObjectCommand({
- Key: key,
- Bucket: process.env.S3_BUCKET,
- ContentType: contentType,
- ACL: "public-read",
- Metadata: metadata,
- });
-
- return s3SignedUrl(client, command, { expiresIn: 3600 });
-}
diff --git a/packages/api/src/lib/userManagement.js b/packages/api/src/lib/userManagement.js
deleted file mode 100644
index f98cbd8..0000000
--- a/packages/api/src/lib/userManagement.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import { CognitoIdentityProvider } from "@aws-sdk/client-cognito-identity-provider";
-import User from "./entities/User";
-
-const cognito = new CognitoIdentityProvider();
-const { USER_POOL_ID: UserPoolId } = process.env;
-
-export const createUser = async (userId) => {
- const user = await cognito.adminGetUser({
- UserPoolId,
- Username: userId,
- });
- if (!user.Enabled) {
- throw new Error("Unknown user.");
- }
- const name = user.UserAttributes?.find(({ Name }) => Name === "name");
- const { Attributes } = await User.update(
- {
- id: user.Username,
- created: new Date(user.UserCreateDate || 0).toISOString(),
- modified: new Date(user.UserLastModifiedDate || 0).toISOString(),
- email: user.UserAttributes?.find(({ Name }) => Name === "email")?.Value,
- name: name && name.Value,
- },
- {
- returnValues: "ALL_NEW",
- },
- );
-
- return Attributes;
-};
-
-export const updateUserAttributes = async (userId, attributes) =>
- cognito.adminUpdateUserAttributes({
- UserPoolId,
- Username: userId,
- UserAttributes: [
- {
- Name: "email_verified",
- Value: "true",
- },
- ...Object.entries(attributes).map(([Name, Value]) => ({ Name, Value })),
- ],
- });
diff --git a/packages/dashboard/.gitignore b/packages/dashboard/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/packages/dashboard/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/packages/dashboard/README.md b/packages/dashboard/README.md
new file mode 100644
index 0000000..f768e33
--- /dev/null
+++ b/packages/dashboard/README.md
@@ -0,0 +1,8 @@
+# React + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
diff --git a/packages/dashboard/eslint.config.js b/packages/dashboard/eslint.config.js
new file mode 100644
index 0000000..238d2e4
--- /dev/null
+++ b/packages/dashboard/eslint.config.js
@@ -0,0 +1,38 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import react from 'eslint-plugin-react'
+import reactHooks from 'eslint-plugin-react-hooks'
+import reactRefresh from 'eslint-plugin-react-refresh'
+
+export default [
+ { ignores: ['dist'] },
+ {
+ files: ['**/*.{js,jsx}'],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ parserOptions: {
+ ecmaVersion: 'latest',
+ ecmaFeatures: { jsx: true },
+ sourceType: 'module',
+ },
+ },
+ settings: { react: { version: '18.3' } },
+ plugins: {
+ react,
+ 'react-hooks': reactHooks,
+ 'react-refresh': reactRefresh,
+ },
+ rules: {
+ ...js.configs.recommended.rules,
+ ...react.configs.recommended.rules,
+ ...react.configs['jsx-runtime'].rules,
+ ...reactHooks.configs.recommended.rules,
+ 'react/jsx-no-target-blank': 'off',
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+ },
+]
diff --git a/packages/dashboard/index.html b/packages/dashboard/index.html
new file mode 100644
index 0000000..0c589ec
--- /dev/null
+++ b/packages/dashboard/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + React
+
+
+
+
+
+
diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json
new file mode 100644
index 0000000..f827a1e
--- /dev/null
+++ b/packages/dashboard/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@trace-stack/dashboard",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "start": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1"
+ },
+ "devDependencies": {
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
+ "@vitejs/plugin-react": "^4.3.1",
+ "globals": "^15.9.0",
+ "vite": "^5.4.1"
+ }
+}
diff --git a/packages/dashboard/public/vite.svg b/packages/dashboard/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/packages/dashboard/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/dashboard/src/App.css b/packages/dashboard/src/App.css
new file mode 100644
index 0000000..b9d355d
--- /dev/null
+++ b/packages/dashboard/src/App.css
@@ -0,0 +1,42 @@
+#root {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+ transition: filter 300ms;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.react:hover {
+ filter: drop-shadow(0 0 2em #61dafbaa);
+}
+
+@keyframes logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ a:nth-of-type(2) .logo {
+ animation: logo-spin infinite 20s linear;
+ }
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
+}
diff --git a/packages/dashboard/src/App.jsx b/packages/dashboard/src/App.jsx
new file mode 100644
index 0000000..b8b8473
--- /dev/null
+++ b/packages/dashboard/src/App.jsx
@@ -0,0 +1,35 @@
+import { useState } from 'react'
+import reactLogo from './assets/react.svg'
+import viteLogo from '/vite.svg'
+import './App.css'
+
+function App() {
+ const [count, setCount] = useState(0)
+
+ return (
+ <>
+
+ Vite + React
+
+
+
+ Edit src/App.jsx
and save to test HMR
+
+
+
+ Click on the Vite and React logos to learn more
+
+ >
+ )
+}
+
+export default App
diff --git a/packages/dashboard/src/assets/react.svg b/packages/dashboard/src/assets/react.svg
new file mode 100644
index 0000000..6c87de9
--- /dev/null
+++ b/packages/dashboard/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/dashboard/src/index.css b/packages/dashboard/src/index.css
new file mode 100644
index 0000000..6119ad9
--- /dev/null
+++ b/packages/dashboard/src/index.css
@@ -0,0 +1,68 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/packages/dashboard/src/main.jsx b/packages/dashboard/src/main.jsx
new file mode 100644
index 0000000..89f91e5
--- /dev/null
+++ b/packages/dashboard/src/main.jsx
@@ -0,0 +1,10 @@
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import App from './App.jsx'
+import './index.css'
+
+createRoot(document.getElementById('root')).render(
+
+
+ ,
+)
diff --git a/packages/dashboard/vite.config.js b/packages/dashboard/vite.config.js
new file mode 100644
index 0000000..5a33944
--- /dev/null
+++ b/packages/dashboard/vite.config.js
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+})
diff --git a/yarn.lock b/yarn.lock
index 124aaf2..24ed6c9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1737,7 +1737,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/core@npm:^7.1.0":
+"@babel/core@npm:^7.1.0, @babel/core@npm:^7.24.5":
version: 7.25.2
resolution: "@babel/core@npm:7.25.2"
dependencies:
@@ -2101,6 +2101,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-plugin-utils@npm:^7.24.7":
+ version: 7.24.8
+ resolution: "@babel/helper-plugin-utils@npm:7.24.8"
+ checksum: 10c0/0376037f94a3bfe6b820a39f81220ac04f243eaee7193774b983e956c1750883ff236b30785795abbcda43fac3ece74750566830c2daa4d6e3870bb0dff34c2d
+ languageName: node
+ linkType: hard
+
"@babel/helper-remap-async-to-generator@npm:^7.22.20":
version: 7.22.20
resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20"
@@ -3064,6 +3071,28 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-react-jsx-self@npm:^7.24.5":
+ version: 7.24.7
+ resolution: "@babel/plugin-transform-react-jsx-self@npm:7.24.7"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.24.7"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/dcf3b732401f47f06bb29d6016e48066f66de00029a0ded98ddd9983c770a00a109d91cd04d2700d15ee0bcec3ae3027a5f12d69e15ec56efc0bcbfac65e92cb
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-react-jsx-source@npm:^7.24.1":
+ version: 7.24.7
+ resolution: "@babel/plugin-transform-react-jsx-source@npm:7.24.7"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.24.7"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/970ef1264c7c6c416ab11610665d5309aec2bd2b9086ae394e1132e65138d97b060a7dc9d31054e050d6dc475b5a213938c9707c0202a5022d55dcb4c5abe28f
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-regenerator@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-regenerator@npm:7.23.3"
@@ -3452,6 +3481,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/aix-ppc64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/aix-ppc64@npm:0.21.5"
+ conditions: os=aix & cpu=ppc64
+ languageName: node
+ linkType: hard
+
"@esbuild/android-arm64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/android-arm64@npm:0.20.1"
@@ -3459,6 +3495,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/android-arm64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/android-arm64@npm:0.21.5"
+ conditions: os=android & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/android-arm@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/android-arm@npm:0.20.1"
@@ -3466,6 +3509,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/android-arm@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/android-arm@npm:0.21.5"
+ conditions: os=android & cpu=arm
+ languageName: node
+ linkType: hard
+
"@esbuild/android-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/android-x64@npm:0.20.1"
@@ -3473,6 +3523,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/android-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/android-x64@npm:0.21.5"
+ conditions: os=android & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/darwin-arm64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/darwin-arm64@npm:0.20.1"
@@ -3480,6 +3537,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/darwin-arm64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/darwin-arm64@npm:0.21.5"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/darwin-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/darwin-x64@npm:0.20.1"
@@ -3487,6 +3551,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/darwin-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/darwin-x64@npm:0.21.5"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/freebsd-arm64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/freebsd-arm64@npm:0.20.1"
@@ -3494,6 +3565,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/freebsd-arm64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/freebsd-arm64@npm:0.21.5"
+ conditions: os=freebsd & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/freebsd-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/freebsd-x64@npm:0.20.1"
@@ -3501,6 +3579,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/freebsd-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/freebsd-x64@npm:0.21.5"
+ conditions: os=freebsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-arm64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-arm64@npm:0.20.1"
@@ -3508,6 +3593,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-arm64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-arm64@npm:0.21.5"
+ conditions: os=linux & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-arm@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-arm@npm:0.20.1"
@@ -3515,6 +3607,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-arm@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-arm@npm:0.21.5"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-ia32@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-ia32@npm:0.20.1"
@@ -3522,6 +3621,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-ia32@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-ia32@npm:0.21.5"
+ conditions: os=linux & cpu=ia32
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-loong64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-loong64@npm:0.20.1"
@@ -3529,6 +3635,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-loong64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-loong64@npm:0.21.5"
+ conditions: os=linux & cpu=loong64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-mips64el@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-mips64el@npm:0.20.1"
@@ -3536,6 +3649,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-mips64el@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-mips64el@npm:0.21.5"
+ conditions: os=linux & cpu=mips64el
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-ppc64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-ppc64@npm:0.20.1"
@@ -3543,6 +3663,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-ppc64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-ppc64@npm:0.21.5"
+ conditions: os=linux & cpu=ppc64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-riscv64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-riscv64@npm:0.20.1"
@@ -3550,6 +3677,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-riscv64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-riscv64@npm:0.21.5"
+ conditions: os=linux & cpu=riscv64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-s390x@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-s390x@npm:0.20.1"
@@ -3557,6 +3691,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-s390x@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-s390x@npm:0.21.5"
+ conditions: os=linux & cpu=s390x
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/linux-x64@npm:0.20.1"
@@ -3564,6 +3705,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/linux-x64@npm:0.21.5"
+ conditions: os=linux & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/netbsd-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/netbsd-x64@npm:0.20.1"
@@ -3571,6 +3719,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/netbsd-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/netbsd-x64@npm:0.21.5"
+ conditions: os=netbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/openbsd-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/openbsd-x64@npm:0.20.1"
@@ -3578,6 +3733,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/openbsd-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/openbsd-x64@npm:0.21.5"
+ conditions: os=openbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/sunos-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/sunos-x64@npm:0.20.1"
@@ -3585,6 +3747,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/sunos-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/sunos-x64@npm:0.21.5"
+ conditions: os=sunos & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/win32-arm64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/win32-arm64@npm:0.20.1"
@@ -3592,6 +3761,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/win32-arm64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/win32-arm64@npm:0.21.5"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/win32-ia32@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/win32-ia32@npm:0.20.1"
@@ -3599,6 +3775,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/win32-ia32@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/win32-ia32@npm:0.21.5"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
"@esbuild/win32-x64@npm:0.20.1":
version: 0.20.1
resolution: "@esbuild/win32-x64@npm:0.20.1"
@@ -3606,6 +3789,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/win32-x64@npm:0.21.5":
+ version: 0.21.5
+ resolution: "@esbuild/win32-x64@npm:0.21.5"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@hapi/accept@npm:^6.0.1":
version: 6.0.3
resolution: "@hapi/accept@npm:6.0.3"
@@ -4721,6 +4911,118 @@ __metadata:
languageName: node
linkType: hard
+"@rollup/rollup-android-arm-eabi@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-android-arm-eabi@npm:4.21.2"
+ conditions: os=android & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-android-arm64@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-android-arm64@npm:4.21.2"
+ conditions: os=android & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-darwin-arm64@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-darwin-arm64@npm:4.21.2"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-darwin-x64@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-darwin-x64@npm:4.21.2"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2"
+ conditions: os=linux & cpu=arm & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-arm-musleabihf@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.21.2"
+ conditions: os=linux & cpu=arm & libc=musl
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-arm64-gnu@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.21.2"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-arm64-musl@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-arm64-musl@npm:4.21.2"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2"
+ conditions: os=linux & cpu=ppc64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-riscv64-gnu@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.21.2"
+ conditions: os=linux & cpu=riscv64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-s390x-gnu@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.2"
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-x64-gnu@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-x64-gnu@npm:4.21.2"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-linux-x64-musl@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-linux-x64-musl@npm:4.21.2"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-win32-arm64-msvc@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.21.2"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-win32-ia32-msvc@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.21.2"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@rollup/rollup-win32-x64-msvc@npm:4.21.2":
+ version: 4.21.2
+ resolution: "@rollup/rollup-win32-x64-msvc@npm:4.21.2"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@serverless/dashboard-plugin@npm:^7.2.0":
version: 7.2.0
resolution: "@serverless/dashboard-plugin@npm:7.2.0"
@@ -5958,6 +6260,20 @@ __metadata:
languageName: unknown
linkType: soft
+"@trace-stack/dashboard@workspace:packages/dashboard":
+ version: 0.0.0-use.local
+ resolution: "@trace-stack/dashboard@workspace:packages/dashboard"
+ dependencies:
+ "@types/react": "npm:^18.3.3"
+ "@types/react-dom": "npm:^18.3.0"
+ "@vitejs/plugin-react": "npm:^4.3.1"
+ globals: "npm:^15.9.0"
+ react: "npm:^18.3.1"
+ react-dom: "npm:^18.3.1"
+ vite: "npm:^5.4.1"
+ languageName: unknown
+ linkType: soft
+
"@trace-stack/lambda-layer@workspace:packages/lambda-layer/nodejs":
version: 0.0.0-use.local
resolution: "@trace-stack/lambda-layer@workspace:packages/lambda-layer/nodejs"
@@ -5968,7 +6284,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@types/babel__core@npm:^7.1.0":
+"@types/babel__core@npm:^7.1.0, @types/babel__core@npm:^7.20.5":
version: 7.20.5
resolution: "@types/babel__core@npm:7.20.5"
dependencies:
@@ -6034,6 +6350,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/estree@npm:1.0.5":
+ version: 1.0.5
+ resolution: "@types/estree@npm:1.0.5"
+ checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d
+ languageName: node
+ linkType: hard
+
"@types/graceful-fs@npm:^4.1.3":
version: 4.1.9
resolution: "@types/graceful-fs@npm:4.1.9"
@@ -6136,6 +6459,32 @@ __metadata:
languageName: node
linkType: hard
+"@types/prop-types@npm:*":
+ version: 15.7.12
+ resolution: "@types/prop-types@npm:15.7.12"
+ checksum: 10c0/1babcc7db6a1177779f8fde0ccc78d64d459906e6ef69a4ed4dd6339c920c2e05b074ee5a92120fe4e9d9f1a01c952f843ebd550bee2332fc2ef81d1706878f8
+ languageName: node
+ linkType: hard
+
+"@types/react-dom@npm:^18.3.0":
+ version: 18.3.0
+ resolution: "@types/react-dom@npm:18.3.0"
+ dependencies:
+ "@types/react": "npm:*"
+ checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b
+ languageName: node
+ linkType: hard
+
+"@types/react@npm:*, @types/react@npm:^18.3.3":
+ version: 18.3.5
+ resolution: "@types/react@npm:18.3.5"
+ dependencies:
+ "@types/prop-types": "npm:*"
+ csstype: "npm:^3.0.2"
+ checksum: 10c0/548b1d3d7c2f0242fbfdbbd658731b4ce69a134be072fa83e6ab516f2840402a3f20e3e7f72e95133b23d4880ef24a6d864050dc8e1f7c68f39fa87ca8445917
+ languageName: node
+ linkType: hard
+
"@types/responselike@npm:^1.0.0":
version: 1.0.0
resolution: "@types/responselike@npm:1.0.0"
@@ -6198,6 +6547,21 @@ __metadata:
languageName: node
linkType: hard
+"@vitejs/plugin-react@npm:^4.3.1":
+ version: 4.3.1
+ resolution: "@vitejs/plugin-react@npm:4.3.1"
+ dependencies:
+ "@babel/core": "npm:^7.24.5"
+ "@babel/plugin-transform-react-jsx-self": "npm:^7.24.5"
+ "@babel/plugin-transform-react-jsx-source": "npm:^7.24.1"
+ "@types/babel__core": "npm:^7.20.5"
+ react-refresh: "npm:^0.14.2"
+ peerDependencies:
+ vite: ^4.2.0 || ^5.0.0
+ checksum: 10c0/39a027feddfd6b3e307121d79631462ef1aae05714ba7a2f9a73d240d0f89c2bf281132568eb27b55d6ddaf08d86ad1bd8b0066090240e570de8c6320eb9a903
+ languageName: node
+ linkType: hard
+
"abab@npm:^2.0.0":
version: 2.0.6
resolution: "abab@npm:2.0.6"
@@ -8007,6 +8371,13 @@ __metadata:
languageName: node
linkType: hard
+"csstype@npm:^3.0.2":
+ version: 3.1.3
+ resolution: "csstype@npm:3.1.3"
+ checksum: 10c0/80c089d6f7e0c5b2bd83cf0539ab41474198579584fa10d86d0cafe0642202343cbc119e076a0b1aece191989477081415d66c9fefbf3c957fc2fc4b7009f248
+ languageName: node
+ linkType: hard
+
"d@npm:1, d@npm:^1.0.1":
version: 1.0.1
resolution: "d@npm:1.0.1"
@@ -8800,6 +9171,86 @@ __metadata:
languageName: node
linkType: hard
+"esbuild@npm:^0.21.3":
+ version: 0.21.5
+ resolution: "esbuild@npm:0.21.5"
+ dependencies:
+ "@esbuild/aix-ppc64": "npm:0.21.5"
+ "@esbuild/android-arm": "npm:0.21.5"
+ "@esbuild/android-arm64": "npm:0.21.5"
+ "@esbuild/android-x64": "npm:0.21.5"
+ "@esbuild/darwin-arm64": "npm:0.21.5"
+ "@esbuild/darwin-x64": "npm:0.21.5"
+ "@esbuild/freebsd-arm64": "npm:0.21.5"
+ "@esbuild/freebsd-x64": "npm:0.21.5"
+ "@esbuild/linux-arm": "npm:0.21.5"
+ "@esbuild/linux-arm64": "npm:0.21.5"
+ "@esbuild/linux-ia32": "npm:0.21.5"
+ "@esbuild/linux-loong64": "npm:0.21.5"
+ "@esbuild/linux-mips64el": "npm:0.21.5"
+ "@esbuild/linux-ppc64": "npm:0.21.5"
+ "@esbuild/linux-riscv64": "npm:0.21.5"
+ "@esbuild/linux-s390x": "npm:0.21.5"
+ "@esbuild/linux-x64": "npm:0.21.5"
+ "@esbuild/netbsd-x64": "npm:0.21.5"
+ "@esbuild/openbsd-x64": "npm:0.21.5"
+ "@esbuild/sunos-x64": "npm:0.21.5"
+ "@esbuild/win32-arm64": "npm:0.21.5"
+ "@esbuild/win32-ia32": "npm:0.21.5"
+ "@esbuild/win32-x64": "npm:0.21.5"
+ dependenciesMeta:
+ "@esbuild/aix-ppc64":
+ optional: true
+ "@esbuild/android-arm":
+ optional: true
+ "@esbuild/android-arm64":
+ optional: true
+ "@esbuild/android-x64":
+ optional: true
+ "@esbuild/darwin-arm64":
+ optional: true
+ "@esbuild/darwin-x64":
+ optional: true
+ "@esbuild/freebsd-arm64":
+ optional: true
+ "@esbuild/freebsd-x64":
+ optional: true
+ "@esbuild/linux-arm":
+ optional: true
+ "@esbuild/linux-arm64":
+ optional: true
+ "@esbuild/linux-ia32":
+ optional: true
+ "@esbuild/linux-loong64":
+ optional: true
+ "@esbuild/linux-mips64el":
+ optional: true
+ "@esbuild/linux-ppc64":
+ optional: true
+ "@esbuild/linux-riscv64":
+ optional: true
+ "@esbuild/linux-s390x":
+ optional: true
+ "@esbuild/linux-x64":
+ optional: true
+ "@esbuild/netbsd-x64":
+ optional: true
+ "@esbuild/openbsd-x64":
+ optional: true
+ "@esbuild/sunos-x64":
+ optional: true
+ "@esbuild/win32-arm64":
+ optional: true
+ "@esbuild/win32-ia32":
+ optional: true
+ "@esbuild/win32-x64":
+ optional: true
+ bin:
+ esbuild: bin/esbuild
+ checksum: 10c0/fa08508adf683c3f399e8a014a6382a6b65542213431e26206c0720e536b31c09b50798747c2a105a4bbba1d9767b8d3615a74c2f7bf1ddf6d836cd11eb672de
+ languageName: node
+ linkType: hard
+
"escalade@npm:^3.1.1":
version: 3.1.1
resolution: "escalade@npm:3.1.1"
@@ -9607,6 +10058,16 @@ __metadata:
languageName: node
linkType: hard
+"fsevents@npm:~2.3.3":
+ version: 2.3.3
+ resolution: "fsevents@npm:2.3.3"
+ dependencies:
+ node-gyp: "npm:latest"
+ checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
"fsevents@patch:fsevents@npm%3A^1.2.7#optional!builtin":
version: 1.2.13
resolution: "fsevents@patch:fsevents@npm%3A1.2.13#optional!builtin::version=1.2.13&hash=d11327"
@@ -9626,6 +10087,15 @@ __metadata:
languageName: node
linkType: hard
+"fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin":
+ version: 2.3.3
+ resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"
+ dependencies:
+ node-gyp: "npm:latest"
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
"function-bind@npm:^1.1.1":
version: 1.1.1
resolution: "function-bind@npm:1.1.1"
@@ -9846,6 +10316,13 @@ __metadata:
languageName: node
linkType: hard
+"globals@npm:^15.9.0":
+ version: 15.9.0
+ resolution: "globals@npm:15.9.0"
+ checksum: 10c0/de4b553e412e7e830998578d51b605c492256fb2a9273eaeec6ec9ee519f1c5aa50de57e3979911607fd7593a4066420e01d8c3d551e7a6a236e96c521aee36c
+ languageName: node
+ linkType: hard
+
"globalthis@npm:^1.0.3":
version: 1.0.4
resolution: "globalthis@npm:1.0.4"
@@ -12465,7 +12942,7 @@ __metadata:
languageName: node
linkType: hard
-"loose-envify@npm:^1.0.0":
+"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
@@ -12942,6 +13419,15 @@ __metadata:
languageName: node
linkType: hard
+"nanoid@npm:^3.3.7":
+ version: 3.3.7
+ resolution: "nanoid@npm:3.3.7"
+ bin:
+ nanoid: bin/nanoid.cjs
+ checksum: 10c0/e3fb661aa083454f40500473bb69eedb85dc160e763150b9a2c567c7e9ff560ce028a9f833123b618a6ea742e311138b591910e795614a629029e86e180660f3
+ languageName: node
+ linkType: hard
+
"nanomatch@npm:^1.2.9":
version: 1.2.13
resolution: "nanomatch@npm:1.2.13"
@@ -13823,6 +14309,17 @@ __metadata:
languageName: node
linkType: hard
+"postcss@npm:^8.4.41":
+ version: 8.4.41
+ resolution: "postcss@npm:8.4.41"
+ dependencies:
+ nanoid: "npm:^3.3.7"
+ picocolors: "npm:^1.0.1"
+ source-map-js: "npm:^1.2.0"
+ checksum: 10c0/c1828fc59e7ec1a3bf52b3a42f615dba53c67960ed82a81df6441b485fe43c20aba7f4e7c55425762fd99c594ecabbaaba8cf5b30fd79dfec5b52a9f63a2d690
+ languageName: node
+ linkType: hard
+
"prelude-ls@npm:~1.1.2":
version: 1.1.2
resolution: "prelude-ls@npm:1.1.2"
@@ -13839,6 +14336,15 @@ __metadata:
languageName: node
linkType: hard
+"prettier@npm:^3.3.3":
+ version: 3.3.3
+ resolution: "prettier@npm:3.3.3"
+ bin:
+ prettier: bin/prettier.cjs
+ checksum: 10c0/b85828b08e7505716324e4245549b9205c0cacb25342a030ba8885aba2039a115dbcf75a0b7ca3b37bc9d101ee61fab8113fc69ca3359f2a226f1ecc07ad2e26
+ languageName: node
+ linkType: hard
+
"pretty-format@npm:^24.9.0":
version: 24.9.0
resolution: "pretty-format@npm:24.9.0"
@@ -14034,6 +14540,18 @@ __metadata:
languageName: node
linkType: hard
+"react-dom@npm:^18.3.1":
+ version: 18.3.1
+ resolution: "react-dom@npm:18.3.1"
+ dependencies:
+ loose-envify: "npm:^1.1.0"
+ scheduler: "npm:^0.23.2"
+ peerDependencies:
+ react: ^18.3.1
+ checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85
+ languageName: node
+ linkType: hard
+
"react-is@npm:^16.8.4":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
@@ -14048,6 +14566,22 @@ __metadata:
languageName: node
linkType: hard
+"react-refresh@npm:^0.14.2":
+ version: 0.14.2
+ resolution: "react-refresh@npm:0.14.2"
+ checksum: 10c0/875b72ef56b147a131e33f2abd6ec059d1989854b3ff438898e4f9310bfcc73acff709445b7ba843318a953cb9424bcc2c05af2b3d80011cee28f25aef3e2ebb
+ languageName: node
+ linkType: hard
+
+"react@npm:^18.3.1":
+ version: 18.3.1
+ resolution: "react@npm:18.3.1"
+ dependencies:
+ loose-envify: "npm:^1.1.0"
+ checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3
+ languageName: node
+ linkType: hard
+
"read-pkg-up@npm:^4.0.0":
version: 4.0.0
resolution: "read-pkg-up@npm:4.0.0"
@@ -14498,6 +15032,69 @@ __metadata:
languageName: node
linkType: hard
+"rollup@npm:^4.20.0":
+ version: 4.21.2
+ resolution: "rollup@npm:4.21.2"
+ dependencies:
+ "@rollup/rollup-android-arm-eabi": "npm:4.21.2"
+ "@rollup/rollup-android-arm64": "npm:4.21.2"
+ "@rollup/rollup-darwin-arm64": "npm:4.21.2"
+ "@rollup/rollup-darwin-x64": "npm:4.21.2"
+ "@rollup/rollup-linux-arm-gnueabihf": "npm:4.21.2"
+ "@rollup/rollup-linux-arm-musleabihf": "npm:4.21.2"
+ "@rollup/rollup-linux-arm64-gnu": "npm:4.21.2"
+ "@rollup/rollup-linux-arm64-musl": "npm:4.21.2"
+ "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.21.2"
+ "@rollup/rollup-linux-riscv64-gnu": "npm:4.21.2"
+ "@rollup/rollup-linux-s390x-gnu": "npm:4.21.2"
+ "@rollup/rollup-linux-x64-gnu": "npm:4.21.2"
+ "@rollup/rollup-linux-x64-musl": "npm:4.21.2"
+ "@rollup/rollup-win32-arm64-msvc": "npm:4.21.2"
+ "@rollup/rollup-win32-ia32-msvc": "npm:4.21.2"
+ "@rollup/rollup-win32-x64-msvc": "npm:4.21.2"
+ "@types/estree": "npm:1.0.5"
+ fsevents: "npm:~2.3.2"
+ dependenciesMeta:
+ "@rollup/rollup-android-arm-eabi":
+ optional: true
+ "@rollup/rollup-android-arm64":
+ optional: true
+ "@rollup/rollup-darwin-arm64":
+ optional: true
+ "@rollup/rollup-darwin-x64":
+ optional: true
+ "@rollup/rollup-linux-arm-gnueabihf":
+ optional: true
+ "@rollup/rollup-linux-arm-musleabihf":
+ optional: true
+ "@rollup/rollup-linux-arm64-gnu":
+ optional: true
+ "@rollup/rollup-linux-arm64-musl":
+ optional: true
+ "@rollup/rollup-linux-powerpc64le-gnu":
+ optional: true
+ "@rollup/rollup-linux-riscv64-gnu":
+ optional: true
+ "@rollup/rollup-linux-s390x-gnu":
+ optional: true
+ "@rollup/rollup-linux-x64-gnu":
+ optional: true
+ "@rollup/rollup-linux-x64-musl":
+ optional: true
+ "@rollup/rollup-win32-arm64-msvc":
+ optional: true
+ "@rollup/rollup-win32-ia32-msvc":
+ optional: true
+ "@rollup/rollup-win32-x64-msvc":
+ optional: true
+ fsevents:
+ optional: true
+ bin:
+ rollup: dist/bin/rollup
+ checksum: 10c0/c9d97f7a21cde110371b2e890a31a996fee09b81e639e79372b962a9638ae653d2d24186b94632fc5dfab8a0582e1d0639dfe34b8b75051facd86915a9585a5f
+ languageName: node
+ linkType: hard
+
"rsvp@npm:^4.8.4":
version: 4.8.5
resolution: "rsvp@npm:4.8.5"
@@ -14639,6 +15236,15 @@ __metadata:
languageName: node
linkType: hard
+"scheduler@npm:^0.23.2":
+ version: 0.23.2
+ resolution: "scheduler@npm:0.23.2"
+ dependencies:
+ loose-envify: "npm:^1.1.0"
+ checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78
+ languageName: node
+ linkType: hard
+
"seek-bzip@npm:^1.0.5":
version: 1.0.6
resolution: "seek-bzip@npm:1.0.6"
@@ -15128,6 +15734,13 @@ __metadata:
languageName: node
linkType: hard
+"source-map-js@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "source-map-js@npm:1.2.0"
+ checksum: 10c0/7e5f896ac10a3a50fe2898e5009c58ff0dc102dcb056ed27a354623a0ece8954d4b2649e1a1b2b52ef2e161d26f8859c7710350930751640e71e374fe2d321a4
+ languageName: node
+ linkType: hard
+
"source-map-resolve@npm:^0.5.0":
version: 0.5.3
resolution: "source-map-resolve@npm:0.5.3"
@@ -15875,6 +16488,8 @@ __metadata:
"trace-stack@workspace:.":
version: 0.0.0-use.local
resolution: "trace-stack@workspace:."
+ dependencies:
+ prettier: "npm:^3.3.3"
languageName: unknown
linkType: soft
@@ -16385,6 +17000,49 @@ __metadata:
languageName: node
linkType: hard
+"vite@npm:^5.4.1":
+ version: 5.4.2
+ resolution: "vite@npm:5.4.2"
+ dependencies:
+ esbuild: "npm:^0.21.3"
+ fsevents: "npm:~2.3.3"
+ postcss: "npm:^8.4.41"
+ rollup: "npm:^4.20.0"
+ peerDependencies:
+ "@types/node": ^18.0.0 || >=20.0.0
+ less: "*"
+ lightningcss: ^1.21.0
+ sass: "*"
+ sass-embedded: "*"
+ stylus: "*"
+ sugarss: "*"
+ terser: ^5.4.0
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ peerDependenciesMeta:
+ "@types/node":
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ bin:
+ vite: bin/vite.js
+ checksum: 10c0/23e347ca8aa6f0a774227e4eb7abae228f12c6806a727b046aa75e7ee37ffc2d68cff74360e12a42c347f79adc294e2363bc723b957bf4b382b5a8fb39e4df9d
+ languageName: node
+ linkType: hard
+
"w3c-hr-time@npm:^1.0.1":
version: 1.0.2
resolution: "w3c-hr-time@npm:1.0.2"