@fias/plugin-dev-harness 1.2.0 → 1.3.1
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/dist/cli/check-auth.d.ts +3 -3
- package/dist/cli/check-auth.d.ts.map +1 -1
- package/dist/cli/check-auth.js +19 -8
- package/dist/cli/check-auth.js.map +1 -1
- package/dist/cli/check-auth.test.d.ts +2 -0
- package/dist/cli/check-auth.test.d.ts.map +1 -0
- package/dist/cli/check-auth.test.js +49 -0
- package/dist/cli/check-auth.test.js.map +1 -0
- package/dist/cli/dev.d.ts +2 -2
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/dev.js +4 -20
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/dev.test.js +10 -38
- package/dist/cli/dev.test.js.map +1 -1
- package/dist/cli/entities.d.ts.map +1 -1
- package/dist/cli/entities.js +8 -6
- package/dist/cli/entities.js.map +1 -1
- package/dist/cli/entities.test.js +15 -24
- package/dist/cli/entities.test.js.map +1 -1
- package/dist/cli/index.test.js +2 -2
- package/dist/cli/login.d.ts +2 -0
- package/dist/cli/login.d.ts.map +1 -1
- package/dist/cli/login.js +19 -14
- package/dist/cli/login.js.map +1 -1
- package/dist/cli/login.test.js +46 -24
- package/dist/cli/login.test.js.map +1 -1
- package/dist/cli/submit.d.ts.map +1 -1
- package/dist/cli/submit.js +13 -11
- package/dist/cli/submit.js.map +1 -1
- package/dist/cli/submit.test.js +13 -22
- package/dist/cli/submit.test.js.map +1 -1
- package/dist/config/config-loader.d.ts +6 -0
- package/dist/config/config-loader.d.ts.map +1 -1
- package/dist/config/config-loader.js +12 -0
- package/dist/config/config-loader.js.map +1 -1
- package/dist/config/credentials.d.ts +19 -1
- package/dist/config/credentials.d.ts.map +1 -1
- package/dist/config/credentials.js +46 -6
- package/dist/config/credentials.js.map +1 -1
- package/dist/config/credentials.test.js +72 -27
- package/dist/config/credentials.test.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/server/harness-server.d.ts +2 -3
- package/dist/server/harness-server.d.ts.map +1 -1
- package/dist/server/harness-server.js +233 -41
- package/dist/server/harness-server.js.map +1 -1
- package/dist/server/harness-server.test.js +60 -3
- package/dist/server/harness-server.test.js.map +1 -1
- package/dist/server/static/static/harness.css +58 -0
- package/dist/server/static/static/harness.html +20 -7
- package/dist/server/static/static/harness.js +139 -2
- package/package.json +10 -10
|
@@ -37,6 +37,28 @@ body {
|
|
|
37
37
|
color: #a78bfa;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/* Environment selector */
|
|
41
|
+
.env-selector {
|
|
42
|
+
background: #27272a;
|
|
43
|
+
color: #a1a1aa;
|
|
44
|
+
border: 1px solid #3f3f46;
|
|
45
|
+
border-radius: 4px;
|
|
46
|
+
padding: 3px 8px;
|
|
47
|
+
font-size: 11px;
|
|
48
|
+
font-weight: 600;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
outline: none;
|
|
51
|
+
text-transform: uppercase;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.env-selector:hover {
|
|
55
|
+
border-color: #52525b;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.env-selector:focus {
|
|
59
|
+
border-color: #a78bfa;
|
|
60
|
+
}
|
|
61
|
+
|
|
40
62
|
.mode-badge {
|
|
41
63
|
padding: 3px 10px;
|
|
42
64
|
border-radius: 4px;
|
|
@@ -193,6 +215,12 @@ body {
|
|
|
193
215
|
cursor: not-allowed;
|
|
194
216
|
}
|
|
195
217
|
|
|
218
|
+
.btn-full {
|
|
219
|
+
width: 100%;
|
|
220
|
+
padding: 10px 16px;
|
|
221
|
+
margin-bottom: 12px;
|
|
222
|
+
}
|
|
223
|
+
|
|
196
224
|
.btn-secondary {
|
|
197
225
|
background: transparent;
|
|
198
226
|
color: #a1a1aa;
|
|
@@ -207,6 +235,36 @@ body {
|
|
|
207
235
|
background: #3f3f46;
|
|
208
236
|
}
|
|
209
237
|
|
|
238
|
+
.btn-link {
|
|
239
|
+
background: none;
|
|
240
|
+
border: none;
|
|
241
|
+
color: #a78bfa;
|
|
242
|
+
cursor: pointer;
|
|
243
|
+
font-size: 12px;
|
|
244
|
+
padding: 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.btn-link:hover {
|
|
248
|
+
text-decoration: underline;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.modal-divider {
|
|
252
|
+
display: flex;
|
|
253
|
+
align-items: center;
|
|
254
|
+
gap: 12px;
|
|
255
|
+
margin: 12px 0;
|
|
256
|
+
color: #6b7280;
|
|
257
|
+
font-size: 12px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.modal-divider::before,
|
|
261
|
+
.modal-divider::after {
|
|
262
|
+
content: '';
|
|
263
|
+
flex: 1;
|
|
264
|
+
height: 1px;
|
|
265
|
+
background: #3f3f46;
|
|
266
|
+
}
|
|
267
|
+
|
|
210
268
|
/* Plugin status overlay */
|
|
211
269
|
.plugin-status {
|
|
212
270
|
flex: 1;
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
<div class="toolbar">
|
|
11
11
|
<div class="toolbar-left">
|
|
12
12
|
<span class="logo">Fias Arche Dev</span>
|
|
13
|
+
<select id="env-selector" class="env-selector">
|
|
14
|
+
<option value="staging">STAGING</option>
|
|
15
|
+
<option value="production">PRODUCTION</option>
|
|
16
|
+
</select>
|
|
13
17
|
<button id="mode-badge" class="mode-badge mode-mock" title="Click to switch mode">MOCK ⇆</button>
|
|
14
18
|
</div>
|
|
15
19
|
<div class="toolbar-right">
|
|
@@ -23,14 +27,23 @@
|
|
|
23
27
|
<div id="login-modal" class="modal-overlay" style="display: none">
|
|
24
28
|
<div class="modal">
|
|
25
29
|
<h3>Connect to FIAS</h3>
|
|
26
|
-
<p>
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<
|
|
30
|
+
<p>Sign in to your FIAS account to enable live mode with real AI responses.</p>
|
|
31
|
+
<div id="login-popup-section">
|
|
32
|
+
<button id="login-popup-btn" class="btn-primary btn-full">Sign in with FIAS</button>
|
|
33
|
+
<p id="login-popup-hint" class="modal-hint" style="display:none">
|
|
34
|
+
Popup blocked? <a id="login-popup-link" href="#" target="_blank" style="color:#a78bfa">Open login page manually</a>
|
|
35
|
+
</p>
|
|
36
|
+
<div class="modal-divider"><span>or</span></div>
|
|
37
|
+
<button id="login-manual-toggle" class="btn-link">Enter API key manually</button>
|
|
38
|
+
</div>
|
|
39
|
+
<div id="login-manual-section" style="display:none">
|
|
40
|
+
<input id="login-input" type="password" class="modal-input" placeholder="fias_sk_..." autocomplete="off" />
|
|
41
|
+
<div class="modal-actions">
|
|
42
|
+
<button id="login-cancel" class="btn-secondary">Cancel</button>
|
|
43
|
+
<button id="login-submit" class="btn-primary">Save & Connect</button>
|
|
44
|
+
</div>
|
|
33
45
|
</div>
|
|
46
|
+
<div id="login-error" class="modal-error" style="display: none"></div>
|
|
34
47
|
</div>
|
|
35
48
|
</div>
|
|
36
49
|
<div id="plugin-status" class="plugin-status">
|
|
@@ -26,12 +26,21 @@
|
|
|
26
26
|
var loginError = document.getElementById('login-error');
|
|
27
27
|
var loginSubmit = document.getElementById('login-submit');
|
|
28
28
|
var loginCancel = document.getElementById('login-cancel');
|
|
29
|
+
var envSelector = document.getElementById('env-selector');
|
|
30
|
+
var loginPopupBtn = document.getElementById('login-popup-btn');
|
|
31
|
+
var loginPopupHint = document.getElementById('login-popup-hint');
|
|
32
|
+
var loginPopupLink = document.getElementById('login-popup-link');
|
|
33
|
+
var loginManualToggle = document.getElementById('login-manual-toggle');
|
|
34
|
+
var loginManualSection = document.getElementById('login-manual-section');
|
|
35
|
+
var loginPopupSection = document.getElementById('login-popup-section');
|
|
29
36
|
|
|
30
37
|
var messageCount = 0;
|
|
31
38
|
var currentTheme = 'dark';
|
|
32
39
|
var currentMode = 'mock';
|
|
40
|
+
var currentEnvironment = 'staging';
|
|
33
41
|
var hasCredentials = false;
|
|
34
42
|
var cachedConfig = null;
|
|
43
|
+
var authPollInterval = null;
|
|
35
44
|
|
|
36
45
|
/** Permission requirements per bridge call type (matches production) */
|
|
37
46
|
var PERMISSION_MAP = {
|
|
@@ -62,8 +71,10 @@
|
|
|
62
71
|
cachedConfig = config;
|
|
63
72
|
currentTheme = config.mockTheme || 'dark';
|
|
64
73
|
currentMode = config.mode || 'mock';
|
|
74
|
+
currentEnvironment = config.environment || 'staging';
|
|
65
75
|
hasCredentials = config.hasCredentials || false;
|
|
66
76
|
|
|
77
|
+
envSelector.value = currentEnvironment;
|
|
67
78
|
updateThemeBadge();
|
|
68
79
|
updateModeBadge();
|
|
69
80
|
|
|
@@ -138,6 +149,42 @@
|
|
|
138
149
|
}
|
|
139
150
|
});
|
|
140
151
|
|
|
152
|
+
// Environment selector
|
|
153
|
+
envSelector.addEventListener('change', function () {
|
|
154
|
+
fetch('/api/environment', {
|
|
155
|
+
method: 'POST',
|
|
156
|
+
headers: { 'Content-Type': 'application/json' },
|
|
157
|
+
body: JSON.stringify({ environment: envSelector.value }),
|
|
158
|
+
})
|
|
159
|
+
.then(function (r) {
|
|
160
|
+
return r.json();
|
|
161
|
+
})
|
|
162
|
+
.then(function (data) {
|
|
163
|
+
currentEnvironment = data.environment;
|
|
164
|
+
currentMode = data.mode;
|
|
165
|
+
hasCredentials = data.hasCredentials;
|
|
166
|
+
updateModeBadge();
|
|
167
|
+
|
|
168
|
+
if (currentMode === 'live') {
|
|
169
|
+
creditBalance.style.display = 'inline';
|
|
170
|
+
fetchCredits();
|
|
171
|
+
} else {
|
|
172
|
+
creditBalance.style.display = 'none';
|
|
173
|
+
creditBalance.textContent = '';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
logMessage(
|
|
177
|
+
'info',
|
|
178
|
+
'Environment: ' +
|
|
179
|
+
currentEnvironment.toUpperCase() +
|
|
180
|
+
(hasCredentials ? '' : ' (not authenticated)'),
|
|
181
|
+
);
|
|
182
|
+
})
|
|
183
|
+
.catch(function (err) {
|
|
184
|
+
logMessage('error', err.message);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
141
188
|
function switchMode(newMode) {
|
|
142
189
|
fetch('/api/mode', {
|
|
143
190
|
method: 'POST',
|
|
@@ -176,15 +223,19 @@
|
|
|
176
223
|
|
|
177
224
|
function showLoginModal() {
|
|
178
225
|
loginModal.style.display = 'flex';
|
|
179
|
-
|
|
226
|
+
loginPopupSection.style.display = 'block';
|
|
227
|
+
loginManualSection.style.display = 'none';
|
|
228
|
+
loginPopupHint.style.display = 'none';
|
|
180
229
|
loginError.style.display = 'none';
|
|
181
|
-
|
|
230
|
+
loginPopupBtn.disabled = false;
|
|
231
|
+
loginPopupBtn.textContent = 'Sign in with FIAS';
|
|
182
232
|
}
|
|
183
233
|
|
|
184
234
|
function hideLoginModal() {
|
|
185
235
|
loginModal.style.display = 'none';
|
|
186
236
|
loginInput.value = '';
|
|
187
237
|
loginError.style.display = 'none';
|
|
238
|
+
stopAuthPolling();
|
|
188
239
|
}
|
|
189
240
|
|
|
190
241
|
loginCancel.addEventListener('click', hideLoginModal);
|
|
@@ -193,6 +244,13 @@
|
|
|
193
244
|
if (e.target === loginModal) hideLoginModal();
|
|
194
245
|
});
|
|
195
246
|
|
|
247
|
+
// Toggle to manual key entry
|
|
248
|
+
loginManualToggle.addEventListener('click', function () {
|
|
249
|
+
loginPopupSection.style.display = 'none';
|
|
250
|
+
loginManualSection.style.display = 'block';
|
|
251
|
+
loginInput.focus();
|
|
252
|
+
});
|
|
253
|
+
|
|
196
254
|
loginInput.addEventListener('keydown', function (e) {
|
|
197
255
|
if (e.key === 'Enter') submitLogin();
|
|
198
256
|
if (e.key === 'Escape') hideLoginModal();
|
|
@@ -200,6 +258,39 @@
|
|
|
200
258
|
|
|
201
259
|
loginSubmit.addEventListener('click', submitLogin);
|
|
202
260
|
|
|
261
|
+
// Popup-based login
|
|
262
|
+
loginPopupBtn.addEventListener('click', function () {
|
|
263
|
+
loginPopupBtn.disabled = true;
|
|
264
|
+
loginPopupBtn.textContent = 'Opening...';
|
|
265
|
+
|
|
266
|
+
fetch('/api/auth/start', { method: 'POST' })
|
|
267
|
+
.then(function (r) {
|
|
268
|
+
return r.json();
|
|
269
|
+
})
|
|
270
|
+
.then(function (data) {
|
|
271
|
+
var popup = window.open(data.authUrl, 'fias-auth', 'width=500,height=650');
|
|
272
|
+
|
|
273
|
+
if (!popup || popup.closed) {
|
|
274
|
+
// Popup was blocked — show fallback link
|
|
275
|
+
loginPopupHint.style.display = 'block';
|
|
276
|
+
loginPopupLink.href = data.authUrl;
|
|
277
|
+
loginPopupBtn.disabled = false;
|
|
278
|
+
loginPopupBtn.textContent = 'Sign in with FIAS';
|
|
279
|
+
} else {
|
|
280
|
+
loginPopupBtn.textContent = 'Waiting for sign-in...';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Start polling as fallback (works even if popup can't postMessage)
|
|
284
|
+
startAuthPolling();
|
|
285
|
+
})
|
|
286
|
+
.catch(function (err) {
|
|
287
|
+
loginError.textContent = err.message;
|
|
288
|
+
loginError.style.display = 'block';
|
|
289
|
+
loginPopupBtn.disabled = false;
|
|
290
|
+
loginPopupBtn.textContent = 'Sign in with FIAS';
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
203
294
|
function submitLogin() {
|
|
204
295
|
var apiKey = loginInput.value.trim();
|
|
205
296
|
if (!apiKey) {
|
|
@@ -241,11 +332,57 @@
|
|
|
241
332
|
});
|
|
242
333
|
}
|
|
243
334
|
|
|
335
|
+
// Auth polling — fallback for popup blocked or postMessage unavailable
|
|
336
|
+
function startAuthPolling() {
|
|
337
|
+
if (authPollInterval) return;
|
|
338
|
+
authPollInterval = setInterval(function () {
|
|
339
|
+
fetch('/api/config')
|
|
340
|
+
.then(function (r) {
|
|
341
|
+
return r.json();
|
|
342
|
+
})
|
|
343
|
+
.then(function (config) {
|
|
344
|
+
if (config.hasCredentials && !hasCredentials) {
|
|
345
|
+
hasCredentials = true;
|
|
346
|
+
stopAuthPolling();
|
|
347
|
+
hideLoginModal();
|
|
348
|
+
logMessage('info', 'Authenticated for ' + currentEnvironment.toUpperCase());
|
|
349
|
+
switchMode('live');
|
|
350
|
+
}
|
|
351
|
+
})
|
|
352
|
+
.catch(function () {});
|
|
353
|
+
}, 2000);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function stopAuthPolling() {
|
|
357
|
+
if (authPollInterval) {
|
|
358
|
+
clearInterval(authPollInterval);
|
|
359
|
+
authPollInterval = null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
244
363
|
// ────────────────────────────────────────────────────────────────
|
|
245
364
|
// Message Handling
|
|
246
365
|
// ────────────────────────────────────────────────────────────────
|
|
247
366
|
|
|
248
367
|
window.addEventListener('message', function (event) {
|
|
368
|
+
// Handle auth callback from popup
|
|
369
|
+
if (event.data && event.data.type === 'auth_callback') {
|
|
370
|
+
stopAuthPolling();
|
|
371
|
+
if (event.data.success) {
|
|
372
|
+
hasCredentials = true;
|
|
373
|
+
hideLoginModal();
|
|
374
|
+
logMessage('info', 'Authenticated for ' + currentEnvironment.toUpperCase());
|
|
375
|
+
switchMode('live');
|
|
376
|
+
} else {
|
|
377
|
+
loginError.textContent = event.data.error || 'Authentication failed';
|
|
378
|
+
loginError.style.display = 'block';
|
|
379
|
+
}
|
|
380
|
+
loginPopupBtn.disabled = false;
|
|
381
|
+
loginPopupBtn.textContent = 'Sign in with FIAS';
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Handle plugin iframe messages
|
|
249
386
|
if (event.source !== iframe.contentWindow) return;
|
|
250
387
|
|
|
251
388
|
var data = event.data;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fias/plugin-dev-harness",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Development harness for building and testing FIAS plugin arches locally",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,6 +15,12 @@
|
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc && cp -r src/server/static dist/server/static",
|
|
20
|
+
"clean": "rm -rf dist",
|
|
21
|
+
"watch": "tsc -w",
|
|
22
|
+
"typecheck": "tsc --noEmit"
|
|
23
|
+
},
|
|
18
24
|
"keywords": [
|
|
19
25
|
"fias",
|
|
20
26
|
"plugin",
|
|
@@ -24,20 +30,14 @@
|
|
|
24
30
|
],
|
|
25
31
|
"license": "MIT",
|
|
26
32
|
"dependencies": {
|
|
33
|
+
"@fias/arche-sdk": "^1.0.0",
|
|
27
34
|
"chalk": "^4.1.2",
|
|
28
35
|
"commander": "^12.0.0",
|
|
29
|
-
"express": "^4.21.0"
|
|
30
|
-
"@fias/arche-sdk": "1.2.1"
|
|
36
|
+
"express": "^4.21.0"
|
|
31
37
|
},
|
|
32
38
|
"devDependencies": {
|
|
33
39
|
"@types/express": "^5.0.0",
|
|
34
40
|
"@types/node": "^25.5.0",
|
|
35
41
|
"typescript": "^5.3.3"
|
|
36
|
-
},
|
|
37
|
-
"scripts": {
|
|
38
|
-
"build": "tsc && cp -r src/server/static dist/server/static",
|
|
39
|
-
"clean": "rm -rf dist",
|
|
40
|
-
"watch": "tsc -w",
|
|
41
|
-
"typecheck": "tsc --noEmit"
|
|
42
42
|
}
|
|
43
|
-
}
|
|
43
|
+
}
|