swift-patterns-mcp 1.0.2
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.
- package/LICENSE +21 -0
- package/README.md +377 -0
- package/build/cli/auth.d.ts +3 -0
- package/build/cli/auth.d.ts.map +1 -0
- package/build/cli/auth.js +43 -0
- package/build/cli/auth.js.map +1 -0
- package/build/cli/setup.d.ts +2 -0
- package/build/cli/setup.d.ts.map +1 -0
- package/build/cli/setup.js +149 -0
- package/build/cli/setup.js.map +1 -0
- package/build/cli/source-manager.d.ts +3 -0
- package/build/cli/source-manager.d.ts.map +1 -0
- package/build/cli/source-manager.js +117 -0
- package/build/cli/source-manager.js.map +1 -0
- package/build/config/creators.d.ts +11 -0
- package/build/config/creators.d.ts.map +1 -0
- package/build/config/creators.js +32 -0
- package/build/config/creators.js.map +1 -0
- package/build/config/sources.d.ts +65 -0
- package/build/config/sources.d.ts.map +1 -0
- package/build/config/sources.js +184 -0
- package/build/config/sources.js.map +1 -0
- package/build/config/sources.test.d.ts +2 -0
- package/build/config/sources.test.d.ts.map +1 -0
- package/build/config/sources.test.js +195 -0
- package/build/config/sources.test.js.map +1 -0
- package/build/config/swift-keywords.d.ts +21 -0
- package/build/config/swift-keywords.d.ts.map +1 -0
- package/build/config/swift-keywords.js +67 -0
- package/build/config/swift-keywords.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +295 -0
- package/build/index.js.map +1 -0
- package/build/integration/mcp-client.test.d.ts +2 -0
- package/build/integration/mcp-client.test.d.ts.map +1 -0
- package/build/integration/mcp-client.test.js +82 -0
- package/build/integration/mcp-client.test.js.map +1 -0
- package/build/integration/response-quality.test.d.ts +2 -0
- package/build/integration/response-quality.test.d.ts.map +1 -0
- package/build/integration/response-quality.test.js +139 -0
- package/build/integration/response-quality.test.js.map +1 -0
- package/build/integration/test-client.d.ts +25 -0
- package/build/integration/test-client.d.ts.map +1 -0
- package/build/integration/test-client.js +93 -0
- package/build/integration/test-client.js.map +1 -0
- package/build/sources/free/rssPatternSource.d.ts +41 -0
- package/build/sources/free/rssPatternSource.d.ts.map +1 -0
- package/build/sources/free/rssPatternSource.js +122 -0
- package/build/sources/free/rssPatternSource.js.map +1 -0
- package/build/sources/free/rssPatternSource.test.d.ts +2 -0
- package/build/sources/free/rssPatternSource.test.d.ts.map +1 -0
- package/build/sources/free/rssPatternSource.test.js +92 -0
- package/build/sources/free/rssPatternSource.test.js.map +1 -0
- package/build/sources/free/sundell.d.ts +9 -0
- package/build/sources/free/sundell.d.ts.map +1 -0
- package/build/sources/free/sundell.js +31 -0
- package/build/sources/free/sundell.js.map +1 -0
- package/build/sources/free/sundell.test.d.ts +2 -0
- package/build/sources/free/sundell.test.d.ts.map +1 -0
- package/build/sources/free/sundell.test.js +63 -0
- package/build/sources/free/sundell.test.js.map +1 -0
- package/build/sources/free/vanderlee.d.ts +9 -0
- package/build/sources/free/vanderlee.d.ts.map +1 -0
- package/build/sources/free/vanderlee.js +71 -0
- package/build/sources/free/vanderlee.js.map +1 -0
- package/build/sources/free/vanderlee.test.d.ts +2 -0
- package/build/sources/free/vanderlee.test.d.ts.map +1 -0
- package/build/sources/free/vanderlee.test.js +73 -0
- package/build/sources/free/vanderlee.test.js.map +1 -0
- package/build/sources/premium/patreon-dl.d.ts +45 -0
- package/build/sources/premium/patreon-dl.d.ts.map +1 -0
- package/build/sources/premium/patreon-dl.js +189 -0
- package/build/sources/premium/patreon-dl.js.map +1 -0
- package/build/sources/premium/patreon-fetch.d.ts +3 -0
- package/build/sources/premium/patreon-fetch.d.ts.map +1 -0
- package/build/sources/premium/patreon-fetch.js +18 -0
- package/build/sources/premium/patreon-fetch.js.map +1 -0
- package/build/sources/premium/patreon-oauth.d.ts +24 -0
- package/build/sources/premium/patreon-oauth.d.ts.map +1 -0
- package/build/sources/premium/patreon-oauth.js +207 -0
- package/build/sources/premium/patreon-oauth.js.map +1 -0
- package/build/sources/premium/patreon-zip.d.ts +17 -0
- package/build/sources/premium/patreon-zip.d.ts.map +1 -0
- package/build/sources/premium/patreon-zip.js +128 -0
- package/build/sources/premium/patreon-zip.js.map +1 -0
- package/build/sources/premium/patreon.d.ts +48 -0
- package/build/sources/premium/patreon.d.ts.map +1 -0
- package/build/sources/premium/patreon.js +248 -0
- package/build/sources/premium/patreon.js.map +1 -0
- package/build/sources/premium/youtube.d.ts +14 -0
- package/build/sources/premium/youtube.d.ts.map +1 -0
- package/build/sources/premium/youtube.js +92 -0
- package/build/sources/premium/youtube.js.map +1 -0
- package/build/tools/extract-cookie.d.ts +2 -0
- package/build/tools/extract-cookie.d.ts.map +1 -0
- package/build/tools/extract-cookie.js +40 -0
- package/build/tools/extract-cookie.js.map +1 -0
- package/build/tools/handlers/enableSource.d.ts +3 -0
- package/build/tools/handlers/enableSource.d.ts.map +1 -0
- package/build/tools/handlers/enableSource.js +39 -0
- package/build/tools/handlers/enableSource.js.map +1 -0
- package/build/tools/handlers/getSwiftPattern.d.ts +3 -0
- package/build/tools/handlers/getSwiftPattern.d.ts.map +1 -0
- package/build/tools/handlers/getSwiftPattern.js +78 -0
- package/build/tools/handlers/getSwiftPattern.js.map +1 -0
- package/build/tools/handlers/handlers.test.d.ts +2 -0
- package/build/tools/handlers/handlers.test.d.ts.map +1 -0
- package/build/tools/handlers/handlers.test.js +189 -0
- package/build/tools/handlers/handlers.test.js.map +1 -0
- package/build/tools/handlers/listContentSources.d.ts +3 -0
- package/build/tools/handlers/listContentSources.d.ts.map +1 -0
- package/build/tools/handlers/listContentSources.js +38 -0
- package/build/tools/handlers/listContentSources.js.map +1 -0
- package/build/tools/handlers/searchSwiftContent.d.ts +3 -0
- package/build/tools/handlers/searchSwiftContent.d.ts.map +1 -0
- package/build/tools/handlers/searchSwiftContent.js +44 -0
- package/build/tools/handlers/searchSwiftContent.js.map +1 -0
- package/build/tools/index.d.ts +3 -0
- package/build/tools/index.d.ts.map +1 -0
- package/build/tools/index.js +14 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/registry.d.ts +14 -0
- package/build/tools/registry.d.ts.map +1 -0
- package/build/tools/registry.js +21 -0
- package/build/tools/registry.js.map +1 -0
- package/build/tools/registry.test.d.ts +2 -0
- package/build/tools/registry.test.d.ts.map +1 -0
- package/build/tools/registry.test.js +54 -0
- package/build/tools/registry.test.js.map +1 -0
- package/build/tools/types.d.ts +25 -0
- package/build/tools/types.d.ts.map +1 -0
- package/build/tools/types.js +3 -0
- package/build/tools/types.js.map +1 -0
- package/build/utils/cache.d.ts +17 -0
- package/build/utils/cache.d.ts.map +1 -0
- package/build/utils/cache.js +144 -0
- package/build/utils/cache.js.map +1 -0
- package/build/utils/errors.d.ts +19 -0
- package/build/utils/errors.d.ts.map +1 -0
- package/build/utils/errors.js +34 -0
- package/build/utils/errors.js.map +1 -0
- package/build/utils/paths.d.ts +27 -0
- package/build/utils/paths.d.ts.map +1 -0
- package/build/utils/paths.js +43 -0
- package/build/utils/paths.js.map +1 -0
- package/build/utils/search.d.ts +29 -0
- package/build/utils/search.d.ts.map +1 -0
- package/build/utils/search.js +165 -0
- package/build/utils/search.js.map +1 -0
- package/build/utils/search.test.d.ts +2 -0
- package/build/utils/search.test.d.ts.map +1 -0
- package/build/utils/search.test.js +199 -0
- package/build/utils/search.test.js.map +1 -0
- package/build/utils/swift-analysis.d.ts +27 -0
- package/build/utils/swift-analysis.d.ts.map +1 -0
- package/build/utils/swift-analysis.js +78 -0
- package/build/utils/swift-analysis.js.map +1 -0
- package/build/utils/swift-analysis.test.d.ts +2 -0
- package/build/utils/swift-analysis.test.d.ts.map +1 -0
- package/build/utils/swift-analysis.test.js +215 -0
- package/build/utils/swift-analysis.test.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// src/sources/premium/patreon-oauth.ts
|
|
2
|
+
import http from 'http';
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import { URL } from 'url';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { homedir } from 'os';
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
import keytar from 'keytar';
|
|
9
|
+
const SERVICE_NAME = 'swift-mcp';
|
|
10
|
+
const ACCOUNT_NAME = 'patreon-tokens';
|
|
11
|
+
const CALLBACK_PORT = 9876;
|
|
12
|
+
const PATREON_AUTH_URL = 'https://www.patreon.com/oauth2/authorize';
|
|
13
|
+
const PATREON_TOKEN_URL = 'https://www.patreon.com/api/oauth2/token';
|
|
14
|
+
// Scopes explained:
|
|
15
|
+
// - identity: Basic user info
|
|
16
|
+
// - identity.memberships: REQUIRED - access to patron memberships via /identity endpoint
|
|
17
|
+
// - campaigns: Access campaigns you manage (creator-only, optional)
|
|
18
|
+
// - campaigns.members: Access members of your own campaign (creator-only, optional)
|
|
19
|
+
export const PATREON_SCOPES = [
|
|
20
|
+
'identity',
|
|
21
|
+
'identity.memberships', // REQUIRED: patron memberships live here
|
|
22
|
+
'campaigns',
|
|
23
|
+
'campaigns.members',
|
|
24
|
+
].join(' ');
|
|
25
|
+
export async function saveTokens(tokens) {
|
|
26
|
+
const encrypted = JSON.stringify(tokens);
|
|
27
|
+
await keytar.setPassword(SERVICE_NAME, ACCOUNT_NAME, encrypted);
|
|
28
|
+
}
|
|
29
|
+
export async function loadTokens() {
|
|
30
|
+
try {
|
|
31
|
+
const encrypted = await keytar.getPassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
32
|
+
if (!encrypted)
|
|
33
|
+
return null;
|
|
34
|
+
return JSON.parse(encrypted);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function clearTokens() {
|
|
41
|
+
await keytar.deletePassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
42
|
+
}
|
|
43
|
+
export function isTokenExpired(tokens) {
|
|
44
|
+
// Refresh 5 minutes before actual expiry
|
|
45
|
+
return Date.now() >= (tokens.expires_at - 5 * 60 * 1000);
|
|
46
|
+
}
|
|
47
|
+
export async function refreshAccessToken(clientId, clientSecret, refreshToken) {
|
|
48
|
+
const response = await fetch(PATREON_TOKEN_URL, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
51
|
+
body: new URLSearchParams({
|
|
52
|
+
grant_type: 'refresh_token',
|
|
53
|
+
refresh_token: refreshToken,
|
|
54
|
+
client_id: clientId,
|
|
55
|
+
client_secret: clientSecret,
|
|
56
|
+
}),
|
|
57
|
+
});
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
throw new Error(`Token refresh failed: ${response.status}`);
|
|
60
|
+
}
|
|
61
|
+
const data = await response.json();
|
|
62
|
+
const tokens = {
|
|
63
|
+
access_token: data.access_token,
|
|
64
|
+
refresh_token: data.refresh_token,
|
|
65
|
+
expires_at: Date.now() + data.expires_in * 1000,
|
|
66
|
+
scope: data.scope,
|
|
67
|
+
};
|
|
68
|
+
await saveTokens(tokens);
|
|
69
|
+
return tokens;
|
|
70
|
+
}
|
|
71
|
+
export async function startOAuthFlow(clientId, clientSecret) {
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
const redirectUri = `http://localhost:${CALLBACK_PORT}/callback`;
|
|
74
|
+
const authUrl = new URL(PATREON_AUTH_URL);
|
|
75
|
+
authUrl.searchParams.set('client_id', clientId);
|
|
76
|
+
authUrl.searchParams.set('redirect_uri', redirectUri);
|
|
77
|
+
authUrl.searchParams.set('response_type', 'code');
|
|
78
|
+
authUrl.searchParams.set('scope', PATREON_SCOPES);
|
|
79
|
+
let serverClosed = false;
|
|
80
|
+
const server = http.createServer(async (req, res) => {
|
|
81
|
+
if (!req.url?.startsWith('/callback')) {
|
|
82
|
+
res.writeHead(404);
|
|
83
|
+
res.end('Not found');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const url = new URL(req.url, `http://localhost:${CALLBACK_PORT}`);
|
|
87
|
+
const code = url.searchParams.get('code');
|
|
88
|
+
const error = url.searchParams.get('error');
|
|
89
|
+
if (error) {
|
|
90
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
91
|
+
res.end('<h1>Authorization Denied</h1><p>You can close this window.</p>');
|
|
92
|
+
if (!serverClosed) {
|
|
93
|
+
serverClosed = true;
|
|
94
|
+
server.close();
|
|
95
|
+
resolve({ success: false, error });
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!code) {
|
|
100
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
101
|
+
res.end('<h1>Error</h1><p>No authorization code received.</p>');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
// Exchange code for tokens
|
|
106
|
+
const tokenResponse = await fetch(PATREON_TOKEN_URL, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
109
|
+
body: new URLSearchParams({
|
|
110
|
+
code,
|
|
111
|
+
grant_type: 'authorization_code',
|
|
112
|
+
client_id: clientId,
|
|
113
|
+
client_secret: clientSecret,
|
|
114
|
+
redirect_uri: redirectUri,
|
|
115
|
+
}),
|
|
116
|
+
});
|
|
117
|
+
if (!tokenResponse.ok) {
|
|
118
|
+
throw new Error(`Token exchange failed: ${tokenResponse.status}`);
|
|
119
|
+
}
|
|
120
|
+
const data = await tokenResponse.json();
|
|
121
|
+
const tokens = {
|
|
122
|
+
access_token: data.access_token,
|
|
123
|
+
refresh_token: data.refresh_token,
|
|
124
|
+
expires_at: Date.now() + data.expires_in * 1000,
|
|
125
|
+
scope: data.scope,
|
|
126
|
+
};
|
|
127
|
+
await saveTokens(tokens);
|
|
128
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
129
|
+
res.end(`
|
|
130
|
+
<html>
|
|
131
|
+
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
132
|
+
<h1>Authorization Successful!</h1>
|
|
133
|
+
<p>You can close this window and return to the terminal.</p>
|
|
134
|
+
</body>
|
|
135
|
+
</html>
|
|
136
|
+
`);
|
|
137
|
+
if (!serverClosed) {
|
|
138
|
+
serverClosed = true;
|
|
139
|
+
server.close();
|
|
140
|
+
resolve({ success: true, tokens });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
res.writeHead(500, { 'Content-Type': 'text/html' });
|
|
145
|
+
res.end('<h1>Error</h1><p>Failed to complete authorization.</p>');
|
|
146
|
+
if (!serverClosed) {
|
|
147
|
+
serverClosed = true;
|
|
148
|
+
server.close();
|
|
149
|
+
resolve({ success: false, error: String(err) });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
server.listen(CALLBACK_PORT, '127.0.0.1', () => {
|
|
154
|
+
console.log(`\nOpening browser for Patreon authorization...`);
|
|
155
|
+
console.log(`If browser doesn't open, visit: ${authUrl.toString()}\n`);
|
|
156
|
+
// Open browser
|
|
157
|
+
const cmd = process.platform === 'darwin' ? 'open' :
|
|
158
|
+
process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
159
|
+
exec(`${cmd} "${authUrl.toString()}"`);
|
|
160
|
+
});
|
|
161
|
+
// Timeout after 60 seconds
|
|
162
|
+
setTimeout(() => {
|
|
163
|
+
if (!serverClosed) {
|
|
164
|
+
serverClosed = true;
|
|
165
|
+
server.close();
|
|
166
|
+
resolve({ success: false, error: 'Authorization timed out after 60 seconds' });
|
|
167
|
+
}
|
|
168
|
+
}, 60000);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
export async function getValidAccessToken(clientId, clientSecret) {
|
|
172
|
+
const tokens = await loadTokens();
|
|
173
|
+
if (!tokens)
|
|
174
|
+
return null;
|
|
175
|
+
if (isTokenExpired(tokens)) {
|
|
176
|
+
try {
|
|
177
|
+
const refreshed = await refreshAccessToken(clientId, clientSecret, tokens.refresh_token);
|
|
178
|
+
return refreshed.access_token;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Refresh failed, need to re-authenticate
|
|
182
|
+
await clearTokens();
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return tokens.access_token;
|
|
187
|
+
}
|
|
188
|
+
// =============================================================================
|
|
189
|
+
// Cleanup & Reset
|
|
190
|
+
// =============================================================================
|
|
191
|
+
/**
|
|
192
|
+
* Clear all Patreon authentication data (keytar + legacy tokens.json)
|
|
193
|
+
*/
|
|
194
|
+
export async function clearPatreonAuth() {
|
|
195
|
+
// Clear from keytar
|
|
196
|
+
await keytar.deletePassword(SERVICE_NAME, "patreon");
|
|
197
|
+
await keytar.deletePassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
198
|
+
// Clear legacy tokens.json file
|
|
199
|
+
const tokensPath = join(homedir(), ".swift-mcp", "tokens.json");
|
|
200
|
+
try {
|
|
201
|
+
await fs.rm(tokensPath, { force: true });
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// Ignore if file doesn't exist
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=patreon-oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patreon-oauth.js","sourceRoot":"","sources":["../../../src/sources/premium/patreon-oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ExtractedPattern {
|
|
2
|
+
filename: string;
|
|
3
|
+
content: string;
|
|
4
|
+
type: 'swift' | 'markdown' | 'playground' | 'other';
|
|
5
|
+
hasCode: boolean;
|
|
6
|
+
topics: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface ZipExtractionResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
patterns: ExtractedPattern[];
|
|
11
|
+
warnings: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function downloadZip(url: string, postId: string, accessToken: string): Promise<string | null>;
|
|
14
|
+
export declare function extractZip(zipPath: string, postId: string): ZipExtractionResult;
|
|
15
|
+
export declare function extractFromAttachment(attachmentUrl: string, postId: string, accessToken: string): Promise<ZipExtractionResult>;
|
|
16
|
+
export declare function clearZipCache(): void;
|
|
17
|
+
//# sourceMappingURL=patreon-zip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patreon-zip.d.ts","sourceRoot":"","sources":["../../../src/sources/premium/patreon-zip.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAuBD,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoCxB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAwD/E;AAED,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAY9B;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// src/sources/premium/patreon-zip.ts
|
|
2
|
+
import AdmZip from 'adm-zip';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { getCacheDir } from '../../utils/paths.js';
|
|
6
|
+
import { detectTopics, hasCodeContent } from '../../utils/swift-analysis.js';
|
|
7
|
+
import { BASE_TOPIC_KEYWORDS, mergeKeywords } from '../../config/swift-keywords.js';
|
|
8
|
+
const MAX_ZIP_SIZE = 50 * 1024 * 1024; // 50MB
|
|
9
|
+
const MAX_FILES = 100;
|
|
10
|
+
// Zip-specific keywords (extends base with more detailed patterns)
|
|
11
|
+
const zipSpecificTopics = {
|
|
12
|
+
'concurrency': ['sendable'], // Adds to base
|
|
13
|
+
'networking': ['request'], // Adds to base
|
|
14
|
+
'testing': ['stub'], // Adds to base
|
|
15
|
+
'architecture': ['repository', 'usecase'], // Adds to base
|
|
16
|
+
'uikit': ['uitableview', 'uicollectionview'], // Adds to base
|
|
17
|
+
};
|
|
18
|
+
const zipTopicKeywords = mergeKeywords(BASE_TOPIC_KEYWORDS, zipSpecificTopics);
|
|
19
|
+
function detectFileType(filename) {
|
|
20
|
+
const ext = path.extname(filename).toLowerCase();
|
|
21
|
+
switch (ext) {
|
|
22
|
+
case '.swift': return 'swift';
|
|
23
|
+
case '.md':
|
|
24
|
+
case '.markdown': return 'markdown';
|
|
25
|
+
case '.playground': return 'playground';
|
|
26
|
+
default: return 'other';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export async function downloadZip(url, postId, accessToken) {
|
|
30
|
+
const cacheDir = getCacheDir('zips');
|
|
31
|
+
const zipPath = path.join(cacheDir, `${postId}.zip`);
|
|
32
|
+
// Check if already cached
|
|
33
|
+
if (fs.existsSync(zipPath)) {
|
|
34
|
+
return zipPath;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetch(url, {
|
|
38
|
+
headers: { 'Authorization': `Bearer ${accessToken}` },
|
|
39
|
+
});
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
console.error(`Failed to download zip: ${response.status}`);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const contentLength = response.headers.get('content-length');
|
|
45
|
+
if (contentLength && parseInt(contentLength, 10) > MAX_ZIP_SIZE) {
|
|
46
|
+
console.warn(`Zip file too large (${contentLength} bytes), skipping`);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
// Ensure cache directory exists
|
|
50
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
51
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
52
|
+
fs.writeFileSync(zipPath, buffer);
|
|
53
|
+
return zipPath;
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error('Zip download failed:', error);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function extractZip(zipPath, postId) {
|
|
61
|
+
const warnings = [];
|
|
62
|
+
const patterns = [];
|
|
63
|
+
const destDir = path.join(getCacheDir('zips'), postId);
|
|
64
|
+
try {
|
|
65
|
+
const zip = new AdmZip(zipPath);
|
|
66
|
+
const entries = zip.getEntries();
|
|
67
|
+
if (entries.length > MAX_FILES) {
|
|
68
|
+
warnings.push(`Zip contains ${entries.length} files, extracting first ${MAX_FILES}`);
|
|
69
|
+
}
|
|
70
|
+
// Ensure destination exists
|
|
71
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
72
|
+
let count = 0;
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
if (count >= MAX_FILES)
|
|
75
|
+
break;
|
|
76
|
+
if (entry.isDirectory)
|
|
77
|
+
continue;
|
|
78
|
+
const filename = entry.entryName;
|
|
79
|
+
const type = detectFileType(filename);
|
|
80
|
+
// Skip non-relevant files
|
|
81
|
+
if (type === 'other')
|
|
82
|
+
continue;
|
|
83
|
+
try {
|
|
84
|
+
const content = entry.getData().toString('utf8');
|
|
85
|
+
const text = `${filename} ${content}`;
|
|
86
|
+
const topics = detectTopics(text, zipTopicKeywords);
|
|
87
|
+
const hasCode = hasCodeContent(content);
|
|
88
|
+
patterns.push({
|
|
89
|
+
filename,
|
|
90
|
+
content,
|
|
91
|
+
type,
|
|
92
|
+
hasCode,
|
|
93
|
+
topics,
|
|
94
|
+
});
|
|
95
|
+
count++;
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
warnings.push(`Failed to read ${filename}: ${err}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { success: true, patterns, warnings };
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return {
|
|
105
|
+
success: false,
|
|
106
|
+
patterns: [],
|
|
107
|
+
warnings: [`Extraction failed: ${error}`],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export async function extractFromAttachment(attachmentUrl, postId, accessToken) {
|
|
112
|
+
const zipPath = await downloadZip(attachmentUrl, postId, accessToken);
|
|
113
|
+
if (!zipPath) {
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
patterns: [],
|
|
117
|
+
warnings: ['Failed to download zip attachment'],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return extractZip(zipPath, postId);
|
|
121
|
+
}
|
|
122
|
+
export function clearZipCache() {
|
|
123
|
+
const cacheDir = getCacheDir('zips');
|
|
124
|
+
if (fs.existsSync(cacheDir)) {
|
|
125
|
+
fs.rmSync(cacheDir, { recursive: true });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=patreon-zip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patreon-zip.js","sourceRoot":"","sources":["../../../src/sources/premium/patreon-zip.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface PatreonPattern {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
url: string;
|
|
5
|
+
publishDate: string;
|
|
6
|
+
excerpt: string;
|
|
7
|
+
content: string;
|
|
8
|
+
creator: string;
|
|
9
|
+
topics: string[];
|
|
10
|
+
relevanceScore: number;
|
|
11
|
+
hasCode: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface CreatorInfo {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
url: string;
|
|
17
|
+
isSwiftRelated: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare class PatreonSource {
|
|
20
|
+
private clientId;
|
|
21
|
+
private clientSecret;
|
|
22
|
+
private enabledCreators;
|
|
23
|
+
constructor();
|
|
24
|
+
private loadEnabledCreators;
|
|
25
|
+
saveEnabledCreators(creatorIds: string[]): void;
|
|
26
|
+
isConfigured(): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns creators the user PAYS (patron memberships).
|
|
29
|
+
*
|
|
30
|
+
* IMPORTANT: This uses the identity endpoint with memberships.campaign include,
|
|
31
|
+
* NOT the /campaigns endpoint. The /campaigns endpoint only returns campaigns
|
|
32
|
+
* you OWN as a creator, not campaigns you subscribe to as a patron.
|
|
33
|
+
*
|
|
34
|
+
* Correct API: GET /identity?include=memberships.campaign
|
|
35
|
+
*/
|
|
36
|
+
getSubscribedCreators(): Promise<CreatorInfo[]>;
|
|
37
|
+
detectSwiftCreators(): Promise<CreatorInfo[]>;
|
|
38
|
+
fetchPatterns(creatorId?: string): Promise<PatreonPattern[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Convert downloaded post to patterns
|
|
41
|
+
*/
|
|
42
|
+
private downloadedPostToPatterns;
|
|
43
|
+
private videoToPattern;
|
|
44
|
+
searchPatterns(query: string): Promise<PatreonPattern[]>;
|
|
45
|
+
isAvailable(): boolean;
|
|
46
|
+
}
|
|
47
|
+
export default PatreonSource;
|
|
48
|
+
//# sourceMappingURL=patreon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patreon.d.ts","sourceRoot":"","sources":["../../../src/sources/premium/patreon.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,OAAO,CAAC;CACzB;AA0DD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAgB;;IAQvC,OAAO,CAAC,mBAAmB;IAY3B,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAOzC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAMtC;;;;;;;;OAQG;IACG,qBAAqB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IA2E/C,mBAAmB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAK7C,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA4DlE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC,OAAO,CAAC,cAAc;IAoBhB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAqB9D,WAAW,IAAI,OAAO;CAGvB;AAED,eAAe,aAAa,CAAC"}
|