@posthog/wizard 2.2.0 → 2.4.0

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 (65) hide show
  1. package/dist/src/lib/__tests__/agent-interface.test.js +22 -0
  2. package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
  3. package/dist/src/lib/agent-interface.d.ts +20 -2
  4. package/dist/src/lib/agent-interface.js +97 -14
  5. package/dist/src/lib/agent-interface.js.map +1 -1
  6. package/dist/src/lib/agent-runner.js +21 -9
  7. package/dist/src/lib/agent-runner.js.map +1 -1
  8. package/dist/src/lib/api.d.ts +4 -4
  9. package/dist/src/lib/constants.d.ts +1 -1
  10. package/dist/src/lib/health-checks/__tests__/health-checks.test.js +11 -4
  11. package/dist/src/lib/health-checks/__tests__/health-checks.test.js.map +1 -1
  12. package/dist/src/lib/health-checks/endpoints.d.ts +1 -0
  13. package/dist/src/lib/health-checks/endpoints.js +3 -1
  14. package/dist/src/lib/health-checks/endpoints.js.map +1 -1
  15. package/dist/src/lib/health-checks/index.d.ts +1 -1
  16. package/dist/src/lib/health-checks/index.js +2 -1
  17. package/dist/src/lib/health-checks/index.js.map +1 -1
  18. package/dist/src/lib/health-checks/readiness.js +12 -3
  19. package/dist/src/lib/health-checks/readiness.js.map +1 -1
  20. package/dist/src/lib/health-checks/types.d.ts +1 -0
  21. package/dist/src/lib/health-checks/types.js.map +1 -1
  22. package/dist/src/lib/version.d.ts +1 -1
  23. package/dist/src/lib/version.js +1 -1
  24. package/dist/src/lib/version.js.map +1 -1
  25. package/dist/src/lib/wizard-session.d.ts +2 -0
  26. package/dist/src/lib/wizard-session.js +1 -0
  27. package/dist/src/lib/wizard-session.js.map +1 -1
  28. package/dist/src/lib/wizard-tools.d.ts +22 -0
  29. package/dist/src/lib/wizard-tools.js +71 -39
  30. package/dist/src/lib/wizard-tools.js.map +1 -1
  31. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +6 -6
  32. package/dist/src/ui/logging-ui.d.ts +3 -1
  33. package/dist/src/ui/logging-ui.js +6 -6
  34. package/dist/src/ui/logging-ui.js.map +1 -1
  35. package/dist/src/ui/tui/ink-ui.d.ts +3 -1
  36. package/dist/src/ui/tui/ink-ui.js +5 -2
  37. package/dist/src/ui/tui/ink-ui.js.map +1 -1
  38. package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js +1 -0
  39. package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js.map +1 -1
  40. package/dist/src/ui/tui/router.d.ts +3 -1
  41. package/dist/src/ui/tui/router.js +2 -0
  42. package/dist/src/ui/tui/router.js.map +1 -1
  43. package/dist/src/ui/tui/screen-registry.js +4 -0
  44. package/dist/src/ui/tui/screen-registry.js.map +1 -1
  45. package/dist/src/ui/tui/screens/AuthErrorScreen.d.ts +7 -0
  46. package/dist/src/ui/tui/screens/AuthErrorScreen.js +16 -0
  47. package/dist/src/ui/tui/screens/AuthErrorScreen.js.map +1 -0
  48. package/dist/src/ui/tui/screens/ManagedSettingsScreen.d.ts +13 -0
  49. package/dist/src/ui/tui/screens/ManagedSettingsScreen.js +32 -0
  50. package/dist/src/ui/tui/screens/ManagedSettingsScreen.js.map +1 -0
  51. package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +0 -4
  52. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +13 -7
  53. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +1 -1
  54. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +50 -5
  55. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -1
  56. package/dist/src/ui/tui/store.d.ts +4 -1
  57. package/dist/src/ui/tui/store.js +16 -3
  58. package/dist/src/ui/tui/store.js.map +1 -1
  59. package/dist/src/ui/wizard-ui.d.ts +4 -2
  60. package/dist/src/ui/wizard-ui.js.map +1 -1
  61. package/dist/src/utils/__tests__/semver.test.js +45 -3
  62. package/dist/src/utils/__tests__/semver.test.js.map +1 -1
  63. package/dist/src/utils/semver.js +25 -0
  64. package/dist/src/utils/semver.js.map +1 -1
  65. package/package.json +1 -1
@@ -7,6 +7,7 @@
7
7
  * No prompt methods — the TUI screens own all user input.
8
8
  * Session-mutating methods trigger reactive screen resolution in the TUI.
9
9
  */
10
+ import type { SettingsConflict } from '../lib/agent-interface';
10
11
  export declare enum TaskStatus {
11
12
  Pending = "pending",
12
13
  InProgress = "in_progress",
@@ -50,8 +51,9 @@ export interface WizardUI {
50
51
  pid: string;
51
52
  user: string;
52
53
  }): Promise<void>;
53
- /** Warn that .claude/settings.json overrides blocking env vars (pushes blocking overlay in TUI). */
54
- showSettingsOverride(keys: string[], backupAndFix: () => boolean): Promise<void>;
54
+ showSettingsOverride(conflicts: SettingsConflict[], backupAndFix: () => boolean): Promise<void>;
55
+ /** Show auth error overlay when Anthropic API returns 401. */
56
+ showAuthError(): void;
55
57
  /** Set the detected framework label (e.g., "Django with Wagtail CMS") */
56
58
  setDetectedFramework(label: string): void;
57
59
  /** Register a callback to run when the TUI transitions onto the given screen. */
@@ -1 +1 @@
1
- {"version":3,"file":"wizard-ui.js","sourceRoot":"","sources":["../../../src/ui/wizard-ui.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,wCAA0B,CAAA;IAC1B,qCAAuB,CAAA;AACzB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["/**\n * WizardUI — abstraction layer for all user-facing operations.\n *\n * Business logic calls `getUI()` instead of importing the store directly.\n * Implementations: InkUI (TUI), LoggingUI (CI).\n *\n * No prompt methods — the TUI screens own all user input.\n * Session-mutating methods trigger reactive screen resolution in the TUI.\n */\n\nexport enum TaskStatus {\n Pending = 'pending',\n InProgress = 'in_progress',\n Completed = 'completed',\n}\n\nexport interface SpinnerHandle {\n start(message?: string): void;\n stop(message?: string): void;\n message(msg?: string): void;\n}\n\nexport interface WizardUI {\n // ── Lifecycle messages ────────────────────────────────────────────\n intro(message: string): void;\n outro(message: string): void;\n cancel(message: string): void;\n\n // ── Logging ───────────────────────────────────────────────────────\n log: {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n success(message: string): void;\n step(message: string): void;\n };\n\n note(message: string): void;\n pushStatus(message: string): void;\n\n // ── Spinner ───────────────────────────────────────────────────────\n spinner(): SpinnerHandle;\n\n // ── Session state (triggers reactive screen resolution in TUI) ────\n /** Signal that the main work (agent run) has started. */\n startRun(): void;\n\n /** Store OAuth/API credentials. Resolves past AuthScreen in TUI. */\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void;\n\n /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */\n showBlockingOutage(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void>;\n\n /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */\n setReadinessWarnings(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void;\n\n /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void>;\n\n /** Warn that .claude/settings.json overrides blocking env vars (pushes blocking overlay in TUI). */\n showSettingsOverride(\n keys: string[],\n backupAndFix: () => boolean,\n ): Promise<void>;\n\n // ── Display state ──────────────────────────────────────────────────\n /** Set the detected framework label (e.g., \"Django with Wagtail CMS\") */\n setDetectedFramework(label: string): void;\n\n /** Register a callback to run when the TUI transitions onto the given screen. */\n onEnterScreen(screen: string, fn: () => void): void;\n\n setLoginUrl(url: string | null): void;\n\n // ── Todo tracking from SDK TodoWrite events ───────────────────────\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void;\n\n // ── Event plan from .posthog-events.json ────────────────────\n setEventPlan(events: Array<{ name: string; description: string }>): void;\n}\n"]}
1
+ {"version":3,"file":"wizard-ui.js","sourceRoot":"","sources":["../../../src/ui/wizard-ui.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAIH,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,wCAA0B,CAAA;IAC1B,qCAAuB,CAAA;AACzB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["/**\n * WizardUI — abstraction layer for all user-facing operations.\n *\n * Business logic calls `getUI()` instead of importing the store directly.\n * Implementations: InkUI (TUI), LoggingUI (CI).\n *\n * No prompt methods — the TUI screens own all user input.\n * Session-mutating methods trigger reactive screen resolution in the TUI.\n */\n\nimport type { SettingsConflict } from '../lib/agent-interface';\n\nexport enum TaskStatus {\n Pending = 'pending',\n InProgress = 'in_progress',\n Completed = 'completed',\n}\n\nexport interface SpinnerHandle {\n start(message?: string): void;\n stop(message?: string): void;\n message(msg?: string): void;\n}\n\nexport interface WizardUI {\n // ── Lifecycle messages ────────────────────────────────────────────\n intro(message: string): void;\n outro(message: string): void;\n cancel(message: string): void;\n\n // ── Logging ───────────────────────────────────────────────────────\n log: {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n success(message: string): void;\n step(message: string): void;\n };\n\n note(message: string): void;\n pushStatus(message: string): void;\n\n // ── Spinner ───────────────────────────────────────────────────────\n spinner(): SpinnerHandle;\n\n // ── Session state (triggers reactive screen resolution in TUI) ────\n /** Signal that the main work (agent run) has started. */\n startRun(): void;\n\n /** Store OAuth/API credentials. Resolves past AuthScreen in TUI. */\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void;\n\n /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */\n showBlockingOutage(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void>;\n\n /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */\n setReadinessWarnings(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void;\n\n /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void>;\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void>;\n\n /** Show auth error overlay when Anthropic API returns 401. */\n showAuthError(): void;\n\n // ── Display state ──────────────────────────────────────────────────\n /** Set the detected framework label (e.g., \"Django with Wagtail CMS\") */\n setDetectedFramework(label: string): void;\n\n /** Register a callback to run when the TUI transitions onto the given screen. */\n onEnterScreen(screen: string, fn: () => void): void;\n\n setLoginUrl(url: string | null): void;\n\n // ── Todo tracking from SDK TodoWrite events ───────────────────────\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void;\n\n // ── Event plan from .posthog-events.json ────────────────────\n setEventPlan(events: Array<{ name: string; description: string }>): void;\n}\n"]}
@@ -108,9 +108,51 @@ describe('createVersionBucket', () => {
108
108
  it('handles versions with build metadata', () => {
109
109
  expect(getVersionBucket('1.0.0+build.123')).toBe('1.x');
110
110
  });
111
- it('handles whitespace-only string (semver treats as version 0)', () => {
112
- // Note: semver's minVersion treats whitespace as a valid range matching version 0
113
- expect(getVersionBucket(' ')).toBe('0.x');
111
+ it('returns "unknown" for whitespace-only string', () => {
112
+ expect(getVersionBucket(' ')).toBe('unknown');
113
+ });
114
+ });
115
+ describe('non-semver package.json version formats', () => {
116
+ const getVersionBucket = (0, semver_1.createVersionBucket)();
117
+ it('returns "unknown" and never throws', () => {
118
+ const cases = [
119
+ 'https://github.com/user/repo/tarball/main',
120
+ 'git+https://github.com/user/repo.git',
121
+ 'user/repo',
122
+ 'file:../my-lib',
123
+ 'workspace:*',
124
+ 'npm:@scope/pkg@^1.0.0',
125
+ 'next',
126
+ 'canary',
127
+ ];
128
+ for (const v of cases) {
129
+ expect(getVersionBucket(v)).toBe('unknown');
130
+ }
131
+ });
132
+ });
133
+ });
134
+ describe('fulfillsVersionRange', () => {
135
+ const check = (version, acceptable = '>=15.0.0', canBeLatest = false) => (0, semver_1.fulfillsVersionRange)({
136
+ version,
137
+ acceptableVersions: acceptable,
138
+ canBeLatest,
139
+ });
140
+ describe('non-semver package.json version formats', () => {
141
+ it('rejects non-semver versions without throwing', () => {
142
+ const cases = [
143
+ 'https://github.com/user/repo/tarball/main',
144
+ 'git+https://github.com/user/repo.git',
145
+ 'user/repo',
146
+ 'file:../my-lib',
147
+ 'workspace:*',
148
+ 'npm:@scope/pkg@^1.0.0',
149
+ '',
150
+ 'next',
151
+ 'canary',
152
+ ];
153
+ for (const v of cases) {
154
+ expect(check(v)).toBe(false);
155
+ }
114
156
  });
115
157
  });
116
158
  });
@@ -1 +1 @@
1
- {"version":3,"file":"semver.test.js","sourceRoot":"","sources":["../../../../src/utils/__tests__/semver.test.ts"],"names":[],"mappings":";;AAAA,sCAAgD;AAEhD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,MAAM,gBAAgB,GAAG,IAAA,4BAAmB,GAAE,CAAC;QAE/C,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;YAC/C,MAAM,gBAAgB,GAAG,IAAA,4BAAmB,EAAC,EAAE,CAAC,CAAC;YAEjD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;gBAClE,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACnD,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAClD,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;gBACzC,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACjD,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;YACnD,MAAM,gBAAgB,GAAG,IAAA,4BAAmB,EAAC,CAAC,CAAC,CAAC;YAEhD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;gBAClE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACjD,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;YAC7C,MAAM,gBAAgB,GAAG,IAAA,4BAAmB,EAAC,CAAC,CAAC,CAAC;YAEhD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;gBAClE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACjD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;YAC5C,MAAM,gBAAgB,GAAG,IAAA,4BAAmB,EAAC,CAAC,CAAC,CAAC;YAEhD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;gBAClE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACjD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;YAC9C,MAAM,gBAAgB,GAAG,IAAA,4BAAmB,EAAC,CAAC,CAAC,CAAC;YAEhD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;gBAClE,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACjD,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,MAAM,gBAAgB,GAAG,IAAA,4BAAmB,GAAE,CAAC;QAE/C,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrD,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnD,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;YACrE,kFAAkF;YAClF,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { createVersionBucket } from '../semver';\n\ndescribe('createVersionBucket', () => {\n describe('without minimum threshold', () => {\n const getVersionBucket = createVersionBucket();\n\n it('returns \"none\" for undefined version', () => {\n expect(getVersionBucket(undefined)).toBe('none');\n });\n\n it('returns \"none\" for empty string', () => {\n expect(getVersionBucket('')).toBe('none');\n });\n\n it('returns major version bucket for exact versions', () => {\n expect(getVersionBucket('1.0.0')).toBe('1.x');\n expect(getVersionBucket('2.5.3')).toBe('2.x');\n expect(getVersionBucket('15.3.2')).toBe('15.x');\n });\n\n it('returns major version bucket for semver ranges', () => {\n expect(getVersionBucket('^1.0.0')).toBe('1.x');\n expect(getVersionBucket('~2.5.0')).toBe('2.x');\n expect(getVersionBucket('>=15.0.0')).toBe('15.x');\n });\n\n it('returns \"unknown\" for invalid semver (caught by try/catch)', () => {\n expect(getVersionBucket('not-a-version')).toBe('unknown');\n expect(getVersionBucket('abc')).toBe('unknown');\n });\n\n it('handles version 0.x correctly', () => {\n expect(getVersionBucket('0.1.0')).toBe('0.x');\n expect(getVersionBucket('0.0.1')).toBe('0.x');\n });\n });\n\n describe('with minimum threshold', () => {\n describe('threshold of 11 (Next.js style)', () => {\n const getVersionBucket = createVersionBucket(11);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('11.0.0')).toBe('11.x');\n expect(getVersionBucket('12.5.3')).toBe('12.x');\n expect(getVersionBucket('15.3.2')).toBe('15.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('10.0.0')).toBe('<11.0.0');\n expect(getVersionBucket('9.5.0')).toBe('<11.0.0');\n expect(getVersionBucket('1.0.0')).toBe('<11.0.0');\n });\n\n it('handles semver ranges correctly', () => {\n expect(getVersionBucket('^15.0.0')).toBe('15.x');\n expect(getVersionBucket('^10.0.0')).toBe('<11.0.0');\n });\n });\n\n describe('threshold of 6 (React Router style)', () => {\n const getVersionBucket = createVersionBucket(6);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('6.0.0')).toBe('6.x');\n expect(getVersionBucket('7.1.0')).toBe('7.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('5.3.0')).toBe('<6.0.0');\n expect(getVersionBucket('4.0.0')).toBe('<6.0.0');\n });\n });\n\n describe('threshold of 3 (Django style)', () => {\n const getVersionBucket = createVersionBucket(3);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('3.0.0')).toBe('3.x');\n expect(getVersionBucket('4.2.1')).toBe('4.x');\n expect(getVersionBucket('5.0.0')).toBe('5.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('2.2.0')).toBe('<3.0.0');\n expect(getVersionBucket('1.11.0')).toBe('<3.0.0');\n });\n });\n\n describe('threshold of 2 (Flask style)', () => {\n const getVersionBucket = createVersionBucket(2);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('2.0.0')).toBe('2.x');\n expect(getVersionBucket('3.0.0')).toBe('3.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('1.1.0')).toBe('<2.0.0');\n expect(getVersionBucket('0.12.0')).toBe('<2.0.0');\n });\n });\n\n describe('threshold of 9 (Laravel style)', () => {\n const getVersionBucket = createVersionBucket(9);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('9.0.0')).toBe('9.x');\n expect(getVersionBucket('10.0.0')).toBe('10.x');\n expect(getVersionBucket('11.0.0')).toBe('11.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('8.0.0')).toBe('<9.0.0');\n expect(getVersionBucket('7.0.0')).toBe('<9.0.0');\n });\n });\n });\n\n describe('edge cases', () => {\n const getVersionBucket = createVersionBucket();\n\n it('handles version with only major.minor', () => {\n expect(getVersionBucket('1.0')).toBe('1.x');\n expect(getVersionBucket('15.3')).toBe('15.x');\n });\n\n it('handles prerelease versions', () => {\n expect(getVersionBucket('1.0.0-beta.1')).toBe('1.x');\n expect(getVersionBucket('2.0.0-rc.1')).toBe('2.x');\n expect(getVersionBucket('15.0.0-canary.1')).toBe('15.x');\n });\n\n it('handles versions with build metadata', () => {\n expect(getVersionBucket('1.0.0+build.123')).toBe('1.x');\n });\n\n it('handles whitespace-only string (semver treats as version 0)', () => {\n // Note: semver's minVersion treats whitespace as a valid range matching version 0\n expect(getVersionBucket(' ')).toBe('0.x');\n });\n });\n});\n"]}
1
+ {"version":3,"file":"semver.test.js","sourceRoot":"","sources":["../../../../src/utils/__tests__/semver.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { createVersionBucket, fulfillsVersionRange } from '../semver';\n\ndescribe('createVersionBucket', () => {\n describe('without minimum threshold', () => {\n const getVersionBucket = createVersionBucket();\n\n it('returns \"none\" for undefined version', () => {\n expect(getVersionBucket(undefined)).toBe('none');\n });\n\n it('returns \"none\" for empty string', () => {\n expect(getVersionBucket('')).toBe('none');\n });\n\n it('returns major version bucket for exact versions', () => {\n expect(getVersionBucket('1.0.0')).toBe('1.x');\n expect(getVersionBucket('2.5.3')).toBe('2.x');\n expect(getVersionBucket('15.3.2')).toBe('15.x');\n });\n\n it('returns major version bucket for semver ranges', () => {\n expect(getVersionBucket('^1.0.0')).toBe('1.x');\n expect(getVersionBucket('~2.5.0')).toBe('2.x');\n expect(getVersionBucket('>=15.0.0')).toBe('15.x');\n });\n\n it('returns \"unknown\" for invalid semver (caught by try/catch)', () => {\n expect(getVersionBucket('not-a-version')).toBe('unknown');\n expect(getVersionBucket('abc')).toBe('unknown');\n });\n\n it('handles version 0.x correctly', () => {\n expect(getVersionBucket('0.1.0')).toBe('0.x');\n expect(getVersionBucket('0.0.1')).toBe('0.x');\n });\n });\n\n describe('with minimum threshold', () => {\n describe('threshold of 11 (Next.js style)', () => {\n const getVersionBucket = createVersionBucket(11);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('11.0.0')).toBe('11.x');\n expect(getVersionBucket('12.5.3')).toBe('12.x');\n expect(getVersionBucket('15.3.2')).toBe('15.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('10.0.0')).toBe('<11.0.0');\n expect(getVersionBucket('9.5.0')).toBe('<11.0.0');\n expect(getVersionBucket('1.0.0')).toBe('<11.0.0');\n });\n\n it('handles semver ranges correctly', () => {\n expect(getVersionBucket('^15.0.0')).toBe('15.x');\n expect(getVersionBucket('^10.0.0')).toBe('<11.0.0');\n });\n });\n\n describe('threshold of 6 (React Router style)', () => {\n const getVersionBucket = createVersionBucket(6);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('6.0.0')).toBe('6.x');\n expect(getVersionBucket('7.1.0')).toBe('7.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('5.3.0')).toBe('<6.0.0');\n expect(getVersionBucket('4.0.0')).toBe('<6.0.0');\n });\n });\n\n describe('threshold of 3 (Django style)', () => {\n const getVersionBucket = createVersionBucket(3);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('3.0.0')).toBe('3.x');\n expect(getVersionBucket('4.2.1')).toBe('4.x');\n expect(getVersionBucket('5.0.0')).toBe('5.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('2.2.0')).toBe('<3.0.0');\n expect(getVersionBucket('1.11.0')).toBe('<3.0.0');\n });\n });\n\n describe('threshold of 2 (Flask style)', () => {\n const getVersionBucket = createVersionBucket(2);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('2.0.0')).toBe('2.x');\n expect(getVersionBucket('3.0.0')).toBe('3.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('1.1.0')).toBe('<2.0.0');\n expect(getVersionBucket('0.12.0')).toBe('<2.0.0');\n });\n });\n\n describe('threshold of 9 (Laravel style)', () => {\n const getVersionBucket = createVersionBucket(9);\n\n it('returns major version bucket for versions >= threshold', () => {\n expect(getVersionBucket('9.0.0')).toBe('9.x');\n expect(getVersionBucket('10.0.0')).toBe('10.x');\n expect(getVersionBucket('11.0.0')).toBe('11.x');\n });\n\n it('returns \"<threshold\" bucket for versions below threshold', () => {\n expect(getVersionBucket('8.0.0')).toBe('<9.0.0');\n expect(getVersionBucket('7.0.0')).toBe('<9.0.0');\n });\n });\n });\n\n describe('edge cases', () => {\n const getVersionBucket = createVersionBucket();\n\n it('handles version with only major.minor', () => {\n expect(getVersionBucket('1.0')).toBe('1.x');\n expect(getVersionBucket('15.3')).toBe('15.x');\n });\n\n it('handles prerelease versions', () => {\n expect(getVersionBucket('1.0.0-beta.1')).toBe('1.x');\n expect(getVersionBucket('2.0.0-rc.1')).toBe('2.x');\n expect(getVersionBucket('15.0.0-canary.1')).toBe('15.x');\n });\n\n it('handles versions with build metadata', () => {\n expect(getVersionBucket('1.0.0+build.123')).toBe('1.x');\n });\n\n it('returns \"unknown\" for whitespace-only string', () => {\n expect(getVersionBucket(' ')).toBe('unknown');\n });\n });\n\n describe('non-semver package.json version formats', () => {\n const getVersionBucket = createVersionBucket();\n\n it('returns \"unknown\" and never throws', () => {\n const cases = [\n 'https://github.com/user/repo/tarball/main',\n 'git+https://github.com/user/repo.git',\n 'user/repo',\n 'file:../my-lib',\n 'workspace:*',\n 'npm:@scope/pkg@^1.0.0',\n 'next',\n 'canary',\n ];\n for (const v of cases) {\n expect(getVersionBucket(v)).toBe('unknown');\n }\n });\n });\n});\n\ndescribe('fulfillsVersionRange', () => {\n const check = (\n version: string,\n acceptable = '>=15.0.0',\n canBeLatest = false,\n ) =>\n fulfillsVersionRange({\n version,\n acceptableVersions: acceptable,\n canBeLatest,\n });\n\n describe('non-semver package.json version formats', () => {\n it('rejects non-semver versions without throwing', () => {\n const cases = [\n 'https://github.com/user/repo/tarball/main',\n 'git+https://github.com/user/repo.git',\n 'user/repo',\n 'file:../my-lib',\n 'workspace:*',\n 'npm:@scope/pkg@^1.0.0',\n '',\n 'next',\n 'canary',\n ];\n for (const v of cases) {\n expect(check(v)).toBe(false);\n }\n });\n });\n});\n"]}
@@ -3,10 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fulfillsVersionRange = fulfillsVersionRange;
4
4
  exports.createVersionBucket = createVersionBucket;
5
5
  const semver_1 = require("semver");
6
+ /**
7
+ * Version strings from package.json that are not semver ranges.
8
+ * URLs, git refs, dist-tags, local paths, workspace protocol, npm aliases, etc.
9
+ * These should be rejected early — we can't determine a clear version from them.
10
+ */
11
+ function isNonSemverVersion(version) {
12
+ const v = version.trim();
13
+ return (v === '' ||
14
+ v.startsWith('http://') ||
15
+ v.startsWith('https://') ||
16
+ v.startsWith('git+') ||
17
+ v.startsWith('git://') ||
18
+ v.startsWith('file:') ||
19
+ v.startsWith('npm:') ||
20
+ v.startsWith('workspace:') ||
21
+ v.startsWith('/') ||
22
+ v.includes('/') // user/repo shorthand
23
+ );
24
+ }
6
25
  function fulfillsVersionRange({ version, acceptableVersions, canBeLatest, }) {
7
26
  if (version === 'latest') {
8
27
  return canBeLatest;
9
28
  }
29
+ if (isNonSemverVersion(version)) {
30
+ return false;
31
+ }
10
32
  let cleanedUserVersion, isRange;
11
33
  if ((0, semver_1.valid)(version)) {
12
34
  cleanedUserVersion = (0, semver_1.valid)(version);
@@ -43,6 +65,9 @@ function createVersionBucket(minMajorVersion) {
43
65
  if (!version) {
44
66
  return 'none';
45
67
  }
68
+ if (isNonSemverVersion(version)) {
69
+ return 'unknown';
70
+ }
46
71
  try {
47
72
  const minVer = (0, semver_1.minVersion)(version);
48
73
  if (!minVer) {
@@ -1 +1 @@
1
- {"version":3,"file":"semver.js","sourceRoot":"","sources":["../../../src/utils/semver.ts"],"names":[],"mappings":";;AASA,oDA8BC;AAiBD,kDAoBC;AA5ED,mCAOgB;AAEhB,SAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,kBAAkB,EAClB,WAAW,GAKZ;IACC,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,kBAAkB,EAAE,OAAO,CAAC;IAEhC,IAAI,IAAA,cAAK,EAAC,OAAO,CAAC,EAAE,CAAC;QACnB,kBAAkB,GAAG,IAAA,cAAK,EAAC,OAAO,CAAC,CAAC;QACpC,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC;SAAM,IAAI,IAAA,mBAAU,EAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,kBAAkB,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,CAAC;QACzC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO;IACL,yGAAyG;IACzG,CAAC,CAAC,kBAAkB;QACpB,CAAC,OAAO;YACN,CAAC,CAAC,IAAA,eAAM,EAAC,kBAAkB,EAAE,kBAAkB,CAAC;YAChD,CAAC,CAAC,IAAA,kBAAS,EAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CACvD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,mBAAmB,CAAC,eAAwB;IAC1D,OAAO,CAAC,OAA2B,EAAU,EAAE;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,MAAM,YAAY,GAAG,IAAA,cAAK,EAAC,MAAM,CAAC,CAAC;YACnC,IAAI,eAAe,KAAK,SAAS,IAAI,YAAY,GAAG,eAAe,EAAE,CAAC;gBACpE,OAAO,IAAI,eAAe,MAAM,CAAC;YACnC,CAAC;YACD,OAAO,GAAG,YAAY,IAAI,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {\n major,\n minVersion,\n satisfies,\n subset,\n valid,\n validRange,\n} from 'semver';\n\nexport function fulfillsVersionRange({\n version,\n acceptableVersions,\n canBeLatest,\n}: {\n version: string;\n acceptableVersions: string;\n canBeLatest: boolean;\n}): boolean {\n if (version === 'latest') {\n return canBeLatest;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\n );\n}\n\n/**\n * Creates a version bucket function for analytics.\n * Converts versions like \"1.2.3\" to \"1.x\" for grouping in analytics.\n *\n * @param minMajorVersion - Optional minimum major version threshold.\n * Versions below this will be bucketed as \"<{min}.0.0\"\n *\n * @example\n * const getVersionBucket = createVersionBucket(); // no minimum\n * getVersionBucket(\"1.2.3\") // \"1.x\"\n *\n * const getVersionBucket = createVersionBucket(11);\n * getVersionBucket(\"15.3.0\") // \"15.x\"\n * getVersionBucket(\"10.0.0\") // \"<11.0.0\"\n */\nexport function createVersionBucket(minMajorVersion?: number) {\n return (version: string | undefined): string => {\n if (!version) {\n return 'none';\n }\n\n try {\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n const majorVersion = major(minVer);\n if (minMajorVersion !== undefined && majorVersion < minMajorVersion) {\n return `<${minMajorVersion}.0.0`;\n }\n return `${majorVersion}.x`;\n } catch {\n return 'unknown';\n }\n };\n}\n"]}
1
+ {"version":3,"file":"semver.js","sourceRoot":"","sources":["../../../src/utils/semver.ts"],"names":[],"mappings":";;AA8BA,oDAkCC;AAiBD,kDAwBC;AAzGD,mCAOgB;AAEhB;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,OAAe;IACzC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IACzB,OAAO,CACL,CAAC,KAAK,EAAE;QACR,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;QACvB,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;QACxB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QACpB,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;QACtB,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;QACrB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QACpB,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QACjB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,sBAAsB;KACvC,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,kBAAkB,EAClB,WAAW,GAKZ;IACC,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,kBAAkB,EAAE,OAAO,CAAC;IAEhC,IAAI,IAAA,cAAK,EAAC,OAAO,CAAC,EAAE,CAAC;QACnB,kBAAkB,GAAG,IAAA,cAAK,EAAC,OAAO,CAAC,CAAC;QACpC,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC;SAAM,IAAI,IAAA,mBAAU,EAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,kBAAkB,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,CAAC;QACzC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO;IACL,yGAAyG;IACzG,CAAC,CAAC,kBAAkB;QACpB,CAAC,OAAO;YACN,CAAC,CAAC,IAAA,eAAM,EAAC,kBAAkB,EAAE,kBAAkB,CAAC;YAChD,CAAC,CAAC,IAAA,kBAAS,EAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CACvD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,mBAAmB,CAAC,eAAwB;IAC1D,OAAO,CAAC,OAA2B,EAAU,EAAE;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,MAAM,YAAY,GAAG,IAAA,cAAK,EAAC,MAAM,CAAC,CAAC;YACnC,IAAI,eAAe,KAAK,SAAS,IAAI,YAAY,GAAG,eAAe,EAAE,CAAC;gBACpE,OAAO,IAAI,eAAe,MAAM,CAAC;YACnC,CAAC;YACD,OAAO,GAAG,YAAY,IAAI,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {\n major,\n minVersion,\n satisfies,\n subset,\n valid,\n validRange,\n} from 'semver';\n\n/**\n * Version strings from package.json that are not semver ranges.\n * URLs, git refs, dist-tags, local paths, workspace protocol, npm aliases, etc.\n * These should be rejected early — we can't determine a clear version from them.\n */\nfunction isNonSemverVersion(version: string): boolean {\n const v = version.trim();\n return (\n v === '' ||\n v.startsWith('http://') ||\n v.startsWith('https://') ||\n v.startsWith('git+') ||\n v.startsWith('git://') ||\n v.startsWith('file:') ||\n v.startsWith('npm:') ||\n v.startsWith('workspace:') ||\n v.startsWith('/') ||\n v.includes('/') // user/repo shorthand\n );\n}\n\nexport function fulfillsVersionRange({\n version,\n acceptableVersions,\n canBeLatest,\n}: {\n version: string;\n acceptableVersions: string;\n canBeLatest: boolean;\n}): boolean {\n if (version === 'latest') {\n return canBeLatest;\n }\n\n if (isNonSemverVersion(version)) {\n return false;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\n );\n}\n\n/**\n * Creates a version bucket function for analytics.\n * Converts versions like \"1.2.3\" to \"1.x\" for grouping in analytics.\n *\n * @param minMajorVersion - Optional minimum major version threshold.\n * Versions below this will be bucketed as \"<{min}.0.0\"\n *\n * @example\n * const getVersionBucket = createVersionBucket(); // no minimum\n * getVersionBucket(\"1.2.3\") // \"1.x\"\n *\n * const getVersionBucket = createVersionBucket(11);\n * getVersionBucket(\"15.3.0\") // \"15.x\"\n * getVersionBucket(\"10.0.0\") // \"<11.0.0\"\n */\nexport function createVersionBucket(minMajorVersion?: number) {\n return (version: string | undefined): string => {\n if (!version) {\n return 'none';\n }\n\n if (isNonSemverVersion(version)) {\n return 'unknown';\n }\n\n try {\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n const majorVersion = major(minVer);\n if (minMajorVersion !== undefined && majorVersion < minMajorVersion) {\n return `<${minMajorVersion}.0.0`;\n }\n return `${majorVersion}.x`;\n } catch {\n return 'unknown';\n }\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/wizard",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
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",