@posthog/wizard 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,13 +5,12 @@ export declare const getPRDescription: ({ integration, addedEditorRules, }: {
5
5
  integration: Integration;
6
6
  addedEditorRules: boolean;
7
7
  }) => string;
8
- export declare const getOutroMessage: ({ options, integration, cloudRegion, addedEditorRules, packageManager, envFileChanged, uploadedEnvVars, prUrl, }: {
8
+ export declare const getOutroMessage: ({ options, integration, cloudRegion, addedEditorRules, packageManager, envFileChanged, uploadedEnvVars, }: {
9
9
  options: WizardOptions;
10
10
  integration: Integration;
11
11
  cloudRegion: CloudRegion;
12
12
  addedEditorRules: boolean;
13
13
  packageManager?: PackageManager;
14
14
  envFileChanged?: string;
15
- prUrl?: string;
16
15
  uploadedEnvVars: string[];
17
16
  }) => string;
@@ -22,14 +22,13 @@ const getPRDescription = ({ integration, addedEditorRules, }) => {
22
22
  Learn more about PostHog + ${integrationConfig.name}: ${integrationConfig.docsUrl}`;
23
23
  };
24
24
  exports.getPRDescription = getPRDescription;
25
- const getOutroMessage = ({ options, integration, cloudRegion, addedEditorRules, packageManager, envFileChanged, uploadedEnvVars, prUrl, }) => {
25
+ const getOutroMessage = ({ options, integration, cloudRegion, addedEditorRules, packageManager, envFileChanged, uploadedEnvVars, }) => {
26
26
  const continueUrl = options.signup
27
27
  ? `${(0, urls_1.getCloudUrlFromRegion)(cloudRegion)}/products?source=wizard`
28
28
  : undefined;
29
29
  const integrationConfig = config_1.INTEGRATION_CONFIG[integration];
30
30
  const changes = [
31
31
  addedEditorRules ? `Added Cursor rules for PostHog` : '',
32
- prUrl ? `Created a PR for your changes: ${chalk_1.default.cyan(prUrl)}` : '',
33
32
  envFileChanged
34
33
  ? `Added your Project API key to your ${envFileChanged} file`
35
34
  : '',
@@ -41,7 +40,7 @@ const getOutroMessage = ({ options, integration, cloudRegion, addedEditorRules,
41
40
  uploadedEnvVars.length === 0
42
41
  ? `Upload your Project API key to your hosting provider`
43
42
  : '',
44
- !prUrl ? `Create a PR for your changes` : '',
43
+ `Create a PR for your changes`,
45
44
  ].filter(Boolean);
46
45
  return `
47
46
  ${chalk_1.default.green('Successfully installed PostHog!')}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/lib/messages.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,wCAAsD;AAEtD,2CAAsD;AACtD,qCAA8C;AAEvC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,WAAW,EACX,gBAAgB,GAIjB,EAAE,EAAE;IACH,MAAM,iBAAiB,GAAG,2BAAkB,CAAC,WAAW,CAAC,CAAC;IAE1D,OAAO;;;IAGL,iBAAiB,CAAC,cAAc;IAChC,gBAAgB,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,EAAE;;;wBAI5D,iBAAiB,CAAC,IACpB;;+BAE6B,iBAAiB,CAAC,IAAI,KACjD,iBAAiB,CAAC,OACpB,EAAE,CAAC;AACL,CAAC,CAAC;AAvBW,QAAA,gBAAgB,oBAuB3B;AAEK,MAAM,eAAe,GAAG,CAAC,EAC9B,OAAO,EACP,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,eAAe,EACf,KAAK,GAUN,EAAE,EAAE;IACH,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM;QAChC,CAAC,CAAC,GAAG,IAAA,4BAAqB,EAAC,WAAW,CAAC,yBAAyB;QAChE,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,iBAAiB,GAAG,2BAAkB,CAAC,WAAW,CAAC,CAAC;IAE1D,MAAM,OAAO,GAAG;QACd,gBAAgB,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE;QACxD,KAAK,CAAC,CAAC,CAAC,kCAAkC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;QAClE,cAAc;YACZ,CAAC,CAAC,sCAAsC,cAAc,OAAO;YAC7D,CAAC,CAAC,EAAE;QACN,eAAe,CAAC,MAAM,GAAG,CAAC;YACxB,CAAC,CAAC,wDAAwD;YAC1D,CAAC,CAAC,EAAE;KACP,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,SAAS,GAAG;QAChB,eAAe,CAAC,MAAM,KAAK,CAAC;YAC1B,CAAC,CAAC,sDAAsD;YACxD,CAAC,CAAC,EAAE;QACN,CAAC,KAAK,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE;KAC7C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,OAAO;EACP,eAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC;;EAE9C,eAAK,CAAC,IAAI,CAAC,eAAe,CAAC;EAC3B,iBAAiB,CAAC,cAAc;EAChC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;EAEjD,eAAK,CAAC,MAAM,CAAC,aAAa,CAAC;EAC3B,iBAAiB,CAAC,SAAS;EAC3B,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;6BAEpB,iBAAiB,CAAC,IAAI,KAAK,eAAK,CAAC,IAAI,CAC9D,iBAAiB,CAAC,OAAO,CAC1B;EACD,WAAW,CAAC,CAAC,CAAC,0BAA0B,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;;qEAItE,cAAc;QACZ,CAAC,CAAC,UAAU,eAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,gBAAgB,MAAM,CAAC,IAAI;QACpE,CAAC,CAAC,GACN;;EAEA,eAAK,CAAC,GAAG,CAAC,kDAAkD,sBAAU,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC,CAAC;AAnEW,QAAA,eAAe,mBAmE1B","sourcesContent":["import chalk from 'chalk';\nimport type { CloudRegion, WizardOptions } from '../utils/types';\nimport { getCloudUrlFromRegion } from '../utils/urls';\nimport type { PackageManager } from '../utils/package-manager';\nimport { ISSUES_URL, Integration } from './constants';\nimport { INTEGRATION_CONFIG } from './config';\n\nexport const getPRDescription = ({\n integration,\n addedEditorRules,\n}: {\n integration: Integration;\n addedEditorRules: boolean;\n}) => {\n const integrationConfig = INTEGRATION_CONFIG[integration];\n\n return `This PR adds an integration for PostHog.\n\n The following changes were made:\n ${integrationConfig.defaultChanges}\n ${addedEditorRules ? `• Added Cursor rules for PostHog\\n` : ''}\n \n \n Note: This used the ${\n integrationConfig.name\n } wizard to setup PostHog, this is still in alpha and like all AI, might have got it wrong. Please check the installation carefully!\n \n Learn more about PostHog + ${integrationConfig.name}: ${\n integrationConfig.docsUrl\n }`;\n};\n\nexport const getOutroMessage = ({\n options,\n integration,\n cloudRegion,\n addedEditorRules,\n packageManager,\n envFileChanged,\n uploadedEnvVars,\n prUrl,\n}: {\n options: WizardOptions;\n integration: Integration;\n cloudRegion: CloudRegion;\n addedEditorRules: boolean;\n packageManager?: PackageManager;\n envFileChanged?: string;\n prUrl?: string;\n uploadedEnvVars: string[];\n}) => {\n const continueUrl = options.signup\n ? `${getCloudUrlFromRegion(cloudRegion)}/products?source=wizard`\n : undefined;\n\n const integrationConfig = INTEGRATION_CONFIG[integration];\n\n const changes = [\n addedEditorRules ? `Added Cursor rules for PostHog` : '',\n prUrl ? `Created a PR for your changes: ${chalk.cyan(prUrl)}` : '',\n envFileChanged\n ? `Added your Project API key to your ${envFileChanged} file`\n : '',\n uploadedEnvVars.length > 0\n ? `Uploaded your Project API key to your hosting provider`\n : '',\n ].filter(Boolean);\n\n const nextSteps = [\n uploadedEnvVars.length === 0\n ? `Upload your Project API key to your hosting provider`\n : '',\n !prUrl ? `Create a PR for your changes` : '',\n ].filter(Boolean);\n\n return `\n${chalk.green('Successfully installed PostHog!')} \n \n${chalk.cyan('Changes made:')}\n${integrationConfig.defaultChanges}\n${changes.map((change) => `• ${change}`).join('\\n')}\n\n${chalk.yellow('Next steps:')}\n${integrationConfig.nextSteps}\n${nextSteps.map((step) => `• ${step}`).join('\\n')}\n\nLearn more about PostHog + ${integrationConfig.name}: ${chalk.cyan(\n integrationConfig.docsUrl,\n )}\n${continueUrl ? `\\nContinue onboarding: ${chalk.cyan(continueUrl)}\\n` : ``}\nNote: This uses experimental AI to setup your project. It might have got it wrong, please check!\n\nYou should validate your setup by (re)starting your dev environment${\n packageManager\n ? ` (e.g. ${chalk.cyan(`${packageManager.runScriptCommand} dev`)}).`\n : `.`\n }\n\n${chalk.dim(`If you encounter any issues, let us know here: ${ISSUES_URL}`)}`;\n};\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/lib/messages.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,wCAAsD;AAEtD,2CAAsD;AACtD,qCAA8C;AAEvC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,WAAW,EACX,gBAAgB,GAIjB,EAAE,EAAE;IACH,MAAM,iBAAiB,GAAG,2BAAkB,CAAC,WAAW,CAAC,CAAC;IAE1D,OAAO;;;IAGL,iBAAiB,CAAC,cAAc;IAChC,gBAAgB,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,EAAE;;;wBAI5D,iBAAiB,CAAC,IACpB;;+BAE6B,iBAAiB,CAAC,IAAI,KACjD,iBAAiB,CAAC,OACpB,EAAE,CAAC;AACL,CAAC,CAAC;AAvBW,QAAA,gBAAgB,oBAuB3B;AAEK,MAAM,eAAe,GAAG,CAAC,EAC9B,OAAO,EACP,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,eAAe,GAShB,EAAE,EAAE;IACH,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM;QAChC,CAAC,CAAC,GAAG,IAAA,4BAAqB,EAAC,WAAW,CAAC,yBAAyB;QAChE,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,iBAAiB,GAAG,2BAAkB,CAAC,WAAW,CAAC,CAAC;IAE1D,MAAM,OAAO,GAAG;QACd,gBAAgB,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE;QACxD,cAAc;YACZ,CAAC,CAAC,sCAAsC,cAAc,OAAO;YAC7D,CAAC,CAAC,EAAE;QACN,eAAe,CAAC,MAAM,GAAG,CAAC;YACxB,CAAC,CAAC,wDAAwD;YAC1D,CAAC,CAAC,EAAE;KACP,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,SAAS,GAAG;QAChB,eAAe,CAAC,MAAM,KAAK,CAAC;YAC1B,CAAC,CAAC,sDAAsD;YACxD,CAAC,CAAC,EAAE;QACN,8BAA8B;KAC/B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,OAAO;EACP,eAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC;;EAE9C,eAAK,CAAC,IAAI,CAAC,eAAe,CAAC;EAC3B,iBAAiB,CAAC,cAAc;EAChC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;EAEjD,eAAK,CAAC,MAAM,CAAC,aAAa,CAAC;EAC3B,iBAAiB,CAAC,SAAS;EAC3B,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;6BAEpB,iBAAiB,CAAC,IAAI,KAAK,eAAK,CAAC,IAAI,CAC9D,iBAAiB,CAAC,OAAO,CAC1B;EACD,WAAW,CAAC,CAAC,CAAC,0BAA0B,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;;qEAItE,cAAc;QACZ,CAAC,CAAC,UAAU,eAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,gBAAgB,MAAM,CAAC,IAAI;QACpE,CAAC,CAAC,GACN;;EAEA,eAAK,CAAC,GAAG,CAAC,kDAAkD,sBAAU,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC,CAAC;AAhEW,QAAA,eAAe,mBAgE1B","sourcesContent":["import chalk from 'chalk';\nimport type { CloudRegion, WizardOptions } from '../utils/types';\nimport { getCloudUrlFromRegion } from '../utils/urls';\nimport type { PackageManager } from '../utils/package-manager';\nimport { ISSUES_URL, Integration } from './constants';\nimport { INTEGRATION_CONFIG } from './config';\n\nexport const getPRDescription = ({\n integration,\n addedEditorRules,\n}: {\n integration: Integration;\n addedEditorRules: boolean;\n}) => {\n const integrationConfig = INTEGRATION_CONFIG[integration];\n\n return `This PR adds an integration for PostHog.\n\n The following changes were made:\n ${integrationConfig.defaultChanges}\n ${addedEditorRules ? `• Added Cursor rules for PostHog\\n` : ''}\n \n \n Note: This used the ${\n integrationConfig.name\n } wizard to setup PostHog, this is still in alpha and like all AI, might have got it wrong. Please check the installation carefully!\n \n Learn more about PostHog + ${integrationConfig.name}: ${\n integrationConfig.docsUrl\n }`;\n};\n\nexport const getOutroMessage = ({\n options,\n integration,\n cloudRegion,\n addedEditorRules,\n packageManager,\n envFileChanged,\n uploadedEnvVars,\n}: {\n options: WizardOptions;\n integration: Integration;\n cloudRegion: CloudRegion;\n addedEditorRules: boolean;\n packageManager?: PackageManager;\n envFileChanged?: string;\n uploadedEnvVars: string[];\n}) => {\n const continueUrl = options.signup\n ? `${getCloudUrlFromRegion(cloudRegion)}/products?source=wizard`\n : undefined;\n\n const integrationConfig = INTEGRATION_CONFIG[integration];\n\n const changes = [\n addedEditorRules ? `Added Cursor rules for PostHog` : '',\n envFileChanged\n ? `Added your Project API key to your ${envFileChanged} file`\n : '',\n uploadedEnvVars.length > 0\n ? `Uploaded your Project API key to your hosting provider`\n : '',\n ].filter(Boolean);\n\n const nextSteps = [\n uploadedEnvVars.length === 0\n ? `Upload your Project API key to your hosting provider`\n : '',\n `Create a PR for your changes`,\n ].filter(Boolean);\n\n return `\n${chalk.green('Successfully installed PostHog!')} \n \n${chalk.cyan('Changes made:')}\n${integrationConfig.defaultChanges}\n${changes.map((change) => `• ${change}`).join('\\n')}\n\n${chalk.yellow('Next steps:')}\n${integrationConfig.nextSteps}\n${nextSteps.map((step) => `• ${step}`).join('\\n')}\n\nLearn more about PostHog + ${integrationConfig.name}: ${chalk.cyan(\n integrationConfig.docsUrl,\n )}\n${continueUrl ? `\\nContinue onboarding: ${chalk.cyan(continueUrl)}\\n` : ``}\nNote: This uses experimental AI to setup your project. It might have got it wrong, please check!\n\nYou should validate your setup by (re)starting your dev environment${\n packageManager\n ? ` (e.g. ${chalk.cyan(`${packageManager.runScriptCommand} dev`)}).`\n : `.`\n }\n\n${chalk.dim(`If you encounter any issues, let us know here: ${ISSUES_URL}`)}`;\n};\n"]}
@@ -25,8 +25,7 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {
25
25
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
26
26
  api_host: "/ingest",
27
27
  ui_host: "${(0, urls_1.getUiHostFromHost)(host)}",
28
- capture_pageview: 'history_change',
29
- capture_pageleave: true, // Enable pageleave capture
28
+ defaults: '2025-05-24',
30
29
  capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this
31
30
  debug: process.env.NODE_ENV === "development",
32
31
  })
@@ -34,7 +33,6 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {
34
33
 
35
34
  return (
36
35
  <PHProvider client={posthog}>
37
- <SuspendedPostHogPageView />
38
36
  {children}
39
37
  </PHProvider>
40
38
  )
@@ -79,10 +77,10 @@ Example:
79
77
  --------------------------------------------------
80
78
  import { PostHog } from "posthog-node"
81
79
 
80
+ // NOTE: This is a Node.js client, so you can use it for sending events from the server side to PostHog.
82
81
  export default function PostHogClient() {
83
82
  const posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
84
83
  host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
85
- capture_pageview: 'history_change',
86
84
  flushAt: 1,
87
85
  flushInterval: 0,
88
86
  })
@@ -139,7 +137,6 @@ Changes:
139
137
  Example:
140
138
  --------------------------------------------------
141
139
  import { useEffect } from "react"
142
- import { Router } from "next/router"
143
140
  import posthog from "posthog-js"
144
141
  import { PostHogProvider } from "posthog-js/react"
145
142
 
@@ -148,11 +145,8 @@ export default function App({ Component, pageProps }) {
148
145
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
149
146
  api_host: "/ingest",
150
147
  ui_host: "${(0, urls_1.getUiHostFromHost)(host)}",
151
- capture_pageview: 'history_change',
148
+ defaults: '2025-05-24',
152
149
  capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this
153
- loaded: (posthog) => {
154
- if (process.env.NODE_ENV === "development") posthog.debug()
155
- },
156
150
  debug: process.env.NODE_ENV === "development",
157
151
  })
158
152
  }, [])
@@ -176,10 +170,10 @@ Example:
176
170
  --------------------------------------------------
177
171
  import { PostHog } from "posthog-node"
178
172
 
173
+ // NOTE: This is a Node.js client, so you can use it for sending events from the server side to PostHog.
179
174
  export default function PostHogClient() {
180
175
  const posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
181
176
  host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
182
- capture_pageview: 'history_change',
183
177
  flushAt: 1,
184
178
  flushInterval: 0,
185
179
  })
@@ -230,8 +224,8 @@ FILE: instrumentation-client.${language === 'typescript' ? 'ts' : 'js'}
230
224
  LOCATION: in the root of the application or inside an src folder.
231
225
  ==============================
232
226
  Changes:
233
- - Create or update the instrumentation-client.${language === 'typescript' ? 'tsx' : 'jsx'} file to use the PostHog client. If the file does not exist yet, create it.
234
- - Do *not* import instrumentation-client.${language === 'typescript' ? 'tsx' : 'jsx'} in any other file; Next.js will automatically handle it.
227
+ - Create or update the instrumentation-client.${language === 'typescript' ? 'ts' : 'js'} file to use the PostHog client. If the file does not exist yet, create it.
228
+ - Do *not* import instrumentation-client.${language === 'typescript' ? 'ts' : 'js'} in any other file; Next.js will automatically handle it.
235
229
  - Do not modify any other pages/components in the Next.js application; the PostHog client will be automatically initialized and handle all pageview tasks on its own.
236
230
 
237
231
  Example:
@@ -242,8 +236,7 @@ import posthog from "posthog-js"
242
236
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
243
237
  api_host: "/ingest",
244
238
  ui_host: "${(0, urls_1.getUiHostFromHost)(host)}",
245
- capture_pageview: 'history_change',
246
- capture_pageleave: true, // Enable pageleave capture
239
+ defaults: '2025-05-24',
247
240
  capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this
248
241
  debug: process.env.NODE_ENV === "development",
249
242
  });
@@ -1 +1 @@
1
- {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/nextjs/docs.ts"],"names":[],"mappings":";;;AAAA,wCAAwE;AAEjE,MAAM,sBAAsB,GAAG,CAAC,EACrC,IAAI,EACJ,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO;;wBAGL,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;;;;;;;;;;kBAmBgB,IAAA,wBAAiB,EAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;eAkB1B,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA2BxC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAsC/B,IAAA,2BAAoB,EAAC,IAAI,CAAC;;;;wBAI1B,IAAI;;;;wBAIJ,IAAI;;;;;;;;mDAQuB,CAAC;AACpD,CAAC,CAAC;AAlIW,QAAA,sBAAsB,0BAkIjC;AAEK,MAAM,wBAAwB,GAAG,CAAC,EACvC,IAAI,EACJ,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO;;aAEI,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;mCAElD,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;;;;;;;;kBAiBgB,IAAA,wBAAiB,EAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;gBAmBzB,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAsC/B,IAAA,2BAAoB,EAAC,IAAI,CAAC;;;;wBAI1B,IAAI;;;;wBAIJ,IAAI;;;;;;;;mDAQuB,CAAC;AACpD,CAAC,CAAC;AAvGW,QAAA,wBAAwB,4BAuGnC;AAEK,MAAM,mBAAmB,GAAG,CAAC,EAClC,IAAI,EACJ,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO;;+BAEsB,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;gDAKlE,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;2CAEE,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;cAUY,IAAA,wBAAiB,EAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;wBAyBb,IAAA,2BAAoB,EAAC,IAAI,CAAC;;;;wBAI1B,IAAI;;;;wBAIJ,IAAI;;;;;;;;mDAQuB,CAAC;AACpD,CAAC,CAAC;AAtEW,QAAA,mBAAmB,uBAsE9B","sourcesContent":["import { getAssetHostFromHost, getUiHostFromHost } from '../utils/urls';\n\nexport const getNextjsAppRouterDocs = ({\n host,\n language,\n}: {\n host: string;\n language: 'typescript' | 'javascript';\n}) => {\n return `\n==============================\nFILE: PostHogProvider.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } (put it somewhere where client files are, like the components folder)\nLOCATION: Wherever other providers are, or the components folder\n==============================\nChanges:\n- Create a PostHogProvider component that will be imported into the layout file.\n\nExample:\n--------------------------------------------------\n\"use client\"\n\nimport posthog from \"posthog-js\"\nimport { PostHogProvider as PHProvider, usePostHog } from \"posthog-js/react\"\nimport { Suspense, useEffect } from \"react\"\nimport { usePathname, useSearchParams } from \"next/navigation\"\n\nexport function PostHogProvider({ children }: { children: React.ReactNode }) {\n useEffect(() => {\n posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n api_host: \"/ingest\",\n ui_host: \"${getUiHostFromHost(host)}\",\n capture_pageview: 'history_change',\n capture_pageleave: true, // Enable pageleave capture\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n debug: process.env.NODE_ENV === \"development\",\n })\n }, [])\n\n return (\n <PHProvider client={posthog}>\n <SuspendedPostHogPageView />\n {children}\n </PHProvider>\n )\n}\n--------------------------------------------------\n\n==============================\nFILE: layout.${language === 'typescript' ? 'tsx' : 'jsx'}\nLOCATION: Wherever the root layout is\n==============================\nChanges:\n- Import the PostHogProvider from the providers file and wrap the app in it.\n\nExample:\n--------------------------------------------------\n// other imports\nimport { PostHogProvider } from \"LOCATION_OF_POSTHOG_PROVIDER\"\n\nexport default function RootLayout({ children }) {\n return (\n <html lang=\"en\">\n <body>\n <PostHogProvider>\n {/* other providers */}\n {children}\n {/* other providers */}\n </PostHogProvider>\n </body>\n </html>\n )\n}\n--------------------------------------------------\n\n==============================\nFILE: posthog.${language === 'typescript' ? 'ts' : 'js'}\nLOCATION: Wherever works best given the project structure\n==============================\nChanges:\n- Initialize the PostHog Node.js client\n\nExample:\n--------------------------------------------------\nimport { PostHog } from \"posthog-node\"\n\nexport default function PostHogClient() {\n const posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n host: process.env.NEXT_PUBLIC_POSTHOG_HOST,\n capture_pageview: 'history_change',\n flushAt: 1,\n flushInterval: 0,\n })\n return posthogClient\n}\n--------------------------------------------------\n\n==============================\nFILE: next.config.{js,ts,mjs,cjs}\nLOCATION: Wherever the root next config is\n==============================\nChanges:\n- Add rewrites to the Next.js config to support PostHog, if there are existing rewrites, add the PostHog rewrites to them.\n- Add skipTrailingSlashRedirect to the Next.js config to support PostHog trailing slash API requests.\n- This can be of type js, ts, mjs, cjs etc. You should adapt the file according to what extension it uses, and if it does not exist yet use '.js'.\n\nExample:\n--------------------------------------------------\nconst nextConfig = {\n // other config\n async rewrites() {\n return [\n {\n source: \"/ingest/static/:path*\",\n destination: \"${getAssetHostFromHost(host)}/static/:path*\",\n },\n {\n source: \"/ingest/:path*\",\n destination: \"${host}/:path*\",\n },\n {\n source: \"/ingest/decide\",\n destination: \"${host}/decide\",\n },\n ];\n },\n // This is required to support PostHog trailing slash API requests\n skipTrailingSlashRedirect: true,\n}\nmodule.exports = nextConfig\n--------------------------------------------------`;\n};\n\nexport const getNextjsPagesRouterDocs = ({\n host,\n language,\n}: {\n host: string;\n language: 'typescript' | 'javascript';\n}) => {\n return `\n==============================\nFILE: _app.${language === 'typescript' ? 'tsx' : 'jsx'}\nLOCATION: Wherever the root _app.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } file is\n==============================\nChanges:\n- Initialize PostHog in _app.js.\n- Wrap the application in PostHogProvider.\n\nExample:\n--------------------------------------------------\nimport { useEffect } from \"react\"\nimport { Router } from \"next/router\"\nimport posthog from \"posthog-js\"\nimport { PostHogProvider } from \"posthog-js/react\"\n\nexport default function App({ Component, pageProps }) {\n useEffect(() => {\n posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {\n api_host: \"/ingest\",\n ui_host: \"${getUiHostFromHost(host)}\",\n capture_pageview: 'history_change',\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n loaded: (posthog) => {\n if (process.env.NODE_ENV === \"development\") posthog.debug()\n },\n debug: process.env.NODE_ENV === \"development\",\n })\n }, [])\n\n return (\n <PostHogProvider client={posthog}>\n <Component {...pageProps} />\n </PostHogProvider>\n )\n}\n--------------------------------------------------\n\n==============================\nFILE: posthog.${language === 'typescript' ? 'ts' : 'js'}\nLOCATION: Wherever works best given the project structure\n==============================\nChanges:\n- Initialize the PostHog Node.js client\n\nExample:\n--------------------------------------------------\nimport { PostHog } from \"posthog-node\"\n\nexport default function PostHogClient() {\n const posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n host: process.env.NEXT_PUBLIC_POSTHOG_HOST,\n capture_pageview: 'history_change',\n flushAt: 1,\n flushInterval: 0,\n })\n return posthogClient\n}\n--------------------------------------------------\n\n==============================\nFILE: next.config.{js,ts,mjs,cjs}\nLOCATION: Wherever the root next config is\n==============================\nChanges:\n- Add rewrites to the Next.js config to support PostHog, if there are existing rewrites, add the PostHog rewrites to them.\n- Add skipTrailingSlashRedirect to the Next.js config to support PostHog trailing slash API requests.\n- This can be of type js, ts, mjs, cjs etc. You should adapt the file according to what extension it uses, and if it does not exist yet use '.js'.\n\nExample:\n--------------------------------------------------\nconst nextConfig = {\n // other config\n async rewrites() {\n return [\n {\n source: \"/ingest/static/:path*\",\n destination: \"${getAssetHostFromHost(host)}/static/:path*\",\n },\n {\n source: \"/ingest/:path*\",\n destination: \"${host}/:path*\",\n },\n {\n source: \"/ingest/decide\",\n destination: \"${host}/decide\",\n },\n ];\n },\n // This is required to support PostHog trailing slash API requests\n skipTrailingSlashRedirect: true,\n}\nmodule.exports = nextConfig\n--------------------------------------------------`;\n};\n\nexport const getModernNextjsDocs = ({\n host,\n language,\n}: {\n host: string;\n language: 'typescript' | 'javascript';\n}) => {\n return `\n==============================\nFILE: instrumentation-client.${language === 'typescript' ? 'ts' : 'js'}\nLOCATION: in the root of the application or inside an src folder.\n==============================\nChanges:\n- Create or update the instrumentation-client.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } file to use the PostHog client. If the file does not exist yet, create it.\n- Do *not* import instrumentation-client.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } in any other file; Next.js will automatically handle it.\n- Do not modify any other pages/components in the Next.js application; the PostHog client will be automatically initialized and handle all pageview tasks on its own.\n\nExample:\n--------------------------------------------------\n\nimport posthog from \"posthog-js\"\n\nposthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n api_host: \"/ingest\",\n ui_host: \"${getUiHostFromHost(host)}\",\n capture_pageview: 'history_change',\n capture_pageleave: true, // Enable pageleave capture\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n debug: process.env.NODE_ENV === \"development\",\n});\n--------------------------------------------------\n\n==============================\nFILE: next.config.{js,ts,mjs,cjs}\nLOCATION: Wherever the root next config is\n==============================\nChanges:\n- Add rewrites to the Next.js config to support PostHog, if there are existing rewrites, add the PostHog rewrites to them.\n- Add skipTrailingSlashRedirect to the Next.js config to support PostHog trailing slash API requests.\n- This can be of type js, ts, mjs, cjs etc. You should adapt the file according to what extension it uses, and if it does not exist yet use '.js'.\n\nExample:\n--------------------------------------------------\nconst nextConfig = {\n // other config\n async rewrites() {\n return [\n {\n source: \"/ingest/static/:path*\",\n destination: \"${getAssetHostFromHost(host)}/static/:path*\",\n },\n {\n source: \"/ingest/:path*\",\n destination: \"${host}/:path*\",\n },\n {\n source: \"/ingest/decide\",\n destination: \"${host}/decide\",\n },\n ];\n },\n // This is required to support PostHog trailing slash API requests\n skipTrailingSlashRedirect: true,\n}\nmodule.exports = nextConfig\n--------------------------------------------------`;\n};\n"]}
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/nextjs/docs.ts"],"names":[],"mappings":";;;AAAA,wCAAwE;AAEjE,MAAM,sBAAsB,GAAG,CAAC,EACrC,IAAI,EACJ,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO;;wBAGL,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;;;;;;;;;;kBAmBgB,IAAA,wBAAiB,EAAC,IAAI,CAAC;;;;;;;;;;;;;;;;eAgB1B,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA2BxC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAsC/B,IAAA,2BAAoB,EAAC,IAAI,CAAC;;;;wBAI1B,IAAI;;;;wBAIJ,IAAI;;;;;;;;mDAQuB,CAAC;AACpD,CAAC,CAAC;AAhIW,QAAA,sBAAsB,0BAgIjC;AAEK,MAAM,wBAAwB,GAAG,CAAC,EACvC,IAAI,EACJ,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO;;aAEI,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;mCAElD,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;;;;;;;kBAgBgB,IAAA,wBAAiB,EAAC,IAAI,CAAC;;;;;;;;;;;;;;;;gBAgBzB,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAsC/B,IAAA,2BAAoB,EAAC,IAAI,CAAC;;;;wBAI1B,IAAI;;;;wBAIJ,IAAI;;;;;;;;mDAQuB,CAAC;AACpD,CAAC,CAAC;AAnGW,QAAA,wBAAwB,4BAmGnC;AAEK,MAAM,mBAAmB,GAAG,CAAC,EAClC,IAAI,EACJ,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO;;+BAEsB,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;gDAKlE,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IACrC;2CAEE,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IACrC;;;;;;;;;;cAUY,IAAA,wBAAiB,EAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;wBAwBb,IAAA,2BAAoB,EAAC,IAAI,CAAC;;;;wBAI1B,IAAI;;;;wBAIJ,IAAI;;;;;;;;mDAQuB,CAAC;AACpD,CAAC,CAAC;AArEW,QAAA,mBAAmB,uBAqE9B","sourcesContent":["import { getAssetHostFromHost, getUiHostFromHost } from '../utils/urls';\n\nexport const getNextjsAppRouterDocs = ({\n host,\n language,\n}: {\n host: string;\n language: 'typescript' | 'javascript';\n}) => {\n return `\n==============================\nFILE: PostHogProvider.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } (put it somewhere where client files are, like the components folder)\nLOCATION: Wherever other providers are, or the components folder\n==============================\nChanges:\n- Create a PostHogProvider component that will be imported into the layout file.\n\nExample:\n--------------------------------------------------\n\"use client\"\n\nimport posthog from \"posthog-js\"\nimport { PostHogProvider as PHProvider, usePostHog } from \"posthog-js/react\"\nimport { Suspense, useEffect } from \"react\"\nimport { usePathname, useSearchParams } from \"next/navigation\"\n\nexport function PostHogProvider({ children }: { children: React.ReactNode }) {\n useEffect(() => {\n posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n api_host: \"/ingest\",\n ui_host: \"${getUiHostFromHost(host)}\",\n defaults: '2025-05-24',\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n debug: process.env.NODE_ENV === \"development\",\n })\n }, [])\n\n return (\n <PHProvider client={posthog}>\n {children}\n </PHProvider>\n )\n}\n--------------------------------------------------\n\n==============================\nFILE: layout.${language === 'typescript' ? 'tsx' : 'jsx'}\nLOCATION: Wherever the root layout is\n==============================\nChanges:\n- Import the PostHogProvider from the providers file and wrap the app in it.\n\nExample:\n--------------------------------------------------\n// other imports\nimport { PostHogProvider } from \"LOCATION_OF_POSTHOG_PROVIDER\"\n\nexport default function RootLayout({ children }) {\n return (\n <html lang=\"en\">\n <body>\n <PostHogProvider>\n {/* other providers */}\n {children}\n {/* other providers */}\n </PostHogProvider>\n </body>\n </html>\n )\n}\n--------------------------------------------------\n\n==============================\nFILE: posthog.${language === 'typescript' ? 'ts' : 'js'}\nLOCATION: Wherever works best given the project structure\n==============================\nChanges:\n- Initialize the PostHog Node.js client\n\nExample:\n--------------------------------------------------\nimport { PostHog } from \"posthog-node\"\n\n// NOTE: This is a Node.js client, so you can use it for sending events from the server side to PostHog.\nexport default function PostHogClient() {\n const posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n host: process.env.NEXT_PUBLIC_POSTHOG_HOST,\n flushAt: 1,\n flushInterval: 0,\n })\n return posthogClient\n}\n--------------------------------------------------\n\n==============================\nFILE: next.config.{js,ts,mjs,cjs}\nLOCATION: Wherever the root next config is\n==============================\nChanges:\n- Add rewrites to the Next.js config to support PostHog, if there are existing rewrites, add the PostHog rewrites to them.\n- Add skipTrailingSlashRedirect to the Next.js config to support PostHog trailing slash API requests.\n- This can be of type js, ts, mjs, cjs etc. You should adapt the file according to what extension it uses, and if it does not exist yet use '.js'.\n\nExample:\n--------------------------------------------------\nconst nextConfig = {\n // other config\n async rewrites() {\n return [\n {\n source: \"/ingest/static/:path*\",\n destination: \"${getAssetHostFromHost(host)}/static/:path*\",\n },\n {\n source: \"/ingest/:path*\",\n destination: \"${host}/:path*\",\n },\n {\n source: \"/ingest/decide\",\n destination: \"${host}/decide\",\n },\n ];\n },\n // This is required to support PostHog trailing slash API requests\n skipTrailingSlashRedirect: true,\n}\nmodule.exports = nextConfig\n--------------------------------------------------`;\n};\n\nexport const getNextjsPagesRouterDocs = ({\n host,\n language,\n}: {\n host: string;\n language: 'typescript' | 'javascript';\n}) => {\n return `\n==============================\nFILE: _app.${language === 'typescript' ? 'tsx' : 'jsx'}\nLOCATION: Wherever the root _app.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } file is\n==============================\nChanges:\n- Initialize PostHog in _app.js.\n- Wrap the application in PostHogProvider.\n\nExample:\n--------------------------------------------------\nimport { useEffect } from \"react\"\nimport posthog from \"posthog-js\"\nimport { PostHogProvider } from \"posthog-js/react\"\n\nexport default function App({ Component, pageProps }) {\n useEffect(() => {\n posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {\n api_host: \"/ingest\",\n ui_host: \"${getUiHostFromHost(host)}\",\n defaults: '2025-05-24',\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n debug: process.env.NODE_ENV === \"development\",\n })\n }, [])\n\n return (\n <PostHogProvider client={posthog}>\n <Component {...pageProps} />\n </PostHogProvider>\n )\n}\n--------------------------------------------------\n\n==============================\nFILE: posthog.${language === 'typescript' ? 'ts' : 'js'}\nLOCATION: Wherever works best given the project structure\n==============================\nChanges:\n- Initialize the PostHog Node.js client\n\nExample:\n--------------------------------------------------\nimport { PostHog } from \"posthog-node\"\n\n// NOTE: This is a Node.js client, so you can use it for sending events from the server side to PostHog.\nexport default function PostHogClient() {\n const posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n host: process.env.NEXT_PUBLIC_POSTHOG_HOST,\n flushAt: 1,\n flushInterval: 0,\n })\n return posthogClient\n}\n--------------------------------------------------\n\n==============================\nFILE: next.config.{js,ts,mjs,cjs}\nLOCATION: Wherever the root next config is\n==============================\nChanges:\n- Add rewrites to the Next.js config to support PostHog, if there are existing rewrites, add the PostHog rewrites to them.\n- Add skipTrailingSlashRedirect to the Next.js config to support PostHog trailing slash API requests.\n- This can be of type js, ts, mjs, cjs etc. You should adapt the file according to what extension it uses, and if it does not exist yet use '.js'.\n\nExample:\n--------------------------------------------------\nconst nextConfig = {\n // other config\n async rewrites() {\n return [\n {\n source: \"/ingest/static/:path*\",\n destination: \"${getAssetHostFromHost(host)}/static/:path*\",\n },\n {\n source: \"/ingest/:path*\",\n destination: \"${host}/:path*\",\n },\n {\n source: \"/ingest/decide\",\n destination: \"${host}/decide\",\n },\n ];\n },\n // This is required to support PostHog trailing slash API requests\n skipTrailingSlashRedirect: true,\n}\nmodule.exports = nextConfig\n--------------------------------------------------`;\n};\n\nexport const getModernNextjsDocs = ({\n host,\n language,\n}: {\n host: string;\n language: 'typescript' | 'javascript';\n}) => {\n return `\n==============================\nFILE: instrumentation-client.${language === 'typescript' ? 'ts' : 'js'}\nLOCATION: in the root of the application or inside an src folder.\n==============================\nChanges:\n- Create or update the instrumentation-client.${\n language === 'typescript' ? 'ts' : 'js'\n } file to use the PostHog client. If the file does not exist yet, create it.\n- Do *not* import instrumentation-client.${\n language === 'typescript' ? 'ts' : 'js'\n } in any other file; Next.js will automatically handle it.\n- Do not modify any other pages/components in the Next.js application; the PostHog client will be automatically initialized and handle all pageview tasks on its own.\n\nExample:\n--------------------------------------------------\n\nimport posthog from \"posthog-js\"\n\nposthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n api_host: \"/ingest\",\n ui_host: \"${getUiHostFromHost(host)}\",\n defaults: '2025-05-24',\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n debug: process.env.NODE_ENV === \"development\",\n});\n--------------------------------------------------\n\n==============================\nFILE: next.config.{js,ts,mjs,cjs}\nLOCATION: Wherever the root next config is\n==============================\nChanges:\n- Add rewrites to the Next.js config to support PostHog, if there are existing rewrites, add the PostHog rewrites to them.\n- Add skipTrailingSlashRedirect to the Next.js config to support PostHog trailing slash API requests.\n- This can be of type js, ts, mjs, cjs etc. You should adapt the file according to what extension it uses, and if it does not exist yet use '.js'.\n\nExample:\n--------------------------------------------------\nconst nextConfig = {\n // other config\n async rewrites() {\n return [\n {\n source: \"/ingest/static/:path*\",\n destination: \"${getAssetHostFromHost(host)}/static/:path*\",\n },\n {\n source: \"/ingest/:path*\",\n destination: \"${host}/:path*\",\n },\n {\n source: \"/ingest/decide\",\n destination: \"${host}/decide\",\n },\n ];\n },\n // This is required to support PostHog trailing slash API requests\n skipTrailingSlashRedirect: true,\n}\nmodule.exports = nextConfig\n--------------------------------------------------`;\n};\n"]}
@@ -151,11 +151,6 @@ async function runNextjsWizard(options) {
151
151
  installDir: options.installDir,
152
152
  integration: constants_1.Integration.nextjs,
153
153
  });
154
- const prUrl = await (0, steps_1.createPRStep)({
155
- installDir: options.installDir,
156
- integration: constants_1.Integration.nextjs,
157
- addedEditorRules,
158
- });
159
154
  await (0, steps_1.addMCPServerToClientsStep)({
160
155
  cloudRegion,
161
156
  integration: constants_1.Integration.nextjs,
@@ -167,7 +162,6 @@ async function runNextjsWizard(options) {
167
162
  addedEditorRules,
168
163
  packageManager: packageManagerForOutro,
169
164
  envFileChanged: addedEnvVariables ? relativeEnvFilePath : undefined,
170
- prUrl,
171
165
  uploadedEnvVars,
172
166
  });
173
167
  clack_1.default.outro(outroMessage);
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs-wizard.js","sourceRoot":"","sources":["../../../src/nextjs/nextjs-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport {\n abort,\n askForAIConsent,\n confirmContinueIfNoOrDirtyGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n getPackageManager,\n installPackage,\n isUsingTypeScript,\n printWelcome,\n} from '../utils/clack-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport {\n getNextJsRouter,\n getNextJsRouterName,\n getNextJsVersionBucket,\n NextJsRouter,\n} from './utils';\nimport clack from '../utils/clack';\nimport { Integration } from '../lib/constants';\nimport {\n getNextjsAppRouterDocs,\n getNextjsPagesRouterDocs,\n getModernNextjsDocs,\n} from './docs';\nimport { analytics } from '../utils/analytics';\nimport {\n generateFileChangesForIntegration,\n getFilesToChange,\n getRelevantFilesForIntegration,\n} from '../utils/file-utils';\nimport type { WizardOptions } from '../utils/types';\nimport { askForCloudRegion } from '../utils/clack-utils';\nimport { getOutroMessage } from '../lib/messages';\nimport {\n addEditorRulesStep,\n addOrUpdateEnvironmentVariablesStep,\n createPRStep,\n runPrettierStep,\n addMCPServerToClientsStep,\n uploadEnvironmentVariablesStep,\n} from '../steps';\n\nimport * as semver from 'semver';\n\nexport async function runNextjsWizard(options: WizardOptions): Promise<void> {\n printWelcome({\n wizardName: 'PostHog Next.js wizard',\n });\n\n const aiConsent = await askForAIConsent(options);\n\n if (!aiConsent) {\n await abort(\n 'The Next.js wizard requires AI to get setup right now. Please view the docs to setup Next.js manually instead: https://posthog.com/docs/libraries/next-js',\n 0,\n );\n }\n\n const cloudRegion = options.cloudRegion ?? (await askForCloudRegion());\n\n const typeScriptDetected = isUsingTypeScript(options);\n\n await confirmContinueIfNoOrDirtyGitRepo(options);\n\n const packageJson = await getPackageDotJson(options);\n\n await ensurePackageIsInstalled(packageJson, 'next', 'Next.js');\n\n const nextVersion = getPackageVersion('next', packageJson);\n\n analytics.setTag('nextjs-version', getNextJsVersionBucket(nextVersion));\n\n const { projectApiKey, wizardHash, host } = await getOrAskForProjectData({\n ...options,\n cloudRegion,\n });\n\n const sdkAlreadyInstalled = hasPackageInstalled('posthog-js', packageJson);\n\n analytics.setTag('sdk-already-installed', sdkAlreadyInstalled);\n\n const { packageManager: packageManagerFromInstallStep } =\n await installPackage({\n packageName: 'posthog-js',\n packageNameDisplayLabel: 'posthog-js',\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-js'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n await installPackage({\n packageName: 'posthog-node',\n packageNameDisplayLabel: 'posthog-node',\n packageManager: packageManagerFromInstallStep,\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-node'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const relevantFiles = await getRelevantFilesForIntegration({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n let installationDocumentation; // Documentation for the installation of the PostHog SDK\n\n if (instrumentationFileAvailable(nextVersion)) {\n installationDocumentation = getModernNextjsDocs({\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(`Reviewing PostHog documentation for Next.js`);\n } else {\n const router = await getNextJsRouter(options);\n\n installationDocumentation = getInstallationDocumentation({\n router,\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(\n `Reviewing PostHog documentation for ${getNextJsRouterName(router)}`,\n );\n }\n\n const filesToChange = await getFilesToChange({\n integration: Integration.nextjs,\n relevantFiles,\n documentation: installationDocumentation,\n wizardHash,\n cloudRegion,\n });\n\n await generateFileChangesForIntegration({\n integration: Integration.nextjs,\n filesToChange,\n wizardHash,\n installDir: options.installDir,\n documentation: installationDocumentation,\n cloudRegion,\n });\n\n const packageManagerForOutro =\n packageManagerFromInstallStep ?? (await getPackageManager(options));\n\n await runPrettierStep({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const { relativeEnvFilePath, addedEnvVariables } =\n await addOrUpdateEnvironmentVariablesStep({\n variables: {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const uploadedEnvVars = await uploadEnvironmentVariablesStep(\n {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n {\n integration: Integration.nextjs,\n options,\n },\n );\n\n const addedEditorRules = await addEditorRulesStep({\n rulesName: 'next-rules.md',\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const prUrl = await createPRStep({\n installDir: options.installDir,\n integration: Integration.nextjs,\n addedEditorRules,\n });\n\n await addMCPServerToClientsStep({\n cloudRegion,\n integration: Integration.nextjs,\n });\n\n const outroMessage = getOutroMessage({\n options,\n integration: Integration.nextjs,\n cloudRegion,\n addedEditorRules,\n packageManager: packageManagerForOutro,\n envFileChanged: addedEnvVariables ? relativeEnvFilePath : undefined,\n prUrl,\n uploadedEnvVars,\n });\n\n clack.outro(outroMessage);\n\n await analytics.shutdown('success');\n}\n\nfunction instrumentationFileAvailable(\n nextVersion: string | undefined,\n): boolean {\n const minimumVersion = '15.3.0'; //instrumentation-client.js|ts was introduced in 15.3\n\n if (!nextVersion) {\n return false;\n }\n const coercedNextVersion = semver.coerce(nextVersion);\n if (!coercedNextVersion) {\n return false; // Unable to parse nextVersion\n }\n return semver.gte(coercedNextVersion, minimumVersion);\n}\n\nfunction getInstallationDocumentation({\n router,\n host,\n language,\n}: {\n router: NextJsRouter;\n host: string;\n language: 'typescript' | 'javascript';\n}) {\n if (router === NextJsRouter.PAGES_ROUTER) {\n return getNextjsPagesRouterDocs({ host, language });\n }\n\n return getNextjsAppRouterDocs({ host, language });\n}\n"]}
1
+ {"version":3,"file":"nextjs-wizard.js","sourceRoot":"","sources":["../../../src/nextjs/nextjs-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport {\n abort,\n askForAIConsent,\n confirmContinueIfNoOrDirtyGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n getPackageManager,\n installPackage,\n isUsingTypeScript,\n printWelcome,\n} from '../utils/clack-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport {\n getNextJsRouter,\n getNextJsRouterName,\n getNextJsVersionBucket,\n NextJsRouter,\n} from './utils';\nimport clack from '../utils/clack';\nimport { Integration } from '../lib/constants';\nimport {\n getNextjsAppRouterDocs,\n getNextjsPagesRouterDocs,\n getModernNextjsDocs,\n} from './docs';\nimport { analytics } from '../utils/analytics';\nimport {\n generateFileChangesForIntegration,\n getFilesToChange,\n getRelevantFilesForIntegration,\n} from '../utils/file-utils';\nimport type { WizardOptions } from '../utils/types';\nimport { askForCloudRegion } from '../utils/clack-utils';\nimport { getOutroMessage } from '../lib/messages';\nimport {\n addEditorRulesStep,\n addOrUpdateEnvironmentVariablesStep,\n runPrettierStep,\n addMCPServerToClientsStep,\n uploadEnvironmentVariablesStep,\n} from '../steps';\n\nimport * as semver from 'semver';\n\nexport async function runNextjsWizard(options: WizardOptions): Promise<void> {\n printWelcome({\n wizardName: 'PostHog Next.js wizard',\n });\n\n const aiConsent = await askForAIConsent(options);\n\n if (!aiConsent) {\n await abort(\n 'The Next.js wizard requires AI to get setup right now. Please view the docs to setup Next.js manually instead: https://posthog.com/docs/libraries/next-js',\n 0,\n );\n }\n\n const cloudRegion = options.cloudRegion ?? (await askForCloudRegion());\n\n const typeScriptDetected = isUsingTypeScript(options);\n\n await confirmContinueIfNoOrDirtyGitRepo(options);\n\n const packageJson = await getPackageDotJson(options);\n\n await ensurePackageIsInstalled(packageJson, 'next', 'Next.js');\n\n const nextVersion = getPackageVersion('next', packageJson);\n\n analytics.setTag('nextjs-version', getNextJsVersionBucket(nextVersion));\n\n const { projectApiKey, wizardHash, host } = await getOrAskForProjectData({\n ...options,\n cloudRegion,\n });\n\n const sdkAlreadyInstalled = hasPackageInstalled('posthog-js', packageJson);\n\n analytics.setTag('sdk-already-installed', sdkAlreadyInstalled);\n\n const { packageManager: packageManagerFromInstallStep } =\n await installPackage({\n packageName: 'posthog-js',\n packageNameDisplayLabel: 'posthog-js',\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-js'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n await installPackage({\n packageName: 'posthog-node',\n packageNameDisplayLabel: 'posthog-node',\n packageManager: packageManagerFromInstallStep,\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-node'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const relevantFiles = await getRelevantFilesForIntegration({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n let installationDocumentation; // Documentation for the installation of the PostHog SDK\n\n if (instrumentationFileAvailable(nextVersion)) {\n installationDocumentation = getModernNextjsDocs({\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(`Reviewing PostHog documentation for Next.js`);\n } else {\n const router = await getNextJsRouter(options);\n\n installationDocumentation = getInstallationDocumentation({\n router,\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(\n `Reviewing PostHog documentation for ${getNextJsRouterName(router)}`,\n );\n }\n\n const filesToChange = await getFilesToChange({\n integration: Integration.nextjs,\n relevantFiles,\n documentation: installationDocumentation,\n wizardHash,\n cloudRegion,\n });\n\n await generateFileChangesForIntegration({\n integration: Integration.nextjs,\n filesToChange,\n wizardHash,\n installDir: options.installDir,\n documentation: installationDocumentation,\n cloudRegion,\n });\n\n const packageManagerForOutro =\n packageManagerFromInstallStep ?? (await getPackageManager(options));\n\n await runPrettierStep({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const { relativeEnvFilePath, addedEnvVariables } =\n await addOrUpdateEnvironmentVariablesStep({\n variables: {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const uploadedEnvVars = await uploadEnvironmentVariablesStep(\n {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n {\n integration: Integration.nextjs,\n options,\n },\n );\n\n const addedEditorRules = await addEditorRulesStep({\n rulesName: 'next-rules.md',\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n await addMCPServerToClientsStep({\n cloudRegion,\n integration: Integration.nextjs,\n });\n\n const outroMessage = getOutroMessage({\n options,\n integration: Integration.nextjs,\n cloudRegion,\n addedEditorRules,\n packageManager: packageManagerForOutro,\n envFileChanged: addedEnvVariables ? relativeEnvFilePath : undefined,\n uploadedEnvVars,\n });\n\n clack.outro(outroMessage);\n\n await analytics.shutdown('success');\n}\n\nfunction instrumentationFileAvailable(\n nextVersion: string | undefined,\n): boolean {\n const minimumVersion = '15.3.0'; //instrumentation-client.js|ts was introduced in 15.3\n\n if (!nextVersion) {\n return false;\n }\n const coercedNextVersion = semver.coerce(nextVersion);\n if (!coercedNextVersion) {\n return false; // Unable to parse nextVersion\n }\n return semver.gte(coercedNextVersion, minimumVersion);\n}\n\nfunction getInstallationDocumentation({\n router,\n host,\n language,\n}: {\n router: NextJsRouter;\n host: string;\n language: 'typescript' | 'javascript';\n}) {\n if (router === NextJsRouter.PAGES_ROUTER) {\n return getNextjsPagesRouterDocs({ host, language });\n }\n\n return getNextjsAppRouterDocs({ host, language });\n}\n"]}
@@ -32,6 +32,7 @@ root.render(
32
32
  apiKey={${apiKeyText}}
33
33
  options={{
34
34
  api_host: ${hostText},
35
+ defaults: '2025-05-24',
35
36
  capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this
36
37
  debug: ${envVarPrefix === 'VITE_PUBLIC_'
37
38
  ? 'import.meta.env.MODE === "development"'
@@ -1 +1 @@
1
- {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/react/docs.ts"],"names":[],"mappings":";;;AAAO,MAAM,qBAAqB,GAAG,CAAC,EACpC,QAAQ,EACR,YAAY,GAIb,EAAE,EAAE;IACH,MAAM,UAAU,GACd,YAAY,KAAK,cAAc;QAC7B,CAAC,CAAC,yCAAyC;QAC3C,CAAC,CAAC,eAAe,YAAY,aAAa,CAAC;IAE/C,MAAM,QAAQ,GACZ,YAAY,KAAK,cAAc;QAC7B,CAAC,CAAC,0CAA0C;QAC5C,CAAC,CAAC,eAAe,YAAY,cAAc,CAAC;IAEhD,OAAO;;sBAGL,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;;;;;;;;;;gBAmBc,UAAU;;oBAEN,QAAQ;;iBAGlB,YAAY,KAAK,cAAc;QAC7B,CAAC,CAAC,wCAAwC;QAC1C,CAAC,CAAC,wCACN;;;;;;mDAM2C,CAAC;AACpD,CAAC,CAAC;AAvDW,QAAA,qBAAqB,yBAuDhC","sourcesContent":["export const getReactDocumentation = ({\n language,\n envVarPrefix,\n}: {\n language: 'typescript' | 'javascript';\n envVarPrefix: string;\n}) => {\n const apiKeyText =\n envVarPrefix === 'VITE_PUBLIC_'\n ? 'import.meta.env.VITE_PUBLIC_POSTHOG_KEY'\n : `process.env.${envVarPrefix}POSTHOG_KEY`;\n\n const hostText =\n envVarPrefix === 'VITE_PUBLIC_'\n ? 'import.meta.env.VITE_PUBLIC_POSTHOG_HOST'\n : `process.env.${envVarPrefix}POSTHOG_HOST`;\n\n return `\n==============================\nFILE: {index / App}.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } (wherever the root of the app is)\nLOCATION: Wherever the root of the app is\n==============================\nChanges:\n- Add the PostHogProvider to the root of the app in the provider tree.\n\nExample:\n--------------------------------------------------\nimport React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport App from './App';\n\nimport { PostHogProvider} from 'posthog-js/react'\n\nconst root = ReactDOM.createRoot(document.getElementById('root'));\n\nroot.render(\n <React.StrictMode>\n <PostHogProvider\n apiKey={${apiKeyText}}\n options={{\n api_host: ${hostText},\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n debug: ${\n envVarPrefix === 'VITE_PUBLIC_'\n ? 'import.meta.env.MODE === \"development\"'\n : 'process.env.NODE_ENV === \"development\"'\n },\n }}\n >\n <App />\n </PostHogProvider>\n </React.StrictMode>\n--------------------------------------------------`;\n};\n"]}
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/react/docs.ts"],"names":[],"mappings":";;;AAAO,MAAM,qBAAqB,GAAG,CAAC,EACpC,QAAQ,EACR,YAAY,GAIb,EAAE,EAAE;IACH,MAAM,UAAU,GACd,YAAY,KAAK,cAAc;QAC7B,CAAC,CAAC,yCAAyC;QAC3C,CAAC,CAAC,eAAe,YAAY,aAAa,CAAC;IAE/C,MAAM,QAAQ,GACZ,YAAY,KAAK,cAAc;QAC7B,CAAC,CAAC,0CAA0C;QAC5C,CAAC,CAAC,eAAe,YAAY,cAAc,CAAC;IAEhD,OAAO;;sBAGL,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;;;;;;;;;;gBAmBc,UAAU;;oBAEN,QAAQ;;;iBAIlB,YAAY,KAAK,cAAc;QAC7B,CAAC,CAAC,wCAAwC;QAC1C,CAAC,CAAC,wCACN;;;;;;mDAM2C,CAAC;AACpD,CAAC,CAAC;AAxDW,QAAA,qBAAqB,yBAwDhC","sourcesContent":["export const getReactDocumentation = ({\n language,\n envVarPrefix,\n}: {\n language: 'typescript' | 'javascript';\n envVarPrefix: string;\n}) => {\n const apiKeyText =\n envVarPrefix === 'VITE_PUBLIC_'\n ? 'import.meta.env.VITE_PUBLIC_POSTHOG_KEY'\n : `process.env.${envVarPrefix}POSTHOG_KEY`;\n\n const hostText =\n envVarPrefix === 'VITE_PUBLIC_'\n ? 'import.meta.env.VITE_PUBLIC_POSTHOG_HOST'\n : `process.env.${envVarPrefix}POSTHOG_HOST`;\n\n return `\n==============================\nFILE: {index / App}.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } (wherever the root of the app is)\nLOCATION: Wherever the root of the app is\n==============================\nChanges:\n- Add the PostHogProvider to the root of the app in the provider tree.\n\nExample:\n--------------------------------------------------\nimport React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport App from './App';\n\nimport { PostHogProvider} from 'posthog-js/react'\n\nconst root = ReactDOM.createRoot(document.getElementById('root'));\n\nroot.render(\n <React.StrictMode>\n <PostHogProvider\n apiKey={${apiKeyText}}\n options={{\n api_host: ${hostText},\n defaults: '2025-05-24',\n capture_exceptions: true, // This enables capturing exceptions using Error Tracking, set to false if you don't want this\n debug: ${\n envVarPrefix === 'VITE_PUBLIC_'\n ? 'import.meta.env.MODE === \"development\"'\n : 'process.env.NODE_ENV === \"development\"'\n },\n }}\n >\n <App />\n </PostHogProvider>\n </React.StrictMode>\n--------------------------------------------------`;\n};\n"]}
@@ -1,5 +1,4 @@
1
1
  export * from './add-editor-rules';
2
- export * from './create-pr';
3
2
  export * from './run-prettier';
4
3
  export * from './add-or-update-environment-variables';
5
4
  export * from './add-mcp-server-to-clients';
@@ -15,7 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./add-editor-rules"), exports);
18
- __exportStar(require("./create-pr"), exports);
19
18
  __exportStar(require("./run-prettier"), exports);
20
19
  __exportStar(require("./add-or-update-environment-variables"), exports);
21
20
  __exportStar(require("./add-mcp-server-to-clients"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/steps/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,8CAA4B;AAC5B,iDAA+B;AAC/B,wEAAsD;AACtD,8DAA4C;AAC5C,iEAA+C","sourcesContent":["export * from './add-editor-rules';\nexport * from './create-pr';\nexport * from './run-prettier';\nexport * from './add-or-update-environment-variables';\nexport * from './add-mcp-server-to-clients';\nexport * from './upload-environment-variables';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/steps/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,iDAA+B;AAC/B,wEAAsD;AACtD,8DAA4C;AAC5C,iEAA+C","sourcesContent":["export * from './add-editor-rules';\nexport * from './run-prettier';\nexport * from './add-or-update-environment-variables';\nexport * from './add-mcp-server-to-clients';\nexport * from './upload-environment-variables';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/wizard",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "homepage": "https://github.com/posthog/wizard",
5
5
  "repository": "https://github.com/posthog/wizard",
6
6
  "description": "The PostHog wizard helps you to configure your project",
@@ -1 +0,0 @@
1
- export {};
@@ -1,193 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- const childProcess = __importStar(require("node:child_process"));
37
- const create_pr_1 = require("../create-pr");
38
- // Mock dependencies
39
- jest.mock('node:child_process', () => ({
40
- exec: jest.fn(),
41
- }));
42
- describe('Git operations', () => {
43
- const execMock = childProcess.exec;
44
- const testDir = '/test/dir';
45
- beforeEach(() => {
46
- jest.clearAllMocks();
47
- });
48
- describe('getCurrentBranch', () => {
49
- it('should return the current branch name on success', async () => {
50
- execMock.mockImplementation((_cmd, _opts, callback) => {
51
- callback(null, 'main', '');
52
- return {};
53
- });
54
- const result = await (0, create_pr_1.getCurrentBranch)(testDir);
55
- expect(result).toEqual({ success: true, data: 'main' });
56
- expect(execMock).toHaveBeenCalledWith('git rev-parse --abbrev-ref HEAD', { cwd: testDir }, expect.any(Function));
57
- });
58
- it('should return error on failure', async () => {
59
- execMock.mockImplementation((_cmd, _opts, callback) => {
60
- callback(new Error('git error'), '', 'Failed to get branch');
61
- return {};
62
- });
63
- const result = await (0, create_pr_1.getCurrentBranch)(testDir);
64
- expect(result).toEqual({ success: false, error: 'Failed to get branch' });
65
- });
66
- });
67
- describe('checkForEnvFiles', () => {
68
- it('should return true when .env files are found', async () => {
69
- execMock.mockImplementation((_cmd, _opts, callback) => {
70
- callback(null, '.env\n.env.local', '');
71
- return {};
72
- });
73
- const result = await (0, create_pr_1.checkForEnvFiles)(testDir);
74
- expect(result).toEqual({ success: true, data: true });
75
- });
76
- it('should return false when no .env files are found', async () => {
77
- const error = new Error('No match');
78
- error.code = 1;
79
- execMock.mockImplementation((_cmd, _opts, callback) => {
80
- callback(error, '', 'command failed with exit code 1');
81
- return {};
82
- });
83
- const result = await (0, create_pr_1.checkForEnvFiles)(testDir);
84
- expect(result).toEqual({
85
- success: false,
86
- error: 'command failed with exit code 1',
87
- });
88
- });
89
- it('should handle grep errors correctly', async () => {
90
- execMock.mockImplementation((_cmd, _opts, callback) => {
91
- callback(new Error('grep error'), '', 'Some other error');
92
- return {};
93
- });
94
- const result = await (0, create_pr_1.checkForEnvFiles)(testDir);
95
- expect(result).toEqual({ success: false, error: 'Some other error' });
96
- });
97
- });
98
- describe('checkBranchExists', () => {
99
- it('should return success when branch does not exist', async () => {
100
- execMock.mockImplementation((_cmd, _opts, callback) => {
101
- callback(new Error('branch not found'), '', 'fatal: not a valid ref');
102
- return {};
103
- });
104
- const result = await (0, create_pr_1.checkBranchExists)('new-branch', testDir);
105
- expect(result).toEqual({ success: true, data: true });
106
- });
107
- it('should return failure when branch exists', async () => {
108
- execMock.mockImplementation((_cmd, _opts, callback) => {
109
- callback(null, 'ref exists', '');
110
- return {};
111
- });
112
- const result = await (0, create_pr_1.checkBranchExists)('existing-branch', testDir);
113
- expect(result).toEqual({ success: false, data: false });
114
- });
115
- });
116
- describe('createGitHubPR', () => {
117
- it('should create PR successfully', async () => {
118
- const prUrl = 'https://github.com/org/repo/pull/1';
119
- execMock.mockImplementation((_cmd, _opts, callback) => {
120
- callback(null, prUrl, '');
121
- return {};
122
- });
123
- const result = await (0, create_pr_1.createGitHubPR)('main', 'feature', 'title', 'body', testDir);
124
- expect(result).toEqual({ success: true, data: prUrl });
125
- expect(execMock).toHaveBeenCalledWith('gh pr create --base main --head feature --title "title" --body "body"', { cwd: testDir }, expect.any(Function));
126
- });
127
- it('should handle PR creation failure', async () => {
128
- execMock.mockImplementation((_cmd, _opts, callback) => {
129
- callback(new Error('PR creation failed'), '', 'Authentication failed');
130
- return {};
131
- });
132
- const result = await (0, create_pr_1.createGitHubPR)('main', 'feature', 'title', 'body', testDir);
133
- expect(result).toEqual({
134
- success: false,
135
- error: 'Authentication failed',
136
- });
137
- });
138
- });
139
- describe('Git operations', () => {
140
- const testCases = [
141
- {
142
- fn: create_pr_1.createBranch,
143
- args: ['new-branch', testDir],
144
- command: 'git checkout -b new-branch',
145
- name: 'createBranch',
146
- },
147
- {
148
- fn: create_pr_1.stageChanges,
149
- args: [testDir],
150
- command: 'git add .',
151
- name: 'stageChanges',
152
- },
153
- {
154
- fn: create_pr_1.commitChanges,
155
- args: ['commit message', testDir],
156
- command: 'git commit -m "commit message"',
157
- name: 'commitChanges',
158
- },
159
- {
160
- fn: create_pr_1.pushBranch,
161
- args: ['branch-name', testDir],
162
- command: 'git push -u origin branch-name',
163
- name: 'pushBranch',
164
- },
165
- {
166
- fn: create_pr_1.checkGitHubAuth,
167
- args: [testDir],
168
- command: 'gh auth status',
169
- name: 'checkGitHubAuth',
170
- },
171
- ];
172
- testCases.forEach(({ fn, args, command, name }) => {
173
- it(`${name} should execute correctly`, async () => {
174
- execMock.mockImplementation((_cmd, _opts, callback) => {
175
- callback(null, 'success', '');
176
- return {};
177
- });
178
- const result = await fn(...args);
179
- expect(result).toEqual({ success: true, data: 'success' });
180
- expect(execMock).toHaveBeenCalledWith(command, { cwd: testDir }, expect.any(Function));
181
- });
182
- it(`${name} should handle errors`, async () => {
183
- execMock.mockImplementation((_cmd, _opts, callback) => {
184
- callback(new Error('operation failed'), '', 'Command failed');
185
- return {};
186
- });
187
- const result = await fn(...args);
188
- expect(result).toEqual({ success: false, error: 'Command failed' });
189
- });
190
- });
191
- });
192
- });
193
- //# sourceMappingURL=create-pr.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-pr.test.js","sourceRoot":"","sources":["../../../../src/steps/__tests__/create-pr.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as childProcess from 'node:child_process';\nimport type { ExecException } from 'node:child_process';\nimport {\n checkBranchExists,\n checkForEnvFiles,\n checkGitHubAuth,\n commitChanges,\n createBranch,\n createGitHubPR,\n getCurrentBranch,\n pushBranch,\n stageChanges,\n} from '../create-pr';\n\n// Mock dependencies\njest.mock('node:child_process', () => ({\n exec: jest.fn(),\n}));\n\ntype ExecCallback = (\n error: ExecException | null,\n stdout: string,\n stderr: string,\n) => void;\n\ntype TestCase = {\n fn: (...args: any[]) => Promise<any>;\n args: readonly any[];\n command: string;\n name: string;\n};\n\ndescribe('Git operations', () => {\n const execMock = childProcess.exec as unknown as jest.Mock;\n const testDir = '/test/dir';\n\n beforeEach(() => {\n jest.clearAllMocks();\n });\n\n describe('getCurrentBranch', () => {\n it('should return the current branch name on success', async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(null, 'main', '');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await getCurrentBranch(testDir);\n expect(result).toEqual({ success: true, data: 'main' });\n expect(execMock).toHaveBeenCalledWith(\n 'git rev-parse --abbrev-ref HEAD',\n { cwd: testDir },\n expect.any(Function),\n );\n });\n\n it('should return error on failure', async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(new Error('git error'), '', 'Failed to get branch');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await getCurrentBranch(testDir);\n expect(result).toEqual({ success: false, error: 'Failed to get branch' });\n });\n });\n\n describe('checkForEnvFiles', () => {\n it('should return true when .env files are found', async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(null, '.env\\n.env.local', '');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await checkForEnvFiles(testDir);\n expect(result).toEqual({ success: true, data: true });\n });\n\n it('should return false when no .env files are found', async () => {\n const error = new Error('No match') as ExecException;\n error.code = 1;\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(error, '', 'command failed with exit code 1');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await checkForEnvFiles(testDir);\n expect(result).toEqual({\n success: false,\n error: 'command failed with exit code 1',\n });\n });\n\n it('should handle grep errors correctly', async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(new Error('grep error'), '', 'Some other error');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await checkForEnvFiles(testDir);\n expect(result).toEqual({ success: false, error: 'Some other error' });\n });\n });\n\n describe('checkBranchExists', () => {\n it('should return success when branch does not exist', async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(new Error('branch not found'), '', 'fatal: not a valid ref');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await checkBranchExists('new-branch', testDir);\n expect(result).toEqual({ success: true, data: true });\n });\n\n it('should return failure when branch exists', async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(null, 'ref exists', '');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await checkBranchExists('existing-branch', testDir);\n expect(result).toEqual({ success: false, data: false });\n });\n });\n\n describe('createGitHubPR', () => {\n it('should create PR successfully', async () => {\n const prUrl = 'https://github.com/org/repo/pull/1';\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(null, prUrl, '');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await createGitHubPR(\n 'main',\n 'feature',\n 'title',\n 'body',\n testDir,\n );\n expect(result).toEqual({ success: true, data: prUrl });\n expect(execMock).toHaveBeenCalledWith(\n 'gh pr create --base main --head feature --title \"title\" --body \"body\"',\n { cwd: testDir },\n expect.any(Function),\n );\n });\n\n it('should handle PR creation failure', async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(\n new Error('PR creation failed'),\n '',\n 'Authentication failed',\n );\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await createGitHubPR(\n 'main',\n 'feature',\n 'title',\n 'body',\n testDir,\n );\n expect(result).toEqual({\n success: false,\n error: 'Authentication failed',\n });\n });\n });\n\n describe('Git operations', () => {\n const testCases: TestCase[] = [\n {\n fn: createBranch,\n args: ['new-branch', testDir] as const,\n command: 'git checkout -b new-branch',\n name: 'createBranch',\n },\n {\n fn: stageChanges,\n args: [testDir] as const,\n command: 'git add .',\n name: 'stageChanges',\n },\n {\n fn: commitChanges,\n args: ['commit message', testDir] as const,\n command: 'git commit -m \"commit message\"',\n name: 'commitChanges',\n },\n {\n fn: pushBranch,\n args: ['branch-name', testDir] as const,\n command: 'git push -u origin branch-name',\n name: 'pushBranch',\n },\n {\n fn: checkGitHubAuth,\n args: [testDir] as const,\n command: 'gh auth status',\n name: 'checkGitHubAuth',\n },\n ];\n\n testCases.forEach(({ fn, args, command, name }) => {\n it(`${name} should execute correctly`, async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(null, 'success', '');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await fn(...args);\n expect(result).toEqual({ success: true, data: 'success' });\n expect(execMock).toHaveBeenCalledWith(\n command,\n { cwd: testDir },\n expect.any(Function),\n );\n });\n\n it(`${name} should handle errors`, async () => {\n execMock.mockImplementation(\n (_cmd: string, _opts: any, callback: ExecCallback) => {\n callback(new Error('operation failed'), '', 'Command failed');\n return {} as childProcess.ChildProcess;\n },\n );\n\n const result = await fn(...args);\n expect(result).toEqual({ success: false, error: 'Command failed' });\n });\n });\n });\n});\n"]}
@@ -1,27 +0,0 @@
1
- import { type Integration } from '../lib/constants';
2
- export declare const PR_CONFIG: {
3
- readonly defaultBranchName: "posthog-integration";
4
- readonly defaultTitle: "feat: add PostHog integration";
5
- };
6
- interface GitCommandResult<T> {
7
- success: boolean;
8
- data?: T;
9
- error?: string;
10
- }
11
- export declare function execGitCommand(command: string, cwd: string): Promise<GitCommandResult<string>>;
12
- export declare function getCurrentBranch(installDir: string): Promise<GitCommandResult<string>>;
13
- export declare function checkGitHubAuth(installDir: string): Promise<GitCommandResult<string>>;
14
- export declare function checkBranchExists(branch: string, installDir: string): Promise<GitCommandResult<boolean>>;
15
- export declare function createBranch(branch: string, installDir: string): Promise<GitCommandResult<string>>;
16
- export declare function stageChanges(installDir: string): Promise<GitCommandResult<string>>;
17
- export declare function checkForEnvFiles(installDir: string): Promise<GitCommandResult<boolean>>;
18
- export declare function commitChanges(message: string, installDir: string): Promise<GitCommandResult<string>>;
19
- export declare function pushBranch(branch: string, installDir: string): Promise<GitCommandResult<string>>;
20
- export declare function createGitHubPR(baseBranch: string, newBranch: string, title: string, body: string, installDir: string): Promise<GitCommandResult<string>>;
21
- interface CreatePRStepOptions {
22
- installDir: string;
23
- integration: Integration;
24
- addedEditorRules: boolean;
25
- }
26
- export declare function createPRStep({ installDir, integration, addedEditorRules, }: CreatePRStepOptions): Promise<string | undefined>;
27
- export {};
@@ -1,305 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.PR_CONFIG = void 0;
40
- exports.execGitCommand = execGitCommand;
41
- exports.getCurrentBranch = getCurrentBranch;
42
- exports.checkGitHubAuth = checkGitHubAuth;
43
- exports.checkBranchExists = checkBranchExists;
44
- exports.createBranch = createBranch;
45
- exports.stageChanges = stageChanges;
46
- exports.checkForEnvFiles = checkForEnvFiles;
47
- exports.commitChanges = commitChanges;
48
- exports.pushBranch = pushBranch;
49
- exports.createGitHubPR = createGitHubPR;
50
- exports.createPRStep = createPRStep;
51
- const chalk_1 = __importDefault(require("chalk"));
52
- const constants_1 = require("../lib/constants");
53
- const telemetry_1 = require("../telemetry");
54
- const analytics_1 = require("../utils/analytics");
55
- const clack_1 = __importDefault(require("../utils/clack"));
56
- const clack_utils_1 = require("../utils/clack-utils");
57
- const childProcess = __importStar(require("node:child_process"));
58
- const messages_1 = require("../lib/messages");
59
- exports.PR_CONFIG = {
60
- defaultBranchName: 'posthog-integration',
61
- defaultTitle: 'feat: add PostHog integration',
62
- };
63
- async function execGitCommand(command, cwd) {
64
- return new Promise((resolve) => {
65
- childProcess.exec(command, { cwd }, (err, stdout, stderr) => {
66
- if (err) {
67
- resolve({ success: false, error: stderr || err.message });
68
- }
69
- else {
70
- resolve({ success: true, data: stdout.trim() });
71
- }
72
- });
73
- });
74
- }
75
- async function getCurrentBranch(installDir) {
76
- return execGitCommand('git rev-parse --abbrev-ref HEAD', installDir);
77
- }
78
- async function checkGitHubAuth(installDir) {
79
- return execGitCommand('gh auth status', installDir);
80
- }
81
- async function checkBranchExists(branch, installDir) {
82
- const result = await execGitCommand(`git rev-parse --verify ${branch}`, installDir);
83
- // If the command fails, the branch does not exist
84
- if (!result.success) {
85
- return { success: true, data: true };
86
- }
87
- // If the command succeeds, the branch exists
88
- return { success: false, data: false };
89
- }
90
- async function createBranch(branch, installDir) {
91
- return execGitCommand(`git checkout -b ${branch}`, installDir);
92
- }
93
- async function stageChanges(installDir) {
94
- return execGitCommand('git add .', installDir);
95
- }
96
- async function checkForEnvFiles(installDir) {
97
- const result = await execGitCommand('git diff --cached --name-only', installDir);
98
- if (!result.success) {
99
- return { success: false, error: result.error };
100
- }
101
- const files = result.data
102
- ? result.data
103
- .split('\n')
104
- .map((f) => f.trim())
105
- .filter(Boolean)
106
- : [];
107
- const hasEnv = files.some((f) => f.startsWith('.env'));
108
- return { success: true, data: hasEnv };
109
- }
110
- async function commitChanges(message, installDir) {
111
- return execGitCommand(`git commit -m "${message}"`, installDir);
112
- }
113
- async function pushBranch(branch, installDir) {
114
- return execGitCommand(`git push -u origin ${branch}`, installDir);
115
- }
116
- async function createGitHubPR(baseBranch, newBranch, title, body, installDir) {
117
- return execGitCommand(`gh pr create --base ${baseBranch} --head ${newBranch} --title "${title}" --body "${body}"`, installDir);
118
- }
119
- async function createPRStep({ installDir, integration, addedEditorRules, }) {
120
- return (0, telemetry_1.traceStep)('create-pr', async () => {
121
- if (!(0, clack_utils_1.isInGitRepo)()) {
122
- clack_1.default.log.warn('Not in a git repository. Cannot create a pull request.');
123
- return;
124
- }
125
- // Get current branch
126
- const currentBranchResult = await getCurrentBranch(installDir);
127
- if (!currentBranchResult.success || !currentBranchResult.data) {
128
- analytics_1.analytics.capture('wizard interaction', {
129
- action: 'skipping pr creation',
130
- reason: 'failed to get current branch',
131
- error: currentBranchResult.error,
132
- integration,
133
- });
134
- if (constants_1.DEBUG) {
135
- clack_1.default.log.error(currentBranchResult.error ?? 'Failed to get current branch');
136
- }
137
- return;
138
- }
139
- const baseBranch = currentBranchResult.data;
140
- if (!['main', 'master'].includes(baseBranch)) {
141
- analytics_1.analytics.capture('wizard interaction', {
142
- action: 'skipping pr creation',
143
- reason: 'not on main or master',
144
- base_branch: baseBranch,
145
- integration,
146
- });
147
- if (constants_1.DEBUG) {
148
- clack_1.default.log.error(`Not on main or master. Skipping PR creation.`);
149
- }
150
- return;
151
- }
152
- // Check GitHub auth
153
- const authResult = await checkGitHubAuth(installDir);
154
- if (!authResult.success) {
155
- analytics_1.analytics.capture('wizard interaction', {
156
- action: 'skipping pr creation',
157
- reason: 'not logged into github',
158
- integration,
159
- });
160
- if (constants_1.DEBUG) {
161
- clack_1.default.log.error(authResult.error ?? 'Failed to check github auth');
162
- }
163
- return;
164
- }
165
- const newBranch = exports.PR_CONFIG.defaultBranchName;
166
- // Check if branch exists
167
- const branchExistsResult = await checkBranchExists(newBranch, installDir);
168
- if (!branchExistsResult.success) {
169
- analytics_1.analytics.capture('wizard interaction', {
170
- action: 'skipping pr creation',
171
- reason: 'branch already exists',
172
- error: branchExistsResult.error,
173
- integration,
174
- });
175
- if (constants_1.DEBUG) {
176
- clack_1.default.log.error(branchExistsResult.error ?? 'Failed to check branch exists');
177
- }
178
- return;
179
- }
180
- const prTitle = exports.PR_CONFIG.defaultTitle;
181
- const prDescription = (0, messages_1.getPRDescription)({
182
- integration,
183
- addedEditorRules,
184
- });
185
- const createPR = await (0, clack_utils_1.abortIfCancelled)(clack_1.default.select({
186
- message: 'Would you like to create a PR automatically?',
187
- initialValue: true,
188
- options: [
189
- {
190
- value: true,
191
- label: 'Yes',
192
- hint: 'We will create a PR for you',
193
- },
194
- {
195
- value: false,
196
- label: 'No',
197
- hint: 'You can create a PR manually later',
198
- },
199
- ],
200
- }), integration);
201
- if (!createPR) {
202
- clack_1.default.log.info('Skipping PR creation');
203
- return;
204
- }
205
- // Create branch
206
- const createBranchResult = await createBranch(newBranch, installDir);
207
- if (!createBranchResult.success) {
208
- analytics_1.analytics.capture('wizard interaction', {
209
- action: 'aborting pr creation',
210
- reason: 'failed to create branch',
211
- error: createBranchResult.error,
212
- integration,
213
- });
214
- clack_1.default.log.warn('Failed to create branch. Aborting PR creation 🚶‍➡️');
215
- return;
216
- }
217
- // Stage changes
218
- const stageResult = await stageChanges(installDir);
219
- if (!stageResult.success) {
220
- analytics_1.analytics.capture('wizard interaction', {
221
- action: 'aborting pr creation',
222
- reason: 'failed to stage changes',
223
- error: stageResult.error,
224
- integration,
225
- });
226
- clack_1.default.log.warn('Failed to stage changes. Aborting PR creation 🚶‍➡️');
227
- return;
228
- }
229
- // Check for env files
230
- const envCheckResult = await checkForEnvFiles(installDir);
231
- if (!envCheckResult.success) {
232
- analytics_1.analytics.capture('wizard interaction', {
233
- action: 'aborting pr creation',
234
- reason: 'failed to check for env files in staged changes',
235
- error: envCheckResult.error,
236
- integration,
237
- });
238
- clack_1.default.log.warn('Failed to check for .env files. Aborting PR creation 🚶‍➡️');
239
- return;
240
- }
241
- if (envCheckResult.data) {
242
- clack_1.default.log.warn('Found .env files in staged changes. Aborting PR creation to prevent exposing sensitive data 🔐');
243
- analytics_1.analytics.capture('wizard interaction', {
244
- action: 'aborting pr creation',
245
- reason: 'env files detected in staged changes',
246
- integration,
247
- });
248
- return;
249
- }
250
- // Commit changes
251
- const commitSpinner = clack_1.default.spinner();
252
- commitSpinner.start('Committing changes...');
253
- const commitResult = await commitChanges(prTitle, installDir);
254
- if (!commitResult.success) {
255
- commitSpinner.stop('Failed to commit changes. Aborting PR creation 🚶‍➡️');
256
- analytics_1.analytics.capture('wizard interaction', {
257
- action: 'aborting pr creation',
258
- reason: 'failed to commit changes',
259
- error: commitResult.error,
260
- integration,
261
- });
262
- return;
263
- }
264
- commitSpinner.stop('Changes committed successfully.');
265
- // Push branch
266
- const pushSpinner = clack_1.default.spinner();
267
- pushSpinner.start('Pushing branch to remote...');
268
- const pushResult = await pushBranch(newBranch, installDir);
269
- if (!pushResult.success) {
270
- pushSpinner.stop('Failed to push branch. Aborting PR creation 🚶‍➡️');
271
- analytics_1.analytics.capture('wizard interaction', {
272
- action: 'aborting pr creation',
273
- reason: 'failed to push branch',
274
- error: pushResult.error,
275
- integration,
276
- });
277
- return;
278
- }
279
- pushSpinner.stop('Branch pushed successfully.');
280
- // Create PR
281
- const prSpinner = clack_1.default.spinner();
282
- prSpinner.start(`Creating a PR on branch '${newBranch}' with base '${baseBranch}'...`);
283
- const prResult = await createGitHubPR(baseBranch, newBranch, prTitle, prDescription, installDir);
284
- if (!prResult.success || !prResult.data) {
285
- prSpinner.stop(`Failed to create PR on branch '${newBranch}'. Aborting PR creation 🚶‍➡️`);
286
- analytics_1.analytics.capture('wizard interaction', {
287
- action: 'aborting pr creation',
288
- reason: 'failed to create pr',
289
- error: prResult.error,
290
- integration,
291
- });
292
- return;
293
- }
294
- const prUrl = prResult.data;
295
- prSpinner.stop(`Successfully created PR! 🎉 You can review it here: ${chalk_1.default.cyan(prUrl)}`);
296
- analytics_1.analytics.capture('wizard interaction', {
297
- action: 'pr created',
298
- branch: newBranch,
299
- base_branch: baseBranch,
300
- integration,
301
- });
302
- return prUrl;
303
- });
304
- }
305
- //# sourceMappingURL=create-pr.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-pr.js","sourceRoot":"","sources":["../../../src/steps/create-pr.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,wCAaC;AAED,4CAIC;AAED,0CAIC;AAED,8CAcC;AAED,oCAKC;AAED,oCAIC;AAED,4CAkBC;AAED,sCAKC;AAED,gCAKC;AAED,wCAWC;AAQD,oCAiPC;AAlXD,kDAA0B;AAC1B,gDAA2D;AAC3D,4CAAyC;AACzC,kDAA+C;AAC/C,2DAAmC;AACnC,sDAAqE;AACrE,iEAAmD;AACnD,8CAAmD;AAEtC,QAAA,SAAS,GAAG;IACvB,iBAAiB,EAAE,qBAAqB;IACxC,YAAY,EAAE,+BAA+B;CACrC,CAAC;AAQJ,KAAK,UAAU,cAAc,CAClC,OAAe,EACf,GAAW;IAEX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC1D,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,gBAAgB,CACpC,UAAkB;IAElB,OAAO,cAAc,CAAC,iCAAiC,EAAE,UAAU,CAAC,CAAC;AACvE,CAAC;AAEM,KAAK,UAAU,eAAe,CACnC,UAAkB;IAElB,OAAO,cAAc,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;AACtD,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,UAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,0BAA0B,MAAM,EAAE,EAClC,UAAU,CACX,CAAC;IACF,kDAAkD;IAClD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IACD,6CAA6C;IAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzC,CAAC;AAEM,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,UAAkB;IAElB,OAAO,cAAc,CAAC,mBAAmB,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC;AACjE,CAAC;AAEM,KAAK,UAAU,YAAY,CAChC,UAAkB;IAElB,OAAO,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AACjD,CAAC;AAEM,KAAK,UAAU,gBAAgB,CACpC,UAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,+BAA+B,EAC/B,UAAU,CACX,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACjD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI;QACvB,CAAC,CAAC,MAAM,CAAC,IAAI;aACR,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC;QACpB,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACzC,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,OAAe,EACf,UAAkB;IAElB,OAAO,cAAc,CAAC,kBAAkB,OAAO,GAAG,EAAE,UAAU,CAAC,CAAC;AAClE,CAAC;AAEM,KAAK,UAAU,UAAU,CAC9B,MAAc,EACd,UAAkB;IAElB,OAAO,cAAc,CAAC,sBAAsB,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC;AACpE,CAAC;AAEM,KAAK,UAAU,cAAc,CAClC,UAAkB,EAClB,SAAiB,EACjB,KAAa,EACb,IAAY,EACZ,UAAkB;IAElB,OAAO,cAAc,CACnB,uBAAuB,UAAU,WAAW,SAAS,aAAa,KAAK,aAAa,IAAI,GAAG,EAC3F,UAAU,CACX,CAAC;AACJ,CAAC;AAQM,KAAK,UAAU,YAAY,CAAC,EACjC,UAAU,EACV,WAAW,EACX,gBAAgB,GACI;IACpB,OAAO,IAAA,qBAAS,EAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QACvC,IAAI,CAAC,IAAA,yBAAW,GAAE,EAAE,CAAC;YACnB,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;YACzE,OAAO;QACT,CAAC;QAED,qBAAqB;QACrB,MAAM,mBAAmB,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC/D,IAAI,CAAC,mBAAmB,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;YAC9D,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,8BAA8B;gBACtC,KAAK,EAAE,mBAAmB,CAAC,KAAK;gBAChC,WAAW;aACZ,CAAC,CAAC;YAEH,IAAI,iBAAK,EAAE,CAAC;gBACV,eAAK,CAAC,GAAG,CAAC,KAAK,CACb,mBAAmB,CAAC,KAAK,IAAI,8BAA8B,CAC5D,CAAC;YACJ,CAAC;YAED,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC;QAE5C,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7C,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,uBAAuB;gBAC/B,WAAW,EAAE,UAAU;gBACvB,WAAW;aACZ,CAAC,CAAC;YAEH,IAAI,iBAAK,EAAE,CAAC;gBACV,eAAK,CAAC,GAAG,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAClE,CAAC;YACD,OAAO;QACT,CAAC;QAED,oBAAoB;QACpB,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,wBAAwB;gBAChC,WAAW;aACZ,CAAC,CAAC;YAEH,IAAI,iBAAK,EAAE,CAAC;gBACV,eAAK,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,IAAI,6BAA6B,CAAC,CAAC;YACrE,CAAC;YAED,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,iBAAS,CAAC,iBAAiB,CAAC;QAE9C,yBAAyB;QACzB,MAAM,kBAAkB,GAAG,MAAM,iBAAiB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC1E,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAChC,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,uBAAuB;gBAC/B,KAAK,EAAE,kBAAkB,CAAC,KAAK;gBAC/B,WAAW;aACZ,CAAC,CAAC;YAEH,IAAI,iBAAK,EAAE,CAAC;gBACV,eAAK,CAAC,GAAG,CAAC,KAAK,CACb,kBAAkB,CAAC,KAAK,IAAI,+BAA+B,CAC5D,CAAC;YACJ,CAAC;YAED,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,iBAAS,CAAC,YAAY,CAAC;QACvC,MAAM,aAAa,GAAG,IAAA,2BAAgB,EAAC;YACrC,WAAW;YACX,gBAAgB;SACjB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,IAAA,8BAAgB,EACrC,eAAK,CAAC,MAAM,CAAC;YACX,OAAO,EAAE,8CAA8C;YACvD,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE;gBACP;oBACE,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,KAAK;oBACZ,IAAI,EAAE,6BAA6B;iBACpC;gBACD;oBACE,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,IAAI;oBACX,IAAI,EAAE,oCAAoC;iBAC3C;aACF;SACF,CAAC,EACF,WAAW,CACZ,CAAC;QAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QAED,gBAAgB;QAChB,MAAM,kBAAkB,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACrE,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAChC,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,yBAAyB;gBACjC,KAAK,EAAE,kBAAkB,CAAC,KAAK;gBAC/B,WAAW;aACZ,CAAC,CAAC;YACH,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,gBAAgB;QAChB,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,yBAAyB;gBACjC,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,WAAW;aACZ,CAAC,CAAC;YACH,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,sBAAsB;QACtB,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC5B,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,iDAAiD;gBACzD,KAAK,EAAE,cAAc,CAAC,KAAK;gBAC3B,WAAW;aACZ,CAAC,CAAC;YACH,eAAK,CAAC,GAAG,CAAC,IAAI,CACZ,4DAA4D,CAC7D,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;YACxB,eAAK,CAAC,GAAG,CAAC,IAAI,CACZ,gGAAgG,CACjG,CAAC;YACF,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,sCAAsC;gBAC9C,WAAW;aACZ,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,iBAAiB;QACjB,MAAM,aAAa,GAAG,eAAK,CAAC,OAAO,EAAE,CAAC;QACtC,aAAa,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC9D,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;YAC1B,aAAa,CAAC,IAAI,CAChB,sDAAsD,CACvD,CAAC;YACF,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,0BAA0B;gBAClC,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,WAAW;aACZ,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAEtD,cAAc;QACd,MAAM,WAAW,GAAG,eAAK,CAAC,OAAO,EAAE,CAAC;QACpC,WAAW,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,WAAW,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YACtE,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,uBAAuB;gBAC/B,KAAK,EAAE,UAAU,CAAC,KAAK;gBACvB,WAAW;aACZ,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAEhD,YAAY;QACZ,MAAM,SAAS,GAAG,eAAK,CAAC,OAAO,EAAE,CAAC;QAClC,SAAS,CAAC,KAAK,CACb,4BAA4B,SAAS,gBAAgB,UAAU,MAAM,CACtE,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,cAAc,CACnC,UAAU,EACV,SAAS,EACT,OAAO,EACP,aAAa,EACb,UAAU,CACX,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,SAAS,CAAC,IAAI,CACZ,kCAAkC,SAAS,+BAA+B,CAC3E,CAAC;YACF,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACtC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,qBAAqB;gBAC7B,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,WAAW;aACZ,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC5B,SAAS,CAAC,IAAI,CACZ,uDAAuD,eAAK,CAAC,IAAI,CAC/D,KAAK,CACN,EAAE,CACJ,CAAC;QAEF,qBAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE;YACtC,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,SAAS;YACjB,WAAW,EAAE,UAAU;YACvB,WAAW;SACZ,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import chalk from 'chalk';\nimport { DEBUG, type Integration } from '../lib/constants';\nimport { traceStep } from '../telemetry';\nimport { analytics } from '../utils/analytics';\nimport clack from '../utils/clack';\nimport { abortIfCancelled, isInGitRepo } from '../utils/clack-utils';\nimport * as childProcess from 'node:child_process';\nimport { getPRDescription } from '../lib/messages';\n\nexport const PR_CONFIG = {\n defaultBranchName: 'posthog-integration',\n defaultTitle: 'feat: add PostHog integration',\n} as const;\n\ninterface GitCommandResult<T> {\n success: boolean;\n data?: T;\n error?: string;\n}\n\nexport async function execGitCommand(\n command: string,\n cwd: string,\n): Promise<GitCommandResult<string>> {\n return new Promise((resolve) => {\n childProcess.exec(command, { cwd }, (err, stdout, stderr) => {\n if (err) {\n resolve({ success: false, error: stderr || err.message });\n } else {\n resolve({ success: true, data: stdout.trim() });\n }\n });\n });\n}\n\nexport async function getCurrentBranch(\n installDir: string,\n): Promise<GitCommandResult<string>> {\n return execGitCommand('git rev-parse --abbrev-ref HEAD', installDir);\n}\n\nexport async function checkGitHubAuth(\n installDir: string,\n): Promise<GitCommandResult<string>> {\n return execGitCommand('gh auth status', installDir);\n}\n\nexport async function checkBranchExists(\n branch: string,\n installDir: string,\n): Promise<GitCommandResult<boolean>> {\n const result = await execGitCommand(\n `git rev-parse --verify ${branch}`,\n installDir,\n );\n // If the command fails, the branch does not exist\n if (!result.success) {\n return { success: true, data: true };\n }\n // If the command succeeds, the branch exists\n return { success: false, data: false };\n}\n\nexport async function createBranch(\n branch: string,\n installDir: string,\n): Promise<GitCommandResult<string>> {\n return execGitCommand(`git checkout -b ${branch}`, installDir);\n}\n\nexport async function stageChanges(\n installDir: string,\n): Promise<GitCommandResult<string>> {\n return execGitCommand('git add .', installDir);\n}\n\nexport async function checkForEnvFiles(\n installDir: string,\n): Promise<GitCommandResult<boolean>> {\n const result = await execGitCommand(\n 'git diff --cached --name-only',\n installDir,\n );\n if (!result.success) {\n return { success: false, error: result.error };\n }\n const files = result.data\n ? result.data\n .split('\\n')\n .map((f) => f.trim())\n .filter(Boolean)\n : [];\n const hasEnv = files.some((f) => f.startsWith('.env'));\n return { success: true, data: hasEnv };\n}\n\nexport async function commitChanges(\n message: string,\n installDir: string,\n): Promise<GitCommandResult<string>> {\n return execGitCommand(`git commit -m \"${message}\"`, installDir);\n}\n\nexport async function pushBranch(\n branch: string,\n installDir: string,\n): Promise<GitCommandResult<string>> {\n return execGitCommand(`git push -u origin ${branch}`, installDir);\n}\n\nexport async function createGitHubPR(\n baseBranch: string,\n newBranch: string,\n title: string,\n body: string,\n installDir: string,\n): Promise<GitCommandResult<string>> {\n return execGitCommand(\n `gh pr create --base ${baseBranch} --head ${newBranch} --title \"${title}\" --body \"${body}\"`,\n installDir,\n );\n}\n\ninterface CreatePRStepOptions {\n installDir: string;\n integration: Integration;\n addedEditorRules: boolean;\n}\n\nexport async function createPRStep({\n installDir,\n integration,\n addedEditorRules,\n}: CreatePRStepOptions): Promise<string | undefined> {\n return traceStep('create-pr', async () => {\n if (!isInGitRepo()) {\n clack.log.warn('Not in a git repository. Cannot create a pull request.');\n return;\n }\n\n // Get current branch\n const currentBranchResult = await getCurrentBranch(installDir);\n if (!currentBranchResult.success || !currentBranchResult.data) {\n analytics.capture('wizard interaction', {\n action: 'skipping pr creation',\n reason: 'failed to get current branch',\n error: currentBranchResult.error,\n integration,\n });\n\n if (DEBUG) {\n clack.log.error(\n currentBranchResult.error ?? 'Failed to get current branch',\n );\n }\n\n return;\n }\n const baseBranch = currentBranchResult.data;\n\n if (!['main', 'master'].includes(baseBranch)) {\n analytics.capture('wizard interaction', {\n action: 'skipping pr creation',\n reason: 'not on main or master',\n base_branch: baseBranch,\n integration,\n });\n\n if (DEBUG) {\n clack.log.error(`Not on main or master. Skipping PR creation.`);\n }\n return;\n }\n\n // Check GitHub auth\n const authResult = await checkGitHubAuth(installDir);\n if (!authResult.success) {\n analytics.capture('wizard interaction', {\n action: 'skipping pr creation',\n reason: 'not logged into github',\n integration,\n });\n\n if (DEBUG) {\n clack.log.error(authResult.error ?? 'Failed to check github auth');\n }\n\n return;\n }\n\n const newBranch = PR_CONFIG.defaultBranchName;\n\n // Check if branch exists\n const branchExistsResult = await checkBranchExists(newBranch, installDir);\n if (!branchExistsResult.success) {\n analytics.capture('wizard interaction', {\n action: 'skipping pr creation',\n reason: 'branch already exists',\n error: branchExistsResult.error,\n integration,\n });\n\n if (DEBUG) {\n clack.log.error(\n branchExistsResult.error ?? 'Failed to check branch exists',\n );\n }\n\n return;\n }\n\n const prTitle = PR_CONFIG.defaultTitle;\n const prDescription = getPRDescription({\n integration,\n addedEditorRules,\n });\n\n const createPR = await abortIfCancelled(\n clack.select({\n message: 'Would you like to create a PR automatically?',\n initialValue: true,\n options: [\n {\n value: true,\n label: 'Yes',\n hint: 'We will create a PR for you',\n },\n {\n value: false,\n label: 'No',\n hint: 'You can create a PR manually later',\n },\n ],\n }),\n integration,\n );\n\n if (!createPR) {\n clack.log.info('Skipping PR creation');\n return;\n }\n\n // Create branch\n const createBranchResult = await createBranch(newBranch, installDir);\n if (!createBranchResult.success) {\n analytics.capture('wizard interaction', {\n action: 'aborting pr creation',\n reason: 'failed to create branch',\n error: createBranchResult.error,\n integration,\n });\n clack.log.warn('Failed to create branch. Aborting PR creation 🚶‍➡️');\n return;\n }\n\n // Stage changes\n const stageResult = await stageChanges(installDir);\n if (!stageResult.success) {\n analytics.capture('wizard interaction', {\n action: 'aborting pr creation',\n reason: 'failed to stage changes',\n error: stageResult.error,\n integration,\n });\n clack.log.warn('Failed to stage changes. Aborting PR creation 🚶‍➡️');\n return;\n }\n\n // Check for env files\n const envCheckResult = await checkForEnvFiles(installDir);\n if (!envCheckResult.success) {\n analytics.capture('wizard interaction', {\n action: 'aborting pr creation',\n reason: 'failed to check for env files in staged changes',\n error: envCheckResult.error,\n integration,\n });\n clack.log.warn(\n 'Failed to check for .env files. Aborting PR creation 🚶‍➡️',\n );\n return;\n }\n\n if (envCheckResult.data) {\n clack.log.warn(\n 'Found .env files in staged changes. Aborting PR creation to prevent exposing sensitive data 🔐',\n );\n analytics.capture('wizard interaction', {\n action: 'aborting pr creation',\n reason: 'env files detected in staged changes',\n integration,\n });\n return;\n }\n\n // Commit changes\n const commitSpinner = clack.spinner();\n commitSpinner.start('Committing changes...');\n const commitResult = await commitChanges(prTitle, installDir);\n if (!commitResult.success) {\n commitSpinner.stop(\n 'Failed to commit changes. Aborting PR creation 🚶‍➡️',\n );\n analytics.capture('wizard interaction', {\n action: 'aborting pr creation',\n reason: 'failed to commit changes',\n error: commitResult.error,\n integration,\n });\n return;\n }\n commitSpinner.stop('Changes committed successfully.');\n\n // Push branch\n const pushSpinner = clack.spinner();\n pushSpinner.start('Pushing branch to remote...');\n const pushResult = await pushBranch(newBranch, installDir);\n if (!pushResult.success) {\n pushSpinner.stop('Failed to push branch. Aborting PR creation 🚶‍➡️');\n analytics.capture('wizard interaction', {\n action: 'aborting pr creation',\n reason: 'failed to push branch',\n error: pushResult.error,\n integration,\n });\n return;\n }\n pushSpinner.stop('Branch pushed successfully.');\n\n // Create PR\n const prSpinner = clack.spinner();\n prSpinner.start(\n `Creating a PR on branch '${newBranch}' with base '${baseBranch}'...`,\n );\n const prResult = await createGitHubPR(\n baseBranch,\n newBranch,\n prTitle,\n prDescription,\n installDir,\n );\n if (!prResult.success || !prResult.data) {\n prSpinner.stop(\n `Failed to create PR on branch '${newBranch}'. Aborting PR creation 🚶‍➡️`,\n );\n analytics.capture('wizard interaction', {\n action: 'aborting pr creation',\n reason: 'failed to create pr',\n error: prResult.error,\n integration,\n });\n return;\n }\n\n const prUrl = prResult.data;\n prSpinner.stop(\n `Successfully created PR! 🎉 You can review it here: ${chalk.cyan(\n prUrl,\n )}`,\n );\n\n analytics.capture('wizard interaction', {\n action: 'pr created',\n branch: newBranch,\n base_branch: baseBranch,\n integration,\n });\n\n return prUrl;\n });\n}\n"]}