+
{
+ if (this.client === undefined) return;
+ this.client.identify({
+ distinctId: user.id,
+ properties: {
+ email: user.email,
+ name: user.name,
+ authenticationMethod: user.authenticationMethod,
+ admin: user.admin,
+ createdAt: user.createdAt,
+ isNewUser,
+ },
+ });
+ },
+ };
+
+ organization = {
+ identify: ({ organization }: { organization: Organization }) => {
+ if (this.client === undefined) return;
+ this.client.groupIdentify({
+ groupType: "organization",
+ groupKey: organization.id,
+ properties: {
+ name: organization.title,
+ slug: organization.slug,
+ createdAt: organization.createdAt,
+ updatedAt: organization.updatedAt,
+ },
+ });
+ },
+ new: ({
+ userId,
+ organization,
+ organizationCount,
+ }: {
+ userId: string;
+ organization: Organization;
+ organizationCount: number;
+ }) => {
+ if (this.client === undefined) return;
+ this.#capture({
+ userId,
+ event: "organization created",
+ organizationId: organization.id,
+ eventProperties: {
+ id: organization.id,
+ slug: organization.slug,
+ title: organization.title,
+ createdAt: organization.createdAt,
+ updatedAt: organization.updatedAt,
+ },
+ userProperties: {
+ organizationCount: organizationCount,
+ },
+ });
+ },
+ };
+
+ workflow = {
+ identify: ({ workflow }: { workflow: Workflow }) => {
+ if (this.client === undefined) return;
+ this.client.groupIdentify({
+ groupType: "workflow",
+ groupKey: workflow.id,
+ properties: {
+ name: workflow.title,
+ slug: workflow.slug,
+ packageJson: workflow.packageJson,
+ jsonSchema: workflow.jsonSchema,
+ createdAt: workflow.createdAt,
+ updatedAt: workflow.updatedAt,
+ organizationId: workflow.organizationId,
+ type: workflow.type,
+ status: workflow.status,
+ externalSourceId: workflow.externalSourceId,
+ service: workflow.service,
+ eventNames: workflow.eventNames,
+ disabledAt: workflow.disabledAt,
+ archivedAt: workflow.archivedAt,
+ isArchived: workflow.isArchived,
+ triggerTtlInSeconds: workflow.triggerTtlInSeconds,
+ },
+ });
+ },
+ new: ({
+ userId,
+ organizationId,
+ workflow,
+ workflowCount,
+ }: {
+ userId: string;
+ organizationId: string;
+ workflow: Workflow;
+ workflowCount: number;
+ }) => {
+ if (this.client === undefined) return;
+ this.#capture({
+ userId,
+ event: "workflow created",
+ organizationId: organizationId,
+ workflowId: workflow.id,
+ eventProperties: {
+ id: workflow.id,
+ slug: workflow.slug,
+ title: workflow.title,
+ packageJson: workflow.packageJson,
+ jsonSchema: workflow.jsonSchema,
+ createdAt: workflow.createdAt,
+ updatedAt: workflow.updatedAt,
+ organizationId: workflow.organizationId,
+ type: workflow.type,
+ status: workflow.status,
+ externalSourceId: workflow.externalSourceId,
+ service: workflow.service,
+ eventNames: workflow.eventNames,
+ disabledAt: workflow.disabledAt,
+ archivedAt: workflow.archivedAt,
+ isArchived: workflow.isArchived,
+ triggerTtlInSeconds: workflow.triggerTtlInSeconds,
+ },
+ userProperties: {
+ workflowCount: workflowCount,
+ },
+ });
+ },
+ };
+
+ workflowRun = {
+ new: ({
+ userId,
+ organizationId,
+ workflowId,
+ workflowRun,
+ runCount,
+ }: {
+ userId: string;
+ organizationId: string;
+ workflowId: string;
+ workflowRun: WorkflowRun;
+ runCount: number;
+ }) => {
+ if (this.client === undefined) return;
+ this.#capture({
+ userId,
+ event: "workflow run created",
+ eventProperties: {
+ id: workflowRun.id,
+ workflowId: workflowRun.workflowId,
+ environmentId: workflowRun.environmentId,
+ eventRuleId: workflowRun.eventRuleId,
+ eventId: workflowRun.eventId,
+ error: workflowRun.error,
+ status: workflowRun.status,
+ attemptCount: workflowRun.attemptCount,
+ createdAt: workflowRun.createdAt,
+ updatedAt: workflowRun.updatedAt,
+ startedAt: workflowRun.startedAt,
+ finishedAt: workflowRun.finishedAt,
+ timedOutAt: workflowRun.timedOutAt,
+ timedOutReason: workflowRun.timedOutReason,
+ isTest: workflowRun.isTest,
+ },
+ userProperties: {
+ runCount: runCount,
+ },
+ organizationId: organizationId,
+ workflowId: workflowId,
+ environmentId: workflowRun.environmentId,
+ });
+ },
+ };
+
+ environment = {
+ identify: ({ environment }: { environment: RuntimeEnvironment }) => {
+ if (this.client === undefined) return;
+ this.client.groupIdentify({
+ groupType: "environment",
+ groupKey: environment.id,
+ properties: {
+ name: environment.slug,
+ slug: environment.slug,
+ organizationId: environment.organizationId,
+ createdAt: environment.createdAt,
+ updatedAt: environment.updatedAt,
+ },
+ });
+ },
+ };
+
+ #capture(event: CaptureEvent) {
+ if (this.client === undefined) return;
+ let groups: Record
= {};
+
+ if (event.organizationId) {
+ groups = {
+ ...groups,
+ organization: event.organizationId,
+ };
+ }
+
+ if (event.workflowId) {
+ groups = {
+ ...groups,
+ workflow: event.workflowId,
+ };
+ }
+
+ if (event.environmentId) {
+ groups = {
+ ...groups,
+ environment: event.environmentId,
+ };
+ }
+
+ let properties: Record = {};
+ if (event.eventProperties) {
+ properties = {
+ ...properties,
+ ...event.eventProperties,
+ };
+ }
+
+ if (event.userProperties) {
+ properties = {
+ ...properties,
+ $set: event.userProperties,
+ };
+ }
+
+ if (event.userOnceProperties) {
+ properties = {
+ ...properties,
+ $set_once: event.userOnceProperties,
+ };
+ }
+
+ const eventData = {
+ distinctId: event.userId,
+ event: event.event,
+ properties,
+ groups,
+ };
+ this.client.capture(eventData);
+ }
+}
+
+type CaptureEvent = {
+ userId: string;
+ event: string;
+ organizationId?: string;
+ workflowId?: string;
+ environmentId?: string;
+ eventProperties?: Record;
+ userProperties?: Record;
+ userOnceProperties?: Record;
+};
+
+export const analytics = new BehaviouralAnalytics(env.POSTHOG_PROJECT_KEY);
diff --git a/apps/webapp/app/services/analyticsEvents/organizationCreated.server.ts b/apps/webapp/app/services/analyticsEvents/organizationCreated.server.ts
new file mode 100644
index 00000000000..3e608ad6cef
--- /dev/null
+++ b/apps/webapp/app/services/analyticsEvents/organizationCreated.server.ts
@@ -0,0 +1,43 @@
+import type { PrismaClient } from "~/db.server";
+import { prisma } from "~/db.server";
+import { analytics } from "../analytics.server";
+
+export class OrganizationCreatedEvent {
+ #prismaClient: PrismaClient;
+
+ constructor(prismaClient: PrismaClient = prisma) {
+ this.#prismaClient = prismaClient;
+ }
+
+ async call(id: string): Promise {
+ const organization = await this.#prismaClient.organization.findUnique({
+ where: { id },
+ include: {
+ users: {
+ select: {
+ id: true,
+ _count: {
+ select: { organizations: true },
+ },
+ },
+ },
+ },
+ });
+
+ if (!organization) {
+ console.error(`Organization ${id} not found`);
+ return false;
+ }
+
+ analytics.organization.identify({ organization });
+ organization.users.forEach((user) => {
+ analytics.organization.new({
+ organization,
+ userId: user.id,
+ organizationCount: user._count.organizations,
+ });
+ });
+
+ return true;
+ }
+}
diff --git a/apps/webapp/app/services/analyticsEvents/workflowCreated.server.ts b/apps/webapp/app/services/analyticsEvents/workflowCreated.server.ts
new file mode 100644
index 00000000000..dadc86b6879
--- /dev/null
+++ b/apps/webapp/app/services/analyticsEvents/workflowCreated.server.ts
@@ -0,0 +1,57 @@
+import type { PrismaClient } from "~/db.server";
+import { prisma } from "~/db.server";
+import { analytics } from "../analytics.server";
+
+export class WorkflowCreatedEvent {
+ #prismaClient: PrismaClient;
+
+ constructor(prismaClient: PrismaClient = prisma) {
+ this.#prismaClient = prismaClient;
+ }
+
+ async call(id: string): Promise {
+ const workflow = await this.#prismaClient.workflow.findUnique({
+ where: { id },
+ include: {
+ organization: {
+ select: {
+ id: true,
+ users: {
+ select: {
+ id: true,
+ organizations: {
+ select: {
+ _count: {
+ select: { workflows: true },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ });
+
+ if (!workflow) {
+ console.error(`Workflow ${id} not found`);
+ return false;
+ }
+
+ analytics.workflow.identify({ workflow });
+ workflow.organization.users.forEach((user) => {
+ const workflowCount = user.organizations.reduce(
+ (acc, org) => acc + org._count.workflows,
+ 0
+ );
+ analytics.workflow.new({
+ workflow,
+ userId: user.id,
+ organizationId: workflow.organizationId,
+ workflowCount,
+ });
+ });
+
+ return true;
+ }
+}
diff --git a/apps/webapp/app/services/analyticsEvents/workflowRunCreated.server.ts b/apps/webapp/app/services/analyticsEvents/workflowRunCreated.server.ts
new file mode 100644
index 00000000000..ff4ce200dc1
--- /dev/null
+++ b/apps/webapp/app/services/analyticsEvents/workflowRunCreated.server.ts
@@ -0,0 +1,71 @@
+import type { PrismaClient } from "~/db.server";
+import { prisma } from "~/db.server";
+import { analytics } from "../analytics.server";
+
+export class WorkflowRunCreatedEvent {
+ #prismaClient: PrismaClient;
+
+ constructor(prismaClient: PrismaClient = prisma) {
+ this.#prismaClient = prismaClient;
+ }
+
+ async call(id: string): Promise {
+ const workflowRun = await this.#prismaClient.workflowRun.findUnique({
+ where: { id },
+ include: {
+ workflow: {
+ select: {
+ id: true,
+ organization: {
+ select: {
+ id: true,
+ users: {
+ select: {
+ id: true,
+ organizations: {
+ select: {
+ workflows: {
+ select: {
+ _count: {
+ select: { runs: true },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ });
+
+ if (!workflowRun) {
+ console.error(`WorkflowRun ${id} not found`);
+ return false;
+ }
+
+ workflowRun.workflow.organization.users.forEach((user) => {
+ const runCount = user.organizations.reduce(
+ (acc, org) =>
+ acc +
+ org.workflows.reduce(
+ (acc, workflow) => acc + workflow._count.runs,
+ 0
+ ),
+ 0
+ );
+ analytics.workflowRun.new({
+ workflowRun,
+ userId: user.id,
+ organizationId: workflowRun.workflow.organization.id,
+ workflowId: workflowRun.workflow.id,
+ runCount,
+ });
+ });
+
+ return true;
+ }
+}
diff --git a/apps/webapp/app/services/emailAuth.server.tsx b/apps/webapp/app/services/emailAuth.server.tsx
index 23af9558570..250449de5aa 100644
--- a/apps/webapp/app/services/emailAuth.server.tsx
+++ b/apps/webapp/app/services/emailAuth.server.tsx
@@ -1,4 +1,3 @@
-import * as emailProvider from "~/services/email.server";
import { EmailLinkStrategy } from "remix-auth-email-link";
import type { Authenticator } from "remix-auth";
import type { AuthUser } from "./authUser";
@@ -6,7 +5,7 @@ import { findOrCreateUser } from "~/models/user.server";
import { env } from "~/env.server";
import { createFirstOrganization } from "~/models/organization.server";
import { sendMagicLinkEmail } from "~/services/email.server";
-import { taskQueue } from "./messageBroker.server";
+import { postAuthentication } from "./postAuth.server";
let secret = env.MAGIC_LINK_SECRET;
if (!secret) throw new Error("Missing MAGIC_LINK_SECRET env variable.");
@@ -33,20 +32,7 @@ const emailStrategy = new EmailLinkStrategy(
authenticationMethod: "MAGIC_LINK",
});
- if (isNewUser) {
- await createFirstOrganization(user);
- await emailProvider.scheduleWelcomeEmail(user);
-
- await taskQueue.publish("SEND_INTERNAL_EVENT", {
- id: user.id,
- name: "user.created",
- payload: {
- id: user.id,
- source: "MAGIC_LINK",
- admin: user.admin,
- },
- });
- }
+ await postAuthentication({ user, isNewUser, loginMethod: "MAGIC_LINK" });
return { userId: user.id };
} catch (error) {
diff --git a/apps/webapp/app/services/events/dispatch.server.ts b/apps/webapp/app/services/events/dispatch.server.ts
index b7727440a7b..986f3fc379a 100644
--- a/apps/webapp/app/services/events/dispatch.server.ts
+++ b/apps/webapp/app/services/events/dispatch.server.ts
@@ -233,6 +233,9 @@ export class DispatchWorkflowRun {
await taskQueue.publish("TRIGGER_WORKFLOW_RUN", {
id: workflowRun.id,
});
+ await taskQueue.publish("WORKFLOW_RUN_CREATED", {
+ id: workflowRun.id,
+ });
return workflowRun;
}
diff --git a/apps/webapp/app/services/gitHubAuth.server.ts b/apps/webapp/app/services/gitHubAuth.server.ts
index 7b5b1a5cc57..0017aad06b8 100644
--- a/apps/webapp/app/services/gitHubAuth.server.ts
+++ b/apps/webapp/app/services/gitHubAuth.server.ts
@@ -6,6 +6,7 @@ import { findOrCreateUser } from "~/models/user.server";
import type { AuthUser } from "./authUser";
import { scheduleWelcomeEmail } from "./email.server";
import { taskQueue } from "./messageBroker.server";
+import { postAuthentication } from "./postAuth.server";
const gitHubStrategy = new GitHubStrategy(
{
@@ -29,20 +30,7 @@ const gitHubStrategy = new GitHubStrategy(
authenticationExtraParams: extraParams,
});
- if (isNewUser) {
- await createFirstOrganization(user);
- await scheduleWelcomeEmail(user);
-
- await taskQueue.publish("SEND_INTERNAL_EVENT", {
- id: user.id,
- name: "user.created",
- payload: {
- id: user.id,
- source: "GITHUB",
- admin: user.admin,
- },
- });
- }
+ await postAuthentication({ user, isNewUser, loginMethod: "GITHUB" });
return {
userId: user.id,
diff --git a/apps/webapp/app/services/messageBroker.server.ts b/apps/webapp/app/services/messageBroker.server.ts
index 20cb6897a4a..a3041a18f5e 100644
--- a/apps/webapp/app/services/messageBroker.server.ts
+++ b/apps/webapp/app/services/messageBroker.server.ts
@@ -55,6 +55,9 @@ import { omit } from "~/utils/objects";
import { findWorkflowStepById } from "~/models/workflowRunStep.server";
import { InitializeRunOnce } from "./runOnce/initializeRunOnce.server";
import { CompleteRunOnce } from "./runOnce/completeRunOnce.server";
+import { OrganizationCreatedEvent } from "./analyticsEvents/organizationCreated.server";
+import { WorkflowCreatedEvent } from "./analyticsEvents/workflowCreated.server";
+import { WorkflowRunCreatedEvent } from "./analyticsEvents/workflowRunCreated.server";
let pulsarClient: PulsarClient;
let triggerPublisher: ZodPublisher;
@@ -460,6 +463,18 @@ const taskQueueCatalog = {
data: z.object({ stepId: z.string(), hasRun: z.boolean() }),
properties: z.object({}),
},
+ ORGANIZATION_CREATED: {
+ data: z.object({ id: z.string() }),
+ properties: z.object({}),
+ },
+ WORKFLOW_CREATED: {
+ data: z.object({ id: z.string() }),
+ properties: z.object({}),
+ },
+ WORKFLOW_RUN_CREATED: {
+ data: z.object({ id: z.string() }),
+ properties: z.object({}),
+ },
};
function createTaskQueue() {
@@ -782,6 +797,30 @@ function createTaskQueue() {
return true;
},
+ ORGANIZATION_CREATED: async (id, data, properties, attributes) => {
+ if (attributes.redeliveryCount >= 4) {
+ return true;
+ }
+
+ const service = new OrganizationCreatedEvent();
+ return service.call(data.id);
+ },
+ WORKFLOW_CREATED: async (id, data, properties, attributes) => {
+ if (attributes.redeliveryCount >= 4) {
+ return true;
+ }
+
+ const service = new WorkflowCreatedEvent();
+ return service.call(data.id);
+ },
+ WORKFLOW_RUN_CREATED: async (id, data, properties, attributes) => {
+ if (attributes.redeliveryCount >= 4) {
+ return true;
+ }
+
+ const service = new WorkflowRunCreatedEvent();
+ return service.call(data.id);
+ },
},
});
diff --git a/apps/webapp/app/services/postAuth.server.ts b/apps/webapp/app/services/postAuth.server.ts
new file mode 100644
index 00000000000..25062400acd
--- /dev/null
+++ b/apps/webapp/app/services/postAuth.server.ts
@@ -0,0 +1,32 @@
+import { createFirstOrganization } from "~/models/organization.server";
+import type { User } from "~/models/user.server";
+import * as emailProvider from "~/services/email.server";
+import { analytics } from "./analytics.server";
+import { taskQueue } from "./messageBroker.server";
+
+export async function postAuthentication({
+ user,
+ loginMethod,
+ isNewUser,
+}: {
+ user: User;
+ loginMethod: User["authenticationMethod"];
+ isNewUser: boolean;
+}) {
+ if (isNewUser) {
+ await createFirstOrganization(user);
+ await emailProvider.scheduleWelcomeEmail(user);
+
+ await taskQueue.publish("SEND_INTERNAL_EVENT", {
+ id: user.id,
+ name: "user.created",
+ payload: {
+ id: user.id,
+ source: loginMethod,
+ admin: user.admin,
+ },
+ });
+ }
+
+ analytics.user.identify({ user, isNewUser });
+}
diff --git a/apps/webapp/app/services/workflows/registerWorkflow.server.ts b/apps/webapp/app/services/workflows/registerWorkflow.server.ts
index bdd5089f2ca..c6c92934b9d 100644
--- a/apps/webapp/app/services/workflows/registerWorkflow.server.ts
+++ b/apps/webapp/app/services/workflows/registerWorkflow.server.ts
@@ -173,6 +173,9 @@ export class RegisterWorkflow {
id: workflow.id,
},
});
+ await taskQueue.publish("WORKFLOW_CREATED", {
+ id: workflow.id,
+ });
}
return workflow;
diff --git a/apps/webapp/package.json b/apps/webapp/package.json
index 0df303eeff6..6a3ee0d289d 100644
--- a/apps/webapp/package.json
+++ b/apps/webapp/package.json
@@ -106,6 +106,7 @@
"openapi-types": "^12.0.0",
"postcss-import": "^14.1.0",
"posthog-js": "^1.31.0",
+ "posthog-node": "^2.4.0",
"pretty-bytes": "^6.0.0",
"prism-react-renderer": "^1.3.5",
"prismjs": "^1.29.0",
diff --git a/flightcontrol.json b/flightcontrol.json
index 5d62d07ec13..6e4daac61b7 100644
--- a/flightcontrol.json
+++ b/flightcontrol.json
@@ -62,9 +62,7 @@
"packages/internal-pulsar/src/**",
"./pnpm-lock.yaml"
],
- "dependsOn": [
- "p-db"
- ],
+ "dependsOn": ["p-db"],
"envVariables": {
"FROM_EMAIL": "hello@email.trigger.dev",
"REPLY_TO_EMAIL": "hello@trigger.dev",
@@ -245,9 +243,7 @@
"packages/internal-pulsar/src/**",
"./pnpm-lock.yaml"
],
- "dependsOn": [
- "s-db"
- ],
+ "dependsOn": ["s-db"],
"envVariables": {
"APP_ENV": "staging",
"FROM_EMAIL": "hello@email.trigger.dev",
@@ -292,6 +288,9 @@
"PIZZLY_SECRET_KEY": {
"fromParameterStore": "/Staging/webapp/PIZZLY_SECRET_KEY"
},
+ "POSTHOG_PROJECT_KEY": {
+ "fromParameterStore": "/Staging/webapp/POSTHOG_PROJECT_KEY"
+ },
"TRIGGER_LOG_LEVEL": "debug",
"PULSAR_ENABLED": "1",
"PULSAR_DEBUG": true
@@ -363,4 +362,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5507848210e..6d6f262ed99 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -146,6 +146,7 @@ importers:
postcss: ^8.4.14
postcss-import: ^14.1.0
posthog-js: ^1.31.0
+ posthog-node: ^2.4.0
prettier: ^2.6.2
prettier-plugin-tailwindcss: ^0.1.13
pretty-bytes: ^6.0.0
@@ -187,7 +188,7 @@ importers:
'@aws-sdk/client-s3': 3.245.0
'@aws-sdk/s3-request-presigner': 3.245.0
'@cfworker/json-schema': 1.12.5
- '@codemirror/autocomplete': 6.4.0_czcfkg2f66rxeiodoti7r2gulu
+ '@codemirror/autocomplete': 6.4.0_eo6pz6bvsllvatnnwfprpuflde
'@codemirror/commands': 6.1.3
'@codemirror/lang-javascript': 6.1.2
'@codemirror/lang-json': 6.0.1
@@ -217,7 +218,7 @@ importers:
'@trigger.dev/slack': link:../../integrations/slack
'@trigger.dev/whatsapp': link:../../integrations/whatsapp
'@typeform/embed-react': 2.14.1_react@18.2.0
- '@uiw/react-codemirror': 4.19.5_k4ec5g7vuuzzonc3d6xbjnmmle
+ '@uiw/react-codemirror': 4.19.5_aguurb4bmecpxzejz52amioxne
bcryptjs: 2.4.3
classnames: 2.3.2
clsx: 1.2.1
@@ -250,6 +251,7 @@ importers:
openapi-types: 12.1.0
postcss-import: 14.1.0_postcss@8.4.21
posthog-js: 1.39.4
+ posthog-node: 2.4.0
pretty-bytes: 6.0.0
prism-react-renderer: 1.3.5_react@18.2.0
prismjs: 1.29.0
@@ -3538,12 +3540,13 @@ packages:
prettier: 2.8.2
dev: false
- /@codemirror/autocomplete/6.4.0_czcfkg2f66rxeiodoti7r2gulu:
+ /@codemirror/autocomplete/6.4.0_eo6pz6bvsllvatnnwfprpuflde:
resolution: {integrity: sha512-HLF2PnZAm1s4kGs30EiqKMgD7XsYaQ0XJnMR0rofEWQ5t5D60SfqpDIkIh1ze5tiEbyUWm8+VJ6W1/erVvBMIA==}
peerDependencies:
'@codemirror/language': ^6.0.0
'@codemirror/state': ^6.0.0
'@codemirror/view': ^6.0.0
+ '@lezer/common': ^1.0.0
dependencies:
'@codemirror/language': 6.3.2
'@codemirror/state': 6.2.0
@@ -3563,7 +3566,7 @@ packages:
/@codemirror/lang-javascript/6.1.2:
resolution: {integrity: sha512-OcwLfZXdQ1OHrLiIcKCn7MqZ7nx205CMKlhe+vL88pe2ymhT9+2P+QhwkYGxMICj8TDHyp8HFKVwpiisUT7iEQ==}
dependencies:
- '@codemirror/autocomplete': 6.4.0_czcfkg2f66rxeiodoti7r2gulu
+ '@codemirror/autocomplete': 6.4.0_eo6pz6bvsllvatnnwfprpuflde
'@codemirror/language': 6.3.2
'@codemirror/lint': 6.1.0
'@codemirror/state': 6.2.0
@@ -4780,7 +4783,7 @@ packages:
eslint: 8.31.0
eslint-import-resolver-node: 0.3.6
eslint-import-resolver-typescript: 3.5.3_hnftvkj7qg3s6bbigj4pr6djxy
- eslint-plugin-import: 2.27.4_2ac3tknkazjoq5fxmuugu665ny
+ eslint-plugin-import: 2.27.4_qdjeohovcytra7xto5vgmxssaq
eslint-plugin-jest: 26.9.0_ohsifnwenhmxgcp7mend4dnv74
eslint-plugin-jest-dom: 4.0.3_eslint@8.31.0
eslint-plugin-jsx-a11y: 6.7.1_eslint@8.31.0
@@ -5901,17 +5904,18 @@ packages:
eslint-visitor-keys: 3.3.0
dev: true
- /@uiw/codemirror-extensions-basic-setup/4.19.5_wd2tsis3in55bkaiwnc2c46tom:
+ /@uiw/codemirror-extensions-basic-setup/4.19.5_tbeldtdcrf45b35pezgkzq2u4e:
resolution: {integrity: sha512-1zt7ZPJ01xKkSW/KDy0FZNga0bngN1fC594wCVG7FBi60ehfcAucpooQ+JSPScKXopxcb+ugPKZvVLzr9/OfzA==}
peerDependencies:
'@codemirror/autocomplete': '>=6.0.0'
'@codemirror/commands': '>=6.0.0'
'@codemirror/language': '>=6.0.0'
+ '@codemirror/lint': '>=6.0.0'
'@codemirror/search': '>=6.0.0'
'@codemirror/state': '>=6.0.0'
'@codemirror/view': '>=6.0.0'
dependencies:
- '@codemirror/autocomplete': 6.4.0_czcfkg2f66rxeiodoti7r2gulu
+ '@codemirror/autocomplete': 6.4.0_eo6pz6bvsllvatnnwfprpuflde
'@codemirror/commands': 6.1.3
'@codemirror/language': 6.3.2
'@codemirror/lint': 6.1.0
@@ -5920,11 +5924,14 @@ packages:
'@codemirror/view': 6.7.2
dev: false
- /@uiw/react-codemirror/4.19.5_k4ec5g7vuuzzonc3d6xbjnmmle:
+ /@uiw/react-codemirror/4.19.5_aguurb4bmecpxzejz52amioxne:
resolution: {integrity: sha512-ZCHh8d7beXbF8/t7F1+yHht6A9Y6CdKeOkZq4A09lxJEnyTQrj1FMf2zvfaqc7K23KNjkTCtSlbqKKbVDgrWaw==}
peerDependencies:
+ '@babel/runtime': '>=7.11.0'
'@codemirror/state': '>=6.0.0'
+ '@codemirror/theme-one-dark': '>=6.0.0'
'@codemirror/view': '>=6.0.0'
+ codemirror: '>=6.0.0'
react: '>=16.8.0'
react-dom: '>=16.8.0'
dependencies:
@@ -5933,13 +5940,14 @@ packages:
'@codemirror/state': 6.2.0
'@codemirror/theme-one-dark': 6.1.0
'@codemirror/view': 6.7.2
- '@uiw/codemirror-extensions-basic-setup': 4.19.5_wd2tsis3in55bkaiwnc2c46tom
- codemirror: 6.0.1
+ '@uiw/codemirror-extensions-basic-setup': 4.19.5_tbeldtdcrf45b35pezgkzq2u4e
+ codemirror: 6.0.1_@lezer+common@1.0.2
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
transitivePeerDependencies:
- '@codemirror/autocomplete'
- '@codemirror/language'
+ - '@codemirror/lint'
- '@codemirror/search'
dev: false
@@ -7174,16 +7182,18 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
- /codemirror/6.0.1:
+ /codemirror/6.0.1_@lezer+common@1.0.2:
resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
dependencies:
- '@codemirror/autocomplete': 6.4.0_czcfkg2f66rxeiodoti7r2gulu
+ '@codemirror/autocomplete': 6.4.0_eo6pz6bvsllvatnnwfprpuflde
'@codemirror/commands': 6.1.3
'@codemirror/language': 6.3.2
'@codemirror/lint': 6.1.0
'@codemirror/search': 6.2.3
'@codemirror/state': 6.2.0
'@codemirror/view': 6.7.2
+ transitivePeerDependencies:
+ - '@lezer/common'
dev: false
/collection-visit/1.0.0:
@@ -8411,7 +8421,7 @@ packages:
debug: 4.3.4
enhanced-resolve: 5.12.0
eslint: 8.31.0
- eslint-plugin-import: 2.27.4_2ac3tknkazjoq5fxmuugu665ny
+ eslint-plugin-import: 2.27.4_qdjeohovcytra7xto5vgmxssaq
get-tsconfig: 4.3.0
globby: 13.1.3
is-core-module: 2.11.0
@@ -8421,7 +8431,7 @@ packages:
- supports-color
dev: true
- /eslint-module-utils/2.7.4_v73lhamtbyinynmwa5fn7kpmfq:
+ /eslint-module-utils/2.7.4_sqt5xxn4ciiurbqrzlaarm6ama:
resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
engines: {node: '>=4'}
peerDependencies:
@@ -8446,7 +8456,6 @@ packages:
debug: 3.2.7
eslint: 8.31.0
eslint-import-resolver-node: 0.3.7
- eslint-import-resolver-typescript: 3.5.3_hnftvkj7qg3s6bbigj4pr6djxy
transitivePeerDependencies:
- supports-color
dev: true
@@ -8471,7 +8480,7 @@ packages:
regexpp: 3.2.0
dev: true
- /eslint-plugin-import/2.27.4_2ac3tknkazjoq5fxmuugu665ny:
+ /eslint-plugin-import/2.27.4_qdjeohovcytra7xto5vgmxssaq:
resolution: {integrity: sha512-Z1jVt1EGKia1X9CnBCkpAOhWy8FgQ7OmJ/IblEkT82yrFU/xJaxwujaTzLWqigewwynRQ9mmHfX9MtAfhxm0sA==}
engines: {node: '>=4'}
peerDependencies:
@@ -8489,7 +8498,7 @@ packages:
doctrine: 2.1.0
eslint: 8.31.0
eslint-import-resolver-node: 0.3.7
- eslint-module-utils: 2.7.4_v73lhamtbyinynmwa5fn7kpmfq
+ eslint-module-utils: 2.7.4_sqt5xxn4ciiurbqrzlaarm6ama
has: 1.0.3
is-core-module: 2.11.0
is-glob: 4.0.3
@@ -12885,6 +12894,15 @@ packages:
rrweb-snapshot: 1.1.14
dev: false
+ /posthog-node/2.4.0:
+ resolution: {integrity: sha512-ijenljLS49AzMskyrDsmEbuPUI641I/qUEUfsVTFZYzNcmmiwWCyJu4v51DjzcH/vAda4p44CIhzL2LkROCl2Q==}
+ engines: {node: '>=14.17.0'}
+ dependencies:
+ axios: 0.27.2
+ transitivePeerDependencies:
+ - debug
+ dev: false
+
/preferred-pm/3.0.3:
resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==}
engines: {node: '>=10'}