@releasehub/cli 1.0.0 → 1.1.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 (41) hide show
  1. package/README.md +184 -0
  2. package/dist/__tests__/ai.test.d.ts +2 -0
  3. package/dist/__tests__/ai.test.d.ts.map +1 -0
  4. package/dist/__tests__/ai.test.js +140 -0
  5. package/dist/__tests__/ai.test.js.map +1 -0
  6. package/dist/__tests__/formatters.test.d.ts +2 -0
  7. package/dist/__tests__/formatters.test.d.ts.map +1 -0
  8. package/dist/__tests__/formatters.test.js +133 -0
  9. package/dist/__tests__/formatters.test.js.map +1 -0
  10. package/dist/__tests__/generate.integration.test.d.ts +2 -0
  11. package/dist/__tests__/generate.integration.test.d.ts.map +1 -0
  12. package/dist/__tests__/generate.integration.test.js +162 -0
  13. package/dist/__tests__/generate.integration.test.js.map +1 -0
  14. package/dist/__tests__/github.test.d.ts +2 -0
  15. package/dist/__tests__/github.test.d.ts.map +1 -0
  16. package/dist/__tests__/github.test.js +44 -0
  17. package/dist/__tests__/github.test.js.map +1 -0
  18. package/dist/commands/ai.d.ts.map +1 -1
  19. package/dist/commands/ai.js +8 -3
  20. package/dist/commands/ai.js.map +1 -1
  21. package/dist/commands/config.d.ts +3 -0
  22. package/dist/commands/config.d.ts.map +1 -0
  23. package/dist/commands/config.js +60 -0
  24. package/dist/commands/config.js.map +1 -0
  25. package/dist/commands/generate.d.ts +1 -0
  26. package/dist/commands/generate.d.ts.map +1 -1
  27. package/dist/commands/generate.js +23 -6
  28. package/dist/commands/generate.js.map +1 -1
  29. package/dist/index.js +2 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/lib/ai.d.ts.map +1 -1
  32. package/dist/lib/ai.js +25 -0
  33. package/dist/lib/ai.js.map +1 -1
  34. package/dist/lib/config.d.ts +3 -1
  35. package/dist/lib/config.d.ts.map +1 -1
  36. package/dist/lib/config.js +11 -1
  37. package/dist/lib/config.js.map +1 -1
  38. package/dist/lib/github.d.ts.map +1 -1
  39. package/dist/lib/github.js +3 -2
  40. package/dist/lib/github.js.map +1 -1
  41. package/package.json +11 -3
package/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # ReleaseHub
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@releasehub/cli.svg)](https://www.npmjs.com/package/@releasehub/cli)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@releasehub/cli.svg)](https://www.npmjs.com/package/@releasehub/cli)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+ [![Node.js 18+](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](https://nodejs.org)
7
+
8
+ > AI-powered release notes from your terminal.
9
+
10
+ ReleaseHub reads your merged pull requests, filters the noise, rewrites technical titles into plain language, and outputs GitHub release notes, a changelog entry, or a Slack message — in one command.
11
+
12
+ ```bash
13
+ npx @releasehub/cli generate --from v2.3.0 --to v2.4.0
14
+ ```
15
+
16
+ ---
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install -g @releasehub/cli
22
+ ```
23
+
24
+ Requires Node.js 18 or later.
25
+
26
+ ---
27
+
28
+ ## Quick start
29
+
30
+ ```bash
31
+ # 1. Connect your GitHub account
32
+ releasehub auth login
33
+
34
+ # 2. Add your AI key (Anthropic or OpenAI)
35
+ releasehub ai add-key
36
+
37
+ # 3. Generate release notes
38
+ releasehub generate --from v2.3.0 --to v2.4.0
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Output formats
44
+
45
+ ```bash
46
+ # GitHub Release markdown (default)
47
+ releasehub generate --from v2.3.0 --to v2.4.0 --format github-release
48
+
49
+ # Keep a Changelog format
50
+ releasehub generate --from v2.3.0 --to v2.4.0 --format changelog
51
+
52
+ # Compact Slack message
53
+ releasehub generate --from v2.3.0 --to v2.4.0 --format slack
54
+ ```
55
+
56
+ **Example output** (`--format github-release`):
57
+
58
+ ```markdown
59
+ ## v2.4.0
60
+
61
+ This release includes 2 new features, 3 improvements and 1 bug fix.
62
+
63
+ ### ✨ New Features
64
+
65
+ - You can now export reports as CSV directly from the dashboard
66
+ - Added keyboard shortcuts for the most common actions
67
+
68
+ ### 🔧 Improvements
69
+
70
+ - Search results now load noticeably faster
71
+ - Dark mode contrast improved across all pages
72
+ - Notification preferences are easier to find in settings
73
+
74
+ ### 🐛 Bug Fixes
75
+
76
+ - Fixed an issue where file uploads would silently fail on slow connections
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Write to a file
82
+
83
+ ```bash
84
+ releasehub generate --from v2.3.0 --to v2.4.0 --output RELEASE.md
85
+ ```
86
+
87
+ ## Publish as a GitHub Release
88
+
89
+ ```bash
90
+ releasehub generate --from v2.3.0 --to v2.4.0 --publish
91
+ ```
92
+
93
+ ## Use in CI (GitHub Actions)
94
+
95
+ ```yaml
96
+ - name: Generate release notes
97
+ env:
98
+ RELEASEHUB_GITHUB_TOKEN: ${{ secrets.RELEASEHUB_GITHUB_TOKEN }}
99
+ RELEASEHUB_ANTHROPIC_KEY: ${{ secrets.RELEASEHUB_ANTHROPIC_KEY }}
100
+ run: |
101
+ npx @releasehub/cli generate \
102
+ --from ${{ github.event.release.target_commitish }} \
103
+ --to ${{ github.ref_name }} \
104
+ --format github-release \
105
+ --quiet \
106
+ --output release-notes.md
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Commands
112
+
113
+ | Command | Description |
114
+ |---|---|
115
+ | `releasehub auth login` | Connect your GitHub account via OAuth |
116
+ | `releasehub auth logout` | Disconnect and remove saved token |
117
+ | `releasehub ai add-key` | Add an Anthropic or OpenAI key |
118
+ | `releasehub ai switch` | Switch active AI provider |
119
+ | `releasehub ai status` | Show provider status and validate keys |
120
+ | `releasehub generate` | Generate release notes from merged PRs |
121
+
122
+ ### `generate` flags
123
+
124
+ | Flag | Default | Description |
125
+ |---|---|---|
126
+ | `--from <tag>` | required | Start tag |
127
+ | `--to <tag>` | required | End tag |
128
+ | `--repo <owner/name>` | auto-detect | Repository (defaults to git remote) |
129
+ | `--format <format>` | `github-release` | `github-release` \| `changelog` \| `slack` |
130
+ | `--output <file>` | stdout | Write output to a file |
131
+ | `--publish` | — | Publish as a GitHub Release |
132
+ | `--quiet` | — | Suppress progress output (CI mode) |
133
+
134
+ ---
135
+
136
+ ## AI providers
137
+
138
+ | Provider | Model | Set key via |
139
+ |---|---|---|
140
+ | Anthropic | claude-sonnet-4-6 | `releasehub ai add-key` or `RELEASEHUB_ANTHROPIC_KEY` |
141
+ | OpenAI | gpt-4o | `releasehub ai add-key` or `RELEASEHUB_OPENAI_KEY` |
142
+
143
+ Anthropic is the default. Switch with `releasehub ai switch`.
144
+
145
+ ---
146
+
147
+ ## Environment variables
148
+
149
+ | Variable | Description |
150
+ |---|---|
151
+ | `RELEASEHUB_GITHUB_TOKEN` | GitHub personal access token (alternative to `auth login`) |
152
+ | `RELEASEHUB_ANTHROPIC_KEY` | Anthropic API key |
153
+ | `RELEASEHUB_OPENAI_KEY` | OpenAI API key |
154
+
155
+ ---
156
+
157
+ ## Repo structure
158
+
159
+ ```
160
+ releasehub/
161
+ ├── apps/
162
+ │ └── web/ # Landing page + docs (React + Vite)
163
+ ├── packages/
164
+ │ └── cli/ # @releasehub/cli npm package
165
+ └── planning/ # Product docs, milestones, architecture
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Support
171
+
172
+ If ReleaseHub saves you time, consider buying me a coffee:
173
+
174
+ <a href="https://www.buymeacoffee.com/beratbozkurt0" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me a Coffee" style="height: 60px !important;width: 217px !important;" ></a>
175
+
176
+ ---
177
+
178
+ ## License
179
+
180
+ MIT — see [LICENSE](LICENSE).
181
+
182
+ ---
183
+
184
+ Built by [@berat](https://twitter.com/beratbuilds)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ai.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ai.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,140 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ // parseResponse is not exported — test it indirectly via the output shape
3
+ // We test the logic that surrounds AI calls: prompt building and response parsing
4
+ // ─── buildUserPrompt (extracted logic) ────────────────────────────────────────
5
+ function buildUserPrompt(prs) {
6
+ const list = prs.map(pr => {
7
+ const labels = pr.labels.length ? `\nLabels: ${pr.labels.join(', ')}` : '';
8
+ const issues = pr.linked_issues.length ? `\nLinked issues: ${pr.linked_issues.join(', ')}` : '';
9
+ const body = pr.body ? `\nBody: ${pr.body.slice(0, 300)}` : '';
10
+ return `#${pr.number}: ${pr.title}${labels}${issues}${body}`;
11
+ }).join('\n\n');
12
+ return `Analyze these ${prs.length} pull requests:\n\n${list}`;
13
+ }
14
+ // ─── parseResponse (extracted logic) ──────────────────────────────────────────
15
+ function parseResponse(raw) {
16
+ const cleaned = raw
17
+ .replace(/```(?:json)?\n?/g, '')
18
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '')
19
+ .trim();
20
+ return JSON.parse(cleaned);
21
+ }
22
+ // ─── Tests ────────────────────────────────────────────────────────────────────
23
+ describe('buildUserPrompt', () => {
24
+ it('includes PR number and title', () => {
25
+ const prompt = buildUserPrompt([
26
+ { number: 42, title: 'Fix login bug', body: null, labels: [], linked_issues: [] },
27
+ ]);
28
+ expect(prompt).toContain('#42: Fix login bug');
29
+ });
30
+ it('includes labels when present', () => {
31
+ const prompt = buildUserPrompt([
32
+ { number: 1, title: 'Add feature', body: null, labels: ['enhancement', 'ui'], linked_issues: [] },
33
+ ]);
34
+ expect(prompt).toContain('Labels: enhancement, ui');
35
+ });
36
+ it('omits labels line when empty', () => {
37
+ const prompt = buildUserPrompt([
38
+ { number: 1, title: 'Add feature', body: null, labels: [], linked_issues: [] },
39
+ ]);
40
+ expect(prompt).not.toContain('Labels:');
41
+ });
42
+ it('includes linked issues when present', () => {
43
+ const prompt = buildUserPrompt([
44
+ { number: 1, title: 'Fix', body: null, labels: [], linked_issues: ['#10', '#11'] },
45
+ ]);
46
+ expect(prompt).toContain('Linked issues: #10, #11');
47
+ });
48
+ it('truncates body to 300 chars', () => {
49
+ const longBody = 'x'.repeat(500);
50
+ const prompt = buildUserPrompt([
51
+ { number: 1, title: 'Fix', body: longBody, labels: [], linked_issues: [] },
52
+ ]);
53
+ const bodyLine = prompt.split('\n').find(l => l.startsWith('Body:'));
54
+ expect(bodyLine.length).toBeLessThanOrEqual(310);
55
+ });
56
+ it('states correct PR count in header', () => {
57
+ const prs = [
58
+ { number: 1, title: 'A', body: null, labels: [], linked_issues: [] },
59
+ { number: 2, title: 'B', body: null, labels: [], linked_issues: [] },
60
+ { number: 3, title: 'C', body: null, labels: [], linked_issues: [] },
61
+ ];
62
+ const prompt = buildUserPrompt(prs);
63
+ expect(prompt).toContain('Analyze these 3 pull requests');
64
+ });
65
+ });
66
+ describe('parseResponse', () => {
67
+ it('parses clean JSON array', () => {
68
+ const raw = JSON.stringify([{ category: 'bugfix', visible: true }]);
69
+ const result = parseResponse(raw);
70
+ expect(result).toHaveLength(1);
71
+ expect(result[0].category).toBe('bugfix');
72
+ });
73
+ it('strips markdown code fences', () => {
74
+ const raw = '```json\n[{"category":"feature"}]\n```';
75
+ const result = parseResponse(raw);
76
+ expect(result[0].category).toBe('feature');
77
+ });
78
+ it('strips code fences without language tag', () => {
79
+ const raw = '```\n[{"category":"bugfix"}]\n```';
80
+ const result = parseResponse(raw);
81
+ expect(result[0].category).toBe('bugfix');
82
+ });
83
+ it('handles multiple items', () => {
84
+ const items = [
85
+ { category: 'feature', visible: true },
86
+ { category: 'internal', visible: false },
87
+ ];
88
+ const result = parseResponse(JSON.stringify(items));
89
+ expect(result).toHaveLength(2);
90
+ });
91
+ it('throws on invalid JSON', () => {
92
+ expect(() => parseResponse('not json')).toThrow();
93
+ });
94
+ });
95
+ // ─── Gemini provider mock ──────────────────────────────────────────────────────
96
+ vi.mock('@google/generative-ai', () => ({
97
+ GoogleGenerativeAI: vi.fn().mockImplementation(() => ({
98
+ getGenerativeModel: vi.fn().mockReturnValue({
99
+ generateContent: vi.fn().mockResolvedValue({
100
+ response: {
101
+ text: () => JSON.stringify([
102
+ {
103
+ original_title: 'Add search',
104
+ rewritten_title: 'You can now search across all items',
105
+ category: 'feature',
106
+ visible: true,
107
+ confidence: 0.95,
108
+ reasoning: 'New user-facing capability',
109
+ },
110
+ ]),
111
+ },
112
+ }),
113
+ }),
114
+ })),
115
+ }));
116
+ vi.mock('../lib/config.js', () => ({
117
+ getActiveProvider: vi.fn(() => 'gemini'),
118
+ getActiveAIKey: vi.fn(() => 'AIza-test-key'),
119
+ }));
120
+ describe('analyzeWithGemini (via analyzePullRequests)', () => {
121
+ it('calls GoogleGenerativeAI with the active key', async () => {
122
+ const { GoogleGenerativeAI } = await import('@google/generative-ai');
123
+ const { analyzePullRequests } = await import('../lib/ai.js');
124
+ await analyzePullRequests([
125
+ { number: 1, title: 'Add search', body: null, labels: [], author: 'alice', merged_at: '', url: '', linked_issues: [] },
126
+ ]);
127
+ expect(GoogleGenerativeAI).toHaveBeenCalledWith('AIza-test-key');
128
+ });
129
+ it('returns parsed AnalyzedChange from Gemini response', async () => {
130
+ const { analyzePullRequests } = await import('../lib/ai.js');
131
+ const result = await analyzePullRequests([
132
+ { number: 1, title: 'Add search', body: null, labels: [], author: 'alice', merged_at: '', url: '', linked_issues: [] },
133
+ ]);
134
+ expect(result.changes).toHaveLength(1);
135
+ expect(result.changes[0].category).toBe('feature');
136
+ expect(result.changes[0].visible).toBe(true);
137
+ expect(result.changes[0].rewritten_title).toContain('search');
138
+ });
139
+ });
140
+ //# sourceMappingURL=ai.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.test.js","sourceRoot":"","sources":["../../src/__tests__/ai.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=formatters.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/formatters.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,133 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { formatGitHubRelease, formatChangelog, formatSlack, formatOutput, } from '../lib/formatters.js';
3
+ // ─── Fixtures ─────────────────────────────────────────────────────────────────
4
+ const change = (overrides = {}) => ({
5
+ original_title: 'fix something',
6
+ rewritten_title: 'Fixed an issue with something',
7
+ category: 'bugfix',
8
+ visible: true,
9
+ confidence: 0.95,
10
+ reasoning: 'user-facing fix',
11
+ ...overrides,
12
+ });
13
+ const feature = (title = 'You can now do something new') => change({ category: 'feature', rewritten_title: title });
14
+ const bugfix = (title = 'Fixed an issue where X happened') => change({ category: 'bugfix', rewritten_title: title });
15
+ const breaking = (title = 'Breaking: old behavior removed') => change({ category: 'breaking', rewritten_title: title });
16
+ const internal = () => change({ category: 'internal', visible: false, rewritten_title: 'Refactored internals' });
17
+ // ─── formatGitHubRelease ──────────────────────────────────────────────────────
18
+ describe('formatGitHubRelease', () => {
19
+ it('renders version heading', () => {
20
+ const out = formatGitHubRelease({ version: 'v1.2.0', changes: [feature()] });
21
+ expect(out).toContain('## v1.2.0');
22
+ });
23
+ it('groups changes under correct headers', () => {
24
+ const out = formatGitHubRelease({
25
+ version: 'v1.0.0',
26
+ changes: [feature(), bugfix(), breaking()],
27
+ });
28
+ expect(out).toContain('### ⚠️ Breaking Changes');
29
+ expect(out).toContain('### ✨ New Features');
30
+ expect(out).toContain('### 🐛 Bug Fixes');
31
+ });
32
+ it('filters out internal changes', () => {
33
+ const out = formatGitHubRelease({
34
+ version: 'v1.0.0',
35
+ changes: [feature(), internal()],
36
+ });
37
+ expect(out).not.toContain('Refactored internals');
38
+ expect(out).toContain('You can now do something new');
39
+ });
40
+ it('shows empty state when all changes are internal', () => {
41
+ const out = formatGitHubRelease({ version: 'v1.0.0', changes: [internal()] });
42
+ expect(out).toContain('No user-facing changes');
43
+ });
44
+ it('includes summary sentence', () => {
45
+ const out = formatGitHubRelease({
46
+ version: 'v1.0.0',
47
+ changes: [feature(), bugfix()],
48
+ });
49
+ expect(out).toContain('This release includes');
50
+ });
51
+ it('puts breaking changes before features', () => {
52
+ const out = formatGitHubRelease({
53
+ version: 'v1.0.0',
54
+ changes: [feature(), breaking()],
55
+ });
56
+ const breakingPos = out.indexOf('Breaking Changes');
57
+ const featurePos = out.indexOf('New Features');
58
+ expect(breakingPos).toBeLessThan(featurePos);
59
+ });
60
+ });
61
+ // ─── formatChangelog ──────────────────────────────────────────────────────────
62
+ describe('formatChangelog', () => {
63
+ it('includes today\'s date', () => {
64
+ const today = new Date().toISOString().split('T')[0];
65
+ const out = formatChangelog({ version: 'v1.0.0', changes: [feature()] });
66
+ expect(out).toContain(today);
67
+ });
68
+ it('renders version in Keep a Changelog format', () => {
69
+ const out = formatChangelog({ version: 'v1.0.0', changes: [feature()] });
70
+ expect(out).toMatch(/## \[v1\.0\.0\]/);
71
+ });
72
+ it('filters out internal changes', () => {
73
+ const out = formatChangelog({ version: 'v1.0.0', changes: [feature(), internal()] });
74
+ expect(out).not.toContain('Refactored internals');
75
+ });
76
+ it('shows empty state when all changes are internal', () => {
77
+ const out = formatChangelog({ version: 'v1.0.0', changes: [internal()] });
78
+ expect(out).toContain('No user-facing changes');
79
+ });
80
+ });
81
+ // ─── formatSlack ──────────────────────────────────────────────────────────────
82
+ describe('formatSlack', () => {
83
+ it('starts with bold version', () => {
84
+ const out = formatSlack({ version: 'v1.0.0', changes: [feature()] });
85
+ expect(out).toContain('*🚀 v1.0.0*');
86
+ });
87
+ it('filters out internal changes', () => {
88
+ const out = formatSlack({ version: 'v1.0.0', changes: [feature(), internal()] });
89
+ expect(out).not.toContain('Refactored internals');
90
+ });
91
+ it('always shows breaking changes', () => {
92
+ const manyFeatures = Array.from({ length: 10 }, (_, i) => feature(`Feature ${i}`));
93
+ const out = formatSlack({
94
+ version: 'v1.0.0',
95
+ changes: [breaking(), ...manyFeatures],
96
+ });
97
+ expect(out).toContain('Breaking: old behavior removed');
98
+ });
99
+ it('caps output at 6 items with overflow message', () => {
100
+ const changes = Array.from({ length: 10 }, (_, i) => feature(`Feature ${i}`));
101
+ const out = formatSlack({ version: 'v1.0.0', changes });
102
+ expect(out).toContain('+ 4 more updates');
103
+ });
104
+ it('shows empty state when all changes are internal', () => {
105
+ const out = formatSlack({ version: 'v1.0.0', changes: [internal()] });
106
+ expect(out).toContain('No user-facing changes');
107
+ });
108
+ it('truncates long titles at 80 chars', () => {
109
+ const longTitle = 'A'.repeat(100);
110
+ const out = formatSlack({ version: 'v1.0.0', changes: [feature(longTitle)] });
111
+ const lines = out.split('\n').filter(l => l.includes('A'));
112
+ expect(lines[0].length).toBeLessThanOrEqual(90); // emoji + space + 80 chars
113
+ });
114
+ });
115
+ // ─── formatOutput ─────────────────────────────────────────────────────────────
116
+ describe('formatOutput', () => {
117
+ it('dispatches to github-release', () => {
118
+ const out = formatOutput('github-release', { version: 'v1.0.0', changes: [feature()] });
119
+ expect(out).toContain('## v1.0.0');
120
+ });
121
+ it('dispatches to changelog', () => {
122
+ const out = formatOutput('changelog', { version: 'v1.0.0', changes: [feature()] });
123
+ expect(out).toContain('[v1.0.0]');
124
+ });
125
+ it('dispatches to slack', () => {
126
+ const out = formatOutput('slack', { version: 'v1.0.0', changes: [feature()] });
127
+ expect(out).toContain('🚀');
128
+ });
129
+ it('throws on unknown format', () => {
130
+ expect(() => formatOutput('unknown', { version: 'v1.0.0', changes: [] })).toThrow('Unknown format');
131
+ });
132
+ });
133
+ //# sourceMappingURL=formatters.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.test.js","sourceRoot":"","sources":["../../src/__tests__/formatters.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generate.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/generate.integration.test.ts"],"names":[],"mappings":""}