@posthog/wizard 0.7.0 → 0.7.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.
Files changed (126) hide show
  1. package/dist/bin.d.ts +2 -0
  2. package/dist/bin.js +28 -0
  3. package/dist/bin.js.map +1 -0
  4. package/dist/src/lib/config.d.ts +49 -0
  5. package/dist/src/lib/config.js +85 -0
  6. package/dist/src/lib/config.js.map +1 -0
  7. package/dist/src/lib/constants.d.ts +25 -0
  8. package/dist/src/lib/constants.js +45 -0
  9. package/dist/src/lib/constants.js.map +1 -0
  10. package/dist/src/lib/messages.d.ts +16 -0
  11. package/dist/src/lib/messages.js +52 -0
  12. package/dist/src/lib/messages.js.map +1 -0
  13. package/dist/src/lib/prompts.d.ts +16 -0
  14. package/dist/src/lib/prompts.js +83 -0
  15. package/dist/src/lib/prompts.js.map +1 -0
  16. package/dist/src/nextjs/docs.d.ts +8 -0
  17. package/dist/src/nextjs/docs.js +257 -0
  18. package/dist/src/nextjs/docs.js.map +1 -0
  19. package/dist/src/nextjs/nextjs-wizard.d.ts +2 -0
  20. package/dist/src/nextjs/nextjs-wizard.js +127 -0
  21. package/dist/src/nextjs/nextjs-wizard.js.map +1 -0
  22. package/dist/src/nextjs/utils.d.ts +9 -0
  23. package/dist/src/nextjs/utils.js +83 -0
  24. package/dist/src/nextjs/utils.js.map +1 -0
  25. package/dist/src/react/docs.d.ts +4 -0
  26. package/dist/src/react/docs.js +46 -0
  27. package/dist/src/react/docs.js.map +1 -0
  28. package/dist/src/react/react-wizard.d.ts +2 -0
  29. package/dist/src/react/react-wizard.js +106 -0
  30. package/dist/src/react/react-wizard.js.map +1 -0
  31. package/dist/src/react-native/docs.d.ts +5 -0
  32. package/dist/src/react-native/docs.js +31 -0
  33. package/dist/src/react-native/docs.js.map +1 -0
  34. package/dist/src/react-native/react-native-wizard.d.ts +2 -0
  35. package/dist/src/react-native/react-native-wizard.js +123 -0
  36. package/dist/src/react-native/react-native-wizard.js.map +1 -0
  37. package/dist/src/run.d.ts +13 -0
  38. package/dist/src/run.js +85 -0
  39. package/dist/src/run.js.map +1 -0
  40. package/dist/src/steps/__tests__/add-editor-rules.test.d.ts +1 -0
  41. package/dist/src/steps/__tests__/add-editor-rules.test.js +218 -0
  42. package/dist/src/steps/__tests__/add-editor-rules.test.js.map +1 -0
  43. package/dist/src/steps/__tests__/create-pr.test.d.ts +1 -0
  44. package/dist/src/steps/__tests__/create-pr.test.js +193 -0
  45. package/dist/src/steps/__tests__/create-pr.test.js.map +1 -0
  46. package/dist/src/steps/add-editor-rules.d.ts +9 -0
  47. package/dist/src/steps/add-editor-rules.js +90 -0
  48. package/dist/src/steps/add-editor-rules.js.map +1 -0
  49. package/dist/src/steps/add-or-update-environment-variables.d.ts +10 -0
  50. package/dist/src/steps/add-or-update-environment-variables.js +194 -0
  51. package/dist/src/steps/add-or-update-environment-variables.js.map +1 -0
  52. package/dist/src/steps/create-pr.d.ts +27 -0
  53. package/dist/src/steps/create-pr.js +305 -0
  54. package/dist/src/steps/create-pr.js.map +1 -0
  55. package/dist/src/steps/index.d.ts +4 -0
  56. package/dist/src/steps/index.js +21 -0
  57. package/dist/src/steps/index.js.map +1 -0
  58. package/dist/src/steps/run-prettier.d.ts +5 -0
  59. package/dist/src/steps/run-prettier.js +93 -0
  60. package/dist/src/steps/run-prettier.js.map +1 -0
  61. package/dist/src/svelte/docs.d.ts +3 -0
  62. package/dist/src/svelte/docs.js +110 -0
  63. package/dist/src/svelte/docs.js.map +1 -0
  64. package/dist/src/svelte/svelte-wizard.d.ts +2 -0
  65. package/dist/src/svelte/svelte-wizard.js +114 -0
  66. package/dist/src/svelte/svelte-wizard.js.map +1 -0
  67. package/dist/src/telemetry.d.ts +2 -0
  68. package/dist/src/telemetry.js +13 -0
  69. package/dist/src/telemetry.js.map +1 -0
  70. package/dist/src/utils/__tests__/clack-utils.test.d.ts +1 -0
  71. package/dist/src/utils/__tests__/clack-utils.test.js +128 -0
  72. package/dist/src/utils/__tests__/clack-utils.test.js.map +1 -0
  73. package/dist/src/utils/analytics.d.ts +12 -0
  74. package/dist/src/utils/analytics.js +59 -0
  75. package/dist/src/utils/analytics.js.map +1 -0
  76. package/dist/src/utils/bash.d.ts +2 -0
  77. package/dist/src/utils/bash.js +54 -0
  78. package/dist/src/utils/bash.js.map +1 -0
  79. package/dist/src/utils/clack-utils.d.ts +180 -0
  80. package/dist/src/utils/clack-utils.js +634 -0
  81. package/dist/src/utils/clack-utils.js.map +1 -0
  82. package/dist/src/utils/clack.d.ts +2 -0
  83. package/dist/src/utils/clack.js +9 -0
  84. package/dist/src/utils/clack.js.map +1 -0
  85. package/dist/src/utils/debug.d.ts +2 -0
  86. package/dist/src/utils/debug.js +22 -0
  87. package/dist/src/utils/debug.js.map +1 -0
  88. package/dist/src/utils/environment.d.ts +3 -0
  89. package/dist/src/utils/environment.js +64 -0
  90. package/dist/src/utils/environment.js.map +1 -0
  91. package/dist/src/utils/file-utils.d.ts +29 -0
  92. package/dist/src/utils/file-utils.js +177 -0
  93. package/dist/src/utils/file-utils.js.map +1 -0
  94. package/dist/src/utils/logging.d.ts +9 -0
  95. package/dist/src/utils/logging.js +50 -0
  96. package/dist/src/utils/logging.js.map +1 -0
  97. package/dist/src/utils/package-json.d.ts +25 -0
  98. package/dist/src/utils/package-json.js +27 -0
  99. package/dist/src/utils/package-json.js.map +1 -0
  100. package/dist/src/utils/package-manager.d.ts +21 -0
  101. package/dist/src/utils/package-manager.js +208 -0
  102. package/dist/src/utils/package-manager.js.map +1 -0
  103. package/dist/src/utils/query.d.ts +8 -0
  104. package/dist/src/utils/query.js +27 -0
  105. package/dist/src/utils/query.js.map +1 -0
  106. package/dist/src/utils/rules/next-rules.md +9 -0
  107. package/dist/src/utils/rules/react-native-rules.md +7 -0
  108. package/dist/src/utils/rules/react-rules.md +7 -0
  109. package/dist/src/utils/rules/svelte-rules.md +7 -0
  110. package/dist/src/utils/rules/universal.md +20 -0
  111. package/dist/src/utils/semver.d.ts +5 -0
  112. package/dist/src/utils/semver.js +25 -0
  113. package/dist/src/utils/semver.js.map +1 -0
  114. package/dist/src/utils/string.d.ts +1 -0
  115. package/dist/src/utils/string.js +9 -0
  116. package/dist/src/utils/string.js.map +1 -0
  117. package/dist/src/utils/types.d.ts +48 -0
  118. package/dist/src/utils/types.js +3 -0
  119. package/dist/src/utils/types.js.map +1 -0
  120. package/dist/src/utils/urls.d.ts +4 -0
  121. package/dist/src/utils/urls.js +35 -0
  122. package/dist/src/utils/urls.js.map +1 -0
  123. package/dist/src/utils/vendor/is-unicorn-supported.d.ts +1 -0
  124. package/dist/src/utils/vendor/is-unicorn-supported.js +24 -0
  125. package/dist/src/utils/vendor/is-unicorn-supported.js.map +1 -0
  126. package/package.json +1 -1
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ /* eslint-disable max-lines */
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.runReactWizard = runReactWizard;
8
+ const clack_utils_1 = require("../utils/clack-utils");
9
+ const package_json_1 = require("../utils/package-json");
10
+ const clack_1 = __importDefault(require("../utils/clack"));
11
+ const constants_1 = require("../lib/constants");
12
+ const docs_1 = require("./docs");
13
+ const analytics_1 = require("../utils/analytics");
14
+ const environment_1 = require("../utils/environment");
15
+ const file_utils_1 = require("../utils/file-utils");
16
+ const clack_utils_2 = require("../utils/clack-utils");
17
+ const messages_1 = require("../lib/messages");
18
+ const steps_1 = require("../steps");
19
+ async function runReactWizard(options) {
20
+ (0, clack_utils_1.printWelcome)({
21
+ wizardName: 'PostHog React Wizard',
22
+ });
23
+ const aiConsent = await (0, clack_utils_1.askForAIConsent)(options);
24
+ if (!aiConsent) {
25
+ await (0, clack_utils_1.abort)('The React wizard requires AI to get setup right now. Please view the docs to setup React manually instead: https://posthog.com/docs/libraries/react', 0);
26
+ }
27
+ const cloudRegion = options.cloudRegion ?? (await (0, clack_utils_2.askForCloudRegion)());
28
+ const typeScriptDetected = (0, clack_utils_1.isUsingTypeScript)(options);
29
+ await (0, clack_utils_1.confirmContinueIfNoOrDirtyGitRepo)(options);
30
+ const packageJson = await (0, clack_utils_1.getPackageDotJson)(options);
31
+ await (0, clack_utils_1.ensurePackageIsInstalled)(packageJson, 'react', 'React');
32
+ const reactVersion = (0, package_json_1.getPackageVersion)('react', packageJson);
33
+ if (reactVersion) {
34
+ analytics_1.analytics.setTag('react-version', reactVersion);
35
+ }
36
+ const { projectApiKey, wizardHash, host } = await (0, clack_utils_1.getOrAskForProjectData)({
37
+ ...options,
38
+ cloudRegion,
39
+ });
40
+ const sdkAlreadyInstalled = (0, package_json_1.hasPackageInstalled)('posthog-js', packageJson);
41
+ analytics_1.analytics.setTag('sdk-already-installed', sdkAlreadyInstalled);
42
+ const { packageManager: packageManagerFromInstallStep } = await (0, clack_utils_1.installPackage)({
43
+ packageName: 'posthog-js',
44
+ packageNameDisplayLabel: 'posthog-js',
45
+ alreadyInstalled: !!packageJson?.dependencies?.['posthog-js'],
46
+ forceInstall: options.forceInstall,
47
+ askBeforeUpdating: false,
48
+ installDir: options.installDir,
49
+ integration: constants_1.Integration.react,
50
+ });
51
+ const relevantFiles = await (0, file_utils_1.getRelevantFilesForIntegration)({
52
+ installDir: options.installDir,
53
+ integration: constants_1.Integration.react,
54
+ });
55
+ const envVarPrefix = await (0, environment_1.detectEnvVarPrefix)(options);
56
+ const installationDocumentation = (0, docs_1.getReactDocumentation)({
57
+ language: typeScriptDetected ? 'typescript' : 'javascript',
58
+ envVarPrefix,
59
+ });
60
+ clack_1.default.log.info(`Reviewing PostHog documentation for React`);
61
+ const filesToChange = await (0, file_utils_1.getFilesToChange)({
62
+ integration: constants_1.Integration.react,
63
+ relevantFiles,
64
+ documentation: installationDocumentation,
65
+ wizardHash,
66
+ cloudRegion,
67
+ });
68
+ await (0, file_utils_1.generateFileChangesForIntegration)({
69
+ integration: constants_1.Integration.react,
70
+ filesToChange,
71
+ wizardHash,
72
+ installDir: options.installDir,
73
+ documentation: installationDocumentation,
74
+ cloudRegion,
75
+ });
76
+ const { relativeEnvFilePath, addedEnvVariables } = await (0, steps_1.addOrUpdateEnvironmentVariablesStep)({
77
+ variables: {
78
+ [envVarPrefix + 'POSTHOG_KEY']: projectApiKey,
79
+ [envVarPrefix + 'POSTHOG_HOST']: host,
80
+ },
81
+ installDir: options.installDir,
82
+ integration: constants_1.Integration.react,
83
+ });
84
+ const packageManagerForOutro = packageManagerFromInstallStep ?? (await (0, clack_utils_1.getPackageManager)(options));
85
+ await (0, steps_1.runPrettierStep)({
86
+ installDir: options.installDir,
87
+ integration: constants_1.Integration.react,
88
+ });
89
+ const addedEditorRules = await (0, steps_1.addEditorRulesStep)({
90
+ installDir: options.installDir,
91
+ rulesName: 'react-rules.md',
92
+ integration: constants_1.Integration.react,
93
+ default: options.default,
94
+ });
95
+ const outroMessage = (0, messages_1.getOutroMessage)({
96
+ options,
97
+ integration: constants_1.Integration.react,
98
+ cloudRegion,
99
+ addedEditorRules,
100
+ packageManager: packageManagerForOutro,
101
+ envFileChanged: addedEnvVariables ? relativeEnvFilePath : undefined,
102
+ });
103
+ clack_1.default.outro(outroMessage);
104
+ await analytics_1.analytics.shutdown('success');
105
+ }
106
+ //# sourceMappingURL=react-wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-wizard.js","sourceRoot":"","sources":["../../../src/react/react-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n\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 clack from '../utils/clack';\nimport { Integration } from '../lib/constants';\nimport { getReactDocumentation } from './docs';\nimport { analytics } from '../utils/analytics';\nimport { detectEnvVarPrefix } from '../utils/environment';\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} from '../steps';\n\nexport async function runReactWizard(options: WizardOptions): Promise<void> {\n printWelcome({\n wizardName: 'PostHog React Wizard',\n });\n\n const aiConsent = await askForAIConsent(options);\n\n if (!aiConsent) {\n await abort(\n 'The React wizard requires AI to get setup right now. Please view the docs to setup React manually instead: https://posthog.com/docs/libraries/react',\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, 'react', 'React');\n\n const reactVersion = getPackageVersion('react', packageJson);\n\n if (reactVersion) {\n analytics.setTag('react-version', reactVersion);\n }\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.react,\n });\n\n const relevantFiles = await getRelevantFilesForIntegration({\n installDir: options.installDir,\n integration: Integration.react,\n });\n\n const envVarPrefix = await detectEnvVarPrefix(options);\n\n const installationDocumentation = getReactDocumentation({\n language: typeScriptDetected ? 'typescript' : 'javascript',\n envVarPrefix,\n });\n\n clack.log.info(`Reviewing PostHog documentation for React`);\n\n const filesToChange = await getFilesToChange({\n integration: Integration.react,\n relevantFiles,\n documentation: installationDocumentation,\n wizardHash,\n cloudRegion,\n });\n\n await generateFileChangesForIntegration({\n integration: Integration.react,\n filesToChange,\n wizardHash,\n installDir: options.installDir,\n documentation: installationDocumentation,\n cloudRegion,\n });\n\n const { relativeEnvFilePath, addedEnvVariables } =\n await addOrUpdateEnvironmentVariablesStep({\n variables: {\n [envVarPrefix + 'POSTHOG_KEY']: projectApiKey,\n [envVarPrefix + 'POSTHOG_HOST']: host,\n },\n installDir: options.installDir,\n integration: Integration.react,\n });\n\n const packageManagerForOutro =\n packageManagerFromInstallStep ?? (await getPackageManager(options));\n\n await runPrettierStep({\n installDir: options.installDir,\n integration: Integration.react,\n });\n\n const addedEditorRules = await addEditorRulesStep({\n installDir: options.installDir,\n rulesName: 'react-rules.md',\n integration: Integration.react,\n default: options.default,\n });\n\n const outroMessage = getOutroMessage({\n options,\n integration: Integration.react,\n cloudRegion,\n addedEditorRules,\n packageManager: packageManagerForOutro,\n envFileChanged: addedEnvVariables ? relativeEnvFilePath : undefined,\n });\n\n clack.outro(outroMessage);\n\n await analytics.shutdown('success');\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export declare const getReactNativeDocumentation: ({ language, host, projectApiKey, }: {
2
+ language: "typescript" | "javascript";
3
+ host: string;
4
+ projectApiKey: string;
5
+ }) => string;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getReactNativeDocumentation = void 0;
4
+ const getReactNativeDocumentation = ({ language, host, projectApiKey, }) => {
5
+ return `
6
+ ==============================
7
+ FILE: Modify the entrypoint for the app code
8
+ LOCATION: Usually app/_layout.${language === 'typescript' ? 'tsx' : 'jsx'}, app/index.${language === 'typescript' ? 'ts' : 'js'}, App.${language === 'typescript' ? 'tsx' : 'jsx'} or something similar. There is only one entrypoint file, so you should edit the existing one.
9
+ ==============================
10
+ Changes:
11
+ - Add the PostHogProvider to the root of the app in the provider tree. If other providers are already present, add it in a suitable location.
12
+
13
+ Example (with the correct API key and host):
14
+ --------------------------------------------------
15
+ import { PostHogProvider } from 'posthog-react-native'
16
+ ...
17
+
18
+ export function MyApp() {
19
+ return (
20
+ <PostHogProvider apiKey="${projectApiKey}" options={{
21
+ host: '${host}',
22
+ enableSessionReplay: true,
23
+ }} autocapture>
24
+ ...
25
+ </PostHogProvider>
26
+ )
27
+ }
28
+ --------------------------------------------------`;
29
+ };
30
+ exports.getReactNativeDocumentation = getReactNativeDocumentation;
31
+ //# sourceMappingURL=docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/react-native/docs.ts"],"names":[],"mappings":";;;AAAO,MAAM,2BAA2B,GAAG,CAAC,EAC1C,QAAQ,EACR,IAAI,EACJ,aAAa,GAKd,EAAE,EAAE;IACH,OAAO;;;gCAIL,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC,eAAe,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,SACpD,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KACtC;;;;;;;;;;;;mCAYiC,aAAa;qBAC3B,IAAI;;;;;;;mDAO0B,CAAC;AACpD,CAAC,CAAC;AArCW,QAAA,2BAA2B,+BAqCtC","sourcesContent":["export const getReactNativeDocumentation = ({\n language,\n host,\n projectApiKey,\n}: {\n language: 'typescript' | 'javascript';\n host: string;\n projectApiKey: string;\n}) => {\n return `\n==============================\nFILE: Modify the entrypoint for the app code\nLOCATION: Usually app/_layout.${\n language === 'typescript' ? 'tsx' : 'jsx'\n }, app/index.${language === 'typescript' ? 'ts' : 'js'}, App.${\n language === 'typescript' ? 'tsx' : 'jsx'\n } or something similar. There is only one entrypoint file, so you should edit the existing one.\n==============================\nChanges:\n- Add the PostHogProvider to the root of the app in the provider tree. If other providers are already present, add it in a suitable location.\n\nExample (with the correct API key and host):\n--------------------------------------------------\nimport { PostHogProvider } from 'posthog-react-native'\n...\n\nexport function MyApp() {\n return (\n <PostHogProvider apiKey=\"${projectApiKey}\" options={{\n host: '${host}', \n enableSessionReplay: true,\n }} autocapture>\n ...\n </PostHogProvider>\n )\n}\n--------------------------------------------------`;\n};\n"]}
@@ -0,0 +1,2 @@
1
+ import type { WizardOptions } from '../utils/types';
2
+ export declare function runReactNativeWizard(options: WizardOptions): Promise<void>;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ /* eslint-disable max-lines */
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.runReactNativeWizard = runReactNativeWizard;
8
+ const clack_utils_1 = require("../utils/clack-utils");
9
+ const package_json_1 = require("../utils/package-json");
10
+ const clack_1 = __importDefault(require("../utils/clack"));
11
+ const constants_1 = require("../lib/constants");
12
+ const docs_1 = require("./docs");
13
+ const analytics_1 = require("../utils/analytics");
14
+ const file_utils_1 = require("../utils/file-utils");
15
+ const clack_utils_2 = require("../utils/clack-utils");
16
+ const steps_1 = require("../steps");
17
+ const package_manager_1 = require("../utils/package-manager");
18
+ const messages_1 = require("../lib/messages");
19
+ async function runReactNativeWizard(options) {
20
+ (0, clack_utils_1.printWelcome)({
21
+ wizardName: 'PostHog React Native Wizard',
22
+ });
23
+ const aiConsent = await (0, clack_utils_1.askForAIConsent)(options);
24
+ if (!aiConsent) {
25
+ await (0, clack_utils_1.abort)('The React Native wizard requires AI to get setup right now. Please view the docs to setup React Native manually instead: https://posthog.com/docs/libraries/react-native', 0);
26
+ }
27
+ const cloudRegion = options.cloudRegion ?? (await (0, clack_utils_2.askForCloudRegion)());
28
+ const typeScriptDetected = (0, clack_utils_1.isUsingTypeScript)(options);
29
+ await (0, clack_utils_1.confirmContinueIfNoOrDirtyGitRepo)(options);
30
+ const packageJson = await (0, clack_utils_1.getPackageDotJson)(options);
31
+ await (0, clack_utils_1.ensurePackageIsInstalled)(packageJson, 'react-native', 'React Native');
32
+ const reactNativeVersion = (0, package_json_1.getPackageVersion)('react-native', packageJson);
33
+ if (reactNativeVersion) {
34
+ analytics_1.analytics.setTag('react-native-version', reactNativeVersion);
35
+ }
36
+ const { projectApiKey, wizardHash, host } = await (0, clack_utils_1.getOrAskForProjectData)({
37
+ ...options,
38
+ cloudRegion,
39
+ });
40
+ const sdkAlreadyInstalled = (0, package_json_1.hasPackageInstalled)('posthog-js', packageJson);
41
+ analytics_1.analytics.setTag('sdk-already-installed', sdkAlreadyInstalled);
42
+ const isUsingExpo = (0, package_json_1.hasPackageInstalled)('expo', packageJson);
43
+ if (isUsingExpo) {
44
+ analytics_1.analytics.setTag('is-using-expo', true);
45
+ analytics_1.analytics.setTag('expo-version', (0, package_json_1.getPackageVersion)('expo', packageJson));
46
+ }
47
+ clack_1.default.log.info(`Detected ${isUsingExpo ? 'Expo' : 'React Native'}`);
48
+ const packagesToInstall = isUsingExpo
49
+ ? [
50
+ 'posthog-react-native',
51
+ 'posthog-react-native-session-replay',
52
+ 'expo-file-system',
53
+ 'expo-application',
54
+ 'expo-device',
55
+ 'expo-localization',
56
+ ]
57
+ : [
58
+ 'posthog-react-native',
59
+ '@react-native-async-storage/async-storage',
60
+ 'react-native-device-info',
61
+ 'react-native-localize',
62
+ ];
63
+ for (const packageName of packagesToInstall) {
64
+ await (0, clack_utils_1.installPackage)({
65
+ packageName,
66
+ packageNameDisplayLabel: packageName,
67
+ alreadyInstalled: !!packageJson?.dependencies?.[packageName],
68
+ forceInstall: options.forceInstall,
69
+ askBeforeUpdating: false,
70
+ installDir: options.installDir,
71
+ integration: constants_1.Integration.reactNative,
72
+ packageManager: isUsingExpo ? package_manager_1.EXPO : undefined,
73
+ });
74
+ }
75
+ const relevantFiles = await (0, file_utils_1.getRelevantFilesForIntegration)({
76
+ installDir: options.installDir,
77
+ integration: constants_1.Integration.reactNative,
78
+ });
79
+ const installationDocumentation = (0, docs_1.getReactNativeDocumentation)({
80
+ language: typeScriptDetected ? 'typescript' : 'javascript',
81
+ host,
82
+ projectApiKey,
83
+ });
84
+ clack_1.default.log.info(`Reviewing PostHog documentation for ${isUsingExpo ? 'Expo' : 'React Native'}`);
85
+ const filesToChange = await (0, file_utils_1.getFilesToChange)({
86
+ integration: constants_1.Integration.reactNative,
87
+ relevantFiles,
88
+ documentation: installationDocumentation,
89
+ wizardHash,
90
+ cloudRegion,
91
+ });
92
+ await (0, file_utils_1.generateFileChangesForIntegration)({
93
+ integration: constants_1.Integration.reactNative,
94
+ filesToChange,
95
+ wizardHash,
96
+ installDir: options.installDir,
97
+ documentation: installationDocumentation,
98
+ cloudRegion,
99
+ });
100
+ await (0, steps_1.runPrettierStep)({
101
+ installDir: options.installDir,
102
+ integration: constants_1.Integration.reactNative,
103
+ });
104
+ const addedEditorRules = await (0, steps_1.addEditorRulesStep)({
105
+ installDir: options.installDir,
106
+ rulesName: 'react-native-rules.md',
107
+ integration: constants_1.Integration.reactNative,
108
+ default: options.default,
109
+ });
110
+ const packageManagerForOutro = await (0, clack_utils_1.getPackageManager)({
111
+ installDir: options.installDir,
112
+ });
113
+ const outroMessage = (0, messages_1.getOutroMessage)({
114
+ options,
115
+ integration: constants_1.Integration.reactNative,
116
+ cloudRegion,
117
+ addedEditorRules,
118
+ packageManager: packageManagerForOutro,
119
+ });
120
+ clack_1.default.outro(outroMessage);
121
+ await analytics_1.analytics.shutdown('success');
122
+ }
123
+ //# sourceMappingURL=react-native-wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native-wizard.js","sourceRoot":"","sources":["../../../src/react-native/react-native-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n\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 clack from '../utils/clack';\nimport { Integration } from '../lib/constants';\nimport { getReactNativeDocumentation } 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 { addEditorRulesStep, runPrettierStep } from '../steps';\nimport { EXPO } from '../utils/package-manager';\nimport { getOutroMessage } from '../lib/messages';\n\nexport async function runReactNativeWizard(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'PostHog React Native Wizard',\n });\n\n const aiConsent = await askForAIConsent(options);\n\n if (!aiConsent) {\n await abort(\n 'The React Native wizard requires AI to get setup right now. Please view the docs to setup React Native manually instead: https://posthog.com/docs/libraries/react-native',\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, 'react-native', 'React Native');\n\n const reactNativeVersion = getPackageVersion('react-native', packageJson);\n\n if (reactNativeVersion) {\n analytics.setTag('react-native-version', reactNativeVersion);\n }\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 isUsingExpo = hasPackageInstalled('expo', packageJson);\n\n if (isUsingExpo) {\n analytics.setTag('is-using-expo', true);\n analytics.setTag('expo-version', getPackageVersion('expo', packageJson));\n }\n\n clack.log.info(`Detected ${isUsingExpo ? 'Expo' : 'React Native'}`);\n\n const packagesToInstall = isUsingExpo\n ? [\n 'posthog-react-native',\n 'posthog-react-native-session-replay',\n 'expo-file-system',\n 'expo-application',\n 'expo-device',\n 'expo-localization',\n ]\n : [\n 'posthog-react-native',\n '@react-native-async-storage/async-storage',\n 'react-native-device-info',\n 'react-native-localize',\n ];\n\n for (const packageName of packagesToInstall) {\n await installPackage({\n packageName,\n packageNameDisplayLabel: packageName,\n alreadyInstalled: !!packageJson?.dependencies?.[packageName],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.reactNative,\n packageManager: isUsingExpo ? EXPO : undefined,\n });\n }\n\n const relevantFiles = await getRelevantFilesForIntegration({\n installDir: options.installDir,\n integration: Integration.reactNative,\n });\n\n const installationDocumentation = getReactNativeDocumentation({\n language: typeScriptDetected ? 'typescript' : 'javascript',\n host,\n projectApiKey,\n });\n\n clack.log.info(\n `Reviewing PostHog documentation for ${\n isUsingExpo ? 'Expo' : 'React Native'\n }`,\n );\n\n const filesToChange = await getFilesToChange({\n integration: Integration.reactNative,\n relevantFiles,\n documentation: installationDocumentation,\n wizardHash,\n cloudRegion,\n });\n\n await generateFileChangesForIntegration({\n integration: Integration.reactNative,\n filesToChange,\n wizardHash,\n installDir: options.installDir,\n documentation: installationDocumentation,\n cloudRegion,\n });\n\n await runPrettierStep({\n installDir: options.installDir,\n integration: Integration.reactNative,\n });\n\n const addedEditorRules = await addEditorRulesStep({\n installDir: options.installDir,\n rulesName: 'react-native-rules.md',\n integration: Integration.reactNative,\n default: options.default,\n });\n\n const packageManagerForOutro = await getPackageManager({\n installDir: options.installDir,\n });\n\n const outroMessage = getOutroMessage({\n options,\n integration: Integration.reactNative,\n cloudRegion,\n addedEditorRules,\n packageManager: packageManagerForOutro,\n });\n\n clack.outro(outroMessage);\n\n await analytics.shutdown('success');\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { CloudRegion } from './utils/types';
2
+ import { Integration } from './lib/constants';
3
+ type Args = {
4
+ integration?: Integration;
5
+ debug?: boolean;
6
+ forceInstall?: boolean;
7
+ installDir?: string;
8
+ region?: CloudRegion;
9
+ default?: boolean;
10
+ signup?: boolean;
11
+ };
12
+ export declare function run(argv: Args): Promise<void>;
13
+ export {};
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.run = run;
7
+ const clack_utils_1 = require("./utils/clack-utils");
8
+ const nextjs_wizard_1 = require("./nextjs/nextjs-wizard");
9
+ const constants_1 = require("./lib/constants");
10
+ const environment_1 = require("./utils/environment");
11
+ const clack_1 = __importDefault(require("./utils/clack"));
12
+ const path_1 = __importDefault(require("path"));
13
+ const config_1 = require("./lib/config");
14
+ const react_wizard_1 = require("./react/react-wizard");
15
+ const analytics_1 = require("./utils/analytics");
16
+ const svelte_wizard_1 = require("./svelte/svelte-wizard");
17
+ const react_native_wizard_1 = require("./react-native/react-native-wizard");
18
+ const events_1 = require("events");
19
+ events_1.EventEmitter.defaultMaxListeners = 50;
20
+ async function run(argv) {
21
+ await runWizard(argv);
22
+ }
23
+ async function runWizard(argv) {
24
+ const finalArgs = {
25
+ ...argv,
26
+ ...(0, environment_1.readEnvironment)(),
27
+ };
28
+ const wizardOptions = {
29
+ debug: finalArgs.debug ?? false,
30
+ forceInstall: finalArgs.forceInstall ?? false,
31
+ installDir: finalArgs.installDir
32
+ ? path_1.default.join(process.cwd(), finalArgs.installDir)
33
+ : process.cwd(),
34
+ cloudRegion: finalArgs.region ?? undefined,
35
+ default: finalArgs.default ?? false,
36
+ signup: finalArgs.signup ?? false,
37
+ };
38
+ clack_1.default.intro(`Welcome to the PostHog setup wizard ✨`);
39
+ const integration = finalArgs.integration ?? (await getIntegrationForSetup(wizardOptions));
40
+ analytics_1.analytics.setTag('integration', integration);
41
+ switch (integration) {
42
+ case constants_1.Integration.nextjs:
43
+ await (0, nextjs_wizard_1.runNextjsWizard)(wizardOptions);
44
+ break;
45
+ case constants_1.Integration.react:
46
+ await (0, react_wizard_1.runReactWizard)(wizardOptions);
47
+ break;
48
+ case constants_1.Integration.svelte:
49
+ await (0, svelte_wizard_1.runSvelteWizard)(wizardOptions);
50
+ break;
51
+ case constants_1.Integration.reactNative:
52
+ await (0, react_native_wizard_1.runReactNativeWizard)(wizardOptions);
53
+ break;
54
+ default:
55
+ clack_1.default.log.error('No setup wizard selected!');
56
+ }
57
+ }
58
+ async function detectIntegration(options) {
59
+ const integrationConfigs = Object.entries(config_1.INTEGRATION_CONFIG).sort(([a], [b]) => config_1.INTEGRATION_ORDER.indexOf(a) -
60
+ config_1.INTEGRATION_ORDER.indexOf(b));
61
+ for (const [integration, config] of integrationConfigs) {
62
+ const detected = await config.detect(options);
63
+ if (detected) {
64
+ return integration;
65
+ }
66
+ }
67
+ }
68
+ async function getIntegrationForSetup(options) {
69
+ const detectedIntegration = await detectIntegration(options);
70
+ if (detectedIntegration) {
71
+ clack_1.default.log.success(`Detected integration: ${(0, constants_1.getIntegrationDescription)(detectedIntegration)}`);
72
+ return detectedIntegration;
73
+ }
74
+ const integration = await (0, clack_utils_1.abortIfCancelled)(clack_1.default.select({
75
+ message: 'What do you want to set up?',
76
+ options: [
77
+ { value: constants_1.Integration.nextjs, label: 'Next.js' },
78
+ { value: constants_1.Integration.react, label: 'React' },
79
+ { value: constants_1.Integration.svelte, label: 'Svelte' },
80
+ { value: constants_1.Integration.reactNative, label: 'React Native' },
81
+ ],
82
+ }));
83
+ return integration;
84
+ }
85
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"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","sourcesContent":["import { abortIfCancelled } from './utils/clack-utils';\n\nimport { runNextjsWizard } from './nextjs/nextjs-wizard';\nimport type { CloudRegion, WizardOptions } from './utils/types';\n\nimport { getIntegrationDescription, Integration } from './lib/constants';\nimport { readEnvironment } from './utils/environment';\nimport clack from './utils/clack';\nimport path from 'path';\nimport { INTEGRATION_CONFIG, INTEGRATION_ORDER } from './lib/config';\nimport { runReactWizard } from './react/react-wizard';\nimport { analytics } from './utils/analytics';\nimport { runSvelteWizard } from './svelte/svelte-wizard';\nimport { runReactNativeWizard } from './react-native/react-native-wizard';\nimport { EventEmitter } from 'events';\n\nEventEmitter.defaultMaxListeners = 50;\n\ntype Args = {\n integration?: Integration;\n debug?: boolean;\n forceInstall?: boolean;\n installDir?: string;\n region?: CloudRegion;\n default?: boolean;\n signup?: boolean;\n};\n\nexport async function run(argv: Args) {\n await runWizard(argv);\n}\n\nasync function runWizard(argv: Args) {\n const finalArgs = {\n ...argv,\n ...readEnvironment(),\n };\n\n const wizardOptions: WizardOptions = {\n debug: finalArgs.debug ?? false,\n forceInstall: finalArgs.forceInstall ?? false,\n installDir: finalArgs.installDir\n ? path.join(process.cwd(), finalArgs.installDir)\n : process.cwd(),\n cloudRegion: finalArgs.region ?? undefined,\n default: finalArgs.default ?? false,\n signup: finalArgs.signup ?? false,\n };\n\n clack.intro(`Welcome to the PostHog setup wizard ✨`);\n\n const integration =\n finalArgs.integration ?? (await getIntegrationForSetup(wizardOptions));\n\n analytics.setTag('integration', integration);\n\n switch (integration) {\n case Integration.nextjs:\n await runNextjsWizard(wizardOptions);\n break;\n case Integration.react:\n await runReactWizard(wizardOptions);\n break;\n case Integration.svelte:\n await runSvelteWizard(wizardOptions);\n break;\n case Integration.reactNative:\n await runReactNativeWizard(wizardOptions);\n break;\n default:\n clack.log.error('No setup wizard selected!');\n }\n}\n\nasync function detectIntegration(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<Integration | undefined> {\n const integrationConfigs = Object.entries(INTEGRATION_CONFIG).sort(\n ([a], [b]) =>\n INTEGRATION_ORDER.indexOf(a as Integration) -\n INTEGRATION_ORDER.indexOf(b as Integration),\n );\n\n for (const [integration, config] of integrationConfigs) {\n const detected = await config.detect(options);\n if (detected) {\n return integration as Integration;\n }\n }\n}\n\nasync function getIntegrationForSetup(\n options: Pick<WizardOptions, 'installDir'>,\n) {\n const detectedIntegration = await detectIntegration(options);\n\n if (detectedIntegration) {\n clack.log.success(\n `Detected integration: ${getIntegrationDescription(detectedIntegration)}`,\n );\n return detectedIntegration;\n }\n\n const integration: Integration = await abortIfCancelled(\n clack.select({\n message: 'What do you want to set up?',\n options: [\n { value: Integration.nextjs, label: 'Next.js' },\n { value: Integration.react, label: 'React' },\n { value: Integration.svelte, label: 'Svelte' },\n { value: Integration.reactNative, label: 'React Native' },\n ],\n }),\n );\n\n return integration;\n}\n"]}
@@ -0,0 +1,218 @@
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
+ const fs = __importStar(require("fs"));
40
+ const path_1 = __importDefault(require("path"));
41
+ const add_editor_rules_1 = require("../add-editor-rules");
42
+ const analytics_1 = require("../../utils/analytics");
43
+ const clack_1 = __importDefault(require("../../utils/clack"));
44
+ const chalk_1 = __importDefault(require("chalk"));
45
+ // Mock dependencies
46
+ jest.mock('fs', () => ({
47
+ promises: {
48
+ mkdir: jest.fn(),
49
+ readFile: jest.fn(),
50
+ writeFile: jest.fn(),
51
+ },
52
+ }));
53
+ jest.mock('../../utils/analytics', () => ({
54
+ analytics: {
55
+ capture: jest.fn(),
56
+ setTag: jest.fn(),
57
+ shutdown: jest.fn().mockResolvedValue(undefined),
58
+ },
59
+ }));
60
+ jest.mock('../../utils/clack', () => ({
61
+ log: {
62
+ info: jest.fn(),
63
+ },
64
+ select: jest.fn().mockResolvedValue(true),
65
+ isCancel: jest.fn((value) => false),
66
+ cancel: jest.fn(),
67
+ }));
68
+ describe('addEditorRules', () => {
69
+ const mockOptions = {
70
+ installDir: '/test/dir',
71
+ rulesName: 'react-rules.md',
72
+ integration: 'react',
73
+ };
74
+ const originalEnv = process.env;
75
+ const mkdirMock = fs.promises.mkdir;
76
+ const readFileMock = fs.promises.readFile;
77
+ const writeFileMock = fs.promises.writeFile;
78
+ // eslint-disable-next-line @typescript-eslint/unbound-method
79
+ const captureMock = analytics_1.analytics.capture;
80
+ const infoMock = clack_1.default.log.info;
81
+ const selectMock = clack_1.default.select;
82
+ const isCancelMock = clack_1.default.isCancel;
83
+ const cancelMock = clack_1.default.cancel;
84
+ beforeEach(() => {
85
+ // Reset all mocks before each test
86
+ jest.clearAllMocks();
87
+ // Clear mock implementations
88
+ fs.promises.mkdir.mockReset();
89
+ fs.promises.readFile.mockReset();
90
+ fs.promises.writeFile.mockReset();
91
+ selectMock.mockReset();
92
+ selectMock.mockResolvedValue(true); // Default to "Yes" for the prompt
93
+ isCancelMock.mockReset();
94
+ isCancelMock.mockReturnValue(false);
95
+ cancelMock.mockReset();
96
+ process.env = { ...originalEnv };
97
+ });
98
+ afterAll(() => {
99
+ process.env = originalEnv;
100
+ });
101
+ it('should not install rules when CURSOR_TRACE_ID is not set', async () => {
102
+ delete process.env.CURSOR_TRACE_ID;
103
+ await (0, add_editor_rules_1.addEditorRulesStep)(mockOptions);
104
+ expect(mkdirMock).not.toHaveBeenCalled();
105
+ expect(readFileMock).not.toHaveBeenCalled();
106
+ expect(writeFileMock).not.toHaveBeenCalled();
107
+ expect(captureMock).not.toHaveBeenCalled();
108
+ expect(infoMock).not.toHaveBeenCalled();
109
+ });
110
+ it('should install rules when CURSOR_TRACE_ID is set', async () => {
111
+ process.env.CURSOR_TRACE_ID = 'test-trace-id';
112
+ const mockFrameworkRules = 'framework rules {universal} content';
113
+ const mockUniversalRules = 'universal rules content';
114
+ const expectedCombinedRules = 'framework rules universal rules content content';
115
+ fs.promises.readFile
116
+ .mockImplementationOnce(() => Promise.resolve(mockFrameworkRules))
117
+ .mockImplementationOnce(() => Promise.resolve(mockUniversalRules));
118
+ await (0, add_editor_rules_1.addEditorRulesStep)(mockOptions);
119
+ // Check if directory was created
120
+ expect(mkdirMock).toHaveBeenCalledWith(path_1.default.join('/test/dir', '.cursor', 'rules'), { recursive: true });
121
+ // Check if correct files were read
122
+ expect(readFileMock).toHaveBeenCalledTimes(2);
123
+ expect(readFileMock).toHaveBeenNthCalledWith(1, expect.stringMatching(/react-rules\.md$/), 'utf8');
124
+ expect(readFileMock).toHaveBeenNthCalledWith(2, expect.stringMatching(/universal\.md$/), 'utf8');
125
+ // Check if combined rules were written correctly
126
+ expect(writeFileMock).toHaveBeenCalledWith(path_1.default.join('/test/dir', '.cursor', 'rules', 'posthog-integration.mdc'), expectedCombinedRules, 'utf8');
127
+ // Check if analytics were captured
128
+ expect(captureMock).toHaveBeenCalledWith('wizard interaction', {
129
+ action: 'added editor rules',
130
+ integration: mockOptions.integration,
131
+ });
132
+ // Check if success message was logged
133
+ expect(infoMock).toHaveBeenCalledWith(`Added Cursor rules to ${chalk_1.default.bold.cyan('.cursor/rules/posthog-integration.mdc')}`);
134
+ });
135
+ it('should handle file system errors gracefully', async () => {
136
+ process.env.CURSOR_TRACE_ID = 'test-trace-id';
137
+ const mockError = new Error('File not found');
138
+ // Mock readFile to throw an error
139
+ fs.promises.readFile.mockRejectedValue(mockError);
140
+ await expect((0, add_editor_rules_1.addEditorRulesStep)(mockOptions)).rejects.toThrow(mockError);
141
+ expect(writeFileMock).not.toHaveBeenCalled();
142
+ expect(captureMock).not.toHaveBeenCalled();
143
+ expect(infoMock).not.toHaveBeenCalled();
144
+ });
145
+ it('should handle missing rules files gracefully', async () => {
146
+ process.env.CURSOR_TRACE_ID = 'test-trace-id';
147
+ const mockError = new Error('File system error');
148
+ // Mock mkdir to throw an error
149
+ fs.promises.mkdir.mockRejectedValue(mockError);
150
+ await expect((0, add_editor_rules_1.addEditorRulesStep)(mockOptions)).rejects.toThrow(mockError);
151
+ expect(writeFileMock).not.toHaveBeenCalled();
152
+ expect(captureMock).not.toHaveBeenCalled();
153
+ expect(infoMock).not.toHaveBeenCalled();
154
+ });
155
+ it('should correctly substitute universal rules with realistic content', async () => {
156
+ process.env.CURSOR_TRACE_ID = 'test-trace-id';
157
+ const mockFrameworkRules = `---
158
+ description: apply when interacting with PostHog/analytics tasks
159
+ globs:
160
+ alwaysApply: true
161
+ ---
162
+
163
+ {universal}
164
+
165
+ # Framework-specific rules
166
+ - Rule 1
167
+ - Rule 2`;
168
+ const mockUniversalRules = `Never hallucinate an API key. Instead, always use the API key populated in the .env file.
169
+
170
+ # Feature flags
171
+
172
+ A given feature flag should be used in as few places as possible. Do not increase the risk of undefined behavior by scattering the same feature flag across multiple areas of code.`;
173
+ const expectedCombinedRules = `---
174
+ description: apply when interacting with PostHog/analytics tasks
175
+ globs:
176
+ alwaysApply: true
177
+ ---
178
+
179
+ Never hallucinate an API key. Instead, always use the API key populated in the .env file.
180
+
181
+ # Feature flags
182
+
183
+ A given feature flag should be used in as few places as possible. Do not increase the risk of undefined behavior by scattering the same feature flag across multiple areas of code.
184
+
185
+ # Framework-specific rules
186
+ - Rule 1
187
+ - Rule 2`;
188
+ fs.promises.readFile
189
+ .mockImplementationOnce(() => Promise.resolve(mockFrameworkRules))
190
+ .mockImplementationOnce(() => Promise.resolve(mockUniversalRules));
191
+ await (0, add_editor_rules_1.addEditorRulesStep)(mockOptions);
192
+ // Check if directory was created
193
+ expect(mkdirMock).toHaveBeenCalledWith(path_1.default.join('/test/dir', '.cursor', 'rules'), { recursive: true });
194
+ // Check if correct files were read
195
+ expect(readFileMock).toHaveBeenCalledWith(expect.stringMatching(/react-rules\.md$/), 'utf8');
196
+ expect(readFileMock).toHaveBeenCalledWith(expect.stringMatching(/universal\.md$/), 'utf8');
197
+ // Check if combined rules were written correctly
198
+ expect(writeFileMock).toHaveBeenCalledWith(path_1.default.join('/test/dir', '.cursor', 'rules', 'posthog-integration.mdc'), expectedCombinedRules, 'utf8');
199
+ // Check if analytics were captured
200
+ expect(captureMock).toHaveBeenCalledWith('wizard interaction', {
201
+ action: 'added editor rules',
202
+ integration: mockOptions.integration,
203
+ });
204
+ // Check if success message was logged
205
+ expect(infoMock).toHaveBeenCalledWith(`Added Cursor rules to ${chalk_1.default.bold.cyan('.cursor/rules/posthog-integration.mdc')}`);
206
+ });
207
+ it('should not install rules when user declines', async () => {
208
+ process.env.CURSOR_TRACE_ID = 'test-trace-id';
209
+ selectMock.mockResolvedValue(false);
210
+ await (0, add_editor_rules_1.addEditorRulesStep)(mockOptions);
211
+ expect(mkdirMock).not.toHaveBeenCalled();
212
+ expect(readFileMock).not.toHaveBeenCalled();
213
+ expect(writeFileMock).not.toHaveBeenCalled();
214
+ expect(captureMock).not.toHaveBeenCalled();
215
+ expect(infoMock).not.toHaveBeenCalled();
216
+ });
217
+ });
218
+ //# sourceMappingURL=add-editor-rules.test.js.map