diff --git a/.env.example b/.env.example index cd7731e..2e43798 100644 --- a/.env.example +++ b/.env.example @@ -56,4 +56,4 @@ MODEL=gpt-4.1-2025-04-14 ## Trigger ## TRIGGER_PROJECT_ID= TRIGGER_SECRET_KEY= -TRIGGER_API_URL=http://localhost:8030 +TRIGGER_API_URL=http://host.docker.internal:8030 diff --git a/apps/webapp/app/models/message.server.ts b/apps/webapp/app/models/message.server.ts index 2aab004..93bf051 100644 --- a/apps/webapp/app/models/message.server.ts +++ b/apps/webapp/app/models/message.server.ts @@ -6,7 +6,6 @@ import { } from "@remix-run/node"; import { env } from "~/env.server"; -import { createThemeSessionResolver } from "remix-themes"; export type ToastMessage = { message: string; diff --git a/apps/webapp/app/services/sessionStorage.server.ts b/apps/webapp/app/services/sessionStorage.server.ts index 4d26749..ff92c4e 100644 --- a/apps/webapp/app/services/sessionStorage.server.ts +++ b/apps/webapp/app/services/sessionStorage.server.ts @@ -9,7 +9,7 @@ export const sessionStorage = createCookieSessionStorage<{ [SESSION_KEY]: AuthUser; }>({ cookie: { - name: "__session", // use any name you want here + name: "__session__core", // use any name you want here sameSite: "lax", // this helps with CSRF path: "/", // remember to add this so the cookie will work in all routes httpOnly: true, // for security reasons, make this cookie http only diff --git a/packages/core-cli/package.json b/packages/core-cli/package.json index 5c9628c..af80f20 100644 --- a/packages/core-cli/package.json +++ b/packages/core-cli/package.json @@ -1,6 +1,6 @@ { "name": "@redplanethq/core", - "version": "0.1.3", + "version": "0.1.4", "description": "A Command-Line Interface for Core", "type": "module", "license": "MIT", @@ -107,11 +107,13 @@ "nypm": "^0.5.4", "object-hash": "^3.0.0", "open": "^10.0.3", + "knex": "3.1.0", "p-limit": "^6.2.0", "p-retry": "^6.1.0", "partysocket": "^1.0.2", "pkg-types": "^1.1.3", "polka": "^0.5.2", + "pg": "8.16.3", "resolve": "^1.22.8", "semver": "^7.5.0", "signal-exit": "^4.1.0", @@ -121,6 +123,7 @@ "tiny-invariant": "^1.2.0", "tinyexec": "^0.3.1", "tinyglobby": "^0.2.10", + "uuid": "11.1.0", "ws": "^8.18.0", "xdg-app-paths": "^8.3.0", "zod": "3.23.8", diff --git a/packages/core-cli/src/commands/init.ts b/packages/core-cli/src/commands/init.ts index d70bb6c..cc5bfd8 100644 --- a/packages/core-cli/src/commands/init.ts +++ b/packages/core-cli/src/commands/init.ts @@ -5,10 +5,11 @@ import { executeCommandInteractive } from "../utils/docker-interactive.js"; import { printCoreBrainLogo } from "../utils/ascii.js"; import { setupEnvFile } from "../utils/env.js"; import { hasTriggerConfig } from "../utils/env-checker.js"; -import { getDockerCompatibleEnvVars } from "../utils/env-docker.js"; import { handleDockerLogin } from "../utils/docker-login.js"; import { deployTriggerTasks } from "../utils/trigger-deploy.js"; import path from "path"; +import * as fs from "fs"; +import { initTriggerDatabase } from "../utils/database-init.js"; export async function initCommand() { // Display the CORE brain logo @@ -22,9 +23,19 @@ export async function initCommand() { "📋 Prerequisites" ); - const isCoreRepo = await confirm({ - message: "Are you currently in the Core repository directory?", - }); + // Check if package.json name has "core" in it, else exit + const pkgPath = path.join(process.cwd(), "package.json"); + let isCoreRepo = false; + try { + if (fs.existsSync(pkgPath)) { + const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); + if (typeof pkg.name === "string" && pkg.name.includes("core")) { + isCoreRepo = true; + } + } + } catch (err) { + // ignore, will prompt below + } if (!isCoreRepo) { note( @@ -132,58 +143,9 @@ export async function initCommand() { } else { // Step 8: Show login instructions outro("🎉 Docker containers are now running!"); - note( - "1. Open http://localhost:8030 in your browser\n2. Login to Trigger.dev (check container logs with: docker logs trigger-webapp --tail 50)", - "Next Steps" - ); - - const loginConfirmed = await confirm({ - message: "Have you logged in to Trigger.dev successfully?", - }); - - if (!loginConfirmed) { - outro("❌ Setup cancelled. Please login to Trigger.dev first and run the command again."); - process.exit(1); - } - - // Step 9: Get project details - note( - "1. Create a new organization and project\n2. Go to project settings\n3. Copy the Project ID and Secret Key", - "In Trigger.dev (http://localhost:8030)" - ); - - const projectCreated = await confirm({ - message: "Have you created an organization and project in Trigger.dev?", - }); - - if (!projectCreated) { - outro( - "❌ Setup cancelled. Please create an organization and project first and run the command again." - ); - process.exit(1); - } - - // Step 10: Get project ID and secret - const projectId = await text({ - message: "Enter your Trigger.dev Project ID:", - validate: (value) => { - if (!value || value.length === 0) { - return "Project ID is required"; - } - return; - }, - }); - - const secretKey = await text({ - message: "Enter your Trigger.dev Secret Key for production:", - validate: (value) => { - if (!value || value.length === 0) { - return "Secret Key is required"; - } - return; - }, - }); + const { prodSecretKey, projectRefId } = await initTriggerDatabase(triggerDir); + console.log(prodSecretKey, projectRefId); const openaiApiKey = await text({ message: "Enter your OpenAI API Key:", validate: (value) => { @@ -199,8 +161,8 @@ export async function initCommand() { s6.start("Updating .env with Trigger.dev configuration..."); try { - await updateEnvFile(envPath, "TRIGGER_PROJECT_ID", projectId as string); - await updateEnvFile(envPath, "TRIGGER_SECRET_KEY", secretKey as string); + await updateEnvFile(envPath, "TRIGGER_PROJECT_ID", projectRefId as string); + await updateEnvFile(envPath, "TRIGGER_SECRET_KEY", prodSecretKey as string); await updateEnvFile(envPath, "OPENAI_API_KEY", openaiApiKey as string); s6.stop("✅ Updated .env with Trigger.dev configuration"); } catch (error: any) { diff --git a/packages/core-cli/src/utils/database-init.ts b/packages/core-cli/src/utils/database-init.ts new file mode 100644 index 0000000..a780115 --- /dev/null +++ b/packages/core-cli/src/utils/database-init.ts @@ -0,0 +1,238 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import Knex, { Knex as KnexT } from "knex"; +import { v4 as uuidv4 } from "uuid"; +import nodeCrypto from "node:crypto"; +import dotenv from "dotenv"; +import dotenvExpand from "dotenv-expand"; +import path from "node:path"; +import { log } from "@clack/prompts"; + +// Generate a new token similar to the original: "tr_pat_" + 40 lowercase alphanumeric chars +function generatePersonalToken(count: number) { + const chars = "abcdefghijklmnopqrstuvwxyz0123456789"; + let token = "tr_pat_"; + for (let i = 0; i < count; i++) { + token += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return token; +} + +// Generate tokens internally +const TRIGGER_TOKEN = nodeCrypto.randomBytes(32).toString("hex"); +const COMMON_ID = "9ea0412ea8ef441ca03c7952d011ab56"; +const key = generatePersonalToken(20); + +export async function createOrg(knex: KnexT) { + try { + log.step("Checking for existing CORE user and organization..."); + const existingUser = await knex("User").where({ id: COMMON_ID }).first(); + + if (existingUser) { + log.info("CORE user and organization already exist. Skipping creation."); + return COMMON_ID; // User already exists, return the ID + } + + log.step("Creating CORE user, organization, and org member..."); + // Create new entries using a transaction + await knex.transaction(async (trx) => { + // Create User + await trx("User").insert({ + id: COMMON_ID, + admin: true, + authenticationMethod: "MAGIC_LINK", + displayName: "CORE", + email: "core@heysol.ai", + name: "CORE", + confirmedBasicDetails: true, + updatedAt: new Date(), + }); + + // Create Organization + await trx("Organization").insert({ + id: COMMON_ID, + slug: "CORE", + title: "CORE", + v3Enabled: true, + updatedAt: new Date(), + }); + + // Create OrgMember + await trx("OrgMember").insert({ + id: COMMON_ID, + organizationId: COMMON_ID, + userId: COMMON_ID, + role: "ADMIN", + updatedAt: new Date(), + }); + }); + + log.success("CORE user, organization, and org member created."); + return COMMON_ID; + } catch (error) { + log.error(`Error creating org: ${error}`); + throw new Error(`Error creating org: ${error}`); + } +} + +export async function createPersonalToken(knex: KnexT) { + const id = uuidv4().replace(/-/g, ""); + + log.step("Checking for existing personal access token for CLI user..."); + const existingToken = await knex("PersonalAccessToken") + .where({ userId: COMMON_ID, name: "cli" }) + .first(); + + if (existingToken) { + log.info("Personal access token for CLI already exists. Skipping creation."); + return; + } + + log.step("Creating CLI personal access token..."); + // Generate a new token similar to the original: "tr_pat_" + 40 lowercase alphanumeric chars + + const personalToken = generatePersonalToken(40); + await knex("PersonalAccessToken").insert({ + id, + name: "cli", + userId: COMMON_ID, + updatedAt: new Date(), + obfuscatedToken: personalToken, + hashedToken: hashToken(personalToken), + encryptedToken: {}, + }); + log.success("CLI personal access token created."); +} + +export async function createProject(knex: KnexT) { + try { + log.step("Checking if CORE project already exists for the organization..."); + const existingProject = await knex("Project") + .where({ name: "CORE", organizationId: COMMON_ID }) + .first(); + + if (existingProject) { + log.info( + "CORE project already exists. Skipping creation of project and runtime environments." + ); + // Fetch the prod runtime environment for this project + const prodRuntimeEnv = await knex("RuntimeEnvironment") + .where({ + projectId: existingProject.id, + slug: "prod", + }) + .first(); + + let prodSecret; + if (prodRuntimeEnv && prodRuntimeEnv.apiKey) { + prodSecret = prodRuntimeEnv.apiKey; + } else { + // fallback to old behavior if not found (should not happen) + prodSecret = `tr_prod_${key}`; + } + + return { + projectId: existingProject.id, + prodSecret, + projectRef: existingProject.externalRef || "proj_core", + }; + } + + const id = uuidv4().replace(/-/g, ""); + + log.step("Creating CORE project and runtime environments..."); + await knex.transaction(async (trx) => { + await knex("Project") + .insert({ + id, + name: "CORE", + organizationId: COMMON_ID, + slug: "CORE", + externalRef: `proj_core`, + version: "V3", + updatedAt: new Date(), + }) + .transacting(trx); + + await knex("RuntimeEnvironment") + .insert( + ["dev", "stg", "prod"].map((env: string) => ({ + id: uuidv4(), + slug: env, + apiKey: `tr_${env}_${key}`, + organizationId: COMMON_ID, + orgMemberId: COMMON_ID, + projectId: id, + type: env === "prod" ? "PRODUCTION" : env === "stg" ? "STAGING" : "DEVELOPMENT", + pkApiKey: `tr_pk_${env}${key}`, + shortcode: env, + updatedAt: new Date(), + })) + ) + .transacting(trx); + }); + + log.success("CORE project and runtime environments created."); + return { projectId: id, prodSecret: `tr_prod_${key}`, projectRef: `proj_core` }; + } catch (error) { + log.error(`Error creating project: ${error}`); + throw new Error(`Error creating project: ${error}`); + } +} + +export function encryptToken(value: string) { + const nonce = nodeCrypto.randomBytes(12); + const cipher = nodeCrypto.createCipheriv("aes-256-gcm", TRIGGER_TOKEN, nonce); + + let encrypted = cipher.update(value, "utf8", "hex"); + encrypted += cipher.final("hex"); + + const tag = cipher.getAuthTag().toString("hex"); + + return { + nonce: nonce.toString("hex"), + ciphertext: encrypted, + tag, + }; +} + +export function hashToken(token: string): string { + const hash = nodeCrypto.createHash("sha256"); + hash.update(token); + return hash.digest("hex"); +} + +// Main initialization function +export async function initTriggerDatabase(triggerDir: string) { + const envPath = path.join(triggerDir, ".env"); + log.step(`Loading environment variables from ${envPath}...`); + const envVarsExpand = + dotenvExpand.expand(dotenv.config({ path: envPath, processEnv: {} })).parsed || {}; + + const knex = Knex({ + client: "pg", // Use PostgreSQL as the database client + connection: envVarsExpand.DIRECT_URL?.replace("host.docker.internal", "localhost"), // Database connection URL from environment variable + }); + + try { + log.step("Initializing Trigger.dev database..."); + + // Create organization and user + await createOrg(knex); + + // Create personal access token + await createPersonalToken(knex); + + // Create project and return details + const projectDetails = await createProject(knex); + + log.success("Trigger.dev database initialized successfully."); + + return { + prodSecretKey: projectDetails.prodSecret, + projectRefId: projectDetails.projectRef, + }; + } catch (error) { + log.error(`Initialization failed: ${error}`); + throw new Error(`Initialization failed: ${error}`); + } +} diff --git a/packages/core-cli/src/utils/env-docker.ts b/packages/core-cli/src/utils/env-docker.ts index 06f767d..9fe37e9 100644 --- a/packages/core-cli/src/utils/env-docker.ts +++ b/packages/core-cli/src/utils/env-docker.ts @@ -1,5 +1,5 @@ import path from "path"; -import fs from "fs"; + import dotenv from "dotenv"; import dotenvExpand from "dotenv-expand"; @@ -12,7 +12,6 @@ export async function getDockerCompatibleEnvVars(rootDir: string): Promise= 0.8'} @@ -6141,6 +6153,15 @@ packages: supports-color: optional: true + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -6667,6 +6688,10 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true + esm@3.2.25: + resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} + engines: {node: '>=6'} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -7008,6 +7033,10 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + get-port@5.1.1: resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} engines: {node: '>=8'} @@ -7035,6 +7064,9 @@ packages: get-tsconfig@4.10.1: resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + getopts@2.3.0: + resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==} + giget@1.2.5: resolution: {integrity: sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==} hasBin: true @@ -7321,6 +7353,10 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} + interpret@2.2.0: + resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} + engines: {node: '>= 0.10'} + ioredis@5.6.1: resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==} engines: {node: '>=12.22.0'} @@ -7720,6 +7756,34 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + knex@3.1.0: + resolution: {integrity: sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==} + engines: {node: '>=16'} + hasBin: true + peerDependencies: + better-sqlite3: '*' + mysql: '*' + mysql2: '*' + pg: '*' + pg-native: '*' + sqlite3: '*' + tedious: '*' + peerDependenciesMeta: + better-sqlite3: + optional: true + mysql: + optional: true + mysql2: + optional: true + pg: + optional: true + pg-native: + optional: true + sqlite3: + optional: true + tedious: + optional: true + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -8365,6 +8429,9 @@ packages: ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -8850,6 +8917,43 @@ packages: periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + pg-cloudflare@1.2.7: + resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} + + pg-connection-string@2.6.2: + resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} + + pg-connection-string@2.9.1: + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.10.1: + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.10.3: + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.16.3: + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + picocolors@0.2.1: resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} @@ -9068,6 +9172,22 @@ packages: resolution: {integrity: sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==} engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + posthog-js@1.250.2: resolution: {integrity: sha512-g/H9lJhjhsYPnpxntqp36osK7oJ6CFqul2+mVUkaacAJUG4DqCG8iawsSnZvvUmapjapbf2HUA7PCRrpRsl06A==} peerDependencies: @@ -9523,6 +9643,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + rechoir@0.8.0: + resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} + engines: {node: '>= 10.13.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -9981,6 +10105,10 @@ packages: spdx-license-ids@3.0.21: resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -10229,6 +10357,10 @@ packages: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + tarn@3.0.2: + resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==} + engines: {node: '>=8.0.0'} + tdigest@0.1.2: resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} @@ -10274,6 +10406,10 @@ packages: through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + tildify@2.0.0: + resolution: {integrity: sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==} + engines: {node: '>=8'} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -10690,6 +10826,10 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -16556,6 +16696,8 @@ snapshots: color-convert: 1.9.3 color-string: 1.9.1 + colorette@2.0.19: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -16948,6 +17090,12 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.3.4(supports-color@10.0.0): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 10.0.0 + debug@4.3.7: dependencies: ms: 2.1.3 @@ -17768,6 +17916,8 @@ snapshots: transitivePeerDependencies: - supports-color + esm@3.2.25: {} + espree@9.6.1: dependencies: acorn: 8.15.0 @@ -18209,6 +18359,8 @@ snapshots: get-nonce@1.0.1: {} + get-package-type@0.1.0: {} + get-port@5.1.1: {} get-proto@1.0.1: @@ -18235,6 +18387,8 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + getopts@2.3.0: {} + giget@1.2.5: dependencies: citty: 0.1.6 @@ -18559,6 +18713,8 @@ snapshots: internmap@2.0.3: {} + interpret@2.2.0: {} + ioredis@5.6.1: dependencies: '@ioredis/commands': 1.2.0 @@ -18923,6 +19079,27 @@ snapshots: kleur@4.1.5: {} + knex@3.1.0(pg@8.16.3)(supports-color@10.0.0): + dependencies: + colorette: 2.0.19 + commander: 10.0.1 + debug: 4.3.4(supports-color@10.0.0) + escalade: 3.2.0 + esm: 3.2.25 + get-package-type: 0.1.0 + getopts: 2.3.0 + interpret: 2.2.0 + lodash: 4.17.21 + pg-connection-string: 2.6.2 + rechoir: 0.8.0 + resolve-from: 5.0.0 + tarn: 3.0.2 + tildify: 2.0.0 + optionalDependencies: + pg: 8.16.3 + transitivePeerDependencies: + - supports-color + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -19834,6 +20011,8 @@ snapshots: ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} msgpackr-extract@3.0.3: @@ -20368,6 +20547,43 @@ snapshots: estree-walker: 3.0.3 is-reference: 3.0.3 + pg-cloudflare@1.2.7: + optional: true + + pg-connection-string@2.6.2: {} + + pg-connection-string@2.9.1: {} + + pg-int8@1.0.1: {} + + pg-pool@3.10.1(pg@8.16.3): + dependencies: + pg: 8.16.3 + + pg-protocol@1.10.3: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.16.3: + dependencies: + pg-connection-string: 2.9.1 + pg-pool: 3.10.1(pg@8.16.3) + pg-protocol: 1.10.3 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.2.7 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + picocolors@0.2.1: {} picocolors@1.1.1: {} @@ -20581,6 +20797,16 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postgres-array@2.0.0: {} + + postgres-bytea@1.0.0: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + posthog-js@1.250.2: dependencies: core-js: 3.43.0 @@ -21145,6 +21371,10 @@ snapshots: readdirp@4.1.2: {} + rechoir@0.8.0: + dependencies: + resolve: 1.22.10 + redent@3.0.0: dependencies: indent-string: 4.0.0 @@ -21740,6 +21970,8 @@ snapshots: spdx-license-ids@3.0.21: {} + split2@4.2.0: {} + sprintf-js@1.0.3: {} ssri@10.0.6: @@ -22064,6 +22296,8 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 + tarn@3.0.2: {} + tdigest@0.1.2: dependencies: bintrees: 1.0.2 @@ -22118,6 +22352,8 @@ snapshots: readable-stream: 2.3.8 xtend: 4.0.2 + tildify@2.0.0: {} + tiny-invariant@1.3.3: {} tinycolor2@1.6.0: {} @@ -22576,6 +22812,8 @@ snapshots: utils-merge@1.0.1: {} + uuid@11.1.0: {} + uuid@9.0.1: {} uvu@0.5.6: