diff --git a/.changeset/breezy-cameras-sit.md b/.changeset/breezy-cameras-sit.md new file mode 100644 index 000000000..336c701ee --- /dev/null +++ b/.changeset/breezy-cameras-sit.md @@ -0,0 +1,8 @@ +--- +"@coursebuilder/adapter-drizzle": major +"utils": major +"@coursebuilder/core": major +"@coursebuilder/ui": major +--- + +adds organizations for multi-tenant diff --git a/.changeset/config.json b/.changeset/config.json index d4e4f7f38..7b2b4905c 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -22,7 +22,6 @@ "epic-web", "pro-nextjs", "astro-party", - "js-visualized", "egghead", "epic-react", "ai-hero", diff --git a/apps/ai-hero/.env.development b/apps/ai-hero/.env.development index b9d82df40..5960cfa81 100644 --- a/apps/ai-hero/.env.development +++ b/apps/ai-hero/.env.development @@ -13,7 +13,7 @@ NEXT_PUBLIC_PRODUCT_DESCRIPTION="From Zero to AI Hero" # App Features CREATE_USER_ON_LOGIN=true LOG_VERIFICATION_URL=true -SKIP_EMAIL=true +SKIP_EMAIL=false SKIP_CK_TAGGING=true DEFAULT_COUNTRY=US diff --git a/apps/ai-hero/package.json b/apps/ai-hero/package.json index c5f3813dd..b46abebbc 100644 --- a/apps/ai-hero/package.json +++ b/apps/ai-hero/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "concurrently --kill-others-on-fail \"npm:dev:*\"", - "dev:next": "next dev --turbo", + "dev:next": "next dev", "dev:inngest": "pnpx inngest-cli@latest dev --no-discovery -u http://localhost:3000/api/inngest", "dev:party": "pnpx partykit dev", "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", @@ -139,6 +139,7 @@ "holy-loader": "^2.2.10", "html-to-text": "^9.0.5", "i": "^0.3.7", + "import-in-the-middle": "^1.11.2", "inngest": "^3.22.5", "intl-segmenter-polyfill": "^0.4.4", "js-cookie": "^3.0.5", diff --git a/apps/ai-hero/src/db/schema.ts b/apps/ai-hero/src/db/schema.ts index 24dae5654..b9d7c002d 100644 --- a/apps/ai-hero/src/db/schema.ts +++ b/apps/ai-hero/src/db/schema.ts @@ -60,4 +60,14 @@ export const { commentsRelations, userPrefs, userPrefsRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, + merchantSubscription, + merchantSubscriptionRelations, + subscription, + subscriptionRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/ai-hero/src/lib/lessons.ts b/apps/ai-hero/src/lib/lessons.ts index 0dc9609de..a1aa47c47 100644 --- a/apps/ai-hero/src/lib/lessons.ts +++ b/apps/ai-hero/src/lib/lessons.ts @@ -1,27 +1,32 @@ import { z } from 'zod' -import { ContentResourceResourceSchema } from '@coursebuilder/core/schemas/content-resource-schema' +import { + ContentResourceResourceSchema, + ContentResourceSchema, +} from '@coursebuilder/core/schemas/content-resource-schema' -export const LessonSchema = z.object({ - id: z.string(), - type: z.string(), - createdById: z.string(), - createdAt: z.coerce.date().nullable(), - updatedAt: z.coerce.date().nullable(), - deletedAt: z.coerce.date().nullable(), - fields: z.object({ - title: z.string().min(2).max(90), - body: z.string().optional(), - slug: z.string(), - description: z.string().optional(), - state: z - .enum(['draft', 'published', 'archived', 'deleted']) - .default('draft'), - visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), - github: z.string().optional(), - gitpod: z.string().optional(), +export const LessonSchema = ContentResourceSchema.merge( + z.object({ + id: z.string(), + type: z.string(), + createdById: z.string(), + createdAt: z.coerce.date().nullable(), + updatedAt: z.coerce.date().nullable(), + deletedAt: z.coerce.date().nullable(), + fields: z.object({ + title: z.string().min(2).max(90), + body: z.string().optional(), + slug: z.string(), + description: z.string().optional(), + state: z + .enum(['draft', 'published', 'archived', 'deleted']) + .default('draft'), + visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), + github: z.string().optional(), + gitpod: z.string().optional(), + }), + resources: z.array(ContentResourceResourceSchema).default([]).nullable(), }), - resources: z.array(ContentResourceResourceSchema).default([]).nullable(), -}) +) export type Lesson = z.infer diff --git a/apps/ai-hero/src/lib/pages-query.ts b/apps/ai-hero/src/lib/pages-query.ts index 3e786022d..5c3984511 100644 --- a/apps/ai-hero/src/lib/pages-query.ts +++ b/apps/ai-hero/src/lib/pages-query.ts @@ -38,7 +38,7 @@ export async function getPages(): Promise { const pagesParsed = z.array(PageSchema).safeParse(pages) if (!pagesParsed.success) { - console.error('Error parsing pages', pagesParsed) + console.debug('Error parsing pages', pagesParsed.error) return [] } diff --git a/apps/astro-party/package.json b/apps/astro-party/package.json index 46faefc29..7d37fe631 100644 --- a/apps/astro-party/package.json +++ b/apps/astro-party/package.json @@ -11,10 +11,10 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", + "db:push": "dotenv drizzle-kit push", "db:studio": "dotenv drizzle-kit studio", "db:seed": "dotenv tsx ./src/db/seed.ts", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:generate": "dotenv drizzle-kit generate", "lint": "next lint", "start": "next start", "typecheck": "tsc --noEmit", diff --git a/apps/astro-party/src/db/schema.ts b/apps/astro-party/src/db/schema.ts index d86787dad..5fb1bc189 100644 --- a/apps/astro-party/src/db/schema.ts +++ b/apps/astro-party/src/db/schema.ts @@ -56,4 +56,10 @@ export const { contentResourceProductRelations, upgradableProducts, upgradableProductsRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/astro-party/src/lib/lessons.ts b/apps/astro-party/src/lib/lessons.ts index 451e20c12..dab35d53e 100644 --- a/apps/astro-party/src/lib/lessons.ts +++ b/apps/astro-party/src/lib/lessons.ts @@ -1,28 +1,33 @@ import { z } from 'zod' -import { ContentResourceResourceSchema } from '@coursebuilder/core/schemas/content-resource-schema' +import { + ContentResourceResourceSchema, + ContentResourceSchema, +} from '@coursebuilder/core/schemas/content-resource-schema' -export const LessonSchema = z.object({ - id: z.string(), - type: z.string(), - createdById: z.string(), - createdAt: z.coerce.date().nullable(), - updatedAt: z.coerce.date().nullable(), - deletedAt: z.coerce.date().nullable(), - fields: z.object({ - title: z.string().min(2).max(90), - body: z.string().optional(), - slug: z.string(), - description: z.string().optional(), - state: z - .enum(['draft', 'published', 'archived', 'deleted']) - .default('draft'), - visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), - github: z.string().optional(), - gitpod: z.string().optional(), +export const LessonSchema = ContentResourceSchema.merge( + z.object({ + id: z.string(), + type: z.string(), + createdById: z.string(), + createdAt: z.coerce.date().nullable(), + updatedAt: z.coerce.date().nullable(), + deletedAt: z.coerce.date().nullable(), + fields: z.object({ + title: z.string().min(2).max(90), + body: z.string().optional(), + slug: z.string(), + description: z.string().optional(), + state: z + .enum(['draft', 'published', 'archived', 'deleted']) + .default('draft'), + visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), + github: z.string().optional(), + gitpod: z.string().optional(), + }), + resources: z.array(ContentResourceResourceSchema).default([]).nullable(), }), - resources: z.array(ContentResourceResourceSchema).default([]).nullable(), -}) +) export type Lesson = z.infer diff --git a/apps/course-builder-video-blog/package.json b/apps/course-builder-video-blog/package.json index 262bb5a29..ece1f09a9 100644 --- a/apps/course-builder-video-blog/package.json +++ b/apps/course-builder-video-blog/package.json @@ -11,9 +11,9 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", + "db:push": "dotenv drizzle-kit push", "db:studio": "dotenv drizzle-kit studio", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:generate": "dotenv drizzle-kit generate", "db:seed": "dotenv tsx ./src/db/seed.ts", "lint": "next lint", "start": "next start", diff --git a/apps/course-builder-video-blog/src/db/schema.ts b/apps/course-builder-video-blog/src/db/schema.ts index 2250657c3..145ac855c 100644 --- a/apps/course-builder-video-blog/src/db/schema.ts +++ b/apps/course-builder-video-blog/src/db/schema.ts @@ -39,4 +39,10 @@ export const { deviceVerificationRelations, deviceAccessToken, deviceAccessTokenRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/course-builder-web/package.json b/apps/course-builder-web/package.json index d2dceebcc..f7580ab9b 100644 --- a/apps/course-builder-web/package.json +++ b/apps/course-builder-web/package.json @@ -11,9 +11,9 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", + "db:push": "dotenv drizzle-kit push", "db:studio": "dotenv drizzle-kit studio", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:generate": "dotenv drizzle-kit generate", "db:seed": "dotenv tsx ./src/db/seed.ts", "lint": "next lint", "start": "next start", diff --git a/apps/course-builder-web/src/db/schema.ts b/apps/course-builder-web/src/db/schema.ts index d86787dad..5fb1bc189 100644 --- a/apps/course-builder-web/src/db/schema.ts +++ b/apps/course-builder-web/src/db/schema.ts @@ -56,4 +56,10 @@ export const { contentResourceProductRelations, upgradableProducts, upgradableProductsRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/egghead/package.json b/apps/egghead/package.json index d40836a1a..1c42fa3a6 100644 --- a/apps/egghead/package.json +++ b/apps/egghead/package.json @@ -11,9 +11,9 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", + "db:push": "dotenv drizzle-kit push", "db:studio": "dotenv drizzle-kit studio", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:generate": "dotenv drizzle-kit generate", "db:seed": "dotenv tsx ./src/db/seed.ts", "lint": "next lint", "start": "next start", diff --git a/apps/egghead/src/app/api/auth/[...nextauth]/route.ts b/apps/egghead/src/app/api/auth/[...nextauth]/route.ts index f372db982..91c8c3ba4 100644 --- a/apps/egghead/src/app/api/auth/[...nextauth]/route.ts +++ b/apps/egghead/src/app/api/auth/[...nextauth]/route.ts @@ -1,5 +1,4 @@ import { GET as authGet, POST as authPost } from '@/server/auth' -import { withSkill } from '@/server/with-skill' -export const GET = withSkill(authGet) -export const POST = withSkill(authPost) +export const GET = authGet +export const POST = authPost diff --git a/apps/egghead/src/db/schema.ts b/apps/egghead/src/db/schema.ts index 81810483e..d72320004 100644 --- a/apps/egghead/src/db/schema.ts +++ b/apps/egghead/src/db/schema.ts @@ -45,4 +45,10 @@ export const { deviceVerificationRelations, deviceAccessToken, deviceAccessTokenRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/epic-react/package.json b/apps/epic-react/package.json index 59fed3f71..60aec6c88 100644 --- a/apps/epic-react/package.json +++ b/apps/epic-react/package.json @@ -11,9 +11,9 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", + "db:push": "dotenv drizzle-kit push", "db:studio": "dotenv drizzle-kit studio", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:generate": "dotenv drizzle-kit generate", "db:seed": "dotenv tsx ./src/db/seed.ts", "lint": "next lint", "start": "next start", diff --git a/apps/epic-react/src/db/schema.ts b/apps/epic-react/src/db/schema.ts index 8eb873aee..158bc6318 100644 --- a/apps/epic-react/src/db/schema.ts +++ b/apps/epic-react/src/db/schema.ts @@ -35,4 +35,10 @@ export const { contributionTypes, contributionTypesRelations, resourceProgress, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/epic-web/package.json b/apps/epic-web/package.json index 1ad6f1d4b..1c8e373b8 100644 --- a/apps/epic-web/package.json +++ b/apps/epic-web/package.json @@ -11,8 +11,8 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:push": "dotenv drizzle-kit push", + "db:generate": "dotenv drizzle-kit generate", "db:studio": "dotenv drizzle-kit studio", "db:seed": "dotenv tsx ./src/db/seed.ts", "lint": "next lint", diff --git a/apps/epic-web/src/db/schema.ts b/apps/epic-web/src/db/schema.ts index 4f31e846e..b23837894 100644 --- a/apps/epic-web/src/db/schema.ts +++ b/apps/epic-web/src/db/schema.ts @@ -65,4 +65,10 @@ export const { userPrefs, userPrefsRelations, lessonProgress, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/go-local-first/src/components/navigation/index.tsx b/apps/go-local-first/src/components/navigation/index.tsx index 4e46817e1..b34cfdd12 100644 --- a/apps/go-local-first/src/components/navigation/index.tsx +++ b/apps/go-local-first/src/components/navigation/index.tsx @@ -3,19 +3,16 @@ import * as React from 'react' import Link from 'next/link' import { useParams, usePathname, useRouter } from 'next/navigation' -import { createAppAbility } from '@/ability' import config from '@/config' -import { env } from '@/env.mjs' import { useFeedback } from '@/feedback-widget/feedback-context' import { useSaleToastNotifier } from '@/hooks/use-sale-toast-notifier' import { api } from '@/trpc/react' import { cn } from '@/utils/cn' -import { Menu, X } from 'lucide-react' +import { X } from 'lucide-react' import { useSession } from 'next-auth/react' import { Button } from '@coursebuilder/ui' -import { useLiveEventToastNotifier } from '../app/use-live-event-toast-notifier' import { useNavLinks } from '../app/use-nav-links' import { LogoMark } from '../logo' import { NavLinkItem } from './nav-link-item' diff --git a/apps/go-local-first/src/db/mysql-table.ts b/apps/go-local-first/src/db/mysql-table.ts index 19daf8e60..4e2ed3e94 100644 --- a/apps/go-local-first/src/db/mysql-table.ts +++ b/apps/go-local-first/src/db/mysql-table.ts @@ -9,5 +9,5 @@ import { mysqlTableCreator } from 'drizzle-orm/mysql-core' */ export const mysqlTable = mysqlTableCreator( (name) => - `${env.DATABASE_TABLE_PREFIX ? `${env.DATABASE_TABLE_PREFIX}_${name}` : ''}${name}`, + `${env.DATABASE_TABLE_PREFIX ? `${env.DATABASE_TABLE_PREFIX}_${name}` : name}`, ) diff --git a/apps/go-local-first/src/db/schema.ts b/apps/go-local-first/src/db/schema.ts index 24dae5654..35a32928c 100644 --- a/apps/go-local-first/src/db/schema.ts +++ b/apps/go-local-first/src/db/schema.ts @@ -60,4 +60,10 @@ export const { commentsRelations, userPrefs, userPrefsRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/go-local-first/src/lib/lessons.ts b/apps/go-local-first/src/lib/lessons.ts index 0dc9609de..a1aa47c47 100644 --- a/apps/go-local-first/src/lib/lessons.ts +++ b/apps/go-local-first/src/lib/lessons.ts @@ -1,27 +1,32 @@ import { z } from 'zod' -import { ContentResourceResourceSchema } from '@coursebuilder/core/schemas/content-resource-schema' +import { + ContentResourceResourceSchema, + ContentResourceSchema, +} from '@coursebuilder/core/schemas/content-resource-schema' -export const LessonSchema = z.object({ - id: z.string(), - type: z.string(), - createdById: z.string(), - createdAt: z.coerce.date().nullable(), - updatedAt: z.coerce.date().nullable(), - deletedAt: z.coerce.date().nullable(), - fields: z.object({ - title: z.string().min(2).max(90), - body: z.string().optional(), - slug: z.string(), - description: z.string().optional(), - state: z - .enum(['draft', 'published', 'archived', 'deleted']) - .default('draft'), - visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), - github: z.string().optional(), - gitpod: z.string().optional(), +export const LessonSchema = ContentResourceSchema.merge( + z.object({ + id: z.string(), + type: z.string(), + createdById: z.string(), + createdAt: z.coerce.date().nullable(), + updatedAt: z.coerce.date().nullable(), + deletedAt: z.coerce.date().nullable(), + fields: z.object({ + title: z.string().min(2).max(90), + body: z.string().optional(), + slug: z.string(), + description: z.string().optional(), + state: z + .enum(['draft', 'published', 'archived', 'deleted']) + .default('draft'), + visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), + github: z.string().optional(), + gitpod: z.string().optional(), + }), + resources: z.array(ContentResourceResourceSchema).default([]).nullable(), }), - resources: z.array(ContentResourceResourceSchema).default([]).nullable(), -}) +) export type Lesson = z.infer diff --git a/apps/pro-aws/package.json b/apps/pro-aws/package.json index 4226d9498..d9de16390 100644 --- a/apps/pro-aws/package.json +++ b/apps/pro-aws/package.json @@ -11,10 +11,10 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", + "db:push": "dotenv drizzle-kit push", "db:studio": "dotenv drizzle-kit studio", "db:seed": "dotenv tsx ./src/db/seed.ts", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:generate": "dotenv drizzle-kit generate", "lint": "next lint", "start": "next start", "typecheck": "tsc --noEmit" diff --git a/apps/pro-aws/src/db/schema.ts b/apps/pro-aws/src/db/schema.ts index 24dae5654..35a32928c 100644 --- a/apps/pro-aws/src/db/schema.ts +++ b/apps/pro-aws/src/db/schema.ts @@ -60,4 +60,10 @@ export const { commentsRelations, userPrefs, userPrefsRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/pro-nextjs/package.json b/apps/pro-nextjs/package.json index ff5d1633e..5d95ec69d 100644 --- a/apps/pro-nextjs/package.json +++ b/apps/pro-nextjs/package.json @@ -15,7 +15,7 @@ "db:studio": "dotenv drizzle-kit studio", "db:seed": "dotenv tsx ./src/db/seed.ts", "db:generate": "dotenv drizzle-kit generate", - "db:migrate": "dotenv drizzle-kit migrate", + "db:migrate": "dotenv drizzle-kit ", "db:introspect": "dotenv drizzle-kit introspect", "lint": "next lint", "start": "next start", diff --git a/apps/pro-nextjs/src/db/schema.ts b/apps/pro-nextjs/src/db/schema.ts index b52a901fa..0d620e968 100644 --- a/apps/pro-nextjs/src/db/schema.ts +++ b/apps/pro-nextjs/src/db/schema.ts @@ -61,4 +61,10 @@ export const { userPrefs, userPrefsRelations, lessonProgress, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/pro-nextjs/src/lib/lessons.ts b/apps/pro-nextjs/src/lib/lessons.ts index 0dc9609de..a1aa47c47 100644 --- a/apps/pro-nextjs/src/lib/lessons.ts +++ b/apps/pro-nextjs/src/lib/lessons.ts @@ -1,27 +1,32 @@ import { z } from 'zod' -import { ContentResourceResourceSchema } from '@coursebuilder/core/schemas/content-resource-schema' +import { + ContentResourceResourceSchema, + ContentResourceSchema, +} from '@coursebuilder/core/schemas/content-resource-schema' -export const LessonSchema = z.object({ - id: z.string(), - type: z.string(), - createdById: z.string(), - createdAt: z.coerce.date().nullable(), - updatedAt: z.coerce.date().nullable(), - deletedAt: z.coerce.date().nullable(), - fields: z.object({ - title: z.string().min(2).max(90), - body: z.string().optional(), - slug: z.string(), - description: z.string().optional(), - state: z - .enum(['draft', 'published', 'archived', 'deleted']) - .default('draft'), - visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), - github: z.string().optional(), - gitpod: z.string().optional(), +export const LessonSchema = ContentResourceSchema.merge( + z.object({ + id: z.string(), + type: z.string(), + createdById: z.string(), + createdAt: z.coerce.date().nullable(), + updatedAt: z.coerce.date().nullable(), + deletedAt: z.coerce.date().nullable(), + fields: z.object({ + title: z.string().min(2).max(90), + body: z.string().optional(), + slug: z.string(), + description: z.string().optional(), + state: z + .enum(['draft', 'published', 'archived', 'deleted']) + .default('draft'), + visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), + github: z.string().optional(), + gitpod: z.string().optional(), + }), + resources: z.array(ContentResourceResourceSchema).default([]).nullable(), }), - resources: z.array(ContentResourceResourceSchema).default([]).nullable(), -}) +) export type Lesson = z.infer diff --git a/apps/value-based-design/package.json b/apps/value-based-design/package.json index ad51c8b4b..191dc3917 100644 --- a/apps/value-based-design/package.json +++ b/apps/value-based-design/package.json @@ -11,10 +11,10 @@ "tunnel": "ngrok http --domain=neatly-diverse-goldfish.ngrok-free.app 3000", "email:preview": "email dev --dir ./src/emails", "build": "next build", - "db:push": "dotenv drizzle-kit push mysql", + "db:push": "dotenv drizzle-kit push", "db:studio": "dotenv drizzle-kit studio", "db:seed": "dotenv tsx ./src/db/seed.ts", - "db:generate": "dotenv drizzle-kit generate mysql", + "db:generate": "dotenv drizzle-kit generate", "lint": "next lint", "start": "next start", "typecheck": "tsc --noEmit", diff --git a/apps/value-based-design/src/db/schema.ts b/apps/value-based-design/src/db/schema.ts index d86787dad..5fb1bc189 100644 --- a/apps/value-based-design/src/db/schema.ts +++ b/apps/value-based-design/src/db/schema.ts @@ -56,4 +56,10 @@ export const { contentResourceProductRelations, upgradableProducts, upgradableProductsRelations, + organization, + organizationRelations, + organizationMemberships, + organizationMembershipRelations, + organizationMembershipRoles, + organizationMembershipRolesRelations, } = getCourseBuilderSchema(mysqlTable) diff --git a/apps/value-based-design/src/lib/lessons.ts b/apps/value-based-design/src/lib/lessons.ts index c60100d0e..86e1bbd66 100644 --- a/apps/value-based-design/src/lib/lessons.ts +++ b/apps/value-based-design/src/lib/lessons.ts @@ -1,28 +1,33 @@ import { z } from 'zod' -import { ContentResourceResourceSchema } from '@coursebuilder/core/schemas/content-resource-schema' +import { + ContentResourceResourceSchema, + ContentResourceSchema, +} from '@coursebuilder/core/schemas/content-resource-schema' -export const LessonSchema = z.object({ - id: z.string(), - type: z.string(), - createdById: z.string(), - createdAt: z.coerce.date().nullable(), - updatedAt: z.coerce.date().nullable(), - deletedAt: z.coerce.date().nullable(), - fields: z.object({ - title: z.string().min(2).max(90), - body: z.string().optional(), - slug: z.string(), - description: z.string().optional(), - state: z - .enum(['draft', 'published', 'archived', 'deleted']) - .default('draft'), - visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), - github: z.string().optional(), - gitpod: z.string().optional(), - isFreeToView: z.boolean().optional(), +export const LessonSchema = ContentResourceSchema.merge( + z.object({ + id: z.string(), + type: z.string(), + createdById: z.string(), + createdAt: z.coerce.date().nullable(), + updatedAt: z.coerce.date().nullable(), + deletedAt: z.coerce.date().nullable(), + fields: z.object({ + title: z.string().min(2).max(90), + body: z.string().optional(), + slug: z.string(), + description: z.string().optional(), + state: z + .enum(['draft', 'published', 'archived', 'deleted']) + .default('draft'), + visibility: z.enum(['public', 'private', 'unlisted']).default('unlisted'), + github: z.string().optional(), + gitpod: z.string().optional(), + isFreeToView: z.boolean().optional(), + }), + resources: z.array(ContentResourceResourceSchema).default([]).nullable(), }), - resources: z.array(ContentResourceResourceSchema).default([]).nullable(), -}) +) export type Lesson = z.infer diff --git a/packages/adapter-drizzle/src/lib/mysql/index.ts b/packages/adapter-drizzle/src/lib/mysql/index.ts index 6eab4b415..28e0976b7 100644 --- a/packages/adapter-drizzle/src/lib/mysql/index.ts +++ b/packages/adapter-drizzle/src/lib/mysql/index.ts @@ -126,6 +126,10 @@ import { getMerchantCustomerSchema } from './schemas/commerce/merchant-customer. import { getMerchantPriceSchema } from './schemas/commerce/merchant-price.js' import { getMerchantProductSchema } from './schemas/commerce/merchant-product.js' import { getMerchantSessionSchema } from './schemas/commerce/merchant-session.js' +import { + getMerchantSubscriptionRelationsSchema, + getMerchantSubscriptionSchema, +} from './schemas/commerce/merchant-subscription.js' import { getPriceSchema } from './schemas/commerce/price.js' import { getProductRelationsSchema, @@ -139,6 +143,10 @@ import { getPurchaseRelationsSchema, getPurchaseSchema, } from './schemas/commerce/purchase.js' +import { + getSubscriptionRelationsSchema, + getSubscriptionSchema, +} from './schemas/commerce/subscription.js' import { getUpgradableProductsRelationsSchema, getUpgradableProductsSchema, @@ -188,6 +196,18 @@ import { getTagTagSchema, } from './schemas/content/tag-tag.js' import { getTagRelationsSchema, getTagSchema } from './schemas/content/tag.js' +import { + getOrganizationMembershipRolesRelationsSchema, + getOrganizationMembershipRolesSchema, +} from './schemas/org/organization-membership-roles.js' +import { + getOrganizationMembershipsRelationsSchema, + getOrganizationMembershipsSchema, +} from './schemas/org/organization-memberships.js' +import { + getOrganizationsRelationsSchema, + getOrganizationsSchema, +} from './schemas/org/organizations.js' export const guid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 5) @@ -271,6 +291,20 @@ export function getCourseBuilderSchema(mysqlTable: MySqlTableFn) { tagTagRelations: getTagTagRelationsSchema(mysqlTable), userPrefs: getUserPrefsSchema(mysqlTable), userPrefsRelations: getUserPrefsRelationsSchema(mysqlTable), + organization: getOrganizationsSchema(mysqlTable), + organizationRelations: getOrganizationsRelationsSchema(mysqlTable), + organizationMemberships: getOrganizationMembershipsSchema(mysqlTable), + organizationMembershipRelations: + getOrganizationMembershipsRelationsSchema(mysqlTable), + organizationMembershipRoles: + getOrganizationMembershipRolesSchema(mysqlTable), + organizationMembershipRolesRelations: + getOrganizationMembershipRolesRelationsSchema(mysqlTable), + merchantSubscription: getMerchantSubscriptionSchema(mysqlTable), + merchantSubscriptionRelations: + getMerchantSubscriptionRelationsSchema(mysqlTable), + subscription: getSubscriptionSchema(mysqlTable), + subscriptionRelations: getSubscriptionRelationsSchema(mysqlTable), } as const } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/device-access-token.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/device-access-token.ts index e3a5450f5..16bb24900 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/device-access-token.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/device-access-token.ts @@ -15,6 +15,9 @@ export function getDeviceAccessTokenSchema(mysqlTable: MySqlTableFn) { { token: varchar('token', { length: 191 }).notNull(), userId: varchar('userId', { length: 191 }).notNull(), + organizationMembershipId: varchar('organizationMembershipId', { + length: 191, + }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3, diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/roles.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/roles.ts index b6807a931..f7e447107 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/roles.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/roles.ts @@ -15,6 +15,7 @@ export function getRolesSchema(mysqlTable: MySqlTableFn) { 'Role', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), name: varchar('name', { length: 255 }).notNull().unique(), description: text('description'), active: boolean('active').notNull().default(true), @@ -33,6 +34,7 @@ export function getRolesSchema(mysqlTable: MySqlTableFn) { }, (role) => ({ nameIdx: index('name_idx').on(role.name), + organizationIdIdx: index('organizationId_idx').on(role.organizationId), }), ) } @@ -40,6 +42,7 @@ export function getRolesSchema(mysqlTable: MySqlTableFn) { export function getRolesRelationsSchema(mysqlTable: MySqlTableFn) { const roles = getRolesSchema(mysqlTable) const userRoles = getUserRolesSchema(mysqlTable) + return relations(roles, ({ many }) => ({ userRoles: many(userRoles, { relationName: 'role' }), })) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-permissions.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-permissions.ts index 2ea113c7a..1396ee6d5 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-permissions.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-permissions.ts @@ -16,6 +16,7 @@ export function getUserPermissionsSchema(mysqlTable: MySqlTableFn) { 'UserPermission', { userId: varchar('userId', { length: 255 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), permissionId: varchar('permissionId', { length: 255 }).notNull(), active: boolean('active').notNull().default(true), createdAt: timestamp('createdAt', { @@ -35,6 +36,7 @@ export function getUserPermissionsSchema(mysqlTable: MySqlTableFn) { pk: primaryKey({ columns: [up.userId, up.permissionId] }), userIdIdx: index('userId_idx').on(up.userId), permissionIdIdx: index('permissionId_idx').on(up.permissionId), + organizationIdIdx: index('organizationId_idx').on(up.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-prefs.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-prefs.ts index c3304f2c1..c2f67abc9 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-prefs.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-prefs.ts @@ -16,6 +16,7 @@ export function getUserPrefsSchema(mysqlTable: MySqlTableFn) { 'UserPrefs', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), type: varchar('type', { length: 191 }).default('Global').notNull(), userId: varchar('userId', { length: 255 }).notNull(), fields: json('fields').$type>().default({}), @@ -35,6 +36,7 @@ export function getUserPrefsSchema(mysqlTable: MySqlTableFn) { (crr) => ({ pk: primaryKey({ columns: [crr.id] }), crrUserIdIdKey: index('crr_userIdId_idx').on(crr.userId), + organizationIdIdx: index('organizationId_idx').on(crr.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-roles.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-roles.ts index fa59c4d3a..ee44cecba 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-roles.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/user-roles.ts @@ -18,6 +18,7 @@ export function getUserRolesSchema(mysqlTable: MySqlTableFn) { userId: varchar('userId', { length: 255 }).notNull(), roleId: varchar('roleId', { length: 255 }).notNull(), active: boolean('active').notNull().default(true), + organizationId: varchar('organizationId', { length: 191 }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3, @@ -35,6 +36,7 @@ export function getUserRolesSchema(mysqlTable: MySqlTableFn) { pk: primaryKey({ columns: [ur.userId, ur.roleId] }), userIdIdx: index('userId_idx').on(ur.userId), roleIdIdx: index('roleId_idx').on(ur.roleId), + organizationIdIdx: index('organizationId_idx').on(ur.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/users.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/users.ts index 2d6735cf8..77316ff5c 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/auth/users.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/auth/users.ts @@ -13,6 +13,7 @@ import { getCommentsSchema } from '../communication/comment.js' import { getCommunicationPreferencesSchema } from '../communication/communication-preferences.js' import { getContentContributionsSchema } from '../content/content-contributions.js' import { getContentResourceSchema } from '../content/content-resource.js' +import { getOrganizationMembershipsSchema } from '../org/organization-memberships.js' import { getAccountsSchema } from './accounts.js' import { getUserPermissionsSchema } from './user-permissions.js' import { getUserPrefsSchema } from './user-prefs.js' @@ -56,6 +57,7 @@ export function getUsersRelationsSchema(mysqlTable: MySqlTableFn) { const purchases = getPurchaseSchema(mysqlTable) const comments = getCommentsSchema(mysqlTable) const userPrefs = getUserPrefsSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) return relations(users, ({ many }) => ({ accounts: many(accounts, { relationName: 'user', @@ -84,5 +86,8 @@ export function getUsersRelationsSchema(mysqlTable: MySqlTableFn) { prefs: many(userPrefs, { relationName: 'user', }), + organizationMemberships: many(organizationMemberships, { + relationName: 'user', + }), })) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/coupon.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/coupon.ts index b0f3379ee..2e27107ee 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/coupon.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/coupon.ts @@ -21,6 +21,7 @@ export function getCouponSchema(mysqlTable: MySqlTableFn) { 'Coupon', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), code: varchar('code', { length: 191 }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3 }) .default(sql`CURRENT_TIMESTAMP(3)`) @@ -46,6 +47,7 @@ export function getCouponSchema(mysqlTable: MySqlTableFn) { ), couponId: primaryKey({ columns: [table.id], name: 'Coupon_id' }), couponCodeKey: unique('Coupon_code_key').on(table.code), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-account.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-account.ts index f5b0101d1..f176294fd 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-account.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-account.ts @@ -1,5 +1,6 @@ import { sql } from 'drizzle-orm' import { + index, int, MySqlTableFn, primaryKey, @@ -12,6 +13,7 @@ export function getMerchantAccountSchema(mysqlTable: MySqlTableFn) { 'MerchantAccount', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), status: int('status').default(0).notNull(), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3 }) .default(sql`CURRENT_TIMESTAMP(3)`) @@ -25,6 +27,7 @@ export function getMerchantAccountSchema(mysqlTable: MySqlTableFn) { columns: [table.id], name: 'MerchantAccount_id', }), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-charge.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-charge.ts index e532922b4..62ff58854 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-charge.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-charge.ts @@ -1,5 +1,6 @@ import { relations, sql } from 'drizzle-orm' import { + index, int, MySqlTableFn, primaryKey, @@ -11,12 +12,14 @@ import { import { getMerchantAccountSchema } from './merchant-account.js' import { getMerchantCustomerSchema } from './merchant-customer.js' import { getMerchantProductSchema } from './merchant-product.js' +import { getMerchantSubscriptionSchema } from './merchant-subscription.js' export function getMerchantChargeSchema(mysqlTable: MySqlTableFn) { return mysqlTable( 'MerchantCharge', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), status: int('status').default(0).notNull(), identifier: varchar('identifier', { length: 191 }).notNull(), userId: varchar('userId', { length: 191 }).notNull(), @@ -26,6 +29,9 @@ export function getMerchantChargeSchema(mysqlTable: MySqlTableFn) { merchantProductId: varchar('merchantProductId', { length: 191, }).notNull(), + merchantSubscriptionId: varchar('merchantSubscriptionId', { + length: 191, + }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3 }) .default(sql`CURRENT_TIMESTAMP(3)`) .notNull(), @@ -42,6 +48,10 @@ export function getMerchantChargeSchema(mysqlTable: MySqlTableFn) { merchantChargeIdentifierKey: unique('MerchantCharge_identifier_key').on( table.identifier, ), + merchantSubscriptionIdIdx: index('merchantSubscriptionId_idx').on( + table.merchantSubscriptionId, + ), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) @@ -52,6 +62,7 @@ export function getMerchantChargeRelationsSchema(mysqlTable: MySqlTableFn) { const merchantAccount = getMerchantAccountSchema(mysqlTable) const merchantProduct = getMerchantProductSchema(mysqlTable) const merchantCustomer = getMerchantCustomerSchema(mysqlTable) + const merchantSubscription = getMerchantSubscriptionSchema(mysqlTable) return relations(merchantCharge, ({ one }) => ({ merchantAccount: one(merchantAccount, { fields: [merchantCharge.merchantAccountId], @@ -68,5 +79,10 @@ export function getMerchantChargeRelationsSchema(mysqlTable: MySqlTableFn) { references: [merchantCustomer.id], relationName: 'merchantCustomer', }), + merchantSubscription: one(merchantSubscription, { + fields: [merchantCharge.merchantSubscriptionId], + references: [merchantSubscription.id], + relationName: 'merchantSubscription', + }), })) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-coupon.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-coupon.ts index 97d7150ac..e0d4c5130 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-coupon.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-coupon.ts @@ -1,5 +1,6 @@ import { decimal, + index, int, MySqlTableFn, primaryKey, @@ -13,6 +14,7 @@ export function getMerchantCouponSchema(mysqlTable: MySqlTableFn) { { id: varchar('id', { length: 191 }).notNull(), identifier: varchar('identifier', { length: 191 }), + organizationId: varchar('organizationId', { length: 191 }), status: int('status').default(0).notNull(), merchantAccountId: varchar('merchantAccountId', { length: 191, @@ -32,6 +34,7 @@ export function getMerchantCouponSchema(mysqlTable: MySqlTableFn) { merchantCouponIdentifierKey: unique('MerchantCoupon_identifier_key').on( table.identifier, ), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-customer.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-customer.ts index a1638189f..68aa7386f 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-customer.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-customer.ts @@ -14,6 +14,7 @@ export function getMerchantCustomerSchema(mysqlTable: MySqlTableFn) { 'MerchantCustomer', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), userId: varchar('userId', { length: 191 }).notNull(), merchantAccountId: varchar('merchantAccountId', { length: 191, @@ -34,6 +35,7 @@ export function getMerchantCustomerSchema(mysqlTable: MySqlTableFn) { 'MerchantCustomer_identifier_key', ).on(table.identifier), userIdIdx: index('idx_MerchantCustomer_on_userId').on(table.userId), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-price.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-price.ts index 0438159d1..fbe90968e 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-price.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-price.ts @@ -1,5 +1,6 @@ import { sql } from 'drizzle-orm' import { + index, int, MySqlTableFn, primaryKey, @@ -13,6 +14,7 @@ export function getMerchantPriceSchema(mysqlTable: MySqlTableFn) { 'MerchantPrice', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), merchantAccountId: varchar('merchantAccountId', { length: 191, }).notNull(), @@ -35,6 +37,7 @@ export function getMerchantPriceSchema(mysqlTable: MySqlTableFn) { merchantPriceIdentifierKey: unique('MerchantPrice_identifier_key').on( table.identifier, ), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-product.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-product.ts index 542327f45..ebefca5f4 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-product.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-product.ts @@ -1,5 +1,6 @@ import { sql } from 'drizzle-orm' import { + index, int, MySqlTableFn, primaryKey, @@ -13,6 +14,7 @@ export function getMerchantProductSchema(mysqlTable: MySqlTableFn) { 'MerchantProduct', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), merchantAccountId: varchar('merchantAccountId', { length: 191, }).notNull(), @@ -32,6 +34,7 @@ export function getMerchantProductSchema(mysqlTable: MySqlTableFn) { merchantProductIdentifierKey: unique( 'MerchantProduct_identifier_key', ).on(table.identifier), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-session.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-session.ts index 765b89dfa..06239323e 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-session.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-session.ts @@ -1,10 +1,16 @@ -import { MySqlTableFn, primaryKey, varchar } from 'drizzle-orm/mysql-core' +import { + index, + MySqlTableFn, + primaryKey, + varchar, +} from 'drizzle-orm/mysql-core' export function getMerchantSessionSchema(mysqlTable: MySqlTableFn) { return mysqlTable( 'MerchantSession', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), identifier: varchar('identifier', { length: 191 }).notNull(), merchantAccountId: varchar('merchantAccountId', { length: 191, @@ -16,6 +22,7 @@ export function getMerchantSessionSchema(mysqlTable: MySqlTableFn) { columns: [table.id], name: 'MerchantSession_id', }), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-subscription.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-subscription.ts new file mode 100644 index 000000000..1a3ba5999 --- /dev/null +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/merchant-subscription.ts @@ -0,0 +1,64 @@ +import { relations, sql } from 'drizzle-orm' +import { + index, + int, + MySqlTableFn, + primaryKey, + timestamp, + varchar, +} from 'drizzle-orm/mysql-core' + +import { getMerchantChargeSchema } from './merchant-charge.js' +import { getSubscriptionSchema } from './subscription.js' + +export function getMerchantSubscriptionSchema(mysqlTable: MySqlTableFn) { + return mysqlTable( + 'MerchantSubscription', + { + id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), + merchantAccountId: varchar('merchantAccountId', { + length: 191, + }).notNull(), + status: int('status').default(0).notNull(), + createdAt: timestamp('createdAt', { mode: 'date', fsp: 3 }) + .default(sql`CURRENT_TIMESTAMP(3)`) + .notNull(), + label: varchar('label', { length: 191 }), + identifier: varchar('identifier', { length: 191 }), + merchantCustomerId: varchar('merchantCustomerId', { + length: 191, + }).notNull(), + merchantProductId: varchar('merchantProductId', { + length: 191, + }).notNull(), + }, + (table) => { + return { + merchantSubscriptionId: primaryKey({ + columns: [table.id], + name: 'MerchantSubscription_id', + }), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), + } + }, + ) +} + +export function getMerchantSubscriptionRelationsSchema( + mysqlTable: MySqlTableFn, +) { + const merchantSubscription = getMerchantSubscriptionSchema(mysqlTable) + const merchantCharge = getMerchantChargeSchema(mysqlTable) + const subscription = getSubscriptionSchema(mysqlTable) + return relations(merchantSubscription, ({ many, one }) => ({ + merchantCharges: many(merchantCharge, { + relationName: 'merchantSubscription', + }), + subscription: one(subscription, { + fields: [merchantSubscription.id], + references: [subscription.merchantSubscriptionId], + relationName: 'subscription', + }), + })) +} diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/price.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/price.ts index be6976c73..0b905f7cb 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/price.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/price.ts @@ -1,6 +1,7 @@ import { relations, sql } from 'drizzle-orm' import { decimal, + index, int, json, MySqlTableFn, @@ -18,6 +19,7 @@ export function getPriceSchema(mysqlTable: MySqlTableFn) { { id: varchar('id', { length: 191 }).notNull(), productId: varchar('productId', { length: 191 }), + organizationId: varchar('organizationId', { length: 191 }), nickname: varchar('nickname', { length: 191 }), status: int('status').default(0).notNull(), unitAmount: decimal('unitAmount', { precision: 10, scale: 2 }).notNull(), @@ -29,6 +31,7 @@ export function getPriceSchema(mysqlTable: MySqlTableFn) { (table) => { return { priceId: primaryKey({ columns: [table.id], name: 'Price_id' }), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/product.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/product.ts index 83f57e6bd..9e70479b9 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/product.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/product.ts @@ -1,5 +1,6 @@ import { relations, sql } from 'drizzle-orm' import { + index, int, json, MySqlTableFn, @@ -17,6 +18,7 @@ export function getProductSchema(mysqlTable: MySqlTableFn) { 'Product', { id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), name: varchar('name', { length: 191 }).notNull(), key: varchar('key', { length: 191 }), type: varchar('type', { length: 191 }), @@ -30,6 +32,7 @@ export function getProductSchema(mysqlTable: MySqlTableFn) { (table) => { return { productId: primaryKey({ columns: [table.id], name: 'Product_id' }), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase-user-transfer.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase-user-transfer.ts index e5a5b5f36..abca79a11 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase-user-transfer.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase-user-transfer.ts @@ -1,5 +1,6 @@ import { relations, sql } from 'drizzle-orm' import { + index, mysqlEnum, MySqlTableFn, primaryKey, @@ -27,6 +28,7 @@ export function getPurchaseUserTransferSchema(mysqlTable: MySqlTableFn) { .default('AVAILABLE') .notNull(), purchaseId: varchar('purchaseId', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), sourceUserId: varchar('sourceUserId', { length: 191 }).notNull(), targetUserId: varchar('targetUserId', { length: 191 }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3 }) @@ -43,6 +45,7 @@ export function getPurchaseUserTransferSchema(mysqlTable: MySqlTableFn) { columns: [table.id], name: 'PurchaseUserTransfer_id', }), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase.ts index 384df1840..0c5a6ae9f 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/purchase.ts @@ -11,6 +11,8 @@ import { } from 'drizzle-orm/mysql-core' import { getUsersSchema } from '../auth/users.js' +import { getOrganizationMembershipsSchema } from '../org/organization-memberships.js' +import { getOrganizationsSchema } from '../org/organizations.js' import { getCouponSchema } from './coupon.js' import { getMerchantChargeSchema } from './merchant-charge.js' import { getMerchantSessionSchema } from './merchant-session.js' @@ -22,6 +24,10 @@ export function getPurchaseSchema(mysqlTable: MySqlTableFn) { { id: varchar('id', { length: 191 }).notNull(), userId: varchar('userId', { length: 191 }), + purchasedByorganizationMembershipId: varchar('organizationMembershipId', { + length: 191, + }), + organizationId: varchar('organizationId', { length: 191 }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3 }) .default(sql`CURRENT_TIMESTAMP(3)`) .notNull(), @@ -52,6 +58,10 @@ export function getPurchaseSchema(mysqlTable: MySqlTableFn) { purchaseUpgradedFromIdKey: unique('Purchase_upgradedFromId_key').on( table.upgradedFromId, ), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), + organizationMembershipIdIdx: index('organizationMembershipId_idx').on( + table.purchasedByorganizationMembershipId, + ), } }, ) @@ -64,6 +74,8 @@ export function getPurchaseRelationsSchema(mysqlTable: MySqlTableFn) { const merchantCharges = getMerchantChargeSchema(mysqlTable) const merchantSessions = getMerchantSessionSchema(mysqlTable) const coupons = getCouponSchema(mysqlTable) + const organizations = getOrganizationsSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) return relations(purchases, ({ many, one }) => ({ redeemedBulkCoupon: one(coupons, { @@ -76,6 +88,16 @@ export function getPurchaseRelationsSchema(mysqlTable: MySqlTableFn) { references: [users.id], relationName: 'user', }), + organization: one(organizations, { + fields: [purchases.organizationId], + references: [organizations.id], + relationName: 'organization', + }), + purchasedBy: one(organizationMemberships, { + fields: [purchases.purchasedByorganizationMembershipId], + references: [organizationMemberships.id], + relationName: 'organizationMembership', + }), product: one(products, { fields: [purchases.productId], references: [products.id], diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/subscription.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/subscription.ts new file mode 100644 index 000000000..8d83f7dc2 --- /dev/null +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/subscription.ts @@ -0,0 +1,71 @@ +import { relations, sql } from 'drizzle-orm' +import { + index, + json, + MySqlTableFn, + primaryKey, + timestamp, + varchar, +} from 'drizzle-orm/mysql-core' + +import { getUsersSchema } from '../auth/users.js' +import { getOrganizationsSchema } from '../org/organizations.js' +import { getCouponSchema } from './coupon.js' +import { getMerchantChargeSchema } from './merchant-charge.js' +import { getMerchantSessionSchema } from './merchant-session.js' +import { getMerchantSubscriptionSchema } from './merchant-subscription.js' +import { getProductSchema } from './product.js' + +export function getSubscriptionSchema(mysqlTable: MySqlTableFn) { + return mysqlTable( + 'Subscription', + { + id: varchar('id', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), + productId: varchar('productId', { length: 191 }).notNull(), + createdAt: timestamp('createdAt', { mode: 'date', fsp: 3 }) + .default(sql`CURRENT_TIMESTAMP(3)`) + .notNull(), + merchantSubscriptionId: varchar('merchantSubscriptionId', { + length: 191, + }).notNull(), + status: varchar('status', { length: 191 }).default('Valid').notNull(), + fields: json('fields').$type>().default({}), + }, + (table) => { + return { + subscriptionId: primaryKey({ + columns: [table.id], + name: 'Subscription_id', + }), + organizationIdIdx: index('organizationId_idx').on(table.organizationId), + } + }, + ) +} + +export function getSubscriptionRelationsSchema(mysqlTable: MySqlTableFn) { + const subscriptions = getSubscriptionSchema(mysqlTable) + const products = getProductSchema(mysqlTable) + + const organizations = getOrganizationsSchema(mysqlTable) + const merchantSubscriptions = getMerchantSubscriptionSchema(mysqlTable) + + return relations(subscriptions, ({ many, one }) => ({ + organization: one(organizations, { + fields: [subscriptions.organizationId], + references: [organizations.id], + relationName: 'organization', + }), + product: one(products, { + fields: [subscriptions.productId], + references: [products.id], + relationName: 'product', + }), + merchantSubscription: one(merchantSubscriptions, { + fields: [subscriptions.merchantSubscriptionId], + references: [merchantSubscriptions.id], + relationName: 'merchantSubscription', + }), + })) +} diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/upgradable-products.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/upgradable-products.ts index cc84699dc..16347ff45 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/upgradable-products.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/commerce/upgradable-products.ts @@ -17,6 +17,7 @@ export function getUpgradableProductsSchema(mysqlTable: MySqlTableFn) { { upgradableToId: varchar('upgradableToId', { length: 255 }).notNull(), upgradableFromId: varchar('upgradableFrom', { length: 255 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), position: double('position').notNull().default(0), metadata: json('metadata').$type>().default({}), createdAt: timestamp('createdAt', { @@ -36,6 +37,7 @@ export function getUpgradableProductsSchema(mysqlTable: MySqlTableFn) { pk: primaryKey({ columns: [crr.upgradableToId, crr.upgradableFromId] }), upgradableToIdIdx: index('upgradableFromId_idx').on(crr.upgradableToId), upgradableFromIdIdx: index('upgradableToId_idx').on(crr.upgradableFromId), + organizationIdIdx: index('organizationId_idx').on(crr.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/comment.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/comment.ts index 0bc2adbb7..b2d1d14f5 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/comment.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/comment.ts @@ -10,6 +10,7 @@ import { } from 'drizzle-orm/mysql-core' import { getUsersSchema } from '../auth/users.js' +import { getOrganizationMembershipsSchema } from '../org/organization-memberships.js' export function getCommentsSchema(mysqlTable: MySqlTableFn) { return mysqlTable( @@ -17,6 +18,9 @@ export function getCommentsSchema(mysqlTable: MySqlTableFn) { { id: varchar('id', { length: 191 }).notNull(), userId: varchar('userId', { length: 255 }).notNull(), + organizationMembershipId: varchar('organizationMembershipId', { + length: 255, + }), context: json('context').$type>().default({}), text: text('text').notNull(), createdAt: timestamp('createdAt', { @@ -35,6 +39,9 @@ export function getCommentsSchema(mysqlTable: MySqlTableFn) { (crr) => ({ pk: primaryKey({ columns: [crr.id] }), crrUserIdIdKey: index('crr_userIdId_idx').on(crr.userId), + organizationMembershipIdIdx: index('organizationMembershipId_idx').on( + crr.organizationMembershipId, + ), }), ) } @@ -42,11 +49,17 @@ export function getCommentsSchema(mysqlTable: MySqlTableFn) { export function getCommentRelationsSchema(mysqlTable: MySqlTableFn) { const comment = getCommentsSchema(mysqlTable) const user = getUsersSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) return relations(comment, ({ one }) => ({ user: one(user, { fields: [comment.userId], references: [user.id], relationName: 'user', }), + organizationMembership: one(organizationMemberships, { + fields: [comment.organizationMembershipId], + references: [organizationMemberships.id], + relationName: 'organizationMembership', + }), })) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-channel.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-channel.ts index e8e12da8b..c41c08b8b 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-channel.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-channel.ts @@ -12,6 +12,7 @@ export function getCommunicationChannelSchema(mysqlTable: MySqlTableFn) { 'CommunicationChannel', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), name: varchar('name', { length: 255 }).notNull(), description: text('description'), active: boolean('active').notNull().default(true), @@ -30,6 +31,7 @@ export function getCommunicationChannelSchema(mysqlTable: MySqlTableFn) { }, (cc) => ({ nameIdx: index('name_idx').on(cc.name), + organizationIdIdx: index('organizationId_idx').on(cc.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preference-types.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preference-types.ts index ce91cf5b9..faa405f24 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preference-types.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preference-types.ts @@ -11,6 +11,7 @@ export function getCommunicationPreferenceTypesSchema( ) { return mysqlTable('CommunicationPreferenceType', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), name: varchar('name', { length: 255 }).notNull(), description: text('description'), active: boolean('active').notNull().default(true), diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preferences.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preferences.ts index e865c282d..f26e94004 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preferences.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/communication/communication-preferences.ts @@ -9,6 +9,7 @@ import { } from 'drizzle-orm/mysql-core' import { getUsersSchema } from '../auth/users.js' +import { getOrganizationMembershipsSchema } from '../org/organization-memberships.js' import { getCommunicationChannelSchema } from './communication-channel.js' import { getCommunicationPreferenceTypesSchema } from './communication-preference-types.js' @@ -17,7 +18,11 @@ export function getCommunicationPreferencesSchema(mysqlTable: MySqlTableFn) { 'CommunicationPreference', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), userId: varchar('userId', { length: 255 }).notNull(), + organizationMembershipId: varchar('organizationMembershipId', { + length: 255, + }), channelId: varchar('channelId', { length: 255 }).notNull(), preferenceLevel: mysqlEnum('preferenceLevel', ['low', 'medium', 'high']) .notNull() @@ -49,6 +54,9 @@ export function getCommunicationPreferencesSchema(mysqlTable: MySqlTableFn) { userIdIdx: index('userId_idx').on(cp.userId), preferenceTypeIdx: index('preferenceTypeId_idx').on(cp.preferenceTypeId), channelIdIdx: index('channelId_idx').on(cp.channelId), + organizationMembershipIdIdx: index('organizationMembershipId_idx').on( + cp.organizationMembershipId, + ), }), ) } @@ -61,12 +69,18 @@ export function getCommunicationPreferencesRelationsSchema( const communicationChannel = getCommunicationChannelSchema(mysqlTable) const communicationPreferenceTypes = getCommunicationPreferenceTypesSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) return relations(communicationPreferences, ({ one }) => ({ user: one(users, { fields: [communicationPreferences.userId], references: [users.id], relationName: 'user', }), + organizationMembership: one(organizationMemberships, { + fields: [communicationPreferences.organizationMembershipId], + references: [organizationMemberships.id], + relationName: 'organizationMembership', + }), channel: one(communicationChannel, { fields: [communicationPreferences.channelId], references: [communicationChannel.id], diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-contributions.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-contributions.ts index 868a75276..8f61bf943 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-contributions.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-contributions.ts @@ -8,6 +8,7 @@ import { } from 'drizzle-orm/mysql-core' import { getUsersSchema } from '../auth/users.js' +import { getOrganizationMembershipsSchema } from '../org/organization-memberships.js' import { getContentResourceSchema } from './content-resource.js' import { getContributionTypesSchema } from './contribution-types.js' @@ -17,6 +18,10 @@ export function getContentContributionsSchema(mysqlTable: MySqlTableFn) { { id: varchar('id', { length: 255 }).notNull().primaryKey(), userId: varchar('userId', { length: 255 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), + organizationMembershipId: varchar('organizationMembershipId', { + length: 255, + }), contentId: varchar('contentId', { length: 255 }).notNull(), contributionTypeId: varchar('contributionTypeId', { length: 255, @@ -41,6 +46,9 @@ export function getContentContributionsSchema(mysqlTable: MySqlTableFn) { contributionTypeIdIdx: index('contributionTypeId_idx').on( cc.contributionTypeId, ), + organizationMembershipIdIdx: index('organizationMembershipId_idx').on( + cc.organizationMembershipId, + ), }), ) } @@ -52,6 +60,7 @@ export function getContentContributionRelationsSchema( const users = getUsersSchema(mysqlTable) const contentResource = getContentResourceSchema(mysqlTable) const contributionTypes = getContributionTypesSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) return relations(contentContributions, ({ one }) => ({ user: one(users, { @@ -69,5 +78,10 @@ export function getContentContributionRelationsSchema( references: [contributionTypes.id], relationName: 'contributionType', }), + organizationMembership: one(organizationMemberships, { + fields: [contentContributions.organizationMembershipId], + references: [organizationMemberships.id], + relationName: 'organizationMembership', + }), })) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-product.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-product.ts index dbbdf356a..32b2eec5d 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-product.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-product.ts @@ -18,6 +18,7 @@ export function getContentResourceProductSchema(mysqlTable: MySqlTableFn) { { productId: varchar('productId', { length: 255 }).notNull(), resourceId: varchar('resourceId', { length: 255 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), position: double('position').notNull().default(0), metadata: json('metadata').$type>().default({}), createdAt: timestamp('createdAt', { @@ -37,6 +38,7 @@ export function getContentResourceProductSchema(mysqlTable: MySqlTableFn) { pk: primaryKey({ columns: [crr.productId, crr.resourceId] }), contentResourceIdIdx: index('contentResourceId_idx').on(crr.productId), resourceIdIdx: index('resourceId_idx').on(crr.resourceId), + organizationIdIdx: index('organizationId_idx').on(crr.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-resource.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-resource.ts index 561047300..76329e75a 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-resource.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-resource.ts @@ -19,6 +19,7 @@ export function getContentResourceResourceSchema(mysqlTable: MySqlTableFn) { resourceId: varchar('resourceId', { length: 255 }).notNull(), position: double('position').notNull().default(0), metadata: json('metadata').$type>().default({}), + organizationId: varchar('organizationId', { length: 191 }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3, @@ -36,6 +37,7 @@ export function getContentResourceResourceSchema(mysqlTable: MySqlTableFn) { pk: primaryKey({ columns: [crr.resourceOfId, crr.resourceId] }), contentResourceIdIdx: index('contentResourceId_idx').on(crr.resourceOfId), resourceIdIdx: index('resourceId_idx').on(crr.resourceId), + organizationIdIdx: index('organizationId_idx').on(crr.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-tag.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-tag.ts index 60a64da20..96f7d0291 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-tag.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-tag.ts @@ -18,6 +18,7 @@ export function getContentResourceTagSchema(mysqlTable: MySqlTableFn) { contentResourceId: varchar('contentResourceId', { length: 255, }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), tagId: varchar('tagId', { length: 255 }).notNull(), position: double('position').notNull().default(0), createdAt: timestamp('createdAt', { @@ -36,6 +37,7 @@ export function getContentResourceTagSchema(mysqlTable: MySqlTableFn) { ), tagIdIdx: index('tagId_idx').on(crt.tagId), positionIdx: index('position_idx').on(crt.position), + organizationIdIdx: index('organizationId_idx').on(crt.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-version.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-version.ts index 4f0895bc7..a6e24c19f 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-version.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource-version.ts @@ -17,6 +17,7 @@ export function getContentResourceVersionSchema(mysqlTable: MySqlTableFn) { 'ContentResourceVersion', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), resourceId: varchar('resourceId', { length: 255 }).notNull(), parentVersionId: varchar('parentVersionId', { length: 255 }), versionNumber: int('versionNumber').notNull(), @@ -38,6 +39,7 @@ export function getContentResourceVersionSchema(mysqlTable: MySqlTableFn) { crv.resourceId, crv.versionNumber, ), + organizationIdIdx: index('organizationId_idx').on(crv.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource.ts index 626eb4f17..ef9c6f0d7 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/content-resource.ts @@ -8,6 +8,7 @@ import { } from 'drizzle-orm/mysql-core' import { getUsersSchema } from '../auth/users.js' +import { getOrganizationMembershipsSchema } from '../org/organization-memberships.js' import { getContentContributionsSchema } from './content-contributions.js' import { getContentResourceProductSchema } from './content-resource-product.js' import { getContentResourceResourceSchema } from './content-resource-resource.js' @@ -20,6 +21,13 @@ export function getContentResourceSchema(mysqlTable: MySqlTableFn) { 'ContentResource', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), + createdByOrganizationMembershipId: varchar( + 'createdByOrganizationMembershipId', + { + length: 191, + }, + ), type: varchar('type', { length: 255 }).notNull(), createdById: varchar('createdById', { length: 255 }).notNull(), fields: json('fields').$type>().default({}), @@ -44,6 +52,9 @@ export function getContentResourceSchema(mysqlTable: MySqlTableFn) { currentVersionIdIdx: index('currentVersionId_idx').on( cm.currentVersionId, ), + createdByOrganizationMembershipIdIdx: index( + 'createdByOrganizationMembershipId_idx', + ).on(cm.createdByOrganizationMembershipId), }), ) } @@ -56,6 +67,7 @@ export function getContentResourceRelationsSchema(mysqlTable: MySqlTableFn) { const contentContributions = getContentContributionsSchema(mysqlTable) const contentResourceTag = getContentResourceTagSchema(mysqlTable) const contentResourceVersion = getContentResourceVersionSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) const tag = getTagSchema(mysqlTable) return relations(contentResource, ({ one, many }) => ({ createdBy: one(users, { @@ -63,6 +75,11 @@ export function getContentResourceRelationsSchema(mysqlTable: MySqlTableFn) { references: [users.id], relationName: 'creator', }), + createdByOrganizationMembership: one(organizationMemberships, { + fields: [contentResource.createdByOrganizationMembershipId], + references: [organizationMemberships.id], + relationName: 'createdByOrganizationMembership', + }), tags: many(contentResourceTag, { relationName: 'contentResource' }), resources: many(contentResourceResource, { relationName: 'resourceOf' }), resourceOf: many(contentResourceResource, { relationName: 'resource' }), diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/contribution-types.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/contribution-types.ts index 7c55d1f28..49c04a3c3 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/contribution-types.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/contribution-types.ts @@ -15,6 +15,7 @@ export function getContributionTypesSchema(mysqlTable: MySqlTableFn) { 'ContributionType', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), slug: varchar('slug', { length: 255 }).notNull().unique(), name: varchar('name', { length: 255 }).notNull(), description: text('description'), @@ -35,6 +36,7 @@ export function getContributionTypesSchema(mysqlTable: MySqlTableFn) { (ct) => ({ nameIdx: index('name_idx').on(ct.name), slugIdx: index('slug_idx').on(ct.slug), + organizationIdIdx: index('organizationId_idx').on(ct.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/lesson-progress.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/lesson-progress.ts index 1793924e4..43e19afe0 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/lesson-progress.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/lesson-progress.ts @@ -14,6 +14,10 @@ export function getLessonProgressSchema(mysqlTable: MySqlTableFn) { { id: varchar('id', { length: 191 }).notNull().primaryKey(), userId: varchar('userId', { length: 191 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), + organizationMembershipId: varchar('organizationMembershipId', { + length: 191, + }), lessonId: varchar('lessonId', { length: 191 }), lessonSlug: varchar('lessonSlug', { length: 191 }), lessonVersion: varchar('lessonVersion', { length: 191 }), @@ -33,6 +37,9 @@ export function getLessonProgressSchema(mysqlTable: MySqlTableFn) { ), userIdIdx: index('userId_idx').on(crp.userId), lessonIdIdx: index('lessonId_idx').on(crp.lessonId), + organizationMembershipIdIdx: index('organizationMembershipId_idx').on( + crp.organizationMembershipId, + ), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/resource-progress.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/resource-progress.ts index 8244ffc46..9973213e9 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/resource-progress.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/resource-progress.ts @@ -13,6 +13,10 @@ export function getResourceProgressSchema(mysqlTable: MySqlTableFn) { 'ResourceProgress', { userId: varchar('userId', { length: 255 }).notNull(), + organizationId: varchar('organizationId', { length: 191 }), + organizationMembershipId: varchar('organizationMembershipId', { + length: 191, + }), resourceId: varchar('resourceId', { length: 255 }), fields: json('fields').$type>().default({}), completedAt: datetime('completedAt', { mode: 'date', fsp: 3 }), @@ -30,6 +34,9 @@ export function getResourceProgressSchema(mysqlTable: MySqlTableFn) { pk: primaryKey({ columns: [crp.userId, crp.resourceId] }), contentResourceIdIdx: index('contentResourceId_idx').on(crp.resourceId), userIdIdx: index('resourceId_idx').on(crp.userId), + organizationMembershipIdIdx: index('organizationMembershipId_idx').on( + crp.organizationMembershipId, + ), } }, ) diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag-tag.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag-tag.ts index a92b4bc92..fd28d72de 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag-tag.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag-tag.ts @@ -19,6 +19,7 @@ export function getTagTagSchema(mysqlTable: MySqlTableFn) { childTagId: varchar('childTagId', { length: 255 }).notNull(), position: double('position').notNull().default(0), metadata: json('metadata').$type>().default({}), + organizationId: varchar('organizationId', { length: 191 }), createdAt: timestamp('createdAt', { mode: 'date', fsp: 3, @@ -37,6 +38,7 @@ export function getTagTagSchema(mysqlTable: MySqlTableFn) { parentTagIdIdx: index('parentTagId_idx').on(tt.parentTagId), childTagIdIdx: index('childTagId_idx').on(tt.childTagId), positionIdx: index('position_idx').on(tt.position), + organizationIdIdx: index('organizationId_idx').on(tt.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag.ts index 94bdca721..2b6df3e8e 100644 --- a/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag.ts +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/content/tag.ts @@ -15,6 +15,7 @@ export function getTagSchema(mysqlTable: MySqlTableFn) { 'Tag', { id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), type: varchar('type', { length: 255 }).notNull(), fields: json('fields').$type>().default({}), createdAt: timestamp('createdAt', { @@ -32,6 +33,7 @@ export function getTagSchema(mysqlTable: MySqlTableFn) { }, (t) => ({ typeIdx: index('type_idx').on(t.type), + organizationIdIdx: index('organizationId_idx').on(t.organizationId), }), ) } diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/org/organization-membership-roles.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/org/organization-membership-roles.ts new file mode 100644 index 000000000..a86d2c848 --- /dev/null +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/org/organization-membership-roles.ts @@ -0,0 +1,68 @@ +import { relations } from 'drizzle-orm' +import { + boolean, + index, + MySqlTableFn, + primaryKey, + timestamp, + varchar, +} from 'drizzle-orm/mysql-core' + +import { getRolesSchema } from '../auth/roles.js' +import { getOrganizationMembershipsSchema } from './organization-memberships.js' + +export function getOrganizationMembershipRolesSchema(mysqlTable: MySqlTableFn) { + return mysqlTable( + 'OrganizationMembershipRole', + { + organizationMembershipId: varchar('organizationMembershipId', { + length: 255, + }).notNull(), + roleId: varchar('roleId', { length: 255 }).notNull(), + active: boolean('active').notNull().default(true), + organizationId: varchar('organizationId', { length: 191 }), + createdAt: timestamp('createdAt', { + mode: 'date', + fsp: 3, + }).defaultNow(), + updatedAt: timestamp('updatedAt', { + mode: 'date', + fsp: 3, + }).defaultNow(), + deletedAt: timestamp('deletedAt', { + mode: 'date', + fsp: 3, + }), + }, + (ur) => ({ + pk: primaryKey({ + columns: [ur.organizationMembershipId, ur.roleId], + name: 'pk', + }), + orgMemberIdIdx: index('orgMemberId_idx').on(ur.organizationMembershipId), + roleIdIdx: index('roleId_idx').on(ur.roleId), + organizationIdIdx: index('organizationId_idx').on(ur.organizationId), + }), + ) +} + +export function getOrganizationMembershipRolesRelationsSchema( + mysqlTable: MySqlTableFn, +) { + const organizationMembershipRoles = + getOrganizationMembershipRolesSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) + const roles = getRolesSchema(mysqlTable) + return relations(organizationMembershipRoles, ({ one }) => ({ + organizationMembership: one(organizationMemberships, { + fields: [organizationMembershipRoles.organizationMembershipId], + references: [organizationMemberships.id], + relationName: 'organizationMembership', + }), + role: one(roles, { + fields: [organizationMembershipRoles.roleId], + references: [roles.id], + relationName: 'role', + }), + })) +} diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/org/organization-memberships.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/org/organization-memberships.ts new file mode 100644 index 000000000..140a8eae0 --- /dev/null +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/org/organization-memberships.ts @@ -0,0 +1,69 @@ +import { relations, sql } from 'drizzle-orm' +import { + index, + json, + mysqlEnum, + MySqlTableFn, + timestamp, + varchar, +} from 'drizzle-orm/mysql-core' + +import { getUsersSchema } from '../auth/users.js' +import { getPurchaseSchema } from '../commerce/purchase.js' +import { getOrganizationsSchema } from './organizations.js' + +export function getOrganizationMembershipsSchema(mysqlTable: MySqlTableFn) { + return mysqlTable( + 'OrganizationMembership', + { + id: varchar('id', { length: 255 }).notNull().primaryKey(), + organizationId: varchar('organizationId', { length: 191 }), + role: varchar('role', { length: 191 }).notNull().default('user'), + invitedById: varchar('invitedById', { length: 255 }).notNull(), + userId: varchar('userId', { length: 255 }).notNull(), + fields: json('fields').$type>().default({}), + createdAt: timestamp('createdAt', { + mode: 'date', + fsp: 3, + }).default(sql`CURRENT_TIMESTAMP(3)`), + }, + (organizationMembership) => ({ + roleIdx: index('role_idx').on(organizationMembership.role), + createdAtIdx: index('created_at_idx').on( + organizationMembership.createdAt, + ), + organizationIdIdx: index('organizationId_idx').on( + organizationMembership.organizationId, + ), + }), + ) +} + +export function getOrganizationMembershipsRelationsSchema( + mysqlTable: MySqlTableFn, +) { + const users = getUsersSchema(mysqlTable) + + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) + const purchases = getPurchaseSchema(mysqlTable) + const organizations = getOrganizationsSchema(mysqlTable) + + return relations(organizationMemberships, ({ one, many }) => ({ + user: one(users, { + fields: [organizationMemberships.userId], + references: [users.id], + relationName: 'user', + }), + invitedBy: one(users, { + fields: [organizationMemberships.invitedById], + references: [users.id], + relationName: 'invitedBy', + }), + purchases: many(purchases), + organization: one(organizations, { + fields: [organizationMemberships.organizationId], + references: [organizations.id], + relationName: 'organization', + }), + })) +} diff --git a/packages/adapter-drizzle/src/lib/mysql/schemas/org/organizations.ts b/packages/adapter-drizzle/src/lib/mysql/schemas/org/organizations.ts new file mode 100644 index 000000000..59f096c15 --- /dev/null +++ b/packages/adapter-drizzle/src/lib/mysql/schemas/org/organizations.ts @@ -0,0 +1,50 @@ +import { relations, sql } from 'drizzle-orm' +import { + index, + json, + mysqlEnum, + MySqlTableFn, + timestamp, + varchar, +} from 'drizzle-orm/mysql-core' + +import { getPurchaseSchema } from '../commerce/purchase.js' +import { getSubscriptionSchema } from '../commerce/subscription.js' +import { getOrganizationMembershipsSchema } from './organization-memberships.js' + +export function getOrganizationsSchema(mysqlTable: MySqlTableFn) { + return mysqlTable( + 'Organization', + { + id: varchar('id', { length: 255 }).notNull().primaryKey(), + name: varchar('name', { length: 255 }), + fields: json('fields').$type>().default({}), + image: varchar('image', { length: 255 }), + createdAt: timestamp('createdAt', { + mode: 'date', + fsp: 3, + }).default(sql`CURRENT_TIMESTAMP(3)`), + }, + (organization) => ({ + createdAtIdx: index('created_at_idx').on(organization.createdAt), + }), + ) +} + +export function getOrganizationsRelationsSchema(mysqlTable: MySqlTableFn) { + const organizations = getOrganizationsSchema(mysqlTable) + const purchases = getPurchaseSchema(mysqlTable) + const subscriptions = getSubscriptionSchema(mysqlTable) + const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable) + return relations(organizations, ({ many }) => ({ + purchases: many(purchases, { + relationName: 'organization', + }), + subscriptions: many(subscriptions, { + relationName: 'organization', + }), + members: many(organizationMemberships, { + relationName: 'organization', + }), + })) +} diff --git a/packages/core/src/schemas/content-resource-schema.ts b/packages/core/src/schemas/content-resource-schema.ts index 245f25f0d..3bd129c6c 100644 --- a/packages/core/src/schemas/content-resource-schema.ts +++ b/packages/core/src/schemas/content-resource-schema.ts @@ -23,7 +23,8 @@ export const ContentResourceSchema = z.object({ updatedAt: z.coerce.date().nullable(), deletedAt: z.coerce.date().nullable(), resources: z.array(ContentResourceResourceSchema).default([]).nullable(), - organizationId: z.string().nullish(), + organizationId: z.string().nullable(), + createdByOrganizationMembershipId: z.string().nullable(), }) export const ContentResourceProductSchema = z.object({ diff --git a/packages/ui/resources-crud/new-resource-with-video-form.tsx b/packages/ui/resources-crud/new-resource-with-video-form.tsx index 15de8fd8b..3ce98afb1 100644 --- a/packages/ui/resources-crud/new-resource-with-video-form.tsx +++ b/packages/ui/resources-crud/new-resource-with-video-form.tsx @@ -52,7 +52,9 @@ export function NewResourceWithVideoForm({ children, }: { getVideoResource: (idOrSlug?: string) => Promise - createResource: (values: NewResourceWithVideo) => Promise + createResource: ( + values: NewResourceWithVideo, + ) => Promise onResourceCreated: (resource: ContentResource, title: string) => Promise availableResourceTypes?: string[] | undefined className?: string diff --git a/packages/utils/adapter.ts b/packages/utils/adapter.ts index 1a1dce759..afa9b4a09 100644 --- a/packages/utils/adapter.ts +++ b/packages/utils/adapter.ts @@ -256,6 +256,8 @@ export async function runBasicTests(options: TestOptions) { id: id(), type: 'tip', currentVersionId: null, + createdByOrganizationMembershipId: null, + organizationId: null, createdById: user.id, createdAt: new Date(), deletedAt: null, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2321448c7..b99f01f0a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -458,6 +458,9 @@ importers: i: specifier: ^0.3.7 version: 0.3.7 + import-in-the-middle: + specifier: ^1.11.2 + version: 1.11.2 inngest: specifier: ^3.22.5 version: 3.22.5(encoding@0.1.13)(next@15.0.3)(typescript@5.4.5) @@ -6795,7 +6798,7 @@ packages: dependencies: '@astrojs/markdown-remark': 3.5.0(astro@3.6.5) '@mdx-js/mdx': 2.3.0 - acorn: 8.11.3 + acorn: 8.14.0 astro: 3.6.5(@types/node@20.12.5)(typescript@5.4.5) es-module-lexer: 1.4.1 estree-util-visit: 1.2.1 @@ -12649,7 +12652,7 @@ packages: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.52.1 '@types/shimmer': 1.2.0 - import-in-the-middle: 1.11.0 + import-in-the-middle: 1.11.2 require-in-the-middle: 7.4.0 semver: 7.6.0 shimmer: 1.2.1 @@ -17476,7 +17479,7 @@ packages: '@sentry/opentelemetry': 8.26.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1)(@opentelemetry/instrumentation@0.52.1)(@opentelemetry/sdk-trace-base@1.25.1)(@opentelemetry/semantic-conventions@1.25.1) '@sentry/types': 8.26.0 '@sentry/utils': 8.26.0 - import-in-the-middle: 1.11.0 + import-in-the-middle: 1.11.2 optionalDependencies: opentelemetry-instrumentation-fetch-node: 1.2.3(@opentelemetry/api@1.9.0) transitivePeerDependencies: @@ -21168,12 +21171,12 @@ packages: acorn: 8.14.0 dev: false - /acorn-import-attributes@1.9.5(acorn@8.12.1): + /acorn-import-attributes@1.9.5(acorn@8.14.0): resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: acorn: ^8 dependencies: - acorn: 8.12.1 + acorn: 8.14.0 dev: false /acorn-jsx@5.3.2(acorn@8.12.1): @@ -27078,11 +27081,11 @@ packages: parent-module: 1.0.1 resolve-from: 4.0.0 - /import-in-the-middle@1.11.0: - resolution: {integrity: sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==} + /import-in-the-middle@1.11.2: + resolution: {integrity: sha512-gK6Rr6EykBcc6cVWRSBR5TWf8nn6hZMYSRYqCcHa0l0d1fPK7JSYo6+Mlmck76jIX9aL/IZ71c06U2VpFwl1zA==} dependencies: - acorn: 8.12.1 - acorn-import-attributes: 1.9.5(acorn@8.12.1) + acorn: 8.14.0 + acorn-import-attributes: 1.9.5(acorn@8.14.0) cjs-module-lexer: 1.2.3 module-details-from-path: 1.0.3 dev: false @@ -36641,7 +36644,7 @@ packages: /unplugin@1.0.1: resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==} dependencies: - acorn: 8.12.1 + acorn: 8.14.0 chokidar: 3.6.0 webpack-sources: 3.2.3 webpack-virtual-modules: 0.5.0 @@ -36651,7 +36654,7 @@ packages: resolution: {integrity: sha512-CuZtvvO8ua2Wl+9q2jEaqH6m3DoQ38N7pvBYQbbaeNlWGvK2l6GHiKi29aIHDPoSxdUzQ7Unevf1/ugil5X6Pg==} engines: {node: '>=14.0.0'} dependencies: - acorn: 8.11.3 + acorn: 8.14.0 chokidar: 3.6.0 webpack-sources: 3.2.3 webpack-virtual-modules: 0.6.1