mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 14:25:02 +00:00
Compare commits
90 Commits
copilot/cl
...
codex/fix-
| Author | SHA1 | Date | |
|---|---|---|---|
| 5c2f15ec12 | |||
| f8efac1188 | |||
| f3b1058d62 | |||
| dc3b2bdfe4 | |||
| 92e9b870fa | |||
| 427f502a3d | |||
| c852289a06 | |||
| a173b41d4b | |||
| 38237123cf | |||
| 0457cbcd61 | |||
| d0dbf45d24 | |||
| 1f88b32d0c | |||
| 6268cbb4bd | |||
| 5d880c6c3b | |||
| 9f10d771d2 | |||
| bc1b8de3e0 | |||
| 21d45bc559 | |||
| df40166a60 | |||
| 3f12f2d23a | |||
| 3f5f9d66cc | |||
| 3265d06737 | |||
| 4d46410015 | |||
| 71a2d784bd | |||
| f8577072cb | |||
| 72be29b288 | |||
| a6e427647c | |||
| b7e6234c38 | |||
| dbfbb32188 | |||
| 50cd5c40b2 | |||
| d305b25c76 | |||
| bccb33e2ba | |||
| 0be0fe9301 | |||
| b9f62c7b5d | |||
| a9d500b940 | |||
| 41d24f94c9 | |||
| c6dc552023 | |||
| bf9bfcf843 | |||
| d0be4da56c | |||
| c2997c915a | |||
| 83d9c16094 | |||
| e2092d146d | |||
| b134f3f8d4 | |||
| 977a2a9e58 | |||
| 89270e1d7e | |||
| cb942f77e7 | |||
| 4918627d42 | |||
| fb38b5b304 | |||
| 8d7d2691b0 | |||
| fbe1f7721f | |||
| f3f60a09a2 | |||
| fd556ad3ee | |||
| 65143eb904 | |||
| f788ade4ab | |||
| cdf022e9c7 | |||
| 7584253a9d | |||
| d4285d10d4 | |||
| 6b31c9df6a | |||
| a60f5ee064 | |||
| 6a9762b99e | |||
| ad5e86c97f | |||
| 1e4f902847 | |||
| 836eb6a086 | |||
| d0ffe58ef5 | |||
| a87b1043dc | |||
| 7e66010928 | |||
| c27843f576 | |||
| e6c368bfbe | |||
| 555589d9a8 | |||
| 3d7061ca3f | |||
| e10feca62c | |||
| ad9fb27e66 | |||
| 4d1ac45b19 | |||
| dfb2ddf337 | |||
| 35e2b02ec1 | |||
| d3f4d6b8d4 | |||
| 75de014884 | |||
| c0e38f393f | |||
| 3092cf5578 | |||
| 7243f29f19 | |||
| b56554287b | |||
| ee67f916e1 | |||
| 9dffeff73d | |||
|
|
5e3a913988 | ||
|
|
56171929b6 | ||
|
|
f955d0d200 | ||
|
|
d2d382a765 | ||
|
|
c8593119b2 | ||
|
|
3970ef22fd | ||
|
|
3ef908051c | ||
| a146c74a2c |
43
.claude/settings.local.json
Normal file
43
.claude/settings.local.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git mv:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(find:*)",
|
||||
"Bash(npm run test:unit:*)",
|
||||
"Bash(npm install:*)",
|
||||
"Bash(xargs:*)",
|
||||
"Bash(npm run db:generate:*)",
|
||||
"Bash(npx prisma generate:*)",
|
||||
"Bash(DATABASE_URL=\"file:./dev.db\" npx prisma generate:*)",
|
||||
"Bash(git rm:*)",
|
||||
"Bash(git log:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(xargs git rm:*)",
|
||||
"Bash(bun add:*)",
|
||||
"Bash(bun install:*)",
|
||||
"Bash(test -f:*)",
|
||||
"Bash(bun run typecheck:*)",
|
||||
"Bash(bun run test:unit:*)",
|
||||
"Bash(echo:*)",
|
||||
"Bash(npx prisma validate:*)",
|
||||
"Bash(npm run typecheck:*)",
|
||||
"Bash(npm run lint)",
|
||||
"Bash(npm audit:*)",
|
||||
"Bash(bun run lint)",
|
||||
"Bash(git checkout:*)",
|
||||
"Bash(bun audit:*)",
|
||||
"Bash(git restore:*)",
|
||||
"Bash(bunx playwright:*)",
|
||||
"Bash(timeout 30 bun run build:*)",
|
||||
"Bash(bun run lint:fix:*)",
|
||||
"Bash(bun run format:*)",
|
||||
"Bash(while read file)",
|
||||
"Bash(do eslint:*)",
|
||||
"Bash(done)",
|
||||
"Bash(eslint:*)",
|
||||
"Bash(bunx eslint:*)",
|
||||
"Bash(bun test:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -98,3 +98,4 @@ todos*.json
|
||||
vite.config.ts.bak*
|
||||
.cache/
|
||||
dist-old/
|
||||
.vscode/claudesync.json
|
||||
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -57,5 +57,7 @@
|
||||
"https://docs.github.com/*": true,
|
||||
"https://www.npmjs.com/*": true,
|
||||
"https://registry.npmjs.org/*": true
|
||||
}
|
||||
},
|
||||
"claudeCode.allowDangerouslySkipPermissions": true,
|
||||
"claudeCode.initialPermissionMode": "bypassPermissions"
|
||||
}
|
||||
95
dbal/shared/api/schema/entities/core/ui_page.yaml
Normal file
95
dbal/shared/api/schema/entities/core/ui_page.yaml
Normal file
@@ -0,0 +1,95 @@
|
||||
entity: UIPage
|
||||
version: "1.0"
|
||||
description: "Declarative JSON-based UI page definitions"
|
||||
|
||||
fields:
|
||||
id:
|
||||
type: uuid
|
||||
primary: true
|
||||
generated: true
|
||||
|
||||
path:
|
||||
type: string
|
||||
required: true
|
||||
unique: true
|
||||
max_length: 500
|
||||
description: "URL path for this page (e.g., /login, /dashboard)"
|
||||
|
||||
title:
|
||||
type: string
|
||||
required: true
|
||||
max_length: 255
|
||||
|
||||
level:
|
||||
type: integer
|
||||
required: true
|
||||
min: 1
|
||||
max: 6
|
||||
description: "Navigation level (1-6)"
|
||||
|
||||
require_auth:
|
||||
type: boolean
|
||||
required: true
|
||||
default: false
|
||||
|
||||
required_role:
|
||||
type: string
|
||||
optional: true
|
||||
max_length: 50
|
||||
description: "Required role to access (user, moderator, admin, god, supergod)"
|
||||
|
||||
layout:
|
||||
type: json
|
||||
required: true
|
||||
description: "Component tree definition (type, props, children)"
|
||||
|
||||
actions:
|
||||
type: json
|
||||
optional: true
|
||||
description: "Action handlers (Lua function references)"
|
||||
|
||||
package_id:
|
||||
type: uuid
|
||||
optional: true
|
||||
foreign_key:
|
||||
entity: Package
|
||||
field: id
|
||||
description: "Package this page belongs to"
|
||||
|
||||
is_active:
|
||||
type: boolean
|
||||
required: true
|
||||
default: true
|
||||
description: "Whether this page is currently active/published"
|
||||
|
||||
created_at:
|
||||
type: datetime
|
||||
generated: true
|
||||
immutable: true
|
||||
|
||||
updated_at:
|
||||
type: datetime
|
||||
auto_update: true
|
||||
|
||||
created_by:
|
||||
type: uuid
|
||||
optional: true
|
||||
foreign_key:
|
||||
entity: User
|
||||
field: id
|
||||
|
||||
indexes:
|
||||
- fields: [path]
|
||||
unique: true
|
||||
- fields: [level, is_active]
|
||||
- fields: [package_id]
|
||||
|
||||
acl:
|
||||
create:
|
||||
role: [admin, god, supergod]
|
||||
read:
|
||||
public: true
|
||||
update:
|
||||
role: [admin, god, supergod]
|
||||
delete:
|
||||
role: [god, supergod]
|
||||
377
docs/architecture/LUA_UI_MIGRATION_STRATEGY.md
Normal file
377
docs/architecture/LUA_UI_MIGRATION_STRATEGY.md
Normal file
@@ -0,0 +1,377 @@
|
||||
# Lua UI Migration Strategy
|
||||
|
||||
## Vision
|
||||
Transform MetaBuilder into a **lean framework that loads Lua code** by migrating UI boilerplate from React/TypeScript to Lua packages.
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### Statistics
|
||||
- **401 React components** in the codebase
|
||||
- **0 Lua UI definition files** currently
|
||||
- **UI already defined in packages** (TypeScript schemas)
|
||||
- **Lua engine operational** with Fengari runtime
|
||||
|
||||
### Existing Architecture
|
||||
```
|
||||
packages/
|
||||
└── core/
|
||||
└── package-definitions/
|
||||
├── set-a/ (forum, guestbook, spotify, youtube)
|
||||
└── set-b/ (ecommerce, irc-webchat, retro-games)
|
||||
└── irc-webchat/
|
||||
├── schema/layout.ts (UI config)
|
||||
├── actions/commands.ts
|
||||
├── actions/events.ts
|
||||
└── validation.ts
|
||||
```
|
||||
|
||||
Currently UI is defined in TypeScript but **already structured for package-based loading**.
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Create Lua UI Definition Format (Weeks 1-2)
|
||||
|
||||
#### 1.1 Define Lua UI Schema
|
||||
Create a Lua DSL for defining UI components:
|
||||
|
||||
```lua
|
||||
-- packages/ui/irc-webchat.lua
|
||||
return {
|
||||
metadata = {
|
||||
id = "irc-webchat",
|
||||
version = "1.0.0",
|
||||
name = "IRC Webchat",
|
||||
description = "Real-time chat interface"
|
||||
},
|
||||
|
||||
pages = {
|
||||
{
|
||||
id = "page_chat",
|
||||
path = "/chat",
|
||||
title = "IRC Webchat",
|
||||
level = 2,
|
||||
requiresAuth = true,
|
||||
requiredRole = "user",
|
||||
|
||||
components = {
|
||||
{
|
||||
id = "comp_chat_root",
|
||||
type = "IRCWebchat",
|
||||
props = {
|
||||
channelName = "general",
|
||||
maxMessages = 100,
|
||||
enableEmoji = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
components = {
|
||||
IRCWebchat = {
|
||||
defaultProps = {
|
||||
channelName = "general",
|
||||
theme = "dark"
|
||||
},
|
||||
validation = {
|
||||
channelName = { type = "string", required = true },
|
||||
maxMessages = { type = "number", min = 1, max = 1000 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 Create Lua-to-React Bridge
|
||||
**New:** `src/lib/lua/ui/lua-ui-loader.ts`
|
||||
|
||||
```typescript
|
||||
import { executeLuaScript } from '@/lib/lua/engine/execute'
|
||||
import type { PackageContent } from '@/lib/packages/package-types'
|
||||
|
||||
export async function loadLuaUIPackage(
|
||||
luaSource: string
|
||||
): Promise<Pick<PackageContent, 'pages' | 'componentConfigs'>> {
|
||||
// Execute Lua and convert to TypeScript types
|
||||
const result = await executeLuaScript(luaSource, {
|
||||
sandbox: true,
|
||||
timeout: 5000
|
||||
})
|
||||
|
||||
return convertLuaToUISchema(result)
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 TypeScript Type Definitions for Lua UI
|
||||
**New:** `src/lib/lua/ui/types.ts`
|
||||
|
||||
```typescript
|
||||
export interface LuaUIMetadata {
|
||||
id: string
|
||||
version: string
|
||||
name: string
|
||||
description: string
|
||||
}
|
||||
|
||||
export interface LuaUIPage {
|
||||
id: string
|
||||
path: string
|
||||
title: string
|
||||
level: number
|
||||
requiresAuth?: boolean
|
||||
requiredRole?: string
|
||||
components: LuaUIComponent[]
|
||||
}
|
||||
|
||||
export interface LuaUIComponent {
|
||||
id: string
|
||||
type: string
|
||||
props: Record<string, unknown>
|
||||
children?: LuaUIComponent[]
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 2: Package Storage System (Weeks 2-3)
|
||||
|
||||
#### 2.1 Lua Package Store in Database
|
||||
Add Lua packages to the database schema:
|
||||
|
||||
```typescript
|
||||
// New table in Prisma schema
|
||||
model LuaPackage {
|
||||
id String @id @default(uuid())
|
||||
packageId String @unique
|
||||
version String
|
||||
name String
|
||||
category String // 'ui', 'action', 'validation'
|
||||
luaSource String @db.Text // Lua code
|
||||
metadata Json
|
||||
|
||||
tenantId String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([tenantId, category])
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 Package Installation Flow
|
||||
```typescript
|
||||
// src/lib/packages/lua/install-lua-package.ts
|
||||
export async function installLuaPackage(params: {
|
||||
packageId: string
|
||||
luaSource: string
|
||||
category: 'ui' | 'action' | 'validation'
|
||||
tenantId: string
|
||||
}) {
|
||||
// 1. Validate Lua syntax
|
||||
await validateLuaSyntax(params.luaSource)
|
||||
|
||||
// 2. Execute in sandbox to extract metadata
|
||||
const metadata = await extractPackageMetadata(params.luaSource)
|
||||
|
||||
// 3. Store in database
|
||||
await db.luaPackage.create({
|
||||
data: {
|
||||
packageId: params.packageId,
|
||||
luaSource: params.luaSource,
|
||||
category: params.category,
|
||||
metadata,
|
||||
tenantId: params.tenantId,
|
||||
version: metadata.version,
|
||||
name: metadata.name
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: Migration of Existing Packages (Weeks 3-5)
|
||||
|
||||
#### Priority Order
|
||||
|
||||
**Tier 1: Simple UI Packages (Week 3)**
|
||||
- Guestbook Retro
|
||||
- Forum Classic
|
||||
- Spotify Clone UI
|
||||
|
||||
**Tier 2: Medium Complexity (Week 4)**
|
||||
- IRC Webchat
|
||||
- YouTube Clone
|
||||
- Ecommerce Basic
|
||||
|
||||
**Tier 3: Complex Packages (Week 5)**
|
||||
- Retro Games
|
||||
- Package Manager UI
|
||||
- Nerd Mode IDE
|
||||
|
||||
#### Migration Template
|
||||
|
||||
For each package:
|
||||
1. Create `packages/lua-ui/{package-name}.lua`
|
||||
2. Convert TypeScript UI schema to Lua DSL
|
||||
3. Write migration tests
|
||||
4. Update package loader to support both formats
|
||||
5. Gradually deprecate TypeScript version
|
||||
|
||||
### Phase 4: Component Abstraction Layer (Weeks 5-6)
|
||||
|
||||
#### 4.1 Core React Components Become "Primitives"
|
||||
|
||||
Keep minimal React components as building blocks:
|
||||
- Form controls (Input, Button, Select)
|
||||
- Layout containers (Box, Stack, Grid)
|
||||
- Data display (Table, List, Card)
|
||||
|
||||
All composition defined in Lua.
|
||||
|
||||
#### 4.2 Component Registry
|
||||
```lua
|
||||
-- Lua can reference registered React components
|
||||
local form = Component.create("Form", {
|
||||
children = {
|
||||
Component.create("Input", { name = "username", label = "Username" }),
|
||||
Component.create("Button", { type = "submit", text = "Login" })
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Maps to React component registry:
|
||||
```typescript
|
||||
const ComponentRegistry = {
|
||||
Form: FormPrimitive,
|
||||
Input: InputPrimitive,
|
||||
Button: ButtonPrimitive,
|
||||
// ... primitives only
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 5: Runtime Package Loading (Weeks 6-7)
|
||||
|
||||
#### 5.1 Dynamic Package Loader
|
||||
```typescript
|
||||
// src/lib/packages/lua/runtime-loader.ts
|
||||
export async function loadPackageAtRuntime(packageId: string) {
|
||||
// 1. Fetch from database or cache
|
||||
const luaPackage = await fetchLuaPackage(packageId)
|
||||
|
||||
// 2. Execute Lua to get UI definition
|
||||
const uiDef = await loadLuaUIPackage(luaPackage.luaSource)
|
||||
|
||||
// 3. Generate React components on-the-fly
|
||||
return generateComponentTree(uiDef)
|
||||
}
|
||||
```
|
||||
|
||||
#### 5.2 Hot Reload Support
|
||||
Lua packages can be updated without rebuilding the framework:
|
||||
- Update Lua code in database
|
||||
- Invalidate cache
|
||||
- UI automatically reflects changes
|
||||
|
||||
### Phase 6: Developer Experience (Weeks 7-8)
|
||||
|
||||
#### 6.1 Lua Package Development Environment
|
||||
- **Lua Editor** with syntax highlighting (Monaco)
|
||||
- **Live Preview** of UI changes
|
||||
- **Validation** feedback
|
||||
- **Version Control** for packages
|
||||
|
||||
#### 6.2 Package Publishing Flow
|
||||
1. Write Lua UI package in browser
|
||||
2. Test in sandbox
|
||||
3. Publish to tenant
|
||||
4. Package becomes available to all users
|
||||
|
||||
## Benefits
|
||||
|
||||
### 1. **Radical Reduction in Build Artifacts**
|
||||
- From 401 React components → ~20-30 primitive components
|
||||
- UI defined in database, not compiled code
|
||||
- Faster builds, smaller bundles
|
||||
|
||||
### 2. **Runtime Flexibility**
|
||||
- Update UI without deploying
|
||||
- Per-tenant customization
|
||||
- A/B testing at the package level
|
||||
|
||||
### 3. **User Empowerment**
|
||||
- Advanced users can create packages
|
||||
- Share packages across tenants
|
||||
- Package marketplace potential
|
||||
|
||||
### 4. **True Multi-Tenancy**
|
||||
- Each tenant can have different package versions
|
||||
- Custom branding via Lua
|
||||
- Isolated package updates
|
||||
|
||||
### 5. **Simplified Architecture**
|
||||
```
|
||||
BEFORE:
|
||||
TypeScript Components → Build → Bundle → Deploy
|
||||
|
||||
AFTER:
|
||||
Lua Packages → Database → Runtime Load → Render
|
||||
```
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
### Foundation
|
||||
- [ ] Create Lua UI DSL specification
|
||||
- [ ] Implement Lua-to-React bridge
|
||||
- [ ] Add LuaPackage database model
|
||||
- [ ] Create package validation system
|
||||
|
||||
### Core Functionality
|
||||
- [ ] Implement runtime package loader
|
||||
- [ ] Create component registry system
|
||||
- [ ] Build package installation API
|
||||
- [ ] Add package version management
|
||||
|
||||
### Migration
|
||||
- [ ] Migrate 3 simple packages (Tier 1)
|
||||
- [ ] Migrate 3 medium packages (Tier 2)
|
||||
- [ ] Migrate complex packages (Tier 3)
|
||||
- [ ] Remove deprecated TypeScript packages
|
||||
|
||||
### Developer Experience
|
||||
- [ ] Lua package editor UI
|
||||
- [ ] Live preview system
|
||||
- [ ] Package testing framework
|
||||
- [ ] Documentation & examples
|
||||
|
||||
### Production Readiness
|
||||
- [ ] Performance optimization
|
||||
- [ ] Caching strategy
|
||||
- [ ] Error handling & recovery
|
||||
- [ ] Security review & sandboxing
|
||||
|
||||
## Success Metrics
|
||||
|
||||
1. **Code Reduction:** 401 → 30 components (-92%)
|
||||
2. **Package Count:** 8 packages successfully running from Lua
|
||||
3. **Build Time:** Reduce by >50%
|
||||
4. **Bundle Size:** Reduce by >60%
|
||||
5. **Deploy Frequency:** UI updates without deploy
|
||||
|
||||
## Timeline
|
||||
|
||||
**8 weeks total** for full migration:
|
||||
- Weeks 1-2: Foundation & DSL
|
||||
- Weeks 3-5: Package migration
|
||||
- Weeks 6-7: Runtime & hot reload
|
||||
- Week 8: DX & polish
|
||||
|
||||
## Risk Mitigation
|
||||
|
||||
1. **Gradual Migration:** Both systems run in parallel
|
||||
2. **Feature Flags:** Toggle Lua/TypeScript per package
|
||||
3. **Rollback Plan:** Keep TypeScript packages until Lua proven
|
||||
4. **Testing:** Comprehensive e2e tests for each migrated package
|
||||
5. **Performance:** Monitor Lua execution times, add caching
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Get approval for Lua UI DSL spec
|
||||
2. Implement proof-of-concept with IRC Webchat
|
||||
3. Measure performance & user experience
|
||||
4. Decide on full migration vs. hybrid approach
|
||||
232
docs/architecture/UI_PIPELINE.md
Normal file
232
docs/architecture/UI_PIPELINE.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# UI Rendering Pipeline
|
||||
|
||||
## Complete Data Flow: JSON → Database → Lua → TSX → User
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ METABUILDER UI PIPELINE │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
Step 1: SEED DATA (JSON)
|
||||
┌────────────────────────────────────────────┐
|
||||
│ packages/ui_pages/seed/pages/login.json │
|
||||
│ { │
|
||||
│ "path": "/login", │
|
||||
│ "title": "Login", │
|
||||
│ "level": 1, │
|
||||
│ "requiresAuth": false, │
|
||||
│ "layout": { │
|
||||
│ "type": "Card", │
|
||||
│ "props": {...}, │
|
||||
│ "children": [...] │
|
||||
│ } │
|
||||
│ } │
|
||||
└────────────────────────────────────────────┘
|
||||
│
|
||||
│ import-ui-pages.ts
|
||||
▼
|
||||
Step 2: DATABASE
|
||||
┌────────────────────────────────────────────┐
|
||||
│ ui_page table │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ │ id: uuid │ │
|
||||
│ │ path: "/login" │ │
|
||||
│ │ title: "Login" │ │
|
||||
│ │ level: 1 │ │
|
||||
│ │ require_auth: false │ │
|
||||
│ │ layout: JSON {...} │ │
|
||||
│ │ actions: JSON {...} │ │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
└────────────────────────────────────────────┘
|
||||
│
|
||||
│ load-page-from-db.ts
|
||||
▼
|
||||
Step 3: LUA RUNTIME (Optional Transforms)
|
||||
┌────────────────────────────────────────────┐
|
||||
│ lua_script table │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ │ name: "/login_transformer" │ │
|
||||
│ │ code: "return transform(layout)" │ │
|
||||
│ │ category: "ui_transform" │ │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Fengari Lua 5.3 Engine │
|
||||
│ - Executes transforms │
|
||||
│ - Runs action handlers │
|
||||
│ - Security sandboxing │
|
||||
└────────────────────────────────────────────┘
|
||||
│
|
||||
│ normalize-lua-structure.ts
|
||||
▼
|
||||
Step 4: NORMALIZED JSON
|
||||
┌────────────────────────────────────────────┐
|
||||
│ UIPageData { │
|
||||
│ path: "/login", │
|
||||
│ title: "Login", │
|
||||
│ layout: { │
|
||||
│ type: "Card", │
|
||||
│ children: [ {...}, {...} ] // Arrays │
|
||||
│ }, │
|
||||
│ actions: { │
|
||||
│ handleLogin: Function │
|
||||
│ } │
|
||||
│ } │
|
||||
└────────────────────────────────────────────┘
|
||||
│
|
||||
│ UIPageRenderer.tsx
|
||||
▼
|
||||
Step 5: TSX RENDERER
|
||||
┌────────────────────────────────────────────┐
|
||||
│ generateComponentTree() │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ │ Component Registry: │ │
|
||||
│ │ - Card → @mui/material/Card │ │
|
||||
│ │ - Button → @mui/material/Button │ │
|
||||
│ │ - Input → @mui/material/TextField │ │
|
||||
│ │ - Typography → @mui/material/Typography│ │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ React.createElement() calls │
|
||||
└────────────────────────────────────────────┘
|
||||
│
|
||||
│ Next.js Server/Client Components
|
||||
▼
|
||||
Step 6: REACT VIRTUAL DOM
|
||||
┌────────────────────────────────────────────┐
|
||||
│ <Card> │
|
||||
│ <CardHeader> │
|
||||
│ <CardTitle>Welcome to MetaBuilder</CardTitle> │
|
||||
│ </CardHeader> │
|
||||
│ <CardContent> │
|
||||
│ <Input name="username" ... /> │
|
||||
│ <Button onClick={handleLogin}> │
|
||||
│ Sign In │
|
||||
│ </Button> │
|
||||
│ </CardContent> │
|
||||
│ </Card> │
|
||||
└────────────────────────────────────────────┘
|
||||
│
|
||||
│ React Reconciliation
|
||||
▼
|
||||
Step 7: USER SEES PAGE
|
||||
┌────────────────────────────────────────────┐
|
||||
│ Browser Renders UI │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────┐ │
|
||||
│ │ Welcome to MetaBuilder │ │
|
||||
│ │ │ │
|
||||
│ │ Username: [____________] │ │
|
||||
│ │ Password: [____________] │ │
|
||||
│ │ │ │
|
||||
│ │ [ Sign In ] │ │
|
||||
│ └────────────────────────────────────┘ │
|
||||
└────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
### 1. Seed Data
|
||||
```
|
||||
packages/ui_pages/
|
||||
├── seed/
|
||||
│ ├── metadata.json # Package metadata
|
||||
│ └── pages/
|
||||
│ ├── login.json # Login page definition
|
||||
│ ├── level1.json # Level 1 home page
|
||||
│ ├── level2.json # Level 2 page
|
||||
│ └── ...
|
||||
```
|
||||
|
||||
### 2. Database Schema
|
||||
```
|
||||
dbal/shared/api/schema/entities/core/
|
||||
└── ui_page.yaml # UIPage entity definition
|
||||
```
|
||||
|
||||
### 3. Importer
|
||||
```
|
||||
frontends/nextjs/src/lib/seed/
|
||||
└── import-ui-pages.ts # JSON → Database importer
|
||||
```
|
||||
|
||||
### 4. Loader
|
||||
```
|
||||
frontends/nextjs/src/lib/ui-pages/
|
||||
└── load-page-from-db.ts # Database → Lua → Normalized JSON
|
||||
```
|
||||
|
||||
### 5. Renderer
|
||||
```
|
||||
frontends/nextjs/src/components/ui-page-renderer/
|
||||
├── UIPageRenderer.tsx # TSX renderer component
|
||||
└── index.ts # Barrel export
|
||||
```
|
||||
|
||||
### 6. Route
|
||||
```
|
||||
frontends/nextjs/src/app/ui/[[...slug]]/
|
||||
└── page.tsx # Generic dynamic route
|
||||
```
|
||||
|
||||
### 7. Component Generator
|
||||
```
|
||||
frontends/nextjs/src/lib/lua/ui/
|
||||
├── generate-component-tree.tsx # JSON → React.createElement
|
||||
└── normalize-lua-structure.ts # Lua tables → JS arrays
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Define a Page (JSON)
|
||||
```json
|
||||
{
|
||||
"path": "/dashboard",
|
||||
"title": "Dashboard",
|
||||
"level": 2,
|
||||
"requiresAuth": true,
|
||||
"layout": {
|
||||
"type": "Box",
|
||||
"children": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Import to Database
|
||||
```typescript
|
||||
import { importUIPages } from '@/lib/seed/import-ui-pages'
|
||||
await importUIPages(db)
|
||||
```
|
||||
|
||||
### Access Page
|
||||
```
|
||||
Navigate to: /ui/dashboard
|
||||
│
|
||||
├─→ app/ui/[[...slug]]/page.tsx
|
||||
├─→ loadPageFromDB("/dashboard")
|
||||
├─→ UIPageRenderer
|
||||
└─→ User sees rendered page
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **No TSX Files Per Page** - Single generic renderer
|
||||
2. **Database-Driven** - Pages stored in DB, modifiable at runtime
|
||||
3. **Lua-Extensible** - Optional Lua transforms and actions
|
||||
4. **Type-Safe** - Full TypeScript types throughout
|
||||
5. **Hot-Reloadable** - Change JSON, refresh page (no rebuild)
|
||||
6. **Version Controlled** - JSON seed data in git
|
||||
7. **User-Editable** - Future: UI builder to modify pages
|
||||
|
||||
## Security
|
||||
|
||||
- **Lua Sandboxing** - Multi-layer security (scanner, environment replacement, runtime guards)
|
||||
- **ACL** - Page-level access control (requiresAuth, requiredRole)
|
||||
- **Type Safety** - TypeScript validation throughout pipeline
|
||||
- **JSON Validation** - Schema validation on import
|
||||
|
||||
## Performance
|
||||
|
||||
- **Static Generation** - Can pre-render at build time via `generateStaticParams`
|
||||
- **Database Caching** - Query optimization and caching
|
||||
- **React Server Components** - Server-side rendering by default
|
||||
- **Lazy Loading** - Components loaded on demand
|
||||
189
docs/refactoring/REFACTORING_SUMMARY.md
Normal file
189
docs/refactoring/REFACTORING_SUMMARY.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Refactoring Summary: Large TypeScript Files
|
||||
|
||||
## Overview
|
||||
Successfully addressed Development Quality Feedback by converting large TypeScript configuration to declarative JSON format, demonstrating the project's "Declarative First" architectural principle.
|
||||
|
||||
## Metrics Improvement
|
||||
|
||||
### Before
|
||||
```
|
||||
📊 Code Metrics
|
||||
- TypeScript files: 1589
|
||||
- Files >150 LOC: 31 ⚠️
|
||||
- JSON config files: 0
|
||||
- Lua scripts: 0
|
||||
- Declarative ratio: 0.0%
|
||||
```
|
||||
|
||||
### After
|
||||
```
|
||||
📊 Code Metrics
|
||||
- TypeScript files: 1589
|
||||
- Files >150 LOC: 30 ✅
|
||||
- JSON config files: 3 ✅
|
||||
- Lua scripts: 0
|
||||
- Declarative ratio: 0.2% ✅
|
||||
```
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Refactored `forms.ts` (244 → 35 lines, -86%)
|
||||
**Location**: `frontends/nextjs/src/lib/schema/default/forms.ts`
|
||||
|
||||
**Before**: 244 lines of TypeScript with hardcoded field configuration arrays
|
||||
**After**: 35 lines that load from JSON and apply validations dynamically
|
||||
|
||||
**Impact**:
|
||||
- Removed from "files >150 LOC" list
|
||||
- Net reduction: -209 lines
|
||||
- Improved maintainability: config changes don't require TypeScript recompilation
|
||||
|
||||
### 2. Created JSON Configuration Files
|
||||
**Location**: `frontends/nextjs/src/lib/schema/default/config/`
|
||||
|
||||
- `post-fields.json` (113 lines, 2.1KB) - Post model field definitions
|
||||
- `author-fields.json` (61 lines, 1.1KB) - Author model field definitions
|
||||
- `product-fields.json` (83 lines, 1.5KB) - Product model field definitions
|
||||
|
||||
### 3. Created Refactoring Helper Tool
|
||||
**Location**: `tools/refactoring/simple-refactor-helper.ts` (116 lines)
|
||||
|
||||
A minimal working script to convert TypeScript config to JSON:
|
||||
- Works around broken auto-refactor tools
|
||||
- Secure (uses `JSON.parse()` not `eval()`)
|
||||
- Reusable for similar refactorings
|
||||
- Well-documented with usage instructions
|
||||
|
||||
### 4. Fixed Orchestrate Refactor Tool
|
||||
**Location**: `tools/refactoring/cli/orchestrate-refactor.ts`
|
||||
|
||||
- Documents that auto-refactor tools have broken dependencies
|
||||
- Provides clear error messages and manual refactoring steps
|
||||
- Removes attempt to instantiate non-existent class
|
||||
|
||||
### 5. Cleanup
|
||||
- Removed 5 leftover `.backup` files (952 lines total)
|
||||
- Updated `docs/todo/LAMBDA_REFACTOR_PROGRESS.md` with latest scan
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Type Safety
|
||||
```typescript
|
||||
// Before: unsafe any[]
|
||||
const postFieldsJson = postFieldsData as any[]
|
||||
|
||||
// After: type-safe with proper Omit<>
|
||||
const postFieldsJson = postFieldsData as Omit<FieldSchema, 'validation'>[]
|
||||
```
|
||||
|
||||
### JSON Import Pattern
|
||||
```typescript
|
||||
// Import JSON configuration files as modules
|
||||
// TypeScript's resolveJsonModule option enables importing .json files as typed objects
|
||||
import postFieldsData from './config/post-fields.json'
|
||||
import authorFieldsData from './config/author-fields.json'
|
||||
import productFieldsData from './config/product-fields.json'
|
||||
```
|
||||
|
||||
### Dynamic Validation Application
|
||||
```typescript
|
||||
export const postFields: FieldSchema[] = postFieldsJson.map(field => {
|
||||
if (field.name === 'title') return { ...field, validation: postValidations.title }
|
||||
if (field.name === 'slug') return { ...field, validation: postValidations.slug }
|
||||
// ... other validations
|
||||
return field
|
||||
})
|
||||
```
|
||||
|
||||
## Code Quality
|
||||
✅ All code review comments addressed
|
||||
✅ No security vulnerabilities (no `eval()`)
|
||||
✅ Type-safe JSON imports
|
||||
✅ Clear comments and error messages
|
||||
✅ Minimal surgical changes (not a rewrite)
|
||||
|
||||
## Architectural Alignment
|
||||
|
||||
### ✅ Declarative First
|
||||
Converted imperative TypeScript arrays to declarative JSON configuration
|
||||
|
||||
### ✅ Database-Driven
|
||||
JSON configs can easily be moved to database storage for runtime updates
|
||||
|
||||
### ✅ Separation of Concerns
|
||||
- **Data**: JSON configuration files
|
||||
- **Logic**: TypeScript validation functions
|
||||
- **Glue**: TypeScript file that combines them
|
||||
|
||||
### ✅ Maintainability
|
||||
- Configuration changes don't require code changes
|
||||
- New fields can be added via JSON
|
||||
- Validation logic remains centralized
|
||||
|
||||
## Issues Discovered
|
||||
|
||||
### Auto-Refactor Tools Are Broken
|
||||
The existing refactoring tools in `tools/refactoring/` were themselves refactored following lambda-per-file pattern, but have broken references:
|
||||
|
||||
**Problems**:
|
||||
- Functions use `this` keyword but are exported as standalone functions
|
||||
- `orchestrate-refactor.ts` tries to instantiate non-existent `ASTLambdaRefactor` class
|
||||
- `error-as-todo-refactor` has duplicate exports causing build errors
|
||||
|
||||
**Solution**: Created `simple-refactor-helper.ts` as a working alternative
|
||||
|
||||
**Documentation**: Updated `orchestrate-refactor.ts` with clear error messages and manual steps
|
||||
|
||||
## Statistics
|
||||
|
||||
```
|
||||
12 files changed
|
||||
+427 additions
|
||||
-1221 deletions
|
||||
Net: -794 lines of code
|
||||
```
|
||||
|
||||
**Breakdown**:
|
||||
- Removed: 952 lines (backup files)
|
||||
- Removed: 209 lines (forms.ts simplification)
|
||||
- Added: 257 lines (JSON config files)
|
||||
- Added: 116 lines (refactor helper tool)
|
||||
- Added: 14 lines (documentation/fixes)
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Immediate Next Steps
|
||||
1. ✅ Use `simple-refactor-helper.ts` pattern for other large config files
|
||||
2. Refactor similar files: `nerd-mode-ide/templates/configs/base.ts` (267 lines)
|
||||
3. Refactor: `seed-default-data/css/categories/base.ts` (278 lines)
|
||||
|
||||
### Long-term Improvements
|
||||
1. **Move validation to Lua scripts** - Fully declarative, no TypeScript
|
||||
2. **Store JSON in database** - Enable runtime configuration updates
|
||||
3. **Fix or deprecate broken refactoring tools** - Resolve technical debt
|
||||
4. **Establish pattern** - All new features: JSON config + Lua logic
|
||||
|
||||
## Lessons Learned
|
||||
|
||||
### Tool Maintenance
|
||||
Even refactoring tools need tests to prevent breakage when refactored
|
||||
|
||||
### Pragmatic Approach
|
||||
When tools are broken, create minimal working alternatives rather than fixing everything
|
||||
|
||||
### Incremental Progress
|
||||
Small, focused refactorings (1 file) are safer than large batch operations (31 files)
|
||||
|
||||
### Documentation
|
||||
Clear error messages and manual steps help when automation fails
|
||||
|
||||
## Conclusion
|
||||
|
||||
Successfully demonstrated the "Declarative First" principle by:
|
||||
- Converting 244 lines of TypeScript config to 3 JSON files
|
||||
- Reducing files >150 LOC from 31 to 30
|
||||
- Improving declarative ratio from 0.0% to 0.2%
|
||||
- Creating reusable tooling for future refactorings
|
||||
- Maintaining all functionality with zero breaking changes
|
||||
|
||||
This is a template for future refactoring efforts in the codebase.
|
||||
@@ -1,11 +1,11 @@
|
||||
# Lambda-per-File Refactoring Progress
|
||||
|
||||
**Generated:** 2025-12-29T19:12:28.334Z
|
||||
**Generated:** 2025-12-29T21:09:00.273Z
|
||||
|
||||
## Summary
|
||||
|
||||
- **Total files > 150 lines:** 53
|
||||
- **Pending:** 43
|
||||
- **Total files > 150 lines:** 52
|
||||
- **Pending:** 42
|
||||
- **In Progress:** 0
|
||||
- **Completed:** 0
|
||||
- **Skipped:** 10
|
||||
@@ -16,7 +16,7 @@
|
||||
- **test:** 10
|
||||
- **library:** 4
|
||||
- **tool:** 4
|
||||
- **other:** 3
|
||||
- **other:** 2
|
||||
- **dbal:** 1
|
||||
|
||||
## Refactoring Queue
|
||||
@@ -30,7 +30,7 @@ Library and tool files - easiest to refactor
|
||||
- [ ] `frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/categories/base.ts` (278 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/nerd-mode-ide/templates/configs/base.ts` (267 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/schema/default/forms.ts` (244 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/db/core/operations.ts` (190 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/db/core/operations.ts` (191 lines)
|
||||
- [ ] `tools/refactoring/cli/orchestrate-refactor.ts` (213 lines)
|
||||
- [ ] `tools/refactoring/orchestrate-refactor/functions/main.ts` (186 lines)
|
||||
- [ ] `tools/refactoring/error-as-todo-refactor/index.ts` (163 lines)
|
||||
@@ -40,7 +40,7 @@ Library and tool files - easiest to refactor
|
||||
|
||||
DBAL and component files - moderate complexity
|
||||
|
||||
- [ ] `frontends/nextjs/src/lib/dbal/core/client/dbal-integration/DbalIntegrationUtils.ts` (174 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/dbal/core/client/dbal-integration/DbalIntegrationUtils.ts` (169 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/data/QuickGuide.tsx` (297 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/data/GenericPage.tsx` (274 lines)
|
||||
- [ ] `frontends/nextjs/src/components/molecules/overlay/DropdownMenu.tsx` (268 lines)
|
||||
@@ -48,7 +48,6 @@ DBAL and component files - moderate complexity
|
||||
- [ ] `frontends/nextjs/src/components/examples/ContactForm.example.tsx` (258 lines)
|
||||
- [ ] `frontends/nextjs/src/components/managers/component/ComponentHierarchyEditor.tsx` (242 lines)
|
||||
- [ ] `frontends/nextjs/src/components/managers/component/ComponentConfigDialog/Fields.tsx` (238 lines)
|
||||
- [ ] `frontends/nextjs/src/components/editors/lua/blocks/BlockItem.tsx` (218 lines)
|
||||
- [ ] `frontends/nextjs/src/components/rendering/FieldRenderer.tsx` (210 lines)
|
||||
- [ ] `frontends/nextjs/src/components/ui/organisms/data/Form.tsx` (210 lines)
|
||||
- [ ] `frontends/nextjs/src/components/level5/tabs/PowerTransferTab.tsx` (207 lines)
|
||||
@@ -60,13 +59,13 @@ DBAL and component files - moderate complexity
|
||||
- [ ] `frontends/nextjs/src/components/editors/JsonEditor.tsx` (191 lines)
|
||||
- [ ] `frontends/nextjs/src/components/rendering/components/RenderNode.tsx` (188 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/viewers/AuditLogViewer.tsx` (188 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/viewers/audit-log/Filters.tsx` (188 lines)
|
||||
- ... and 12 more
|
||||
|
||||
### Low Priority (3 files)
|
||||
### Low Priority (2 files)
|
||||
|
||||
- [ ] `frontends/nextjs/src/components/nerd-mode-ide/core/NerdModeIDE/useNerdIdeState.ts` (274 lines)
|
||||
- [ ] `frontends/nextjs/src/components/editors/lua/hooks/useLuaBlocksState/actions.ts` (208 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/demos/IRCWebchatDeclarative/functions/i-r-c-webchat-declarative.ts` (158 lines)
|
||||
|
||||
### Skipped Files (10)
|
||||
|
||||
|
||||
8
frontends/nextjs/.prettierignore
Normal file
8
frontends/nextjs/.prettierignore
Normal file
@@ -0,0 +1,8 @@
|
||||
node_modules
|
||||
.next
|
||||
dist
|
||||
build
|
||||
coverage
|
||||
*.min.js
|
||||
*.d.ts
|
||||
**/DbalIntegrationUtils.ts
|
||||
10
frontends/nextjs/.prettierrc.json
Normal file
10
frontends/nextjs/.prettierrc.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 100,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
15
frontends/nextjs/.vscode/settings.json
vendored
Normal file
15
frontends/nextjs/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true
|
||||
}
|
||||
@@ -8,39 +8,40 @@
|
||||
"@aws-sdk/client-s3": "^3.958.0",
|
||||
"@aws-sdk/lib-storage": "^3.958.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.958.0",
|
||||
"@emotion/react": "^11.13.5",
|
||||
"@emotion/styled": "^11.13.5",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@github/spark": ">=0.43.1 <1",
|
||||
"@hookform/resolvers": "^4.1.3",
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@mui/icons-material": "^6.3.1",
|
||||
"@mui/material": "^6.3.1",
|
||||
"@mui/x-data-grid": "^7.24.2",
|
||||
"@mui/x-date-pickers": "^7.24.1",
|
||||
"@mui/icons-material": "^7.3.6",
|
||||
"@mui/material": "^7.3.6",
|
||||
"@mui/x-data-grid": "^8.23.0",
|
||||
"@mui/x-date-pickers": "^8.23.0",
|
||||
"@next/third-parties": "^16.1.1",
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/core": "^7.0.6",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@prisma/client": "^6.19.1",
|
||||
"@tanstack/react-query": "^5.83.1",
|
||||
"@types/jszip": "^3.4.0",
|
||||
"@prisma/adapter-better-sqlite3": "^7.2.0",
|
||||
"@prisma/client": "^7.2.0",
|
||||
"@tanstack/react-query": "^5.90.12",
|
||||
"better-sqlite3": "^12.5.0",
|
||||
"d3": "^7.9.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"fengari-interop": "^0.1.4",
|
||||
"fengari-web": "^0.1.4",
|
||||
"framer-motion": "^12.6.2",
|
||||
"jszip": "^3.10.1",
|
||||
"marked": "^17.0.1",
|
||||
"motion": "^12.6.2",
|
||||
"next": "16.1.1",
|
||||
"octokit": "^5.0.5",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"react-error-boundary": "^6.0.0",
|
||||
"react-hook-form": "^7.69.0",
|
||||
"recharts": "^2.15.1",
|
||||
"recharts": "^3.6.0",
|
||||
"server-only": "^0.0.1",
|
||||
"sharp": "^0.34.5",
|
||||
"sonner": "^2.0.7",
|
||||
"three": "^0.175.0",
|
||||
"three": "^0.182.0",
|
||||
"uuid": "^13.0.0",
|
||||
"zod": "^4.2.1",
|
||||
},
|
||||
@@ -50,17 +51,20 @@
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/react": "^16.3.1",
|
||||
"@types/node": "^25.0.3",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react-swc": "^4.2.2",
|
||||
"@vitest/coverage-v8": "^4.0.16",
|
||||
"eslint": "^9.28.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.19",
|
||||
"eslint-plugin-react-refresh": "^0.4.26",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"globals": "^16.5.0",
|
||||
"jsdom": "^27.3.0",
|
||||
"prisma": "^6.19.1",
|
||||
"prettier": "^3.4.2",
|
||||
"prisma": "^7.2.0",
|
||||
"sass": "^1.97.1",
|
||||
"typescript": "~5.9.3",
|
||||
"typescript-eslint": "^8.50.1",
|
||||
@@ -190,6 +194,14 @@
|
||||
|
||||
"@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="],
|
||||
|
||||
"@chevrotain/cst-dts-gen": ["@chevrotain/cst-dts-gen@10.5.0", "", { "dependencies": { "@chevrotain/gast": "10.5.0", "@chevrotain/types": "10.5.0", "lodash": "4.17.21" } }, "sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw=="],
|
||||
|
||||
"@chevrotain/gast": ["@chevrotain/gast@10.5.0", "", { "dependencies": { "@chevrotain/types": "10.5.0", "lodash": "4.17.21" } }, "sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A=="],
|
||||
|
||||
"@chevrotain/types": ["@chevrotain/types@10.5.0", "", {}, "sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A=="],
|
||||
|
||||
"@chevrotain/utils": ["@chevrotain/utils@10.5.0", "", {}, "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ=="],
|
||||
|
||||
"@csstools/color-helpers": ["@csstools/color-helpers@5.1.0", "", {}, "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA=="],
|
||||
|
||||
"@csstools/css-calc": ["@csstools/css-calc@2.1.4", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4" } }, "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ=="],
|
||||
@@ -202,6 +214,12 @@
|
||||
|
||||
"@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="],
|
||||
|
||||
"@electric-sql/pglite": ["@electric-sql/pglite@0.3.2", "", {}, "sha512-zfWWa+V2ViDCY/cmUfRqeWY1yLto+EpxjXnZzenB1TyxsTiXaTWeZFIZw6mac52BsuQm0RjCnisjBtdBaXOI6w=="],
|
||||
|
||||
"@electric-sql/pglite-socket": ["@electric-sql/pglite-socket@0.0.6", "", { "peerDependencies": { "@electric-sql/pglite": "0.3.2" }, "bin": { "pglite-server": "dist/scripts/server.js" } }, "sha512-6RjmgzphIHIBA4NrMGJsjNWK4pu+bCWJlEWlwcxFTVY3WT86dFpKwbZaGWZV6C5Rd7sCk1Z0CI76QEfukLAUXw=="],
|
||||
|
||||
"@electric-sql/pglite-tools": ["@electric-sql/pglite-tools@0.2.7", "", { "peerDependencies": { "@electric-sql/pglite": "0.3.2" } }, "sha512-9dAccClqxx4cZB+Ar9B+FZ5WgxDc/Xvl9DPrTWv+dYTf0YNubLzi4wHHRGRGhrJv15XwnyKcGOZAP1VXSneSUg=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
|
||||
|
||||
"@emotion/babel-plugin": ["@emotion/babel-plugin@11.13.5", "", { "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/serialize": "^1.3.3", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", "stylis": "4.2.0" } }, "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ=="],
|
||||
@@ -302,7 +320,9 @@
|
||||
|
||||
"@github/spark": ["@github/spark@0.44.15", "", { "dependencies": { "body-parser": "^1.20.3", "express": "^5.2.0", "octokit": "^5.0.3" }, "peerDependencies": { "react": "^19.0.0", "vite": "^7.0.0 || ^6.4.1" } }, "sha512-3FVJIdyd0eJ8kHvaM8M0zVFZOq8ZBJm5nTBb9y6qxTjLNq+D/ejxedMTnK1cAj9U48YHIlQKv6O97ahvacOAKw=="],
|
||||
|
||||
"@hookform/resolvers": ["@hookform/resolvers@4.1.3", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.0.0" } }, "sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ=="],
|
||||
"@hono/node-server": ["@hono/node-server@1.19.6", "", { "peerDependencies": { "hono": "^4" } }, "sha512-Shz/KjlIeAhfiuE93NDKVdZ7HdBVLQAfdbaXEaoAVO3ic9ibRSLGIQGkcBbFyuLr+7/1D5ZCINM8B+6IvXeMtw=="],
|
||||
|
||||
"@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
||||
@@ -374,27 +394,31 @@
|
||||
|
||||
"@monaco-editor/react": ["@monaco-editor/react@4.7.0", "", { "dependencies": { "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA=="],
|
||||
|
||||
"@mui/core-downloads-tracker": ["@mui/core-downloads-tracker@6.5.0", "", {}, "sha512-LGb8t8i6M2ZtS3Drn3GbTI1DVhDY6FJ9crEey2lZ0aN2EMZo8IZBZj9wRf4vqbZHaWjsYgtbOnJw5V8UWbmK2Q=="],
|
||||
"@mrleebo/prisma-ast": ["@mrleebo/prisma-ast@0.12.1", "", { "dependencies": { "chevrotain": "^10.5.0", "lilconfig": "^2.1.0" } }, "sha512-JwqeCQ1U3fvccttHZq7Tk0m/TMC6WcFAQZdukypW3AzlJYKYTGNVd1ANU2GuhKnv4UQuOFj3oAl0LLG/gxFN1w=="],
|
||||
|
||||
"@mui/icons-material": ["@mui/icons-material@6.5.0", "", { "dependencies": { "@babel/runtime": "^7.26.0" }, "peerDependencies": { "@mui/material": "^6.5.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-VPuPqXqbBPlcVSA0BmnoE4knW4/xG6Thazo8vCLWkOKusko6DtwFV6B665MMWJ9j0KFohTIf3yx2zYtYacvG1g=="],
|
||||
"@mui/core-downloads-tracker": ["@mui/core-downloads-tracker@7.3.6", "", {}, "sha512-QaYtTHlr8kDFN5mE1wbvVARRKH7Fdw1ZuOjBJcFdVpfNfRYKF3QLT4rt+WaB6CKJvpqxRsmEo0kpYinhH5GeHg=="],
|
||||
|
||||
"@mui/material": ["@mui/material@6.5.0", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mui/core-downloads-tracker": "^6.5.0", "@mui/system": "^6.5.0", "@mui/types": "~7.2.24", "@mui/utils": "^6.4.9", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^19.0.0", "react-transition-group": "^4.4.5" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@mui/material-pigment-css": "^6.5.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@mui/material-pigment-css"] }, "sha512-yjvtXoFcrPLGtgKRxFaH6OQPtcLPhkloC0BML6rBG5UeldR0nPULR/2E2BfXdo5JNV7j7lOzrrLX2Qf/iSidow=="],
|
||||
"@mui/icons-material": ["@mui/icons-material@7.3.6", "", { "dependencies": { "@babel/runtime": "^7.28.4" }, "peerDependencies": { "@mui/material": "^7.3.6", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-0FfkXEj22ysIq5pa41A2NbcAhJSvmcZQ/vcTIbjDsd6hlslG82k5BEBqqS0ZJprxwIL3B45qpJ+bPHwJPlF7uQ=="],
|
||||
|
||||
"@mui/private-theming": ["@mui/private-theming@6.4.9", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mui/utils": "^6.4.9", "prop-types": "^15.8.1" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw=="],
|
||||
"@mui/material": ["@mui/material@7.3.6", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/core-downloads-tracker": "^7.3.6", "@mui/system": "^7.3.6", "@mui/types": "^7.4.9", "@mui/utils": "^7.3.6", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^19.2.0", "react-transition-group": "^4.4.5" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@mui/material-pigment-css": "^7.3.6", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled", "@mui/material-pigment-css", "@types/react"] }, "sha512-R4DaYF3dgCQCUAkr4wW1w26GHXcf5rCmBRHVBuuvJvaGLmZdD8EjatP80Nz5JCw0KxORAzwftnHzXVnjR8HnFw=="],
|
||||
|
||||
"@mui/styled-engine": ["@mui/styled-engine@6.5.0", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@emotion/cache": "^11.13.5", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-8woC2zAqF4qUDSPIBZ8v3sakj+WgweolpyM/FXf8jAx6FMls+IE4Y8VDZc+zS805J7PRz31vz73n2SovKGaYgw=="],
|
||||
"@mui/private-theming": ["@mui/private-theming@7.3.6", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/utils": "^7.3.6", "prop-types": "^15.8.1" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-Ws9wZpqM+FlnbZXaY/7yvyvWQo1+02Tbx50mVdNmzWEi51C51y56KAbaDCYyulOOBL6BJxuaqG8rNNuj7ivVyw=="],
|
||||
|
||||
"@mui/system": ["@mui/system@6.5.0", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mui/private-theming": "^6.4.9", "@mui/styled-engine": "^6.5.0", "@mui/types": "~7.2.24", "@mui/utils": "^6.4.9", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-XcbBYxDS+h/lgsoGe78ExXFZXtuIlSBpn/KsZq8PtZcIkUNJInkuDqcLd2rVBQrDC1u+rvVovdaWPf2FHKJf3w=="],
|
||||
"@mui/styled-engine": ["@mui/styled-engine@7.3.6", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled"] }, "sha512-+wiYbtvj+zyUkmDB+ysH6zRjuQIJ+CM56w0fEXV+VDNdvOuSywG+/8kpjddvvlfMLsaWdQe5oTuYGBcodmqGzQ=="],
|
||||
|
||||
"@mui/types": ["@mui/types@7.2.24", "", { "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw=="],
|
||||
"@mui/system": ["@mui/system@7.3.6", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/private-theming": "^7.3.6", "@mui/styled-engine": "^7.3.6", "@mui/types": "^7.4.9", "@mui/utils": "^7.3.6", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled", "@types/react"] }, "sha512-8fehAazkHNP1imMrdD2m2hbA9sl7Ur6jfuNweh5o4l9YPty4iaZzRXqYvBCWQNwFaSHmMEj2KPbyXGp7Bt73Rg=="],
|
||||
|
||||
"@mui/utils": ["@mui/utils@6.4.9", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mui/types": "~7.2.24", "@types/prop-types": "^15.7.14", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.0.0" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg=="],
|
||||
"@mui/types": ["@mui/types@7.4.9", "", { "dependencies": { "@babel/runtime": "^7.28.4" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-dNO8Z9T2cujkSIaCnWwprfeKmTWh97cnjkgmpFJ2sbfXLx8SMZijCYHOtP/y5nnUb/Rm2omxbDMmtUoSaUtKaw=="],
|
||||
|
||||
"@mui/x-data-grid": ["@mui/x-data-grid@7.29.12", "", { "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0", "@mui/x-internals": "7.29.0", "clsx": "^2.1.1", "prop-types": "^15.8.1", "reselect": "^5.1.1", "use-sync-external-store": "^1.0.0" }, "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-MaEC7ubr/je8jVWjdRU7LxBXAzlOZwFEdNdvlDUJIYkRa3TRCQ1HsY8Gd8Od0jnlnMYn9M4BrEfOrq9VRnt4bw=="],
|
||||
"@mui/utils": ["@mui/utils@7.3.6", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/types": "^7.4.9", "@types/prop-types": "^15.7.15", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.2.0" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-jn+Ba02O6PiFs7nKva8R2aJJ9kJC+3kQ2R0BbKNY3KQQ36Qng98GnPRFTlbwYTdMD6hLEBKaMLUktyg/rTfd2w=="],
|
||||
|
||||
"@mui/x-date-pickers": ["@mui/x-date-pickers@7.29.4", "", { "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0", "@mui/x-internals": "7.29.0", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0", "date-fns": "^2.25.0 || ^3.2.0 || ^4.0.0", "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0", "dayjs": "^1.10.7", "luxon": "^3.0.2", "moment": "^2.29.4", "moment-hijri": "^2.1.2 || ^3.0.0", "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["date-fns-jalali", "dayjs", "luxon", "moment", "moment-hijri", "moment-jalaali"] }, "sha512-wJ3tsqk/y6dp+mXGtT9czciAMEO5Zr3IIAHg9x6IL0Eqanqy0N3chbmQQZv3iq0m2qUpQDLvZ4utZBUTJdjNzw=="],
|
||||
"@mui/x-data-grid": ["@mui/x-data-grid@8.23.0", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/utils": "^7.3.5", "@mui/x-internals": "8.23.0", "@mui/x-virtualizer": "0.3.0", "clsx": "^2.1.1", "prop-types": "^15.8.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled"] }, "sha512-fv8AiibTgwPKJsXtYdc5bYDDW3EQp/ieQ0iUejvZ2JbYikMIPTYjI4pHy7zW3F3RDsi6DGQnw5AW6LeoDcT0fA=="],
|
||||
|
||||
"@mui/x-internals": ["@mui/x-internals@7.29.0", "", { "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA=="],
|
||||
"@mui/x-date-pickers": ["@mui/x-date-pickers@8.23.0", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/utils": "^7.3.5", "@mui/x-internals": "8.23.0", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0", "date-fns": "^2.25.0 || ^3.2.0 || ^4.0.0", "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0", "dayjs": "^1.10.7", "luxon": "^3.0.2", "moment": "^2.29.4", "moment-hijri": "^2.1.2 || ^3.0.0", "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled", "date-fns", "date-fns-jalali", "dayjs", "luxon", "moment", "moment-hijri", "moment-jalaali"] }, "sha512-uKtam5wqMEuErmRxZLPEX/7CZZFTMfrl05V9cWNjBkpGTcdDBIs1Kba8z2pfQU93e9lSLrRlxbCMJzCu6iF0Rg=="],
|
||||
|
||||
"@mui/x-internals": ["@mui/x-internals@8.23.0", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/utils": "^7.3.5", "reselect": "^5.1.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-FN7wdqwTxqq1tJBYVz8TA/HMcViuaHS0Jphr4pEjT/8Iuf94Yt3P82WbsTbXyYrgOQDQl07UqE7qWcJetRcHcg=="],
|
||||
|
||||
"@mui/x-virtualizer": ["@mui/x-virtualizer@0.3.0", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/utils": "^7.3.5", "@mui/x-internals": "8.23.0" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-ScQ3xullKQAtbIT9N7PVhgW9BDTo2Hu8fr/+N08TdRMJcq8bsVJB25mlcHk6zxjlgCuojqaeGfw71S1FOvyCXQ=="],
|
||||
|
||||
"@next/env": ["@next/env@16.1.1", "", {}, "sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA=="],
|
||||
|
||||
@@ -426,15 +450,15 @@
|
||||
|
||||
"@octokit/auth-oauth-user": ["@octokit/auth-oauth-user@6.0.2", "", { "dependencies": { "@octokit/auth-oauth-device": "^8.0.3", "@octokit/oauth-methods": "^6.0.2", "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-qLoPPc6E6GJoz3XeDG/pnDhJpTkODTGG4kY0/Py154i/I003O9NazkrwJwRuzgCalhzyIeWQ+6MDvkUmKXjg/A=="],
|
||||
|
||||
"@octokit/auth-token": ["@octokit/auth-token@5.1.2", "", {}, "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw=="],
|
||||
"@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
|
||||
|
||||
"@octokit/auth-unauthenticated": ["@octokit/auth-unauthenticated@7.0.3", "", { "dependencies": { "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0" } }, "sha512-8Jb1mtUdmBHL7lGmop9mU9ArMRUTRhg8vp0T1VtZ4yd9vEm3zcLwmjQkhNEduKawOOORie61xhtYIhTDN+ZQ3g=="],
|
||||
|
||||
"@octokit/core": ["@octokit/core@6.1.6", "", { "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.2.2", "@octokit/request": "^9.2.3", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "before-after-hook": "^3.0.2", "universal-user-agent": "^7.0.0" } }, "sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA=="],
|
||||
"@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="],
|
||||
|
||||
"@octokit/endpoint": ["@octokit/endpoint@10.1.4", "", { "dependencies": { "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA=="],
|
||||
"@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/graphql": ["@octokit/graphql@8.2.2", "", { "dependencies": { "@octokit/request": "^9.2.3", "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-Yi8hcoqsrXGdt0yObxbebHXFOiUA+2v3n53epuOg1QUgOB6c4XzvisBNVXJSl8RYA5KrDuSL2yq9Qmqe5N0ryA=="],
|
||||
"@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="],
|
||||
|
||||
"@octokit/oauth-app": ["@octokit/oauth-app@8.0.3", "", { "dependencies": { "@octokit/auth-oauth-app": "^9.0.2", "@octokit/auth-oauth-user": "^6.0.1", "@octokit/auth-unauthenticated": "^7.0.2", "@octokit/core": "^7.0.5", "@octokit/oauth-authorization-url": "^8.0.0", "@octokit/oauth-methods": "^6.0.1", "@types/aws-lambda": "^8.10.83", "universal-user-agent": "^7.0.0" } }, "sha512-jnAjvTsPepyUaMu9e69hYBuozEPgYqP4Z3UnpmvoIzHDpf8EXDGvTY1l1jK0RsZ194oRd+k6Hm13oRU8EoDFwg=="],
|
||||
|
||||
@@ -442,7 +466,7 @@
|
||||
|
||||
"@octokit/oauth-methods": ["@octokit/oauth-methods@6.0.2", "", { "dependencies": { "@octokit/oauth-authorization-url": "^8.0.0", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0" } }, "sha512-HiNOO3MqLxlt5Da5bZbLV8Zarnphi4y9XehrbaFMkcoJ+FL7sMxH/UlUsCVxpddVu4qvNDrBdaTVE2o4ITK8ng=="],
|
||||
|
||||
"@octokit/openapi-types": ["@octokit/openapi-types@25.1.0", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="],
|
||||
"@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/openapi-webhooks-types": ["@octokit/openapi-webhooks-types@12.1.0", "", {}, "sha512-WiuzhOsiOvb7W3Pvmhf8d2C6qaLHXrWiLBP4nJ/4kydu+wpagV5Fkz9RfQwV2afYzv3PB+3xYgp4mAdNGjDprA=="],
|
||||
|
||||
@@ -456,11 +480,11 @@
|
||||
|
||||
"@octokit/plugin-throttling": ["@octokit/plugin-throttling@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "bottleneck": "^2.15.3" }, "peerDependencies": { "@octokit/core": "^7.0.0" } }, "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg=="],
|
||||
|
||||
"@octokit/request": ["@octokit/request@9.2.4", "", { "dependencies": { "@octokit/endpoint": "^10.1.4", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "fast-content-type-parse": "^2.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-q8ybdytBmxa6KogWlNa818r0k1wlqzNC+yNkcQDECHvQo8Vmstrg18JwqJHdJdUiHD2sjlwBgSm9kHkOKe2iyA=="],
|
||||
"@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/request-error": ["@octokit/request-error@6.1.8", "", { "dependencies": { "@octokit/types": "^14.0.0" } }, "sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ=="],
|
||||
"@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/types": ["@octokit/types@14.1.0", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
|
||||
"@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/webhooks": ["@octokit/webhooks@14.2.0", "", { "dependencies": { "@octokit/openapi-webhooks-types": "12.1.0", "@octokit/request-error": "^7.0.0", "@octokit/webhooks-methods": "^6.0.0" } }, "sha512-da6KbdNCV5sr1/txD896V+6W0iamFWrvVl8cHkBSPT+YlvmT3DwXa4jxZnQc+gnuTEqSWbBeoSZYTayXH9wXcw=="],
|
||||
|
||||
@@ -500,19 +524,33 @@
|
||||
|
||||
"@popperjs/core": ["@popperjs/core@2.11.8", "", {}, "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="],
|
||||
|
||||
"@prisma/client": ["@prisma/client@6.19.1", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" } }, "sha512-4SXj4Oo6HyQkLUWT8Ke5R0PTAfVOKip5Roo+6+b2EDTkFg5be0FnBWiuRJc0BC0sRQIWGMLKW1XguhVfW/z3/A=="],
|
||||
"@prisma/adapter-better-sqlite3": ["@prisma/adapter-better-sqlite3@7.2.0", "", { "dependencies": { "@prisma/driver-adapter-utils": "7.2.0", "better-sqlite3": "^12.4.5" } }, "sha512-ZowCgDOnv0nk0VIUSPp6y8ns+wXRctVADPSu/vluznAYDx/Xy0dK4nTr7+7XVX/XqUrPPtOYdCBELwjEklS8vQ=="],
|
||||
|
||||
"@prisma/config": ["@prisma/config@6.19.1", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-bUL/aYkGXLwxVGhJmQMtslLT7KPEfUqmRa919fKI4wQFX4bIFUKiY8Jmio/2waAjjPYrtuDHa7EsNCnJTXxiOw=="],
|
||||
"@prisma/client": ["@prisma/client@7.2.0", "", { "dependencies": { "@prisma/client-runtime-utils": "7.2.0" }, "peerDependencies": { "prisma": "*", "typescript": ">=5.4.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-JdLF8lWZ+LjKGKpBqyAlenxd/kXjd1Abf/xK+6vUA7R7L2Suo6AFTHFRpPSdAKCan9wzdFApsUpSa/F6+t1AtA=="],
|
||||
|
||||
"@prisma/debug": ["@prisma/debug@6.19.1", "", {}, "sha512-h1JImhlAd/s5nhY/e9qkAzausWldbeT+e4nZF7A4zjDYBF4BZmKDt4y0jK7EZapqOm1kW7V0e9agV/iFDy3fWw=="],
|
||||
"@prisma/client-runtime-utils": ["@prisma/client-runtime-utils@7.2.0", "", {}, "sha512-dn7oB53v0tqkB0wBdMuTNFNPdEbfICEUe82Tn9FoKAhJCUkDH+fmyEp0ClciGh+9Hp2Tuu2K52kth2MTLstvmA=="],
|
||||
|
||||
"@prisma/engines": ["@prisma/engines@6.19.1", "", { "dependencies": { "@prisma/debug": "6.19.1", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/fetch-engine": "6.19.1", "@prisma/get-platform": "6.19.1" } }, "sha512-xy95dNJ7DiPf9IJ3oaVfX785nbFl7oNDzclUF+DIiJw6WdWCvPl0LPU0YqQLsrwv8N64uOQkH391ujo3wSo+Nw=="],
|
||||
"@prisma/config": ["@prisma/config@7.2.0", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-qmvSnfQ6l/srBW1S7RZGfjTQhc44Yl3ldvU6y3pgmuLM+83SBDs6UQVgMtQuMRe9J3gGqB0RF8wER6RlXEr6jQ=="],
|
||||
|
||||
"@prisma/engines-version": ["@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "", {}, "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA=="],
|
||||
"@prisma/debug": ["@prisma/debug@7.2.0", "", {}, "sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw=="],
|
||||
|
||||
"@prisma/fetch-engine": ["@prisma/fetch-engine@6.19.1", "", { "dependencies": { "@prisma/debug": "6.19.1", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/get-platform": "6.19.1" } }, "sha512-mmgcotdaq4VtAHO6keov3db+hqlBzQS6X7tR7dFCbvXjLVTxBYdSJFRWz+dq7F9p6dvWyy1X0v8BlfRixyQK6g=="],
|
||||
"@prisma/dev": ["@prisma/dev@0.17.0", "", { "dependencies": { "@electric-sql/pglite": "0.3.2", "@electric-sql/pglite-socket": "0.0.6", "@electric-sql/pglite-tools": "0.2.7", "@hono/node-server": "1.19.6", "@mrleebo/prisma-ast": "0.12.1", "@prisma/get-platform": "6.8.2", "@prisma/query-plan-executor": "6.18.0", "foreground-child": "3.3.1", "get-port-please": "3.1.2", "hono": "4.10.6", "http-status-codes": "2.3.0", "pathe": "2.0.3", "proper-lockfile": "4.1.2", "remeda": "2.21.3", "std-env": "3.9.0", "valibot": "1.2.0", "zeptomatch": "2.0.2" } }, "sha512-6sGebe5jxX+FEsQTpjHLzvOGPn6ypFQprcs3jcuIWv1Xp/5v6P/rjfdvAwTkP2iF6pDx2tCd8vGLNWcsWzImTA=="],
|
||||
|
||||
"@prisma/get-platform": ["@prisma/get-platform@6.19.1", "", { "dependencies": { "@prisma/debug": "6.19.1" } }, "sha512-zsg44QUiQAnFUyh6Fbt7c9HjMXHwFTqtrgcX7DAZmRgnkPyYT7Sh8Mn8D5PuuDYNtMOYcpLGg576MLfIORsBYw=="],
|
||||
"@prisma/driver-adapter-utils": ["@prisma/driver-adapter-utils@7.2.0", "", { "dependencies": { "@prisma/debug": "7.2.0" } }, "sha512-gzrUcbI9VmHS24Uf+0+7DNzdIw7keglJsD5m/MHxQOU68OhGVzlphQRobLiDMn8CHNA2XN8uugwKjudVtnfMVQ=="],
|
||||
|
||||
"@prisma/engines": ["@prisma/engines@7.2.0", "", { "dependencies": { "@prisma/debug": "7.2.0", "@prisma/engines-version": "7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3", "@prisma/fetch-engine": "7.2.0", "@prisma/get-platform": "7.2.0" } }, "sha512-HUeOI/SvCDsHrR9QZn24cxxZcujOjcS3w1oW/XVhnSATAli5SRMOfp/WkG3TtT5rCxDA4xOnlJkW7xkho4nURA=="],
|
||||
|
||||
"@prisma/engines-version": ["@prisma/engines-version@7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3", "", {}, "sha512-KezsjCZDsbjNR7SzIiVlUsn9PnLePI7r5uxABlwL+xoerurZTfgQVbIjvjF2sVr3Uc0ZcsnREw3F84HvbggGdA=="],
|
||||
|
||||
"@prisma/fetch-engine": ["@prisma/fetch-engine@7.2.0", "", { "dependencies": { "@prisma/debug": "7.2.0", "@prisma/engines-version": "7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3", "@prisma/get-platform": "7.2.0" } }, "sha512-Z5XZztJ8Ap+wovpjPD2lQKnB8nWFGNouCrglaNFjxIWAGWz0oeHXwUJRiclIoSSXN/ptcs9/behptSk8d0Yy6w=="],
|
||||
|
||||
"@prisma/get-platform": ["@prisma/get-platform@6.8.2", "", { "dependencies": { "@prisma/debug": "6.8.2" } }, "sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow=="],
|
||||
|
||||
"@prisma/query-plan-executor": ["@prisma/query-plan-executor@6.18.0", "", {}, "sha512-jZ8cfzFgL0jReE1R10gT8JLHtQxjWYLiQ//wHmVYZ2rVkFHoh0DT8IXsxcKcFlfKN7ak7k6j0XMNn2xVNyr5cA=="],
|
||||
|
||||
"@prisma/studio-core": ["@prisma/studio-core@0.9.0", "", { "peerDependencies": { "@types/react": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-xA2zoR/ADu/NCSQuriBKTh6Ps4XjU0bErkEcgMfnSGh346K1VI7iWKnoq1l2DoxUqiddPHIEWwtxJ6xCHG6W7g=="],
|
||||
|
||||
"@reduxjs/toolkit": ["@reduxjs/toolkit@2.11.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0", "immer": "^11.0.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "reselect": "^5.1.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" }, "optionalPeers": ["react", "react-redux"] }, "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ=="],
|
||||
|
||||
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.47", "", {}, "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw=="],
|
||||
|
||||
@@ -732,8 +770,6 @@
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/jszip": ["@types/jszip@3.4.0", "", { "dependencies": { "jszip": "*" } }, "sha512-GFHqtQQP3R4NNuvZH3hNCYD0NbyBZ42bkN7kO3NDrU/SnvIZWMS8Bp38XCsRKBT5BXvgm0y1zqpZWp/ZkRzBzg=="],
|
||||
|
||||
"@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="],
|
||||
|
||||
"@types/parse-json": ["@types/parse-json@4.0.2", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="],
|
||||
@@ -748,6 +784,8 @@
|
||||
|
||||
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
||||
|
||||
"@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.50.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.50.1", "@typescript-eslint/type-utils": "8.50.1", "@typescript-eslint/utils": "8.50.1", "@typescript-eslint/visitor-keys": "8.50.1", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.50.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw=="],
|
||||
|
||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.50.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.50.1", "@typescript-eslint/types": "8.50.1", "@typescript-eslint/typescript-estree": "8.50.1", "@typescript-eslint/visitor-keys": "8.50.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg=="],
|
||||
@@ -826,6 +864,8 @@
|
||||
|
||||
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
||||
|
||||
"aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="],
|
||||
|
||||
"babel-plugin-macros": ["babel-plugin-macros@3.1.0", "", { "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" } }, "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg=="],
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
@@ -834,10 +874,16 @@
|
||||
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.9.11", "", { "bin": "dist/cli.js" }, "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ=="],
|
||||
|
||||
"before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="],
|
||||
"before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||
|
||||
"better-sqlite3": ["better-sqlite3@12.5.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-WwCZ/5Diz7rsF29o27o0Gcc1Du+l7Zsv7SYtVPG0X3G/uUI1LqdxrQI7c9Hs2FWpqXXERjW9hp6g3/tH7DlVKg=="],
|
||||
|
||||
"bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
|
||||
|
||||
"bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="],
|
||||
|
||||
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
|
||||
|
||||
"body-parser": ["body-parser@1.20.4", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.14.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA=="],
|
||||
|
||||
"bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="],
|
||||
@@ -868,8 +914,12 @@
|
||||
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"chevrotain": ["chevrotain@10.5.0", "", { "dependencies": { "@chevrotain/cst-dts-gen": "10.5.0", "@chevrotain/gast": "10.5.0", "@chevrotain/types": "10.5.0", "@chevrotain/utils": "10.5.0", "lodash": "4.17.21", "regexp-to-ast": "0.5.0" } }, "sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A=="],
|
||||
|
||||
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
||||
|
||||
"chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
|
||||
|
||||
"citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="],
|
||||
|
||||
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
|
||||
@@ -980,7 +1030,7 @@
|
||||
|
||||
"data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
|
||||
|
||||
"date-fns": ["date-fns@3.6.0", "", {}, "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww=="],
|
||||
"date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
@@ -988,6 +1038,10 @@
|
||||
|
||||
"decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="],
|
||||
|
||||
"decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="],
|
||||
|
||||
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
|
||||
|
||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||
|
||||
"deepmerge-ts": ["deepmerge-ts@7.1.5", "", {}, "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw=="],
|
||||
@@ -1000,6 +1054,8 @@
|
||||
|
||||
"delaunator": ["delaunator@5.0.1", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw=="],
|
||||
|
||||
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
||||
|
||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||
|
||||
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
|
||||
@@ -1018,7 +1074,7 @@
|
||||
|
||||
"dompurify": ["dompurify@3.2.7", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw=="],
|
||||
|
||||
"dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
|
||||
"dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
|
||||
|
||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||
|
||||
@@ -1030,6 +1086,8 @@
|
||||
|
||||
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
||||
|
||||
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
||||
|
||||
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="],
|
||||
@@ -1052,6 +1110,8 @@
|
||||
|
||||
"es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
|
||||
|
||||
"es-toolkit": ["es-toolkit@1.43.0", "", {}, "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA=="],
|
||||
|
||||
"esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": "bin/esbuild" }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="],
|
||||
|
||||
"escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
|
||||
@@ -1066,6 +1126,8 @@
|
||||
|
||||
"eslint-plugin-react-refresh": ["eslint-plugin-react-refresh@0.4.26", "", { "peerDependencies": { "eslint": ">=8.40" } }, "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ=="],
|
||||
|
||||
"eslint-plugin-simple-import-sort": ["eslint-plugin-simple-import-sort@12.1.1", "", { "peerDependencies": { "eslint": ">=5.0.0" } }, "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
||||
|
||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
|
||||
@@ -1084,10 +1146,12 @@
|
||||
|
||||
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
|
||||
|
||||
"eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="],
|
||||
"eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
|
||||
|
||||
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
|
||||
|
||||
"expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
|
||||
|
||||
"expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
|
||||
|
||||
"express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
|
||||
@@ -1096,12 +1160,10 @@
|
||||
|
||||
"fast-check": ["fast-check@3.23.2", "", { "dependencies": { "pure-rand": "^6.1.0" } }, "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A=="],
|
||||
|
||||
"fast-content-type-parse": ["fast-content-type-parse@2.0.1", "", {}, "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="],
|
||||
"fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||
|
||||
"fast-equals": ["fast-equals@5.4.0", "", {}, "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw=="],
|
||||
|
||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||
|
||||
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
||||
@@ -1118,6 +1180,8 @@
|
||||
|
||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||
|
||||
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
|
||||
|
||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||
|
||||
"finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="],
|
||||
@@ -1132,12 +1196,16 @@
|
||||
|
||||
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
||||
|
||||
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
|
||||
|
||||
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
|
||||
|
||||
"framer-motion": ["framer-motion@12.23.26", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA=="],
|
||||
|
||||
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
|
||||
|
||||
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
@@ -1146,16 +1214,22 @@
|
||||
|
||||
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
|
||||
|
||||
"generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="],
|
||||
|
||||
"generator-function": ["generator-function@2.0.1", "", {}, "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g=="],
|
||||
|
||||
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||
|
||||
"get-port-please": ["get-port-please@3.1.2", "", {}, "sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ=="],
|
||||
|
||||
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
||||
|
||||
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
|
||||
|
||||
"giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": "dist/cli.mjs" }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
|
||||
|
||||
"github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
|
||||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="],
|
||||
@@ -1164,6 +1238,10 @@
|
||||
|
||||
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"grammex": ["grammex@3.1.12", "", {}, "sha512-6ufJOsSA7LcQehIJNCO7HIBykfM7DXQual0Ny780/DEcJIpBlHRvcqEBWGPYd7hrXL2GJ3oJI1MIhaXjWmLQOQ=="],
|
||||
|
||||
"has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
|
||||
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
@@ -1180,6 +1258,8 @@
|
||||
|
||||
"hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="],
|
||||
|
||||
"hono": ["hono@4.10.6", "", {}, "sha512-BIdolzGpDO9MQ4nu3AUuDwHZZ+KViNm+EZ75Ae55eMXMqLVhDFqEMXxtUe9Qh8hjL+pIna/frs2j6Y2yD5Ua/g=="],
|
||||
|
||||
"html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="],
|
||||
|
||||
"html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="],
|
||||
@@ -1188,6 +1268,8 @@
|
||||
|
||||
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
|
||||
|
||||
"http-status-codes": ["http-status-codes@2.3.0", "", {}, "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA=="],
|
||||
|
||||
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
@@ -1198,6 +1280,8 @@
|
||||
|
||||
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
|
||||
|
||||
"immer": ["immer@10.2.0", "", {}, "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw=="],
|
||||
|
||||
"immutable": ["immutable@5.1.4", "", {}, "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA=="],
|
||||
|
||||
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
||||
@@ -1206,6 +1290,8 @@
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
|
||||
|
||||
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
|
||||
|
||||
"internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
|
||||
@@ -1250,6 +1336,8 @@
|
||||
|
||||
"is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
|
||||
|
||||
"is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="],
|
||||
|
||||
"is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
|
||||
|
||||
"is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="],
|
||||
@@ -1310,6 +1398,8 @@
|
||||
|
||||
"lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
|
||||
|
||||
"lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
|
||||
|
||||
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
||||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
@@ -1318,10 +1408,14 @@
|
||||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
||||
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||
|
||||
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
|
||||
|
||||
"lru-cache": ["lru-cache@11.2.4", "", {}, "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg=="],
|
||||
|
||||
"lru.min": ["lru.min@1.1.3", "", {}, "sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q=="],
|
||||
|
||||
"lz-string": ["lz-string@1.5.0", "", { "bin": "bin/bin.js" }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
@@ -1346,24 +1440,40 @@
|
||||
|
||||
"mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
|
||||
|
||||
"mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
|
||||
|
||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||
|
||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||
|
||||
"mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
|
||||
|
||||
"monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="],
|
||||
|
||||
"motion": ["motion@12.23.26", "", { "dependencies": { "framer-motion": "^12.23.26", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Ll8XhVxY8LXMVYTCfme27WH2GjBrCIzY4+ndr5QKxsK+YwCtOi2B/oBi5jcIbik5doXuWT/4KKDOVAZJkeY5VQ=="],
|
||||
|
||||
"motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="],
|
||||
|
||||
"motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"mysql2": ["mysql2@3.15.3", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg=="],
|
||||
|
||||
"named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
|
||||
"napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
|
||||
|
||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||
|
||||
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||
|
||||
"next": ["next@16.1.1", "", { "dependencies": { "@next/env": "16.1.1", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.1", "@next/swc-darwin-x64": "16.1.1", "@next/swc-linux-arm64-gnu": "16.1.1", "@next/swc-linux-arm64-musl": "16.1.1", "@next/swc-linux-x64-gnu": "16.1.1", "@next/swc-linux-x64-musl": "16.1.1", "@next/swc-win32-arm64-msvc": "16.1.1", "@next/swc-win32-x64-msvc": "16.1.1", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "babel-plugin-react-compiler"], "bin": "dist/bin/next" }, "sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w=="],
|
||||
|
||||
"node-abi": ["node-abi@3.85.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg=="],
|
||||
|
||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
||||
|
||||
"node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
|
||||
@@ -1442,18 +1552,28 @@
|
||||
|
||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||
|
||||
"postgres": ["postgres@3.4.7", "", {}, "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw=="],
|
||||
|
||||
"prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="],
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.7.4", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA=="],
|
||||
|
||||
"pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="],
|
||||
|
||||
"prisma": ["prisma@6.19.1", "", { "dependencies": { "@prisma/config": "6.19.1", "@prisma/engines": "6.19.1" }, "peerDependencies": { "typescript": ">=5.1.0" }, "bin": "build/index.js" }, "sha512-XRfmGzh6gtkc/Vq3LqZJcS2884dQQW3UhPo6jNRoiTW95FFQkXFg8vkYEy6og+Pyv0aY7zRQ7Wn1Cvr56XjhQQ=="],
|
||||
"prisma": ["prisma@7.2.0", "", { "dependencies": { "@prisma/config": "7.2.0", "@prisma/dev": "0.17.0", "@prisma/engines": "7.2.0", "@prisma/studio-core": "0.9.0", "mysql2": "3.15.3", "postgres": "3.4.7" }, "peerDependencies": { "better-sqlite3": ">=9.0.0", "typescript": ">=5.4.0" }, "optionalPeers": ["better-sqlite3", "typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-jSdHWgWOgFF24+nRyyNRVBIgGDQEsMEF8KPHvhBBg3jWyR9fUAK0Nq9ThUmiGlNgq2FA7vSk/ZoCvefod+a8qg=="],
|
||||
|
||||
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
||||
|
||||
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
||||
|
||||
"proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="],
|
||||
|
||||
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
||||
|
||||
"pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
|
||||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
"pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="],
|
||||
@@ -1464,6 +1584,8 @@
|
||||
|
||||
"raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="],
|
||||
|
||||
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
|
||||
|
||||
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
|
||||
|
||||
"react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
|
||||
@@ -1476,7 +1598,7 @@
|
||||
|
||||
"react-is": ["react-is@19.2.3", "", {}, "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA=="],
|
||||
|
||||
"react-smooth": ["react-smooth@4.0.4", "", { "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q=="],
|
||||
"react-redux": ["react-redux@9.2.0", "", { "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "@types/react": "^18.2.25 || ^19", "react": "^18.0 || ^19", "redux": "^5.0.0" }, "optionalPeers": ["@types/react", "redux"] }, "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g=="],
|
||||
|
||||
"react-transition-group": ["react-transition-group@4.4.5", "", { "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" }, "peerDependencies": { "react": ">=16.6.0", "react-dom": ">=16.6.0" } }, "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="],
|
||||
|
||||
@@ -1486,14 +1608,20 @@
|
||||
|
||||
"readline-sync": ["readline-sync@1.4.10", "", {}, "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw=="],
|
||||
|
||||
"recharts": ["recharts@2.15.4", "", { "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", "lodash": "^4.17.21", "react-is": "^18.3.1", "react-smooth": "^4.0.4", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw=="],
|
||||
"recharts": ["recharts@3.6.0", "", { "dependencies": { "@reduxjs/toolkit": "1.x.x || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-L5bjxvQRAe26RlToBAziKUB7whaGKEwD3znoM6fz3DrTowCIC/FnJYnuq1GEzB8Zv2kdTfaxQfi5GoH0tBinyg=="],
|
||||
|
||||
"recharts-scale": ["recharts-scale@0.4.5", "", { "dependencies": { "decimal.js-light": "^2.4.1" } }, "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w=="],
|
||||
"redux": ["redux@5.0.1", "", {}, "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="],
|
||||
|
||||
"redux-thunk": ["redux-thunk@3.1.0", "", { "peerDependencies": { "redux": "^5.0.0" } }, "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw=="],
|
||||
|
||||
"reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="],
|
||||
|
||||
"regexp-to-ast": ["regexp-to-ast@0.5.0", "", {}, "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw=="],
|
||||
|
||||
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
|
||||
|
||||
"remeda": ["remeda@2.21.3", "", { "dependencies": { "type-fest": "^4.39.1" } }, "sha512-XXrZdLA10oEOQhLLzEJEiFFSKi21REGAkHdImIb4rt/XXy8ORGXh5HCcpUOsElfPNDb+X6TA/+wkh+p2KffYmg=="],
|
||||
|
||||
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
||||
|
||||
"reselect": ["reselect@5.1.1", "", {}, "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w=="],
|
||||
@@ -1502,6 +1630,8 @@
|
||||
|
||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||
|
||||
"retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="],
|
||||
|
||||
"robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="],
|
||||
|
||||
"rollup": ["rollup@4.54.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.54.0", "@rollup/rollup-android-arm64": "4.54.0", "@rollup/rollup-darwin-arm64": "4.54.0", "@rollup/rollup-darwin-x64": "4.54.0", "@rollup/rollup-freebsd-arm64": "4.54.0", "@rollup/rollup-freebsd-x64": "4.54.0", "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", "@rollup/rollup-linux-arm-musleabihf": "4.54.0", "@rollup/rollup-linux-arm64-gnu": "4.54.0", "@rollup/rollup-linux-arm64-musl": "4.54.0", "@rollup/rollup-linux-loong64-gnu": "4.54.0", "@rollup/rollup-linux-ppc64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-musl": "4.54.0", "@rollup/rollup-linux-s390x-gnu": "4.54.0", "@rollup/rollup-linux-x64-gnu": "4.54.0", "@rollup/rollup-linux-x64-musl": "4.54.0", "@rollup/rollup-openharmony-arm64": "4.54.0", "@rollup/rollup-win32-arm64-msvc": "4.54.0", "@rollup/rollup-win32-ia32-msvc": "4.54.0", "@rollup/rollup-win32-x64-gnu": "4.54.0", "@rollup/rollup-win32-x64-msvc": "4.54.0", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw=="],
|
||||
@@ -1530,6 +1660,8 @@
|
||||
|
||||
"send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="],
|
||||
|
||||
"seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="],
|
||||
|
||||
"serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="],
|
||||
|
||||
"server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="],
|
||||
@@ -1560,6 +1692,12 @@
|
||||
|
||||
"siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
|
||||
|
||||
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
||||
|
||||
"simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="],
|
||||
|
||||
"simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
|
||||
|
||||
"sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="],
|
||||
|
||||
"source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="],
|
||||
@@ -1568,6 +1706,8 @@
|
||||
|
||||
"sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
|
||||
|
||||
"sqlstring": ["sqlstring@2.3.3", "", {}, "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="],
|
||||
|
||||
"stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
|
||||
|
||||
"state-local": ["state-local@1.0.7", "", {}, "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="],
|
||||
@@ -1606,9 +1746,13 @@
|
||||
|
||||
"symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
|
||||
|
||||
"tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
|
||||
|
||||
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
||||
|
||||
"third-party-capital": ["third-party-capital@1.0.20", "", {}, "sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA=="],
|
||||
|
||||
"three": ["three@0.175.0", "", {}, "sha512-nNE3pnTHxXN/Phw768u0Grr7W4+rumGg/H6PgeseNJojkJtmeHJfZWi41Gp2mpXl1pg1pf1zjwR4McM1jTqkpg=="],
|
||||
"three": ["three@0.182.0", "", {}, "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ=="],
|
||||
|
||||
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
|
||||
|
||||
@@ -1640,8 +1784,12 @@
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
||||
|
||||
"type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
|
||||
|
||||
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
|
||||
@@ -1674,9 +1822,11 @@
|
||||
|
||||
"uuid": ["uuid@13.0.0", "", { "bin": "dist-node/bin/uuid" }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="],
|
||||
|
||||
"valibot": ["valibot@1.2.0", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg=="],
|
||||
|
||||
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
|
||||
|
||||
"victory-vendor": ["victory-vendor@36.9.2", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ=="],
|
||||
"victory-vendor": ["victory-vendor@37.3.6", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ=="],
|
||||
|
||||
"vite": ["vite@7.3.0", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["less", "lightningcss", "sass-embedded", "stylus", "sugarss", "terser", "tsx"], "bin": "bin/vite.js" }, "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg=="],
|
||||
|
||||
@@ -1718,6 +1868,8 @@
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"zeptomatch": ["zeptomatch@2.0.2", "", { "dependencies": { "grammex": "^3.1.10" } }, "sha512-H33jtSKf8Ijtb5BW6wua3G5DhnFjbFML36eFu+VdOoVY4HD9e7ggjqdM6639B+L87rjnR6Y+XeRzBXZdy52B/g=="],
|
||||
|
||||
"zod": ["zod@4.2.1", "", {}, "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw=="],
|
||||
|
||||
"@aws-crypto/sha1-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
|
||||
@@ -1730,54 +1882,18 @@
|
||||
|
||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"@octokit/app/@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="],
|
||||
|
||||
"@octokit/app/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/auth-app/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/auth-app/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/auth-app/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/auth-oauth-app/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/auth-oauth-app/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/auth-oauth-device/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/auth-oauth-device/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/auth-oauth-user/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/auth-oauth-user/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/auth-unauthenticated/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/auth-unauthenticated/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="],
|
||||
|
||||
"@octokit/oauth-methods/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/oauth-methods/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/oauth-methods/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/plugin-retry/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/plugin-retry/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/plugin-throttling/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/webhooks/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@parcel/watcher/detect-libc": ["detect-libc@1.0.3", "", { "bin": "bin/detect-libc.js" }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||
|
||||
"@prisma/dev/std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="],
|
||||
|
||||
"@prisma/engines/@prisma/get-platform": ["@prisma/get-platform@7.2.0", "", { "dependencies": { "@prisma/debug": "7.2.0" } }, "sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA=="],
|
||||
|
||||
"@prisma/fetch-engine/@prisma/get-platform": ["@prisma/get-platform@7.2.0", "", { "dependencies": { "@prisma/debug": "7.2.0" } }, "sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA=="],
|
||||
|
||||
"@prisma/get-platform/@prisma/debug": ["@prisma/debug@6.8.2", "", {}, "sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg=="],
|
||||
|
||||
"@reduxjs/toolkit/immer": ["immer@11.1.3", "", {}, "sha512-6jQTc5z0KJFtr1UgFpIL3N9XSC3saRaI9PwWtzM2pSqkNGtiNkYY2OSwkOGDK2XcTRcLb1pi/aNkKZz0nxVH4Q=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
@@ -1788,18 +1904,20 @@
|
||||
|
||||
"babel-plugin-macros/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
|
||||
|
||||
"bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||
|
||||
"body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||
|
||||
"body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
|
||||
|
||||
"c12/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
|
||||
|
||||
"c12/magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="],
|
||||
|
||||
"chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"cosmiconfig/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
|
||||
|
||||
"d3-dsv/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
||||
"express/body-parser": ["body-parser@2.2.1", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw=="],
|
||||
|
||||
"express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
|
||||
@@ -1812,13 +1930,11 @@
|
||||
|
||||
"monaco-editor/marked": ["marked@14.0.0", "", { "bin": "bin/marked.js" }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="],
|
||||
|
||||
"mysql2/iconv-lite": ["iconv-lite@0.7.1", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw=="],
|
||||
|
||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||
|
||||
"octokit/@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="],
|
||||
|
||||
"octokit/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"octokit/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
"node-abi/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||
|
||||
"playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
|
||||
|
||||
@@ -1826,9 +1942,11 @@
|
||||
|
||||
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||
|
||||
"proper-lockfile/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
||||
|
||||
"raw-body/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
|
||||
|
||||
"recharts/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
|
||||
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
||||
|
||||
"rollup/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
|
||||
|
||||
@@ -1840,14 +1958,10 @@
|
||||
|
||||
"stream-browserify/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||
|
||||
"tinyglobby/fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
"tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||
|
||||
"type-is/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||
|
||||
"vitest/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
|
||||
"which-builtin-type/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
|
||||
|
||||
"@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="],
|
||||
@@ -1856,78 +1970,6 @@
|
||||
|
||||
"@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="],
|
||||
|
||||
"@octokit/app/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
|
||||
|
||||
"@octokit/app/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="],
|
||||
|
||||
"@octokit/app/@octokit/core/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/app/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/app/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||
|
||||
"@octokit/app/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/auth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/auth-app/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"@octokit/auth-app/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/auth-oauth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/auth-oauth-app/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/auth-oauth-app/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"@octokit/auth-oauth-app/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/auth-oauth-device/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/auth-oauth-device/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/auth-oauth-device/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"@octokit/auth-oauth-device/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/auth-oauth-user/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/auth-oauth-user/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/auth-oauth-user/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"@octokit/auth-oauth-user/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/auth-unauthenticated/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||
|
||||
"@octokit/oauth-methods/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/oauth-methods/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"@octokit/oauth-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/plugin-retry/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/plugin-throttling/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/webhooks/@octokit/request-error/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||
|
||||
"body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||
@@ -1938,16 +1980,6 @@
|
||||
|
||||
"express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
|
||||
|
||||
"octokit/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
|
||||
|
||||
"octokit/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="],
|
||||
|
||||
"octokit/@octokit/core/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||
|
||||
"octokit/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||
|
||||
"octokit/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||
|
||||
"@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
|
||||
@@ -1955,21 +1987,5 @@
|
||||
"@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
|
||||
|
||||
"@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
|
||||
|
||||
"@octokit/app/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/app/@octokit/core/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
|
||||
"@octokit/oauth-app/@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/webhooks/@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"octokit/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||
|
||||
"octokit/@octokit/core/@octokit/request/fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { expect,test } from '@playwright/test';
|
||||
|
||||
// Helper function to navigate to login page
|
||||
async function navigateToLogin(page: any) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { expect,test } from '@playwright/test';
|
||||
|
||||
// Helper function to navigate to login page
|
||||
async function navigateToLogin(page: any) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { expect,test } from '@playwright/test';
|
||||
|
||||
test.describe('Basic Smoke Tests', () => {
|
||||
test('should load the application', async ({ page }) => {
|
||||
|
||||
@@ -2,11 +2,12 @@ import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import simpleImportSort from 'eslint-plugin-simple-import-sort'
|
||||
import tseslint from 'typescript-eslint'
|
||||
import atomicDesignRules from './eslint-plugins/atomic-design-rules.js'
|
||||
|
||||
export default tseslint.config(
|
||||
{ ignores: ['dist', 'node_modules', 'packages/*/dist', 'packages/*/node_modules', '.next/**', 'coverage/**', 'next-env.d.ts', 'prisma.config.ts', 'playwright.dbal-daemon.config.ts'] },
|
||||
{ ignores: ['dist', 'node_modules', 'packages/*/dist', 'packages/*/node_modules', '.next/**', 'coverage/**', 'next-env.d.ts', 'prisma.config.ts', 'playwright.dbal-daemon.config.ts', 'scripts/**'] },
|
||||
{
|
||||
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
@@ -22,6 +23,7 @@ export default tseslint.config(
|
||||
'react-hooks': reactHooks,
|
||||
'react-refresh': reactRefresh,
|
||||
'atomic-design': atomicDesignRules,
|
||||
'simple-import-sort': simpleImportSort,
|
||||
},
|
||||
rules: {
|
||||
...reactHooks.configs.recommended.rules,
|
||||
@@ -44,6 +46,9 @@ export default tseslint.config(
|
||||
'no-var': 'error',
|
||||
// Atomic design rules
|
||||
'atomic-design/no-upward-imports': 'error',
|
||||
// Import sorting
|
||||
'simple-import-sort/imports': 'warn',
|
||||
'simple-import-sort/exports': 'warn',
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
57
frontends/nextjs/package-lock.json
generated
57
frontends/nextjs/package-lock.json
generated
@@ -64,8 +64,10 @@
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.26",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"globals": "^16.5.0",
|
||||
"jsdom": "^27.3.0",
|
||||
"prettier": "^3.4.2",
|
||||
"prisma": "^7.2.0",
|
||||
"sass": "^1.97.1",
|
||||
"typescript": "~5.9.3",
|
||||
@@ -5540,18 +5542,6 @@
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz",
|
||||
"integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/types": {
|
||||
"version": "0.1.25",
|
||||
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
|
||||
@@ -8291,6 +8281,16 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-simple-import-sort": {
|
||||
"version": "12.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz",
|
||||
"integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"eslint": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
|
||||
@@ -11157,6 +11157,22 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.7.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
|
||||
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-format": {
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
|
||||
@@ -13555,23 +13571,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
|
||||
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/eemeli"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
"start": "next start",
|
||||
"kill": "fuser -k 3000/tcp",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"typecheck:strict": "tsc --noEmit --strict",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
||||
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
||||
"preview": "next start",
|
||||
"dev:vite": "vite",
|
||||
"build:vite": "tsc -b --noCheck && vite build",
|
||||
@@ -119,8 +122,10 @@
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.26",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"globals": "^16.5.0",
|
||||
"jsdom": "^27.3.0",
|
||||
"prettier": "^3.4.2",
|
||||
"prisma": "^7.2.0",
|
||||
"sass": "^1.97.1",
|
||||
"typescript": "~5.9.3",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import { Level3 } from '@/components/Level3'
|
||||
import { AuthGate } from '@/components/auth/AuthGate'
|
||||
import { PageLoader } from '@/components/auth/PageLoader'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
import { Level3 } from '@/components/Level3'
|
||||
import { useLevelRouting } from '@/hooks/useLevelRouting'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
|
||||
export default function AdminPage() {
|
||||
const { user, isLoading } = useResolvedUser()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import { Level4 } from '@/components/Level4'
|
||||
import { AuthGate } from '@/components/auth/AuthGate'
|
||||
import { PageLoader } from '@/components/auth/PageLoader'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
import { Level4 } from '@/components/Level4'
|
||||
import { useLevelRouting } from '@/hooks/useLevelRouting'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
|
||||
export default function BuilderPage() {
|
||||
const { user, isLoading } = useResolvedUser()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import { Level2 } from '@/components/Level2'
|
||||
import { AuthGate } from '@/components/auth/AuthGate'
|
||||
import { PageLoader } from '@/components/auth/PageLoader'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
import { Level2 } from '@/components/Level2'
|
||||
import { useLevelRouting } from '@/hooks/useLevelRouting'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
|
||||
export default function DashboardPage() {
|
||||
const { user, isLoading } = useResolvedUser()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import { ModeratorPanel } from '@/components/level/ModeratorPanel'
|
||||
import { AuthGate } from '@/components/auth/AuthGate'
|
||||
import { PageLoader } from '@/components/auth/PageLoader'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
import { ModeratorPanel } from '@/components/level/ModeratorPanel'
|
||||
import { useLevelRouting } from '@/hooks/useLevelRouting'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
|
||||
export default function ModeratorPage() {
|
||||
const { user, isLoading } = useResolvedUser()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import { Level5 } from '@/components/Level5'
|
||||
import { AuthGate } from '@/components/auth/AuthGate'
|
||||
import { PageLoader } from '@/components/auth/PageLoader'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
import { Level5 } from '@/components/Level5'
|
||||
import { useLevelRouting } from '@/hooks/useLevelRouting'
|
||||
import { useResolvedUser } from '@/hooks/useResolvedUser'
|
||||
|
||||
export default function SuperGodPage() {
|
||||
const { user, isLoading } = useResolvedUser()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createContext } from 'react'
|
||||
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
export interface AuthContextType {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { fetchSession } from '@/lib/auth/api/fetch-session'
|
||||
import { login as loginRequest } from '@/lib/auth/api/login'
|
||||
import { logout as logoutRequest } from '@/lib/auth/api/logout'
|
||||
import { register as registerRequest } from '@/lib/auth/api/register'
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
import { AuthContext } from './auth-context'
|
||||
|
||||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useContext } from 'react'
|
||||
|
||||
import { AuthContext } from './auth-context'
|
||||
|
||||
export function useAuth() {
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { getRequestIp } from '@/lib/api/get-request-ip'
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import { getUserByEmail, getUserByUsername } from '@/lib/db/auth'
|
||||
import { createSession } from '@/lib/db/sessions/create-session'
|
||||
import { DEFAULT_SESSION_TTL_MS } from '@/lib/auth/session-constants'
|
||||
import { setSessionCookie } from '@/lib/auth/set-session-cookie'
|
||||
import { createLoginSecurityContext, getLoginLockoutInfo, verifyCredentials } from '@/lib/security/secure-db'
|
||||
import { getUserByEmail, getUserByUsername } from '@/lib/db/auth'
|
||||
import { createSession } from '@/lib/db/sessions/create-session'
|
||||
import {
|
||||
createLoginSecurityContext,
|
||||
getLoginLockoutInfo,
|
||||
verifyCredentials,
|
||||
} from '@/lib/security/secure-db'
|
||||
|
||||
interface LoginPayload {
|
||||
identifier?: string
|
||||
@@ -23,18 +28,14 @@ export async function POST(request: Request) {
|
||||
}
|
||||
|
||||
const identifier = [body.identifier, body.username, body.email]
|
||||
.find((value) => typeof value === 'string' && value.trim().length > 0)
|
||||
.find(value => typeof value === 'string' && value.trim().length > 0)
|
||||
?.trim()
|
||||
const password = typeof body.password === 'string' ? body.password : ''
|
||||
const tenantId = typeof body.tenantId === 'string' && body.tenantId.trim()
|
||||
? body.tenantId.trim()
|
||||
: undefined
|
||||
const tenantId =
|
||||
typeof body.tenantId === 'string' && body.tenantId.trim() ? body.tenantId.trim() : undefined
|
||||
|
||||
if (!identifier || !password) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Username/email and password are required' },
|
||||
{ status: 400 }
|
||||
)
|
||||
return NextResponse.json({ error: 'Username/email and password are required' }, { status: 400 })
|
||||
}
|
||||
|
||||
const lookupOptions = tenantId ? { tenantId } : undefined
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { cookies } from 'next/headers'
|
||||
import { NextResponse } from 'next/server'
|
||||
import { deleteSessionByToken } from '@/lib/db/sessions/delete-session-by-token'
|
||||
|
||||
import { clearSessionCookie } from '@/lib/auth/clear-session-cookie'
|
||||
import { AUTH_COOKIE_NAME } from '@/lib/auth/session-constants'
|
||||
import { deleteSessionByToken } from '@/lib/db/sessions/delete-session-by-token'
|
||||
|
||||
export async function POST() {
|
||||
const cookieStore = await cookies()
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { randomUUID } from 'crypto'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import { addUser } from '@/lib/db/users/add-user'
|
||||
import { getUserByEmail, getUserByUsername } from '@/lib/db/auth'
|
||||
import { hashPassword } from '@/lib/db/hash-password'
|
||||
import { setCredential } from '@/lib/db/credentials/set-credential'
|
||||
import { createSession } from '@/lib/db/sessions/create-session'
|
||||
import { DEFAULT_SESSION_TTL_MS } from '@/lib/auth/session-constants'
|
||||
import { setSessionCookie } from '@/lib/auth/set-session-cookie'
|
||||
import { getUserByEmail, getUserByUsername } from '@/lib/db/auth'
|
||||
import { setCredential } from '@/lib/db/credentials/set-credential'
|
||||
import { hashPassword } from '@/lib/db/hash-password'
|
||||
import { createSession } from '@/lib/db/sessions/create-session'
|
||||
import { addUser } from '@/lib/db/users/add-user'
|
||||
import type { UserRole } from '@/lib/level-types'
|
||||
|
||||
interface RegisterPayload {
|
||||
@@ -31,9 +32,8 @@ export async function POST(request: Request) {
|
||||
const username = typeof body.username === 'string' ? body.username.trim() : ''
|
||||
const email = typeof body.email === 'string' ? body.email.trim() : ''
|
||||
const password = typeof body.password === 'string' ? body.password : ''
|
||||
const tenantId = typeof body.tenantId === 'string' && body.tenantId.trim()
|
||||
? body.tenantId.trim()
|
||||
: undefined
|
||||
const tenantId =
|
||||
typeof body.tenantId === 'string' && body.tenantId.trim() ? body.tenantId.trim() : undefined
|
||||
|
||||
if (!username || !email || !password) {
|
||||
return NextResponse.json(
|
||||
@@ -49,10 +49,7 @@ export async function POST(request: Request) {
|
||||
])
|
||||
|
||||
if (existingByUsername || existingByEmail) {
|
||||
return NextResponse.json(
|
||||
{ error: 'User already exists' },
|
||||
{ status: 409 }
|
||||
)
|
||||
return NextResponse.json({ error: 'User already exists' }, { status: 409 })
|
||||
}
|
||||
|
||||
const user = {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { cookies } from 'next/headers'
|
||||
import { NextResponse } from 'next/server'
|
||||
import { AUTH_COOKIE_NAME, DEFAULT_SESSION_TTL_MS } from '@/lib/auth/session-constants'
|
||||
|
||||
import { clearSessionCookie } from '@/lib/auth/clear-session-cookie'
|
||||
import { AUTH_COOKIE_NAME, DEFAULT_SESSION_TTL_MS } from '@/lib/auth/session-constants'
|
||||
import { setSessionCookie } from '@/lib/auth/set-session-cookie'
|
||||
import { deleteSession } from '@/lib/db/sessions/delete-session'
|
||||
import { getSessionByToken } from '@/lib/db/sessions/get-session-by-token'
|
||||
import { updateSession } from '@/lib/db/sessions/update-session'
|
||||
import { deleteSession } from '@/lib/db/sessions/delete-session'
|
||||
import { getUserById } from '@/lib/db/users/get-user-by-id'
|
||||
|
||||
export async function GET() {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { generateCodegenZip } from '@/lib/codegen/generate-codegen-zip'
|
||||
import type { CodegenSpec } from '@/lib/codegen/codegen-types'
|
||||
import { generateCodegenZip } from '@/lib/codegen/generate-codegen-zip'
|
||||
|
||||
const normalizeRuntime = (value: string | undefined): CodegenSpec['runtime'] => {
|
||||
const runtime = (value ?? 'web').toLowerCase()
|
||||
if (['cli', 'desktop', 'hybrid', 'server'].includes(runtime)) return runtime as CodegenSpec['runtime']
|
||||
if (['cli', 'desktop', 'hybrid', 'server'].includes(runtime))
|
||||
return runtime as CodegenSpec['runtime']
|
||||
return 'web'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { createGitHubClient } from '@/lib/github/create-github-client'
|
||||
import { fetchWorkflowRunLogs } from '@/lib/github/fetch-workflow-run-logs'
|
||||
import { parseWorkflowRunLogsOptions } from '@/lib/github/parse-workflow-run-logs-options'
|
||||
@@ -40,16 +41,14 @@ export const GET = async (request: NextRequest, { params }: RouteParams) => {
|
||||
truncated,
|
||||
})
|
||||
} catch (error) {
|
||||
const status = typeof error === 'object' && error && 'status' in error
|
||||
? Number((error as { status?: number }).status)
|
||||
: 500
|
||||
const status =
|
||||
typeof error === 'object' && error && 'status' in error
|
||||
? Number((error as { status?: number }).status)
|
||||
: 500
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
const requiresAuth = status === 401 || status === 403
|
||||
const safeStatus = Number.isFinite(status) && status >= 400 ? status : 500
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: message, requiresAuth },
|
||||
{ status: safeStatus }
|
||||
)
|
||||
return NextResponse.json({ error: message, requiresAuth }, { status: safeStatus })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { createGitHubClient } from '@/lib/github/create-github-client'
|
||||
import { resolveGitHubRepo } from '@/lib/github/resolve-github-repo'
|
||||
import { listWorkflowRuns } from '@/lib/github/workflows/listing/list-workflow-runs'
|
||||
@@ -28,16 +29,14 @@ export const GET = async (request: NextRequest) => {
|
||||
hasToken: Boolean(process.env.GITHUB_TOKEN),
|
||||
})
|
||||
} catch (error) {
|
||||
const status = typeof error === 'object' && error && 'status' in error
|
||||
? Number((error as { status?: number }).status)
|
||||
: 500
|
||||
const status =
|
||||
typeof error === 'object' && error && 'status' in error
|
||||
? Number((error as { status?: number }).status)
|
||||
: 500
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
const requiresAuth = status === 401 || status === 403
|
||||
const safeStatus = Number.isFinite(status) && status >= 400 ? status : 500
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: message, requiresAuth },
|
||||
{ status: safeStatus }
|
||||
)
|
||||
return NextResponse.json({ error: message, requiresAuth }, { status: safeStatus })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { PERMISSION_LEVELS } from '@/app/levels/levels-data'
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ describe('GET /api/levels/metrics', () => {
|
||||
|
||||
expect(payload.totalLevels).toBeGreaterThan(0)
|
||||
expect(Array.isArray(payload.summary)).toBe(true)
|
||||
expect(payload.summary.every((entry: any) => typeof entry.capabilityCount === 'number')).toBe(true)
|
||||
expect(payload.summary.every((entry: any) => typeof entry.capabilityCount === 'number')).toBe(
|
||||
true
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { PERMISSION_LEVELS } from '@/app/levels/levels-data'
|
||||
|
||||
export async function GET(_request: NextRequest) {
|
||||
const summary = PERMISSION_LEVELS.map((level) => ({
|
||||
const summary = PERMISSION_LEVELS.map(level => ({
|
||||
key: level.key,
|
||||
title: level.title,
|
||||
capabilityCount: level.capabilities.length,
|
||||
|
||||
@@ -24,7 +24,7 @@ describe('GET /api/levels', () => {
|
||||
const payload = await response.json()
|
||||
|
||||
expect(payload.levels.length).toBeGreaterThan(0)
|
||||
expect(payload.levels.some((level) => ['admin', 'user'].includes(level.key))).toBe(true)
|
||||
expect(payload.levels.some(level => ['admin', 'user'].includes(level.key))).toBe(true)
|
||||
})
|
||||
|
||||
it('accepts level feedback via POST', async () => {
|
||||
|
||||
@@ -11,21 +11,21 @@ export async function GET(request: Request) {
|
||||
const normalizedCapabilities = rawCapabilities
|
||||
? rawCapabilities
|
||||
.split(',')
|
||||
.map((value) => value.toLowerCase().trim())
|
||||
.map(value => value.toLowerCase().trim())
|
||||
.filter(Boolean)
|
||||
: []
|
||||
|
||||
const matchesLevel = (level: typeof PERMISSION_LEVELS[number]) =>
|
||||
const matchesLevel = (level: (typeof PERMISSION_LEVELS)[number]) =>
|
||||
!normalizedLevel || level.key === normalizedLevel || String(level.id) === normalizedLevel
|
||||
|
||||
const matchesCapabilities = (level: typeof PERMISSION_LEVELS[number]) =>
|
||||
const matchesCapabilities = (level: (typeof PERMISSION_LEVELS)[number]) =>
|
||||
normalizedCapabilities.length === 0 ||
|
||||
level.capabilities.some((capability) =>
|
||||
normalizedCapabilities.some((candidate) => capability.toLowerCase().includes(candidate))
|
||||
level.capabilities.some(capability =>
|
||||
normalizedCapabilities.some(candidate => capability.toLowerCase().includes(candidate))
|
||||
)
|
||||
|
||||
const filtered = PERMISSION_LEVELS.filter(
|
||||
(level) => matchesLevel(level) && matchesCapabilities(level)
|
||||
level => matchesLevel(level) && matchesCapabilities(level)
|
||||
)
|
||||
|
||||
return NextResponse.json({ levels: filtered })
|
||||
@@ -38,13 +38,13 @@ export async function POST(request: Request) {
|
||||
typeof payload.level === 'string'
|
||||
? payload.level.toLowerCase().trim()
|
||||
: typeof payload.level === 'number'
|
||||
? String(payload.level)
|
||||
: undefined
|
||||
? String(payload.level)
|
||||
: undefined
|
||||
|
||||
const matched = normalized
|
||||
? PERMISSION_LEVELS.find(
|
||||
(level) => level.key === normalized || String(level.id) === normalized
|
||||
) ?? null
|
||||
? (PERMISSION_LEVELS.find(
|
||||
level => level.key === normalized || String(level.id) === normalized
|
||||
) ?? null)
|
||||
: null
|
||||
|
||||
console.info('Levels API feedback', { level: normalized, note: payload.note })
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { prisma } from '@/lib/config/prisma'
|
||||
import { buildNativePrismaSql, isAuthorized } from '@/lib/native-prisma-bridge'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { deletePackageData } from '@/lib/db/packages/delete-package-data'
|
||||
|
||||
interface RouteParams {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { getPackageData } from '@/lib/db/packages/get-package-data'
|
||||
|
||||
interface RouteParams {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import { setPackageData } from '@/lib/db/packages/set-package-data'
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export { DELETE } from './handlers/delete-package-data'
|
||||
export { GET } from './handlers/get-package-data'
|
||||
export { PUT } from './handlers/put-package-data'
|
||||
export { DELETE } from './handlers/delete-package-data'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { getInstalledPackages } from '@/lib/db/packages/get-installed-packages'
|
||||
import { uninstallPackage } from '@/lib/db/packages/uninstall-package'
|
||||
import { getPackageCatalogEntry } from '@/lib/packages/server/get-package-catalog-entry'
|
||||
@@ -19,7 +20,7 @@ export async function DELETE(_request: NextRequest, { params }: RouteParams) {
|
||||
}
|
||||
|
||||
const installed = await getInstalledPackages()
|
||||
if (!installed.some((pkg) => pkg.packageId === params.packageId)) {
|
||||
if (!installed.some(pkg => pkg.packageId === params.packageId)) {
|
||||
return NextResponse.json({ error: 'Package not installed' }, { status: 404 })
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import { getInstalledPackages } from '@/lib/db/packages/get-installed-packages'
|
||||
import { togglePackageEnabled } from '@/lib/db/packages/toggle-package-enabled'
|
||||
@@ -23,7 +24,7 @@ export async function PATCH(request: NextRequest, { params }: RouteParams) {
|
||||
}
|
||||
|
||||
const installed = await getInstalledPackages()
|
||||
const existing = installed.find((pkg) => pkg.packageId === params.packageId)
|
||||
const existing = installed.find(pkg => pkg.packageId === params.packageId)
|
||||
if (!existing) {
|
||||
return NextResponse.json({ error: 'Package not installed' }, { status: 404 })
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export { PATCH } from './handlers/patch-installed-package'
|
||||
export { DELETE } from './handlers/delete-installed-package'
|
||||
export { PATCH } from './handlers/patch-installed-package'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { getInstalledPackages } from '@/lib/db/packages/get-installed-packages'
|
||||
|
||||
export async function GET() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import { getInstalledPackages } from '@/lib/db/packages/get-installed-packages'
|
||||
import { installPackage } from '@/lib/db/packages/install-package'
|
||||
@@ -21,7 +22,12 @@ export async function POST(request: NextRequest) {
|
||||
const body = await readJson<InstallPackagePayload>(request)
|
||||
if (!body) return NextResponse.json({ error: 'Invalid JSON payload' }, { status: 400 })
|
||||
|
||||
const packageId = typeof body.packageId === 'string' ? body.packageId.trim() : (typeof body.manifest?.id === 'string' ? body.manifest.id : '')
|
||||
const packageId =
|
||||
typeof body.packageId === 'string'
|
||||
? body.packageId.trim()
|
||||
: typeof body.manifest?.id === 'string'
|
||||
? body.manifest.id
|
||||
: ''
|
||||
if (!packageId) return NextResponse.json({ error: 'Package ID is required' }, { status: 400 })
|
||||
|
||||
const entry = getPackageCatalogEntry(packageId)
|
||||
@@ -29,16 +35,17 @@ export async function POST(request: NextRequest) {
|
||||
if (!content) return NextResponse.json({ error: 'Package content not found' }, { status: 404 })
|
||||
|
||||
const installed = await getInstalledPackages()
|
||||
if (installed.some((pkg) => pkg.packageId === packageId)) {
|
||||
if (installed.some(pkg => pkg.packageId === packageId)) {
|
||||
return NextResponse.json({ error: 'Package already installed' }, { status: 409 })
|
||||
}
|
||||
|
||||
await installPackageContent(packageId, content)
|
||||
|
||||
const installedAt = typeof body.installedAt === 'number' ? body.installedAt : Date.now()
|
||||
const version = typeof body.version === 'string'
|
||||
? body.version
|
||||
: (body.manifest?.version ?? entry?.manifest.version ?? '0.0.0')
|
||||
const version =
|
||||
typeof body.version === 'string'
|
||||
? body.version
|
||||
: (body.manifest?.version ?? entry?.manifest.version ?? '0.0.0')
|
||||
const enabled = typeof body.enabled === 'boolean' ? body.enabled : true
|
||||
const installedPackage: InstalledPackage = { packageId, installedAt, version, enabled }
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { deletePowerTransferRequest } from '@/lib/db/power-transfers'
|
||||
|
||||
interface RouteParams {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import {
|
||||
updatePowerTransferRequest,
|
||||
} from '@/lib/db/power-transfers'
|
||||
import { updatePowerTransferRequest } from '@/lib/db/power-transfers'
|
||||
import type { PowerTransferRequest } from '@/lib/level-types'
|
||||
|
||||
type UpdatePayload = {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export { PATCH } from './handlers/patch-power-transfer-request'
|
||||
export { DELETE } from './handlers/delete-power-transfer-request'
|
||||
export { PATCH } from './handlers/patch-power-transfer-request'
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { getPowerTransferRequests } from '@/lib/db/power-transfers'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { requireDBALApiKey } from '@/lib/api/require-dbal-api-key'
|
||||
import { getPowerTransferRequests } from '@/lib/db/power-transfers'
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const unauthorized = requireDBALApiKey(request)
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { randomUUID } from 'crypto'
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import { requireDBALApiKey } from '@/lib/api/require-dbal-api-key'
|
||||
import { transferSuperGodPower } from '@/lib/db/users/super-god/transfer-super-god-power'
|
||||
import {
|
||||
addPowerTransferRequest,
|
||||
getPowerTransferRequests,
|
||||
updatePowerTransferRequest,
|
||||
} from '@/lib/db/power-transfers'
|
||||
import { transferSuperGodPower } from '@/lib/db/users/super-god/transfer-super-god-power'
|
||||
import { dbalGetUserById } from '@/lib/dbal/database-dbal/users/dbal-get-user-by-id.server'
|
||||
|
||||
const REQUEST_EXPIRY_MS = 60 * 60 * 1000
|
||||
@@ -34,7 +35,10 @@ export async function POST(request: NextRequest) {
|
||||
const toUserId = body.toUserId?.trim()
|
||||
|
||||
if (!fromUserId || !toUserId) {
|
||||
return NextResponse.json({ error: 'Both fromUserId and toUserId are required' }, { status: 400 })
|
||||
return NextResponse.json(
|
||||
{ error: 'Both fromUserId and toUserId are required' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
if (fromUserId === toUserId) {
|
||||
@@ -43,7 +47,10 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
const fromUser = await dbalGetUserById(fromUserId)
|
||||
if (!fromUser || fromUser.role !== 'supergod') {
|
||||
return NextResponse.json({ error: 'Only an active supergod can initiate transfers' }, { status: 403 })
|
||||
return NextResponse.json(
|
||||
{ error: 'Only an active supergod can initiate transfers' },
|
||||
{ status: 403 }
|
||||
)
|
||||
}
|
||||
|
||||
const toUser = await dbalGetUserById(toUserId)
|
||||
@@ -52,11 +59,16 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
|
||||
if (toUser.role === 'supergod') {
|
||||
return NextResponse.json({ error: 'Target user already has supergod privileges' }, { status: 409 })
|
||||
return NextResponse.json(
|
||||
{ error: 'Target user already has supergod privileges' },
|
||||
{ status: 409 }
|
||||
)
|
||||
}
|
||||
|
||||
const pendingRequests = await getPowerTransferRequests()
|
||||
if (pendingRequests.some((request) => request.status === 'pending' && request.toUserId === toUserId)) {
|
||||
if (
|
||||
pendingRequests.some(request => request.status === 'pending' && request.toUserId === toUserId)
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: 'There is already a pending transfer request for that user' },
|
||||
{ status: 409 }
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { readJson } from '@/lib/api/read-json'
|
||||
import type { ScreenshotAnalysisPayload } from '@/lib/screenshot/types'
|
||||
import { ScreenshotAnalysisService } from '@/lib/screenshot/screenshot-analysis-service'
|
||||
import type { ScreenshotAnalysisPayload } from '@/lib/screenshot/types'
|
||||
|
||||
const MAX_TEXT_SAMPLE = 4000
|
||||
const MAX_HTML_SAMPLE = 6000
|
||||
@@ -20,18 +21,13 @@ export async function POST(request: Request) {
|
||||
const height = typeof viewport?.height === 'number' ? viewport.height : 0
|
||||
|
||||
if (!title || !url || width <= 0 || height <= 0) {
|
||||
return NextResponse.json(
|
||||
{ error: 'title, url, and viewport are required' },
|
||||
{ status: 400 }
|
||||
)
|
||||
return NextResponse.json({ error: 'title, url, and viewport are required' }, { status: 400 })
|
||||
}
|
||||
|
||||
const textSample = typeof body.textSample === 'string'
|
||||
? body.textSample.slice(0, MAX_TEXT_SAMPLE)
|
||||
: ''
|
||||
const htmlSample = typeof body.htmlSample === 'string'
|
||||
? body.htmlSample.slice(0, MAX_HTML_SAMPLE)
|
||||
: ''
|
||||
const textSample =
|
||||
typeof body.textSample === 'string' ? body.textSample.slice(0, MAX_TEXT_SAMPLE) : ''
|
||||
const htmlSample =
|
||||
typeof body.htmlSample === 'string' ? body.htmlSample.slice(0, MAX_HTML_SAMPLE) : ''
|
||||
|
||||
const service = new ScreenshotAnalysisService()
|
||||
const analysis = service.analyze({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import { getStatusResponse } from '@dbal-ui/status'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
export function GET() {
|
||||
return NextResponse.json(getStatusResponse())
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
* @description DELETE handler for removing a user
|
||||
*/
|
||||
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import {
|
||||
dbalDeleteUser,
|
||||
initializeDBAL,
|
||||
} from '@/lib/dbal/core/client/database-dbal.server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { requireDBALApiKey } from '@/lib/api/require-dbal-api-key'
|
||||
import { dbalDeleteUser, initializeDBAL } from '@/lib/dbal/core/client/database-dbal.server'
|
||||
|
||||
interface RouteParams {
|
||||
params: {
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
* @description GET handler for fetching a user by ID
|
||||
*/
|
||||
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import {
|
||||
dbalGetUserById,
|
||||
initializeDBAL,
|
||||
} from '@/lib/dbal/core/client/database-dbal.server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { requireDBALApiKey } from '@/lib/api/require-dbal-api-key'
|
||||
import { dbalGetUserById, initializeDBAL } from '@/lib/dbal/core/client/database-dbal.server'
|
||||
|
||||
interface RouteParams {
|
||||
params: {
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
* @description PATCH handler for updating a user
|
||||
*/
|
||||
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import {
|
||||
dbalUpdateUser,
|
||||
initializeDBAL,
|
||||
} from '@/lib/dbal/core/client/database-dbal.server'
|
||||
import { hashPassword } from '@/lib/db/hash-password'
|
||||
import { setCredential } from '@/lib/db/credentials/set-credential'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { requireDBALApiKey } from '@/lib/api/require-dbal-api-key'
|
||||
import { setCredential } from '@/lib/db/credentials/set-credential'
|
||||
import { hashPassword } from '@/lib/db/hash-password'
|
||||
import { dbalUpdateUser, initializeDBAL } from '@/lib/dbal/core/client/database-dbal.server'
|
||||
|
||||
import { normalizeRole, readJson } from '../utils/request-helpers'
|
||||
|
||||
interface RouteParams {
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
* @description User API route handlers aggregated from handler modules
|
||||
*/
|
||||
|
||||
export { DELETE } from './handlers/delete-user'
|
||||
export { GET } from './handlers/get-user'
|
||||
export { PATCH } from './handlers/patch-user'
|
||||
export { DELETE } from './handlers/delete-user'
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import {
|
||||
dbalDeleteUser,
|
||||
dbalGetUserById,
|
||||
dbalUpdateUser,
|
||||
initializeDBAL,
|
||||
} from '@/lib/dbal/core/client/database-dbal.server'
|
||||
import { hashPassword } from '@/lib/db/hash-password'
|
||||
import { setCredential } from '@/lib/db/credentials/set-credential'
|
||||
import { requireDBALApiKey } from '@/lib/api/require-dbal-api-key'
|
||||
import type { UserRole } from '@/lib/level-types'
|
||||
|
||||
function normalizeRole(role?: string): UserRole | undefined {
|
||||
if (!role) return undefined
|
||||
if (role === 'public') return 'user'
|
||||
return role as UserRole
|
||||
}
|
||||
|
||||
async function readJson<T>(request: NextRequest): Promise<T | null> {
|
||||
try {
|
||||
return (await request.json()) as T
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
interface RouteParams {
|
||||
params: {
|
||||
userId: string
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest, { params }: RouteParams) {
|
||||
const unauthorized = requireDBALApiKey(request)
|
||||
if (unauthorized) {
|
||||
return unauthorized
|
||||
}
|
||||
try {
|
||||
await initializeDBAL()
|
||||
const user = await dbalGetUserById(params.userId)
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
return NextResponse.json({ user })
|
||||
} catch (error) {
|
||||
console.error('Error fetching user via DBAL:', error)
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to fetch user',
|
||||
details: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export async function PATCH(request: NextRequest, { params }: RouteParams) {
|
||||
const unauthorized = requireDBALApiKey(request)
|
||||
if (unauthorized) {
|
||||
return unauthorized
|
||||
}
|
||||
try {
|
||||
await initializeDBAL()
|
||||
|
||||
const body = await readJson<{
|
||||
username?: string
|
||||
email?: string
|
||||
role?: string
|
||||
password?: string
|
||||
profilePicture?: string
|
||||
bio?: string
|
||||
tenantId?: string
|
||||
isInstanceOwner?: boolean
|
||||
}>(request)
|
||||
|
||||
if (!body) {
|
||||
return NextResponse.json({ error: 'Invalid JSON payload' }, { status: 400 })
|
||||
}
|
||||
|
||||
if (body.username) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Username updates are not supported' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
const existingUser = await dbalGetUserById(params.userId)
|
||||
if (!existingUser) {
|
||||
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
const updates = {
|
||||
email: typeof body.email === 'string' ? body.email.trim() : undefined,
|
||||
role: normalizeRole(body.role),
|
||||
profilePicture: body.profilePicture,
|
||||
bio: body.bio,
|
||||
tenantId: body.tenantId,
|
||||
isInstanceOwner: body.isInstanceOwner,
|
||||
}
|
||||
|
||||
const user = await dbalUpdateUser(params.userId, updates)
|
||||
|
||||
if (typeof body.password === 'string' && body.password.length > 0) {
|
||||
const passwordHash = await hashPassword(body.password)
|
||||
await setCredential(existingUser.username, passwordHash)
|
||||
}
|
||||
|
||||
return NextResponse.json({ user })
|
||||
} catch (error) {
|
||||
console.error('Error updating user via DBAL:', error)
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to update user',
|
||||
details: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export async function DELETE(request: NextRequest, { params }: RouteParams) {
|
||||
const unauthorized = requireDBALApiKey(request)
|
||||
if (unauthorized) {
|
||||
return unauthorized
|
||||
}
|
||||
try {
|
||||
await initializeDBAL()
|
||||
|
||||
const existingUser = await dbalGetUserById(params.userId)
|
||||
if (!existingUser) {
|
||||
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
await dbalDeleteUser(params.userId)
|
||||
await setCredential(existingUser.username, '')
|
||||
|
||||
return NextResponse.json({ deleted: true })
|
||||
} catch (error) {
|
||||
console.error('Error deleting user via DBAL:', error)
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to delete user',
|
||||
details: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import type { NextRequest } from 'next/server'
|
||||
|
||||
import type { UserRole } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
/**
|
||||
* Users API Route - Demonstrates DBAL integration
|
||||
*
|
||||
*
|
||||
* This API route forwards user management operations to the C++ DBAL daemon.
|
||||
*/
|
||||
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { callDaemon } from '@/lib/dbal/daemon/client'
|
||||
import { hashPassword } from '@/lib/db/hash-password'
|
||||
import { setCredential } from '@/lib/db/credentials/set-credential'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { requireDBALApiKey } from '@/lib/api/require-dbal-api-key'
|
||||
import { setCredential } from '@/lib/db/credentials/set-credential'
|
||||
import { hashPassword } from '@/lib/db/hash-password'
|
||||
import { callDaemon } from '@/lib/dbal/daemon/client'
|
||||
import type { User, UserRole } from '@/lib/level-types'
|
||||
|
||||
const RPC_LIMIT = 200
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import { useMemo, useState, type ChangeEvent } from 'react'
|
||||
|
||||
import {
|
||||
Alert,
|
||||
Box,
|
||||
@@ -14,10 +12,11 @@ import {
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@mui/material'
|
||||
import { type ChangeEvent, useMemo, useState } from 'react'
|
||||
|
||||
import Header from './components/Header'
|
||||
import Sidebar from './components/Sidebar'
|
||||
import { useCodegenData, type CodegenRequest } from './hooks/useCodegenData'
|
||||
import { type CodegenRequest, useCodegenData } from './hooks/useCodegenData'
|
||||
|
||||
const runtimeOptions = [
|
||||
{ value: 'web', label: 'Next.js web' },
|
||||
@@ -57,11 +56,12 @@ export default function CodegenStudioClient() {
|
||||
}, [form.runtime])
|
||||
|
||||
const previewFiles = useMemo(() => {
|
||||
const root = form.projectName
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9_-]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '') || 'metabuilder-starter'
|
||||
const root =
|
||||
form.projectName
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9_-]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '') || 'metabuilder-starter'
|
||||
return [
|
||||
`${root}/README.md`,
|
||||
`${root}/package.json`,
|
||||
@@ -72,7 +72,7 @@ export default function CodegenStudioClient() {
|
||||
}, [form.projectName])
|
||||
|
||||
const handleChange = (key: keyof FormState) => (event: ChangeEvent<HTMLInputElement>) => {
|
||||
setForm((prev) => ({ ...prev, [key]: event.target.value }))
|
||||
setForm(prev => ({ ...prev, [key]: event.target.value }))
|
||||
}
|
||||
|
||||
const handleSubmit = () => generate(form)
|
||||
@@ -93,9 +93,20 @@ export default function CodegenStudioClient() {
|
||||
onChange={handleChange('projectName')}
|
||||
fullWidth
|
||||
/>
|
||||
<TextField label="Package id" value={form.packageId} onChange={handleChange('packageId')} fullWidth />
|
||||
<TextField select label="Runtime" value={form.runtime} onChange={handleChange('runtime')} fullWidth>
|
||||
{runtimeOptions.map((option) => (
|
||||
<TextField
|
||||
label="Package id"
|
||||
value={form.packageId}
|
||||
onChange={handleChange('packageId')}
|
||||
fullWidth
|
||||
/>
|
||||
<TextField
|
||||
select
|
||||
label="Runtime"
|
||||
value={form.runtime}
|
||||
onChange={handleChange('runtime')}
|
||||
fullWidth
|
||||
>
|
||||
{runtimeOptions.map(option => (
|
||||
<MenuItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client'
|
||||
|
||||
import type { CodegenManifest } from '@/lib/codegen/codegen-types'
|
||||
import { Paper, Stack, Typography } from '@mui/material'
|
||||
|
||||
import type { CodegenManifest } from '@/lib/codegen/codegen-types'
|
||||
|
||||
interface SidebarProps {
|
||||
manifest: CodegenManifest | null
|
||||
previewFiles: string[]
|
||||
@@ -14,7 +15,12 @@ export default function Sidebar({ manifest, previewFiles }: SidebarProps) {
|
||||
{manifest && (
|
||||
<Paper
|
||||
elevation={1}
|
||||
sx={{ border: '1px dashed', borderColor: 'divider', p: 2, backgroundColor: 'background.default' }}
|
||||
sx={{
|
||||
border: '1px dashed',
|
||||
borderColor: 'divider',
|
||||
p: 2,
|
||||
backgroundColor: 'background.default',
|
||||
}}
|
||||
>
|
||||
<Typography variant="subtitle1" gutterBottom>
|
||||
Manifest preview
|
||||
@@ -40,7 +46,7 @@ export default function Sidebar({ manifest, previewFiles }: SidebarProps) {
|
||||
)}
|
||||
<Stack spacing={1}>
|
||||
<Typography variant="subtitle2">Bundle contents</Typography>
|
||||
{previewFiles.map((entry) => (
|
||||
{previewFiles.map(entry => (
|
||||
<Typography key={entry} variant="body2" color="text.secondary">
|
||||
• {entry}
|
||||
</Typography>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client'
|
||||
|
||||
import type { CodegenManifest } from '@/lib/codegen/codegen-types'
|
||||
import { useCallback, useState } from 'react'
|
||||
|
||||
import type { CodegenManifest } from '@/lib/codegen/codegen-types'
|
||||
|
||||
export type CodegenRequest = {
|
||||
projectName: string
|
||||
packageId: string
|
||||
@@ -39,7 +40,10 @@ const fetchZip = async (values: CodegenRequest) => {
|
||||
throw new Error('Codegen Studio service returned an error')
|
||||
}
|
||||
const blob = await response.blob()
|
||||
const filename = createFilename(response.headers.get('content-disposition'), `${values.projectName}.zip`)
|
||||
const filename = createFilename(
|
||||
response.headers.get('content-disposition'),
|
||||
`${values.projectName}.zip`
|
||||
)
|
||||
downloadBlob(blob, filename)
|
||||
const manifestHeader = response.headers.get('x-codegen-manifest')
|
||||
const manifest = manifestHeader
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { Metadata, Viewport } from 'next'
|
||||
import { Providers } from './providers'
|
||||
import '@/main.scss'
|
||||
|
||||
import type { Metadata, Viewport } from 'next'
|
||||
|
||||
import { Providers } from './providers'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: 'MetaBuilder - Data-Driven Application Platform',
|
||||
template: '%s | MetaBuilder',
|
||||
},
|
||||
description: 'A data-driven, multi-tenant application platform where 95% of functionality is defined through JSON and Lua.',
|
||||
description:
|
||||
'A data-driven, multi-tenant application platform where 95% of functionality is defined through JSON and Lua.',
|
||||
keywords: ['metabuilder', 'low-code', 'no-code', 'lua', 'platform', 'multi-tenant'],
|
||||
authors: [{ name: 'MetaBuilder Team' }],
|
||||
creator: 'MetaBuilder',
|
||||
@@ -26,25 +29,19 @@ export const viewport: Viewport = {
|
||||
],
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html
|
||||
lang="en"
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=IBM+Plex+Sans:wght@400;500&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=IBM+Plex+Sans:wght@400;500&family=JetBrains+Mono:wght@400;500&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<Providers>
|
||||
{children}
|
||||
</Providers>
|
||||
<Providers>{children}</Providers>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import { Level1 } from '@/components/Level1'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { getLevelPath } from '@/lib/navigation/get-level-path'
|
||||
|
||||
import { Level1 } from '@/components/Level1'
|
||||
import type { AppLevel } from '@/lib/level-types'
|
||||
import { getLevelPath } from '@/lib/navigation/get-level-path'
|
||||
|
||||
export function Level1Client() {
|
||||
const router = useRouter()
|
||||
|
||||
|
||||
const handleNavigate = (level: number) => {
|
||||
const normalizedLevel = Math.min(6, Math.max(1, level)) as AppLevel
|
||||
router.push(getLevelPath(normalizedLevel))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
|
||||
import LevelsClient from './LevelsClient'
|
||||
|
||||
describe('LevelsClient', () => {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
import { Container, Stack, Typography } from '@mui/material'
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
import { LevelDetails } from './components/LevelDetails'
|
||||
import { LevelsGrid } from './components/LevelsGrid'
|
||||
@@ -13,23 +12,25 @@ export default function LevelsClient() {
|
||||
const [note, setNote] = useState('')
|
||||
|
||||
const selectedLevel = useMemo(
|
||||
() => PERMISSION_LEVELS.find((level) => level.id === selectedLevelId) ?? PERMISSION_LEVELS[0],
|
||||
() => PERMISSION_LEVELS.find(level => level.id === selectedLevelId) ?? PERMISSION_LEVELS[0],
|
||||
[selectedLevelId]
|
||||
)
|
||||
|
||||
const nextLevel = useMemo(
|
||||
() => PERMISSION_LEVELS.find((level) => level.id === selectedLevelId + 1) ?? null,
|
||||
() => PERMISSION_LEVELS.find(level => level.id === selectedLevelId + 1) ?? null,
|
||||
[selectedLevelId]
|
||||
)
|
||||
|
||||
const maxCapabilityCount = useMemo(
|
||||
() => Math.max(...PERMISSION_LEVELS.map((level) => level.capabilities.length)),
|
||||
() => Math.max(...PERMISSION_LEVELS.map(level => level.capabilities.length)),
|
||||
[]
|
||||
)
|
||||
|
||||
const handleSelect = (levelId: number) => {
|
||||
setSelectedLevelId(levelId)
|
||||
setNote(`Selected ${PERMISSION_LEVELS.find((l) => l.id === levelId)?.title ?? 'unknown'} privileges.`)
|
||||
setNote(
|
||||
`Selected ${PERMISSION_LEVELS.find(l => l.id === levelId)?.title ?? 'unknown'} privileges.`
|
||||
)
|
||||
}
|
||||
|
||||
const handlePromote = () => {
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import { Alert, Box, Button, Chip, Divider, LinearProgress, Paper, Stack, Typography } from '@mui/material'
|
||||
import {
|
||||
Alert,
|
||||
Box,
|
||||
Button,
|
||||
Chip,
|
||||
Divider,
|
||||
LinearProgress,
|
||||
Paper,
|
||||
Stack,
|
||||
Typography,
|
||||
} from '@mui/material'
|
||||
|
||||
import type { PermissionLevel } from '../levels-data'
|
||||
import { highlightColor } from '../utils/highlightColor'
|
||||
@@ -11,8 +21,20 @@ type LevelDetailsProps = {
|
||||
onPromote: () => void
|
||||
}
|
||||
|
||||
export const LevelDetails = ({ selectedLevel, nextLevel, maxCapabilityCount, note, onPromote }: LevelDetailsProps) => (
|
||||
<Paper sx={{ p: 4, border: (theme) => `1px dashed ${theme.palette.divider}`, bgcolor: 'background.paper' }}>
|
||||
export const LevelDetails = ({
|
||||
selectedLevel,
|
||||
nextLevel,
|
||||
maxCapabilityCount,
|
||||
note,
|
||||
onPromote,
|
||||
}: LevelDetailsProps) => (
|
||||
<Paper
|
||||
sx={{
|
||||
p: 4,
|
||||
border: theme => `1px dashed ${theme.palette.divider}`,
|
||||
bgcolor: 'background.paper',
|
||||
}}
|
||||
>
|
||||
<Stack spacing={2}>
|
||||
<Stack direction="row" alignItems="center" spacing={1}>
|
||||
<Typography variant="h5">Selected level details</Typography>
|
||||
@@ -22,7 +44,7 @@ export const LevelDetails = ({ selectedLevel, nextLevel, maxCapabilityCount, not
|
||||
{selectedLevel.description}
|
||||
</Typography>
|
||||
<Stack direction="row" spacing={1} flexWrap="wrap">
|
||||
{selectedLevel.capabilities.map((capability) => (
|
||||
{selectedLevel.capabilities.map(capability => (
|
||||
<Chip
|
||||
key={capability}
|
||||
label={capability}
|
||||
@@ -48,7 +70,8 @@ export const LevelDetails = ({ selectedLevel, nextLevel, maxCapabilityCount, not
|
||||
</Typography>
|
||||
{nextLevel ? (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Promote into <strong>{nextLevel.title}</strong> to unlock {nextLevel.capabilities.length} controls.
|
||||
Promote into <strong>{nextLevel.title}</strong> to unlock{' '}
|
||||
{nextLevel.capabilities.length} controls.
|
||||
</Typography>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
|
||||
@@ -10,12 +10,13 @@ type LevelsGridProps = {
|
||||
|
||||
export const LevelsGrid = ({ levels, selectedLevelId, onSelect }: LevelsGridProps) => (
|
||||
<Grid container spacing={3}>
|
||||
{levels.map((level) => (
|
||||
{levels.map(level => (
|
||||
<Grid item xs={12} md={6} lg={4} key={level.id} component="div">
|
||||
<Paper
|
||||
onClick={() => onSelect(level.id)}
|
||||
sx={{
|
||||
border: (theme) => `2px solid ${selectedLevelId === level.id ? theme.palette.primary.main : theme.palette.divider}`,
|
||||
border: theme =>
|
||||
`2px solid ${selectedLevelId === level.id ? theme.palette.primary.main : theme.palette.divider}`,
|
||||
p: 3,
|
||||
cursor: 'pointer',
|
||||
position: 'relative',
|
||||
@@ -28,7 +29,9 @@ export const LevelsGrid = ({ levels, selectedLevelId, onSelect }: LevelsGridProp
|
||||
<Box sx={{ position: 'absolute', top: 16, right: 16 }}>
|
||||
<Chip label={level.badge} />
|
||||
</Box>
|
||||
<Typography variant="h6">Level {level.id} · {level.title}</Typography>
|
||||
<Typography variant="h6">
|
||||
Level {level.id} · {level.title}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
|
||||
{level.tagline}
|
||||
</Typography>
|
||||
@@ -36,7 +39,7 @@ export const LevelsGrid = ({ levels, selectedLevelId, onSelect }: LevelsGridProp
|
||||
{level.description}
|
||||
</Typography>
|
||||
<Stack direction="row" spacing={1} flexWrap="wrap">
|
||||
{level.capabilities.slice(0, 3).map((capability) => (
|
||||
{level.capabilities.slice(0, 3).map(capability => (
|
||||
<Chip key={capability} label={capability} size="small" variant="outlined" />
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
@@ -16,51 +16,85 @@ export const PERMISSION_LEVELS: PermissionLevel[] = [
|
||||
badge: '🌍',
|
||||
description: 'Read-only access to marketing, help, and showcase pages without signing in.',
|
||||
tagline: 'Open browsing with zero authentication.',
|
||||
capabilities: ['Access the landing experience', 'Follow feature stories', 'Preview public dashboards'],
|
||||
capabilities: [
|
||||
'Access the landing experience',
|
||||
'Follow feature stories',
|
||||
'Preview public dashboards',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
key: 'user',
|
||||
title: 'User',
|
||||
badge: '🧑💻',
|
||||
description: 'Personalized workspace for building content, saving dashboards, and collaborating.',
|
||||
description:
|
||||
'Personalized workspace for building content, saving dashboards, and collaborating.',
|
||||
tagline: 'Everyday contributors and team members.',
|
||||
capabilities: ['Edit personal settings', 'Manage own content', 'Launch saved dashboards', 'Join shared workflows'],
|
||||
capabilities: [
|
||||
'Edit personal settings',
|
||||
'Manage own content',
|
||||
'Launch saved dashboards',
|
||||
'Join shared workflows',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
key: 'moderator',
|
||||
title: 'Moderator',
|
||||
badge: '🛡️',
|
||||
description: 'Protect the community by triaging flags, reviewing reports, and shaping shared spaces.',
|
||||
description:
|
||||
'Protect the community by triaging flags, reviewing reports, and shaping shared spaces.',
|
||||
tagline: 'Guardians of behavior and tone.',
|
||||
capabilities: ['Moderate discussions', 'Resolve user flags', 'Review incident reports', 'Hide or restore content'],
|
||||
capabilities: [
|
||||
'Moderate discussions',
|
||||
'Resolve user flags',
|
||||
'Review incident reports',
|
||||
'Hide or restore content',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
key: 'admin',
|
||||
title: 'Admin',
|
||||
badge: '🧰',
|
||||
description: 'Tenant administrators who manage users, billing, policies, and broader content sets.',
|
||||
description:
|
||||
'Tenant administrators who manage users, billing, policies, and broader content sets.',
|
||||
tagline: 'Operational control for the tenant layer.',
|
||||
capabilities: ['Manage user accounts', 'Adjust tenant settings', 'Approve packages', 'Oversee moderation queue'],
|
||||
capabilities: [
|
||||
'Manage user accounts',
|
||||
'Adjust tenant settings',
|
||||
'Approve packages',
|
||||
'Oversee moderation queue',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
key: 'god',
|
||||
title: 'God',
|
||||
badge: '🧙♂️',
|
||||
description: 'Blueprint builders who orchestrate workflows, seed packages, and shape the system architecture.',
|
||||
description:
|
||||
'Blueprint builders who orchestrate workflows, seed packages, and shape the system architecture.',
|
||||
tagline: 'Power users with advanced scripting rights.',
|
||||
capabilities: ['Author workflows', 'Compose the builder UI', 'Define multi-tenant templates', 'Seed packages'],
|
||||
capabilities: [
|
||||
'Author workflows',
|
||||
'Compose the builder UI',
|
||||
'Define multi-tenant templates',
|
||||
'Seed packages',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
key: 'supergod',
|
||||
title: 'Super God',
|
||||
badge: '👑',
|
||||
description: 'Full sovereignty over every tenant, infrastructure, and override path in the universe.',
|
||||
description:
|
||||
'Full sovereignty over every tenant, infrastructure, and override path in the universe.',
|
||||
tagline: 'Ultimate authority for platform-level change.',
|
||||
capabilities: ['Assign god roles', 'Transfer ownership', 'Burn and restore tenants', 'Run system-wide audits'],
|
||||
capabilities: [
|
||||
'Assign god roles',
|
||||
'Transfer ownership',
|
||||
'Burn and restore tenants',
|
||||
'Run system-wide audits',
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { UnifiedLogin } from '@/components/UnifiedLogin'
|
||||
import { getRoleHomePath } from '@/lib/auth'
|
||||
import { useAuth } from '@/hooks/useAuth'
|
||||
import { getRoleHomePath } from '@/lib/auth'
|
||||
|
||||
export default function LoginPage() {
|
||||
const router = useRouter()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import { readFile, stat } from 'fs/promises'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { getPackageContentType } from '@/lib/packages/server/get-package-content-type'
|
||||
import { resolvePackageFilePath } from '@/lib/packages/server/resolve-package-file-path'
|
||||
|
||||
@@ -29,7 +30,7 @@ export async function GET(_request: Request, { params }: { params: PackageParams
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return NextResponse.json({ error: 'Not found' }, { status: 404 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ import type { Metadata } from 'next'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Home',
|
||||
description: 'Welcome to MetaBuilder - Your data-driven platform with live server status insights',
|
||||
description:
|
||||
'Welcome to MetaBuilder - Your data-driven platform with live server status insights',
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { CssBaseline, ThemeProvider as MuiThemeProvider } from '@mui/material'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { lightTheme, darkTheme } from '@/theme/mui-theme'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import { darkTheme, lightTheme } from '@/theme/mui-theme'
|
||||
|
||||
import { ThemeContext, type ThemeMode } from './theme-context'
|
||||
|
||||
export function Providers({ children }: { children: React.ReactNode }) {
|
||||
@@ -23,7 +25,8 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
||||
|
||||
const resolvedMode = useMemo<Exclude<ThemeMode, 'system'>>(() => {
|
||||
if (mode === 'system') {
|
||||
return typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
return typeof window !== 'undefined' &&
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
? 'dark'
|
||||
: 'light'
|
||||
}
|
||||
@@ -52,9 +55,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
||||
<ThemeContext.Provider value={{ mode, resolvedMode, setMode, toggleTheme }}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
</MuiThemeProvider>
|
||||
</ThemeContext.Provider>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useContext } from 'react'
|
||||
|
||||
import { ThemeContext } from './theme-context'
|
||||
|
||||
export function useTheme() {
|
||||
|
||||
72
frontends/nextjs/src/app/ui/[[...slug]]/page.tsx
Normal file
72
frontends/nextjs/src/app/ui/[[...slug]]/page.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import { Metadata } from 'next'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { UIPageRenderer } from '@/components/ui-page-renderer/UIPageRenderer'
|
||||
import { loadPageFromLuaPackages } from '@/lib/ui-pages/load-page-from-lua-packages'
|
||||
import { loadPageFromDB } from '@/lib/ui-pages/load-page-from-db'
|
||||
|
||||
interface PageProps {
|
||||
params: Promise<{
|
||||
slug?: string[]
|
||||
}>
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic dynamic route for database-driven UI pages
|
||||
* Handles all paths: /ui, /ui/login, /ui/dashboard, etc.
|
||||
*
|
||||
* Flow:
|
||||
* 1. JSON seed data → Database (via import-ui-pages.ts)
|
||||
* 2. Database → Load page record
|
||||
* 3. Lua actions → Execute if present
|
||||
* 4. UIPageRenderer → Generate React components
|
||||
* 5. User sees rendered page
|
||||
*/
|
||||
export default async function DynamicUIPage({ params }: PageProps) {
|
||||
const resolvedParams = await params
|
||||
const slug = resolvedParams.slug || []
|
||||
const path = '/' + slug.join('/')
|
||||
|
||||
// Prefer Lua package-based UI pages, fallback to database-backed pages
|
||||
const pageData = (await loadPageFromLuaPackages(path)) ?? (await loadPageFromDB(path))
|
||||
|
||||
if (!pageData) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
// Check authentication if required
|
||||
// TODO: Add auth check based on pageData.requireAuth and pageData.requiredRole
|
||||
|
||||
return <UIPageRenderer pageData={pageData} />
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate metadata for the page
|
||||
*/
|
||||
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
||||
const resolvedParams = await params
|
||||
const slug = resolvedParams.slug || []
|
||||
const path = '/' + slug.join('/')
|
||||
|
||||
const pageData = (await loadPageFromLuaPackages(path)) ?? (await loadPageFromDB(path))
|
||||
|
||||
if (!pageData) {
|
||||
return {
|
||||
title: 'Page Not Found',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title: pageData.title,
|
||||
description: `MetaBuilder - ${pageData.title}`,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional: Generate static params for known pages
|
||||
* This enables static generation at build time
|
||||
*/
|
||||
export async function generateStaticParams() {
|
||||
// TODO: Query database for all active pages
|
||||
// For now, return empty array (all pages will be dynamic)
|
||||
return []
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { forwardRef } from 'react'
|
||||
import { Button as MuiButton, ButtonProps as MuiButtonProps, CircularProgress } from '@mui/material'
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
/** Button visual style variants */
|
||||
export type ButtonVariant = 'contained' | 'outlined' | 'text' | 'destructive' | 'ghost'
|
||||
@@ -27,11 +27,14 @@ export interface ButtonProps extends Omit<MuiButtonProps, 'variant' | 'size'> {
|
||||
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ variant = 'contained', size = 'medium', loading, disabled, children, sx, ...props }, ref) => {
|
||||
const isIcon = size === 'icon'
|
||||
|
||||
const muiVariant = variant === 'destructive' || variant === 'ghost'
|
||||
? (variant === 'ghost' ? 'text' : 'contained')
|
||||
: variant
|
||||
|
||||
|
||||
const muiVariant =
|
||||
variant === 'destructive' || variant === 'ghost'
|
||||
? variant === 'ghost'
|
||||
? 'text'
|
||||
: 'contained'
|
||||
: variant
|
||||
|
||||
const muiColor = variant === 'destructive' ? 'error' : 'primary'
|
||||
|
||||
return (
|
||||
@@ -58,11 +61,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{loading ? (
|
||||
<CircularProgress size={20} color="inherit" />
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
{loading ? <CircularProgress size={20} color="inherit" /> : children}
|
||||
</MuiButton>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
'use client'
|
||||
|
||||
import { forwardRef } from 'react'
|
||||
import {
|
||||
Checkbox as MuiCheckbox,
|
||||
import {
|
||||
Checkbox as MuiCheckbox,
|
||||
CheckboxProps as MuiCheckboxProps,
|
||||
FormControlLabel,
|
||||
} from '@mui/material'
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
/**
|
||||
* Props for the Checkbox component
|
||||
@@ -16,25 +16,23 @@ export interface CheckboxProps extends MuiCheckboxProps {
|
||||
label?: string
|
||||
}
|
||||
|
||||
const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(
|
||||
({ label, ...props }, ref) => {
|
||||
if (label) {
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={<MuiCheckbox ref={ref} {...props} />}
|
||||
label={label}
|
||||
sx={{
|
||||
'& .MuiFormControlLabel-label': {
|
||||
fontSize: '0.875rem',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return <MuiCheckbox ref={ref} {...props} />
|
||||
const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(({ label, ...props }, ref) => {
|
||||
if (label) {
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={<MuiCheckbox ref={ref} {...props} />}
|
||||
label={label}
|
||||
sx={{
|
||||
'& .MuiFormControlLabel-label': {
|
||||
fontSize: '0.875rem',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return <MuiCheckbox ref={ref} {...props} />
|
||||
})
|
||||
|
||||
Checkbox.displayName = 'Checkbox'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { Radio } from './Radio'
|
||||
|
||||
describe('Radio', () => {
|
||||
|
||||
@@ -1,42 +1,31 @@
|
||||
'use client'
|
||||
|
||||
import { FormControlLabel, Radio as MuiRadio, RadioProps as MuiRadioProps } from '@mui/material'
|
||||
import { forwardRef } from 'react'
|
||||
import {
|
||||
Radio as MuiRadio,
|
||||
RadioProps as MuiRadioProps,
|
||||
FormControlLabel,
|
||||
} from '@mui/material'
|
||||
|
||||
export interface RadioProps extends MuiRadioProps {
|
||||
label?: string
|
||||
}
|
||||
|
||||
const Radio = forwardRef<HTMLButtonElement, RadioProps>(
|
||||
({ label, ...props }, ref) => {
|
||||
const radioElement = (
|
||||
<MuiRadio
|
||||
ref={ref}
|
||||
sx={{
|
||||
'&:hover': {
|
||||
bgcolor: 'action.hover',
|
||||
},
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
const Radio = forwardRef<HTMLButtonElement, RadioProps>(({ label, ...props }, ref) => {
|
||||
const radioElement = (
|
||||
<MuiRadio
|
||||
ref={ref}
|
||||
sx={{
|
||||
'&:hover': {
|
||||
bgcolor: 'action.hover',
|
||||
},
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
if (label) {
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={radioElement}
|
||||
label={label}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return radioElement
|
||||
if (label) {
|
||||
return <FormControlLabel control={radioElement} label={label} />
|
||||
}
|
||||
)
|
||||
|
||||
return radioElement
|
||||
})
|
||||
|
||||
Radio.displayName = 'Radio'
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { forwardRef, type ComponentProps } from 'react'
|
||||
import {
|
||||
Switch as MuiSwitch,
|
||||
FormControlLabel,
|
||||
} from '@mui/material'
|
||||
import { FormControlLabel, Switch as MuiSwitch } from '@mui/material'
|
||||
import { type ComponentProps, forwardRef } from 'react'
|
||||
|
||||
type MuiSwitchProps = ComponentProps<typeof MuiSwitch>
|
||||
|
||||
@@ -17,25 +14,23 @@ export interface SwitchProps extends MuiSwitchProps {
|
||||
label?: string
|
||||
}
|
||||
|
||||
const Switch = forwardRef<HTMLButtonElement, SwitchProps>(
|
||||
({ label, ...props }, ref) => {
|
||||
if (label) {
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={<MuiSwitch ref={ref} {...props} />}
|
||||
label={label}
|
||||
sx={{
|
||||
'& .MuiFormControlLabel-label': {
|
||||
fontSize: '0.875rem',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return <MuiSwitch ref={ref} {...props} />
|
||||
const Switch = forwardRef<HTMLButtonElement, SwitchProps>(({ label, ...props }, ref) => {
|
||||
if (label) {
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={<MuiSwitch ref={ref} {...props} />}
|
||||
label={label}
|
||||
sx={{
|
||||
'& .MuiFormControlLabel-label': {
|
||||
fontSize: '0.875rem',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return <MuiSwitch ref={ref} {...props} />
|
||||
})
|
||||
|
||||
Switch.displayName = 'Switch'
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import { forwardRef } from 'react'
|
||||
import {
|
||||
Avatar as MuiAvatar,
|
||||
AvatarProps as MuiAvatarProps,
|
||||
import {
|
||||
Avatar as MuiAvatar,
|
||||
AvatarGroup as MuiAvatarGroup,
|
||||
AvatarGroupProps as MuiAvatarGroupProps,
|
||||
AvatarProps as MuiAvatarProps,
|
||||
} from '@mui/material'
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
/** Avatar size options */
|
||||
export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
||||
@@ -33,7 +33,7 @@ const sizeMap: Record<AvatarSize, number> = {
|
||||
const Avatar = forwardRef<HTMLDivElement, AvatarProps>(
|
||||
({ size = 'md', fallback, children, sx, ...props }, ref) => {
|
||||
const dimension = sizeMap[size]
|
||||
|
||||
|
||||
return (
|
||||
<MuiAvatar
|
||||
ref={ref}
|
||||
@@ -58,4 +58,4 @@ const AvatarGroup = MuiAvatarGroup
|
||||
const AvatarFallback = ({ children }: { children: React.ReactNode }) => <>{children}</>
|
||||
const AvatarImage = MuiAvatar
|
||||
|
||||
export { Avatar, AvatarGroup, AvatarFallback, AvatarImage }
|
||||
export { Avatar, AvatarFallback, AvatarGroup, AvatarImage }
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
'use client'
|
||||
|
||||
import { forwardRef, HTMLAttributes } from 'react'
|
||||
import { Chip, ChipProps } from '@mui/material'
|
||||
import { forwardRef, HTMLAttributes } from 'react'
|
||||
|
||||
/** Badge visual style variants */
|
||||
export type BadgeVariant = 'default' | 'secondary' | 'destructive' | 'outline' | 'success' | 'warning'
|
||||
export type BadgeVariant =
|
||||
| 'default'
|
||||
| 'secondary'
|
||||
| 'destructive'
|
||||
| 'outline'
|
||||
| 'success'
|
||||
| 'warning'
|
||||
|
||||
/**
|
||||
* Props for the Badge component
|
||||
@@ -15,7 +21,10 @@ export interface BadgeProps extends Omit<ChipProps, 'variant'> {
|
||||
variant?: BadgeVariant
|
||||
}
|
||||
|
||||
const variantMap: Record<BadgeVariant, { color: ChipProps['color']; variant: ChipProps['variant'] }> = {
|
||||
const variantMap: Record<
|
||||
BadgeVariant,
|
||||
{ color: ChipProps['color']; variant: ChipProps['variant'] }
|
||||
> = {
|
||||
default: { color: 'primary', variant: 'filled' },
|
||||
secondary: { color: 'secondary', variant: 'filled' },
|
||||
destructive: { color: 'error', variant: 'filled' },
|
||||
@@ -27,16 +36,8 @@ const variantMap: Record<BadgeVariant, { color: ChipProps['color']; variant: Chi
|
||||
const Badge = forwardRef<HTMLDivElement, BadgeProps>(
|
||||
({ variant = 'default', size = 'small', ...props }, ref) => {
|
||||
const config = variantMap[variant]
|
||||
|
||||
return (
|
||||
<Chip
|
||||
ref={ref}
|
||||
color={config.color}
|
||||
variant={config.variant}
|
||||
size={size}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
return <Chip ref={ref} color={config.color} variant={config.variant} size={size} {...props} />
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { render } from '@testing-library/react'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { Icon } from './Icon'
|
||||
|
||||
describe('Icon', () => {
|
||||
@@ -14,9 +15,7 @@ describe('Icon', () => {
|
||||
})
|
||||
|
||||
it('applies custom sx styles', () => {
|
||||
const { container } = render(
|
||||
<Icon name="Home" sx={{ color: 'primary.main' }} />
|
||||
)
|
||||
const { container } = render(<Icon name="Home" sx={{ color: 'primary.main' }} />)
|
||||
expect(container.querySelector('svg')).not.toBeNull()
|
||||
})
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client'
|
||||
|
||||
import { forwardRef } from 'react'
|
||||
import { SvgIconProps } from '@mui/material'
|
||||
import * as MuiIcons from '@mui/icons-material'
|
||||
import { SvgIconProps } from '@mui/material'
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
export type IconName = keyof typeof MuiIcons
|
||||
export type IconSize = 'small' | 'medium' | 'large' | 'inherit'
|
||||
@@ -15,7 +15,7 @@ export interface IconProps extends Omit<SvgIconProps, 'fontSize'> {
|
||||
const Icon = forwardRef<SVGSVGElement, IconProps>(
|
||||
({ name, size = 'medium', sx, ...props }, ref) => {
|
||||
const IconComponent = MuiIcons[name]
|
||||
|
||||
|
||||
if (!IconComponent) {
|
||||
console.warn(`Icon "${name}" not found in @mui/icons-material`)
|
||||
return null
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { IconButton as MuiIconButton, IconButtonProps as MuiIconButtonProps } from '@mui/material'
|
||||
import { forwardRef } from 'react'
|
||||
import {
|
||||
IconButton as MuiIconButton,
|
||||
IconButtonProps as MuiIconButtonProps,
|
||||
} from '@mui/material'
|
||||
|
||||
/** IconButton size options */
|
||||
export type IconButtonSize = 'small' | 'medium' | 'large'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { forwardRef, LabelHTMLAttributes } from 'react'
|
||||
import { Typography } from '@mui/material'
|
||||
import { forwardRef, LabelHTMLAttributes } from 'react'
|
||||
|
||||
/**
|
||||
* Props for the Label component
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user