waitspin 0.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.
- package/README.md +84 -0
- package/assets/waitspin-vscode/out/extension.js +446 -0
- package/assets/waitspin-vscode/out/extension.js.map +1 -0
- package/assets/waitspin-vscode/package.json +64 -0
- package/dist/cli.js +675 -0
- package/dist/cli.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# waitspin
|
|
2
|
+
|
|
3
|
+
Command-line client for [WaitSpin](https://waitspin.com) — sponsored
|
|
4
|
+
wait-state ads for verified developer surfaces.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
Run this only after `npm view waitspin version` succeeds in launch evidence:
|
|
9
|
+
|
|
10
|
+
Before install, publisher registration, or Checkout, review:
|
|
11
|
+
|
|
12
|
+
- Public API and agent docs: `https://waitspin.com/waitspin/docs`
|
|
13
|
+
- Terms: `https://waitspin.com/waitspin/terms`
|
|
14
|
+
- Privacy: `https://waitspin.com/waitspin/privacy`
|
|
15
|
+
|
|
16
|
+
Refund/account-credit policy: unused prepaid blocks are account credit unless a
|
|
17
|
+
cash refund is required by law or approved through support review. Self-serve
|
|
18
|
+
cash refund requests and credit redemption are not public launch capabilities
|
|
19
|
+
yet.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm view waitspin version
|
|
23
|
+
npx --yes waitspin init --email you@example.com --key-profile control
|
|
24
|
+
export WAITSPIN_API_KEY=wts_live_...
|
|
25
|
+
waitspin extension install --target vscode
|
|
26
|
+
waitspin extension status --target vscode
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
- `waitspin init` — email OTP onboarding
|
|
32
|
+
- `waitspin bid create` — create a campaign draft
|
|
33
|
+
- `waitspin bids list` — list campaigns
|
|
34
|
+
- `waitspin bid checkout <campaign-id>` — Stripe Checkout for blocks
|
|
35
|
+
- `waitspin market` — public leaderboard
|
|
36
|
+
- `waitspin wallet connect` — Stripe Connect Express onboarding
|
|
37
|
+
- `waitspin wallet status` — publisher balance, payout, and Connect status
|
|
38
|
+
- `waitspin wallet ledger` — publisher delivery ledger
|
|
39
|
+
- `waitspin wallet payout --dry-run` — payout eligibility preview
|
|
40
|
+
- `waitspin extension install --target vscode` — install the VS Code status-bar fallback
|
|
41
|
+
- `waitspin extension status --target vscode` — inspect managed fallback lifecycle state
|
|
42
|
+
- `waitspin extension uninstall --target vscode` — remove the managed fallback runtime and local state
|
|
43
|
+
|
|
44
|
+
API base: `https://api.waitspin.com`
|
|
45
|
+
|
|
46
|
+
The public package currently installs only the verified VS Code status-bar
|
|
47
|
+
fallback. Native Claude/Codex spinner patching is deferred until that lifecycle
|
|
48
|
+
has its own install/status/uninstall proof.
|
|
49
|
+
|
|
50
|
+
Payout execution is guarded server-side. Public launch proof uses Stripe test
|
|
51
|
+
mode with `waitspin wallet payout --confirm-test-transfer`; live transfers stay
|
|
52
|
+
disabled until the operator enables the explicit live payout flags.
|
|
53
|
+
|
|
54
|
+
Native Claude Code/Codex spinner patches, account-credit redemption, cash refund
|
|
55
|
+
self-service, and click billing are not public paid-launch capabilities yet.
|
|
56
|
+
|
|
57
|
+
## VS Code publisher credentials
|
|
58
|
+
|
|
59
|
+
Use a publisher-extension key for extension polling/events:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx waitspin init --email you@example.com --key-profile publisher-extension
|
|
63
|
+
npx waitspin extension install --target vscode --api-key wts_live_...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- `WAITSPIN_API_KEY` — temporary publisher-extension key for first activation
|
|
67
|
+
- `WAITSPIN_INSTALL_ID` — from `waitspin extension install`
|
|
68
|
+
|
|
69
|
+
The VS Code extension migrates `waitspin.apiKey` from User settings into VS Code
|
|
70
|
+
SecretStorage on activation. `WAITSPIN_API_KEY` is an env-only temporary
|
|
71
|
+
fallback and is not persisted by the extension. Store `waitspin.installId` in
|
|
72
|
+
User settings; do not store broad control keys or workspace-scoped credentials
|
|
73
|
+
for normal publisher operation.
|
|
74
|
+
|
|
75
|
+
## Release validation
|
|
76
|
+
|
|
77
|
+
Before advertising the public `npx waitspin` path, release operators should run:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm pack --dry-run --json
|
|
81
|
+
npm run test:waitspin:distribution
|
|
82
|
+
npm view waitspin version
|
|
83
|
+
npx --yes waitspin --help
|
|
84
|
+
```
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.activate = activate;
|
|
37
|
+
exports.deactivate = deactivate;
|
|
38
|
+
const vscode = __importStar(require("vscode"));
|
|
39
|
+
const DEFAULT_API_BASE = "https://api.waitspin.com";
|
|
40
|
+
const POLL_INTERVAL_MS = 15_000;
|
|
41
|
+
const MIN_VISIBLE_MS = 5_000;
|
|
42
|
+
const FETCH_TIMEOUT_MS = 10_000;
|
|
43
|
+
const API_KEY_SECRET_STORAGE_KEY = "waitspin.publisherApiKey";
|
|
44
|
+
let statusBarItem;
|
|
45
|
+
let pollTimer;
|
|
46
|
+
let impressionTimeout;
|
|
47
|
+
let outputChannel;
|
|
48
|
+
let secretApiKey;
|
|
49
|
+
let authPollingStopped = false;
|
|
50
|
+
let isPolling = false;
|
|
51
|
+
let invalidApiBaseWarned = false;
|
|
52
|
+
let activeServe;
|
|
53
|
+
function getOutputChannel() {
|
|
54
|
+
if (!outputChannel) {
|
|
55
|
+
outputChannel = vscode.window.createOutputChannel("WaitSpin");
|
|
56
|
+
}
|
|
57
|
+
return outputChannel;
|
|
58
|
+
}
|
|
59
|
+
function logWaitSpin(message) {
|
|
60
|
+
getOutputChannel().appendLine(`[${new Date().toISOString()}] ${message}`);
|
|
61
|
+
}
|
|
62
|
+
function formatCredentialError(error) {
|
|
63
|
+
return error instanceof Error ? error.message : String(error);
|
|
64
|
+
}
|
|
65
|
+
function warnCredentialStorageFailure(action, error) {
|
|
66
|
+
const message = `${action}: ${formatCredentialError(error)}`;
|
|
67
|
+
logWaitSpin(message);
|
|
68
|
+
void vscode.window.showWarningMessage(`WaitSpin: ${message}`);
|
|
69
|
+
}
|
|
70
|
+
function resolveApiKey() {
|
|
71
|
+
if (secretApiKey) {
|
|
72
|
+
return secretApiKey;
|
|
73
|
+
}
|
|
74
|
+
const fromConfig = readGlobalWaitSpinSetting("apiKey");
|
|
75
|
+
if (fromConfig) {
|
|
76
|
+
return fromConfig;
|
|
77
|
+
}
|
|
78
|
+
return process.env.WAITSPIN_API_KEY?.trim();
|
|
79
|
+
}
|
|
80
|
+
async function migratePublisherApiKeyToSecretStorage(context) {
|
|
81
|
+
let stored;
|
|
82
|
+
try {
|
|
83
|
+
stored = (await context.secrets.get(API_KEY_SECRET_STORAGE_KEY))?.trim();
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
secretApiKey = undefined;
|
|
87
|
+
warnCredentialStorageFailure("Unable to read WaitSpin publisher key from SecretStorage", error);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (stored) {
|
|
91
|
+
secretApiKey = stored;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
secretApiKey = undefined;
|
|
95
|
+
const fromConfig = readGlobalWaitSpinSetting("apiKey");
|
|
96
|
+
if (!fromConfig) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
await context.secrets.store(API_KEY_SECRET_STORAGE_KEY, fromConfig);
|
|
101
|
+
secretApiKey = fromConfig;
|
|
102
|
+
await vscode.workspace
|
|
103
|
+
.getConfiguration("waitspin")
|
|
104
|
+
.update("apiKey", undefined, vscode.ConfigurationTarget.Global);
|
|
105
|
+
logWaitSpin("Migrated waitspin.apiKey into VS Code SecretStorage for publisher polling.");
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
secretApiKey = fromConfig;
|
|
109
|
+
warnCredentialStorageFailure("Unable to migrate waitspin.apiKey into VS Code SecretStorage", error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function resolveInstallId() {
|
|
113
|
+
const fromConfig = readGlobalWaitSpinSetting("installId");
|
|
114
|
+
if (fromConfig) {
|
|
115
|
+
return fromConfig;
|
|
116
|
+
}
|
|
117
|
+
return process.env.WAITSPIN_INSTALL_ID?.trim();
|
|
118
|
+
}
|
|
119
|
+
function readGlobalWaitSpinSetting(name) {
|
|
120
|
+
const config = vscode.workspace.getConfiguration("waitspin");
|
|
121
|
+
const inspected = config.inspect(name);
|
|
122
|
+
const globalValue = inspected?.globalValue?.trim();
|
|
123
|
+
return globalValue || undefined;
|
|
124
|
+
}
|
|
125
|
+
function allowDeveloperApiBase() {
|
|
126
|
+
return process.env.WAITSPIN_ALLOW_DEV_API_BASE === "1";
|
|
127
|
+
}
|
|
128
|
+
function normalizeTrustedApiBase(value) {
|
|
129
|
+
try {
|
|
130
|
+
const parsed = new URL(value);
|
|
131
|
+
const hostname = parsed.hostname.toLowerCase().replace(/\.$/, "");
|
|
132
|
+
const isProductionApi = parsed.protocol === "https:" &&
|
|
133
|
+
hostname === "api.waitspin.com" &&
|
|
134
|
+
!parsed.username &&
|
|
135
|
+
!parsed.password &&
|
|
136
|
+
(parsed.pathname === "/" || parsed.pathname === "");
|
|
137
|
+
if (isProductionApi) {
|
|
138
|
+
return parsed.origin;
|
|
139
|
+
}
|
|
140
|
+
if (allowDeveloperApiBase() && !parsed.username && !parsed.password) {
|
|
141
|
+
return parsed.origin.replace(/\/+$/, "");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
function resolveApiBase() {
|
|
150
|
+
const configured = readGlobalWaitSpinSetting("apiBase") ||
|
|
151
|
+
process.env.WAITSPIN_BASE_URL?.trim() ||
|
|
152
|
+
DEFAULT_API_BASE;
|
|
153
|
+
const normalized = normalizeTrustedApiBase(configured);
|
|
154
|
+
if (!normalized && !invalidApiBaseWarned) {
|
|
155
|
+
invalidApiBaseWarned = true;
|
|
156
|
+
logWaitSpin("Ignoring untrusted waitspin.apiBase. Store credentials globally and use https://api.waitspin.com for publisher polling.");
|
|
157
|
+
}
|
|
158
|
+
return normalized;
|
|
159
|
+
}
|
|
160
|
+
function isSafeExternalUrl(url) {
|
|
161
|
+
try {
|
|
162
|
+
const { hostname, protocol } = new URL(url);
|
|
163
|
+
if (protocol !== "http:" && protocol !== "https:") {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
const host = hostname.toLowerCase();
|
|
167
|
+
if (["localhost", "127.0.0.1", "0.0.0.0", "::1", "[::1]"].includes(host)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
if (/^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(host)) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
if (/^169\.254\./.test(host)) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
if (host.startsWith("fe80:") || host.startsWith("[fe80:")) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
if (["metadata.google.internal", "metadata", "fd00:ec2::254"].includes(host)) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function parseServePayload(payload) {
|
|
189
|
+
if (!payload || typeof payload !== "object") {
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
const record = payload;
|
|
193
|
+
const serveId = record.serve_id;
|
|
194
|
+
if (typeof serveId !== "string" || serveId.trim().length < 8) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
const creative = record.creative;
|
|
198
|
+
if (!creative || typeof creative !== "object") {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
const creativeRecord = creative;
|
|
202
|
+
const line = creativeRecord.line;
|
|
203
|
+
const destinationUrl = creativeRecord.destination_url;
|
|
204
|
+
if (typeof line !== "string" || line.trim().length === 0) {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
if (typeof destinationUrl !== "string" ||
|
|
208
|
+
!isSafeExternalUrl(destinationUrl)) {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
const minVisibleMs = typeof record.min_visible_ms === "number" && record.min_visible_ms >= 5000
|
|
212
|
+
? record.min_visible_ms
|
|
213
|
+
: MIN_VISIBLE_MS;
|
|
214
|
+
return {
|
|
215
|
+
serveId: serveId.trim(),
|
|
216
|
+
line: line.trim(),
|
|
217
|
+
destinationUrl: destinationUrl.trim(),
|
|
218
|
+
minVisibleMs,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function resetPollingAfterConfigChange() {
|
|
222
|
+
authPollingStopped = false;
|
|
223
|
+
if (pollTimer) {
|
|
224
|
+
clearInterval(pollTimer);
|
|
225
|
+
pollTimer = undefined;
|
|
226
|
+
}
|
|
227
|
+
startPollingIfConfigured();
|
|
228
|
+
}
|
|
229
|
+
function isAuthError(status) {
|
|
230
|
+
return status === 401 || status === 403;
|
|
231
|
+
}
|
|
232
|
+
function stopPollingForAuth(message) {
|
|
233
|
+
if (authPollingStopped) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
authPollingStopped = true;
|
|
237
|
+
if (pollTimer) {
|
|
238
|
+
clearInterval(pollTimer);
|
|
239
|
+
pollTimer = undefined;
|
|
240
|
+
}
|
|
241
|
+
logWaitSpin(message);
|
|
242
|
+
void vscode.window.showWarningMessage(`WaitSpin: ${message}`);
|
|
243
|
+
}
|
|
244
|
+
function ensureStatusBarFallback() {
|
|
245
|
+
if (!statusBarItem) {
|
|
246
|
+
statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 50);
|
|
247
|
+
statusBarItem.command = "waitspin.openAd";
|
|
248
|
+
statusBarItem.tooltip = "WaitSpin sponsored message (fallback surface)";
|
|
249
|
+
}
|
|
250
|
+
return statusBarItem;
|
|
251
|
+
}
|
|
252
|
+
async function fetchWithTimeout(url, init) {
|
|
253
|
+
const controller = new AbortController();
|
|
254
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
255
|
+
try {
|
|
256
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
clearTimeout(timeout);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async function fetchNextCreative() {
|
|
263
|
+
if (isPolling || authPollingStopped) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const apiKey = resolveApiKey();
|
|
267
|
+
const installId = resolveInstallId();
|
|
268
|
+
const apiBase = resolveApiBase();
|
|
269
|
+
if (!apiKey || !installId || !apiBase) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
isPolling = true;
|
|
273
|
+
try {
|
|
274
|
+
const response = await fetchWithTimeout(`${apiBase}/v1/serve/next`, {
|
|
275
|
+
method: "POST",
|
|
276
|
+
headers: {
|
|
277
|
+
Authorization: `Bearer ${apiKey}`,
|
|
278
|
+
"Content-Type": "application/json",
|
|
279
|
+
},
|
|
280
|
+
body: JSON.stringify({ install_id: installId }),
|
|
281
|
+
});
|
|
282
|
+
if (response.status === 204) {
|
|
283
|
+
hideAdSurfaces();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (isAuthError(response.status)) {
|
|
287
|
+
stopPollingForAuth(`Serve auth failed (HTTP ${response.status}). Check your publisher-scoped WaitSpin key and waitspin.installId.`);
|
|
288
|
+
hideAdSurfaces();
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (!response.ok) {
|
|
292
|
+
logWaitSpin(`Serve request failed: HTTP ${response.status}`);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const payload = await response.json();
|
|
296
|
+
const parsed = parseServePayload(payload);
|
|
297
|
+
if (!parsed) {
|
|
298
|
+
logWaitSpin("Serve response failed validation");
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
activeServe = {
|
|
302
|
+
serveId: parsed.serveId,
|
|
303
|
+
line: parsed.line,
|
|
304
|
+
destinationUrl: parsed.destinationUrl,
|
|
305
|
+
shownAt: Date.now(),
|
|
306
|
+
minVisibleMs: parsed.minVisibleMs,
|
|
307
|
+
};
|
|
308
|
+
// Native spinner patch hooks ship separately.
|
|
309
|
+
// The public publisher surface is the status bar fallback.
|
|
310
|
+
showStatusBarAd(activeServe, parsed.minVisibleMs);
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
logWaitSpin(`Serve network error: ${error instanceof Error ? error.message : String(error)}`);
|
|
314
|
+
}
|
|
315
|
+
finally {
|
|
316
|
+
isPolling = false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function showStatusBarAd(serve, minVisibleMs) {
|
|
320
|
+
const item = ensureStatusBarFallback();
|
|
321
|
+
item.text = `$(sync~spin) ${serve.line}`;
|
|
322
|
+
item.show();
|
|
323
|
+
if (impressionTimeout) {
|
|
324
|
+
clearTimeout(impressionTimeout);
|
|
325
|
+
}
|
|
326
|
+
impressionTimeout = setTimeout(() => {
|
|
327
|
+
impressionTimeout = undefined;
|
|
328
|
+
if (!activeServe || activeServe.serveId !== serve.serveId) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
const visibleMs = Math.max(Date.now() - serve.shownAt, minVisibleMs);
|
|
332
|
+
void recordImpression(serve.serveId, visibleMs, resolveInstallId());
|
|
333
|
+
}, minVisibleMs);
|
|
334
|
+
}
|
|
335
|
+
function flushPendingImpressionIfEligible() {
|
|
336
|
+
const serve = activeServe;
|
|
337
|
+
if (!serve) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const visibleMs = Date.now() - serve.shownAt;
|
|
341
|
+
if (visibleMs >= serve.minVisibleMs) {
|
|
342
|
+
void recordImpression(serve.serveId, visibleMs, resolveInstallId());
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function clearImpressionSchedulingAndFlush() {
|
|
346
|
+
if (impressionTimeout) {
|
|
347
|
+
clearTimeout(impressionTimeout);
|
|
348
|
+
impressionTimeout = undefined;
|
|
349
|
+
}
|
|
350
|
+
flushPendingImpressionIfEligible();
|
|
351
|
+
}
|
|
352
|
+
function stopPollingAndFlushImpression() {
|
|
353
|
+
if (pollTimer) {
|
|
354
|
+
clearInterval(pollTimer);
|
|
355
|
+
pollTimer = undefined;
|
|
356
|
+
}
|
|
357
|
+
clearImpressionSchedulingAndFlush();
|
|
358
|
+
}
|
|
359
|
+
function hideAdSurfaces() {
|
|
360
|
+
clearImpressionSchedulingAndFlush();
|
|
361
|
+
statusBarItem?.hide();
|
|
362
|
+
activeServe = undefined;
|
|
363
|
+
}
|
|
364
|
+
function disposeExtensionResources() {
|
|
365
|
+
stopPollingAndFlushImpression();
|
|
366
|
+
statusBarItem?.dispose();
|
|
367
|
+
outputChannel?.dispose();
|
|
368
|
+
}
|
|
369
|
+
function startPollingIfConfigured() {
|
|
370
|
+
if (authPollingStopped || pollTimer) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (!resolveApiKey() || !resolveInstallId()) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
void fetchNextCreative();
|
|
377
|
+
pollTimer = setInterval(() => {
|
|
378
|
+
void fetchNextCreative();
|
|
379
|
+
}, POLL_INTERVAL_MS);
|
|
380
|
+
}
|
|
381
|
+
async function recordImpression(serveId, visibleMs, installId) {
|
|
382
|
+
const apiKey = resolveApiKey();
|
|
383
|
+
const apiBase = resolveApiBase();
|
|
384
|
+
if (!apiKey || !installId || !apiBase) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
try {
|
|
388
|
+
const response = await fetchWithTimeout(`${apiBase}/v1/events/impression`, {
|
|
389
|
+
method: "POST",
|
|
390
|
+
headers: {
|
|
391
|
+
Authorization: `Bearer ${apiKey}`,
|
|
392
|
+
"Content-Type": "application/json",
|
|
393
|
+
},
|
|
394
|
+
body: JSON.stringify({
|
|
395
|
+
serve_id: serveId,
|
|
396
|
+
install_id: installId,
|
|
397
|
+
visible_ms: visibleMs,
|
|
398
|
+
}),
|
|
399
|
+
});
|
|
400
|
+
if (isAuthError(response.status)) {
|
|
401
|
+
stopPollingForAuth(`Impression auth failed (HTTP ${response.status}). Check your publisher-scoped WaitSpin key and waitspin.installId.`);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (!response.ok) {
|
|
405
|
+
logWaitSpin(`Impression request failed: HTTP ${response.status}`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
logWaitSpin(`Impression network error: ${error instanceof Error ? error.message : String(error)}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function activate(context) {
|
|
413
|
+
const openAd = vscode.commands.registerCommand("waitspin.openAd", () => {
|
|
414
|
+
const destinationUrl = activeServe?.destinationUrl;
|
|
415
|
+
if (!destinationUrl || !isSafeExternalUrl(destinationUrl)) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
void vscode.env.openExternal(vscode.Uri.parse(destinationUrl));
|
|
419
|
+
});
|
|
420
|
+
context.subscriptions.push(openAd);
|
|
421
|
+
const activatePublisher = vscode.commands.registerCommand("waitspin.activatePublisher", () => {
|
|
422
|
+
authPollingStopped = false;
|
|
423
|
+
startPollingIfConfigured();
|
|
424
|
+
});
|
|
425
|
+
context.subscriptions.push(activatePublisher);
|
|
426
|
+
authPollingStopped = false;
|
|
427
|
+
void migratePublisherApiKeyToSecretStorage(context).finally(() => {
|
|
428
|
+
startPollingIfConfigured();
|
|
429
|
+
});
|
|
430
|
+
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration((event) => {
|
|
431
|
+
if (event.affectsConfiguration("waitspin.apiKey") ||
|
|
432
|
+
event.affectsConfiguration("waitspin.installId") ||
|
|
433
|
+
event.affectsConfiguration("waitspin.apiBase")) {
|
|
434
|
+
void migratePublisherApiKeyToSecretStorage(context).finally(() => {
|
|
435
|
+
resetPollingAfterConfigChange();
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}));
|
|
439
|
+
context.subscriptions.push({
|
|
440
|
+
dispose: disposeExtensionResources,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
function deactivate() {
|
|
444
|
+
disposeExtensionResources();
|
|
445
|
+
}
|
|
446
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "waitspin-vscode",
|
|
3
|
+
"displayName": "WaitSpin",
|
|
4
|
+
"description": "WaitSpin sponsored wait-state ads through the verified VS Code status bar fallback.",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"publisher": "waitspin",
|
|
7
|
+
"engines": {
|
|
8
|
+
"vscode": "^1.85.0"
|
|
9
|
+
},
|
|
10
|
+
"categories": [
|
|
11
|
+
"Other"
|
|
12
|
+
],
|
|
13
|
+
"activationEvents": [
|
|
14
|
+
"onCommand:waitspin.activatePublisher",
|
|
15
|
+
"onStartupFinished"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/nttylock/saas-blog.git",
|
|
20
|
+
"directory": "extensions/waitspin-vscode"
|
|
21
|
+
},
|
|
22
|
+
"main": "./out/extension.js",
|
|
23
|
+
"contributes": {
|
|
24
|
+
"commands": [
|
|
25
|
+
{
|
|
26
|
+
"command": "waitspin.activatePublisher",
|
|
27
|
+
"title": "WaitSpin: Start publisher polling"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"command": "waitspin.openAd",
|
|
31
|
+
"title": "WaitSpin: Open sponsored link"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"configuration": {
|
|
35
|
+
"title": "WaitSpin",
|
|
36
|
+
"properties": {
|
|
37
|
+
"waitspin.apiKey": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"default": "",
|
|
40
|
+
"description": "Publisher-scoped WaitSpin API key. On activation the extension migrates this setting into VS Code SecretStorage; WAITSPIN_API_KEY is an env-only fallback."
|
|
41
|
+
},
|
|
42
|
+
"waitspin.installId": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"default": "",
|
|
45
|
+
"description": "Publisher install id from waitspin publishers register. Store in user settings."
|
|
46
|
+
},
|
|
47
|
+
"waitspin.apiBase": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"default": "https://api.waitspin.com",
|
|
50
|
+
"description": "WaitSpin control API base URL. Credentialed polling trusts only user settings and https://api.waitspin.com by default."
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"compile": "tsc -p .",
|
|
57
|
+
"watch": "tsc -watch -p ."
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/node": "^22.18.0",
|
|
61
|
+
"@types/vscode": "^1.85.0",
|
|
62
|
+
"typescript": "5.9.2"
|
|
63
|
+
}
|
|
64
|
+
}
|