@better-webhook/cli 3.4.3 → 3.5.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 +35 -0
  2. package/dist/dashboard/assets/index-CxrRCNTh.css +1 -0
  3. package/dist/dashboard/assets/index-Dlqdzwyc.js +23 -0
  4. package/dist/dashboard/index.html +2 -2
  5. package/dist/index.cjs +341 -24
  6. package/dist/index.js +341 -24
  7. package/package.json +5 -4
  8. package/dist/commands/capture.d.ts +0 -2
  9. package/dist/commands/capture.js +0 -30
  10. package/dist/commands/captures.d.ts +0 -2
  11. package/dist/commands/captures.js +0 -217
  12. package/dist/commands/dashboard.d.ts +0 -2
  13. package/dist/commands/dashboard.js +0 -65
  14. package/dist/commands/index.d.ts +0 -6
  15. package/dist/commands/index.js +0 -6
  16. package/dist/commands/replay.d.ts +0 -2
  17. package/dist/commands/replay.js +0 -140
  18. package/dist/commands/run.d.ts +0 -2
  19. package/dist/commands/run.js +0 -181
  20. package/dist/commands/templates.d.ts +0 -2
  21. package/dist/commands/templates.js +0 -285
  22. package/dist/core/capture-server.d.ts +0 -31
  23. package/dist/core/capture-server.js +0 -298
  24. package/dist/core/dashboard-api.d.ts +0 -8
  25. package/dist/core/dashboard-api.js +0 -271
  26. package/dist/core/dashboard-server.d.ts +0 -20
  27. package/dist/core/dashboard-server.js +0 -124
  28. package/dist/core/executor.d.ts +0 -11
  29. package/dist/core/executor.js +0 -130
  30. package/dist/core/index.d.ts +0 -5
  31. package/dist/core/index.js +0 -5
  32. package/dist/core/replay-engine.d.ts +0 -18
  33. package/dist/core/replay-engine.js +0 -208
  34. package/dist/core/signature.d.ts +0 -24
  35. package/dist/core/signature.js +0 -199
  36. package/dist/core/template-manager.d.ts +0 -24
  37. package/dist/core/template-manager.js +0 -246
  38. package/dist/dashboard/assets/index-BSfTbn4Y.js +0 -23
  39. package/dist/dashboard/assets/index-zDTVdss_.css +0 -1
  40. package/dist/types/index.d.ts +0 -299
  41. package/dist/types/index.js +0 -86
@@ -1,246 +0,0 @@
1
- import { request } from "undici";
2
- import { existsSync, mkdirSync, readFileSync, readdirSync, rmdirSync, unlinkSync, writeFileSync, } from "fs";
3
- import { join, basename } from "path";
4
- import { homedir } from "os";
5
- import { TemplatesIndexSchema, WebhookTemplateSchema, } from "../types/index.js";
6
- const GITHUB_RAW_BASE = "https://raw.githubusercontent.com/endalk200/better-webhook/main";
7
- const TEMPLATES_INDEX_URL = `${GITHUB_RAW_BASE}/templates/templates.json`;
8
- export class TemplateManager {
9
- baseDir;
10
- templatesDir;
11
- cacheFile;
12
- indexCache = null;
13
- constructor(baseDir) {
14
- this.baseDir = baseDir || join(homedir(), ".better-webhook");
15
- this.templatesDir = join(this.baseDir, "templates");
16
- this.cacheFile = join(this.baseDir, "templates-cache.json");
17
- if (!existsSync(this.baseDir)) {
18
- mkdirSync(this.baseDir, { recursive: true });
19
- }
20
- if (!existsSync(this.templatesDir)) {
21
- mkdirSync(this.templatesDir, { recursive: true });
22
- }
23
- }
24
- getTemplatesDir() {
25
- return this.templatesDir;
26
- }
27
- async fetchRemoteIndex(forceRefresh = false) {
28
- if (!forceRefresh && this.indexCache) {
29
- return this.indexCache;
30
- }
31
- if (!forceRefresh && existsSync(this.cacheFile)) {
32
- try {
33
- const cached = JSON.parse(readFileSync(this.cacheFile, "utf-8"));
34
- const cacheAge = Date.now() - (cached.cachedAt || 0);
35
- if (cacheAge < 3600000) {
36
- this.indexCache = cached.index;
37
- return cached.index;
38
- }
39
- }
40
- catch {
41
- }
42
- }
43
- try {
44
- const { statusCode, body } = await request(TEMPLATES_INDEX_URL);
45
- if (statusCode !== 200) {
46
- throw new Error(`HTTP ${statusCode}`);
47
- }
48
- const text = await body.text();
49
- const json = JSON.parse(text);
50
- const index = TemplatesIndexSchema.parse(json);
51
- this.indexCache = index;
52
- writeFileSync(this.cacheFile, JSON.stringify({ index, cachedAt: Date.now() }, null, 2));
53
- return index;
54
- }
55
- catch (error) {
56
- if (existsSync(this.cacheFile)) {
57
- try {
58
- const cached = JSON.parse(readFileSync(this.cacheFile, "utf-8"));
59
- if (cached.index) {
60
- this.indexCache = cached.index;
61
- return cached.index;
62
- }
63
- }
64
- catch {
65
- }
66
- }
67
- throw new Error(`Failed to fetch templates index: ${error.message}`);
68
- }
69
- }
70
- async listRemoteTemplates(options) {
71
- const index = await this.fetchRemoteIndex(!!options?.forceRefresh);
72
- const localIds = new Set(this.listLocalTemplates().map((t) => t.id));
73
- return index.templates.map((metadata) => ({
74
- metadata,
75
- isDownloaded: localIds.has(metadata.id),
76
- }));
77
- }
78
- async downloadTemplate(templateId) {
79
- const index = await this.fetchRemoteIndex();
80
- const templateMeta = index.templates.find((t) => t.id === templateId);
81
- if (!templateMeta) {
82
- throw new Error(`Template not found: ${templateId}`);
83
- }
84
- const templateUrl = `${GITHUB_RAW_BASE}/templates/${templateMeta.file}`;
85
- try {
86
- const { statusCode, body } = await request(templateUrl);
87
- if (statusCode !== 200) {
88
- throw new Error(`HTTP ${statusCode}`);
89
- }
90
- const text = await body.text();
91
- const json = JSON.parse(text);
92
- const template = WebhookTemplateSchema.parse(json);
93
- const providerDir = join(this.templatesDir, templateMeta.provider);
94
- if (!existsSync(providerDir)) {
95
- mkdirSync(providerDir, { recursive: true });
96
- }
97
- const fileName = `${templateId}.json`;
98
- const filePath = join(providerDir, fileName);
99
- const localTemplate = {
100
- id: templateId,
101
- metadata: templateMeta,
102
- template,
103
- downloadedAt: new Date().toISOString(),
104
- filePath,
105
- };
106
- const saveData = {
107
- ...template,
108
- _metadata: {
109
- ...templateMeta,
110
- downloadedAt: localTemplate.downloadedAt,
111
- },
112
- };
113
- writeFileSync(filePath, JSON.stringify(saveData, null, 2));
114
- return localTemplate;
115
- }
116
- catch (error) {
117
- throw new Error(`Failed to download template ${templateId}: ${error.message}`);
118
- }
119
- }
120
- listLocalTemplates() {
121
- const templates = [];
122
- if (!existsSync(this.templatesDir)) {
123
- return templates;
124
- }
125
- const scanDir = (dir) => {
126
- const entries = readdirSync(dir, { withFileTypes: true });
127
- for (const entry of entries) {
128
- const fullPath = join(dir, entry.name);
129
- if (entry.isDirectory()) {
130
- scanDir(fullPath);
131
- }
132
- else if (entry.isFile() && entry.name.endsWith(".json")) {
133
- try {
134
- const content = JSON.parse(readFileSync(fullPath, "utf-8"));
135
- const metadata = content._metadata;
136
- if (metadata) {
137
- const { _metadata, ...templateData } = content;
138
- templates.push({
139
- id: metadata.id,
140
- metadata,
141
- template: templateData,
142
- downloadedAt: metadata.downloadedAt || new Date().toISOString(),
143
- filePath: fullPath,
144
- });
145
- }
146
- else {
147
- const id = basename(entry.name, ".json");
148
- templates.push({
149
- id,
150
- metadata: {
151
- id,
152
- name: id,
153
- provider: "custom",
154
- event: "unknown",
155
- file: entry.name,
156
- },
157
- template: content,
158
- downloadedAt: new Date().toISOString(),
159
- filePath: fullPath,
160
- });
161
- }
162
- }
163
- catch {
164
- }
165
- }
166
- }
167
- };
168
- scanDir(this.templatesDir);
169
- return templates;
170
- }
171
- getLocalTemplate(templateId) {
172
- const templates = this.listLocalTemplates();
173
- return templates.find((t) => t.id === templateId) || null;
174
- }
175
- deleteLocalTemplate(templateId) {
176
- const template = this.getLocalTemplate(templateId);
177
- if (!template) {
178
- return false;
179
- }
180
- try {
181
- unlinkSync(template.filePath);
182
- return true;
183
- }
184
- catch {
185
- return false;
186
- }
187
- }
188
- async searchTemplates(query) {
189
- const queryLower = query.toLowerCase();
190
- const remote = await this.listRemoteTemplates();
191
- const local = this.listLocalTemplates();
192
- const matchesMeta = (meta) => {
193
- return (meta.id.toLowerCase().includes(queryLower) ||
194
- meta.name.toLowerCase().includes(queryLower) ||
195
- meta.provider.toLowerCase().includes(queryLower) ||
196
- meta.event.toLowerCase().includes(queryLower) ||
197
- (meta.description?.toLowerCase().includes(queryLower) ?? false));
198
- };
199
- return {
200
- remote: remote.filter((t) => matchesMeta(t.metadata)),
201
- local: local.filter((t) => matchesMeta(t.metadata)),
202
- };
203
- }
204
- clearCache() {
205
- this.indexCache = null;
206
- if (existsSync(this.cacheFile)) {
207
- unlinkSync(this.cacheFile);
208
- }
209
- }
210
- deleteAllLocalTemplates() {
211
- const templates = this.listLocalTemplates();
212
- let deleted = 0;
213
- for (const template of templates) {
214
- try {
215
- unlinkSync(template.filePath);
216
- deleted++;
217
- }
218
- catch {
219
- }
220
- }
221
- if (existsSync(this.templatesDir)) {
222
- const entries = readdirSync(this.templatesDir, { withFileTypes: true });
223
- for (const entry of entries) {
224
- if (entry.isDirectory()) {
225
- const dirPath = join(this.templatesDir, entry.name);
226
- try {
227
- const contents = readdirSync(dirPath);
228
- if (contents.length === 0) {
229
- rmdirSync(dirPath);
230
- }
231
- }
232
- catch {
233
- }
234
- }
235
- }
236
- }
237
- return deleted;
238
- }
239
- }
240
- let instance = null;
241
- export function getTemplateManager(baseDir) {
242
- if (!instance) {
243
- instance = new TemplateManager(baseDir);
244
- }
245
- return instance;
246
- }