@matdata/yasqe 5.9.0 → 5.10.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/build/ts/src/__tests__/share-test.d.ts +1 -0
- package/build/ts/src/__tests__/share-test.js +202 -0
- package/build/ts/src/__tests__/share-test.js.map +1 -0
- package/build/ts/src/index.d.ts +3 -0
- package/build/ts/src/index.js +176 -49
- package/build/ts/src/index.js.map +1 -1
- package/build/ts/src/sparql.d.ts +3 -0
- package/build/ts/src/sparql.js +176 -16
- package/build/ts/src/sparql.js.map +1 -1
- package/build/yasqe.min.css +1 -1
- package/build/yasqe.min.css.map +3 -3
- package/build/yasqe.min.js +84 -78
- package/build/yasqe.min.js.map +3 -3
- package/package.json +1 -1
- package/src/__tests__/share-test.ts +237 -0
- package/src/index.ts +214 -65
- package/src/scss/buttons.scss +107 -4
- package/src/sparql.ts +232 -20
package/src/scss/buttons.scss
CHANGED
|
@@ -89,15 +89,40 @@
|
|
|
89
89
|
}
|
|
90
90
|
.yasqe_sharePopup {
|
|
91
91
|
position: absolute;
|
|
92
|
-
padding:
|
|
92
|
+
padding: 12px;
|
|
93
93
|
margin-left: 0px;
|
|
94
94
|
background-color: #fff;
|
|
95
95
|
border: 1px solid #e3e3e3;
|
|
96
|
-
border-radius:
|
|
97
|
-
box-shadow:
|
|
98
|
-
width:
|
|
96
|
+
border-radius: 4px;
|
|
97
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
98
|
+
width: auto;
|
|
99
|
+
min-width: 300px;
|
|
100
|
+
max-width: 400px;
|
|
99
101
|
height: auto;
|
|
100
102
|
display: flex;
|
|
103
|
+
flex-direction: column;
|
|
104
|
+
gap: 8px;
|
|
105
|
+
|
|
106
|
+
.yasqe_sharePopup_title {
|
|
107
|
+
font-weight: 600;
|
|
108
|
+
font-size: 14px;
|
|
109
|
+
color: #333;
|
|
110
|
+
margin-bottom: 4px;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.yasqe_sharePopup_buttons {
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
gap: 6px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.yasqe_shareBtn {
|
|
120
|
+
width: 100%;
|
|
121
|
+
text-align: left;
|
|
122
|
+
justify-content: flex-start;
|
|
123
|
+
padding: 8px 12px;
|
|
124
|
+
font-size: 13px;
|
|
125
|
+
}
|
|
101
126
|
|
|
102
127
|
.inputWrapper {
|
|
103
128
|
flex-grow: 100;
|
|
@@ -129,6 +154,13 @@
|
|
|
129
154
|
textarea {
|
|
130
155
|
width: 100%;
|
|
131
156
|
}
|
|
157
|
+
|
|
158
|
+
.shortlinkErr {
|
|
159
|
+
color: #d32f2f;
|
|
160
|
+
font-size: 12px;
|
|
161
|
+
padding: 8px;
|
|
162
|
+
display: block;
|
|
163
|
+
}
|
|
132
164
|
}
|
|
133
165
|
.yasqe_queryButton {
|
|
134
166
|
display: inline-block;
|
|
@@ -440,3 +472,74 @@
|
|
|
440
472
|
}
|
|
441
473
|
}
|
|
442
474
|
}
|
|
475
|
+
|
|
476
|
+
// Toast notification styles - scoped with yasqe_ prefix
|
|
477
|
+
// These are appended to document.body and must be outside .yasqe selector
|
|
478
|
+
// The yasqe_ prefix prevents naming conflicts with other components
|
|
479
|
+
.yasqe_toast {
|
|
480
|
+
position: fixed;
|
|
481
|
+
bottom: 20px;
|
|
482
|
+
right: 20px;
|
|
483
|
+
background-color: #323232;
|
|
484
|
+
color: #fff;
|
|
485
|
+
padding: 12px 20px;
|
|
486
|
+
border-radius: 4px;
|
|
487
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
488
|
+
z-index: 10000;
|
|
489
|
+
font-size: 14px;
|
|
490
|
+
max-width: 400px;
|
|
491
|
+
animation: yasqe_toast-fadein 0.3s ease-in;
|
|
492
|
+
display: flex;
|
|
493
|
+
align-items: center;
|
|
494
|
+
gap: 12px;
|
|
495
|
+
|
|
496
|
+
&.yasqe_toast-warning {
|
|
497
|
+
background-color: #ffc107;
|
|
498
|
+
color: #000;
|
|
499
|
+
padding: 14px 20px;
|
|
500
|
+
box-shadow: 0 3px 10px rgba(255, 193, 7, 0.4);
|
|
501
|
+
|
|
502
|
+
.yasqe_toast-icon {
|
|
503
|
+
display: flex;
|
|
504
|
+
align-items: center;
|
|
505
|
+
flex-shrink: 0;
|
|
506
|
+
|
|
507
|
+
svg {
|
|
508
|
+
width: 24px;
|
|
509
|
+
height: 24px;
|
|
510
|
+
fill: #000;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.yasqe_toast-message {
|
|
516
|
+
flex: 1;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
&.yasqe_toast-fadeout {
|
|
520
|
+
animation: yasqe_toast-fadeout 0.3s ease-out;
|
|
521
|
+
opacity: 0;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
@keyframes yasqe_toast-fadein {
|
|
526
|
+
from {
|
|
527
|
+
opacity: 0;
|
|
528
|
+
transform: translateY(20px);
|
|
529
|
+
}
|
|
530
|
+
to {
|
|
531
|
+
opacity: 1;
|
|
532
|
+
transform: translateY(0);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
@keyframes yasqe_toast-fadeout {
|
|
537
|
+
from {
|
|
538
|
+
opacity: 1;
|
|
539
|
+
transform: translateY(0);
|
|
540
|
+
}
|
|
541
|
+
to {
|
|
542
|
+
opacity: 0;
|
|
543
|
+
transform: translateY(20px);
|
|
544
|
+
}
|
|
545
|
+
}
|
package/src/sparql.ts
CHANGED
|
@@ -360,38 +360,250 @@ export function getAcceptHeader(yasqe: Yasqe, _config: Config["requestConfig"])
|
|
|
360
360
|
}
|
|
361
361
|
return acceptHeader;
|
|
362
362
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
if (
|
|
368
|
-
//
|
|
369
|
-
|
|
370
|
-
url
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
url += ajaxConfig.url;
|
|
363
|
+
/**
|
|
364
|
+
* Helper to normalize URL for command-line tools
|
|
365
|
+
*/
|
|
366
|
+
function normalizeUrl(url: string): string {
|
|
367
|
+
if (url.indexOf("http") !== 0) {
|
|
368
|
+
// Relative or absolute URL - add domain, schema, etc
|
|
369
|
+
let fullUrl = `${window.location.protocol}//${window.location.host}`;
|
|
370
|
+
if (url.indexOf("/") === 0) {
|
|
371
|
+
// Absolute path
|
|
372
|
+
fullUrl += url;
|
|
374
373
|
} else {
|
|
375
|
-
//
|
|
376
|
-
|
|
374
|
+
// Relative path - ensure proper path joining
|
|
375
|
+
let basePath = window.location.pathname;
|
|
376
|
+
// If pathname does not end with "/", treat it as a file and use its directory
|
|
377
|
+
if (!basePath.endsWith("/")) {
|
|
378
|
+
const lastSlashIndex = basePath.lastIndexOf("/");
|
|
379
|
+
basePath = lastSlashIndex >= 0 ? basePath.substring(0, lastSlashIndex + 1) : "/";
|
|
380
|
+
}
|
|
381
|
+
fullUrl += basePath + url;
|
|
382
|
+
}
|
|
383
|
+
return fullUrl;
|
|
384
|
+
}
|
|
385
|
+
return url;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Check if ajax config contains authentication credentials
|
|
390
|
+
*/
|
|
391
|
+
export function hasAuthenticationCredentials(ajaxConfig: PopulatedAjaxConfig): boolean {
|
|
392
|
+
if (!ajaxConfig) return false;
|
|
393
|
+
|
|
394
|
+
// Check for Authorization header (Bearer, Basic, OAuth2)
|
|
395
|
+
if (ajaxConfig.headers && ajaxConfig.headers["Authorization"]) {
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Check for API Key headers - use more specific patterns to avoid false positives
|
|
400
|
+
if (ajaxConfig.headers) {
|
|
401
|
+
for (const headerName in ajaxConfig.headers) {
|
|
402
|
+
const lowerHeader = headerName.toLowerCase();
|
|
403
|
+
// Match common authentication header patterns with stricter rules to avoid false positives
|
|
404
|
+
// Only match headers that are clearly authentication-related
|
|
405
|
+
if (
|
|
406
|
+
lowerHeader.startsWith("x-api-key") ||
|
|
407
|
+
lowerHeader.startsWith("x-auth-") ||
|
|
408
|
+
lowerHeader === "apikey" ||
|
|
409
|
+
lowerHeader === "api-key" ||
|
|
410
|
+
// Only match token headers that end with "token" or have "auth" in the middle
|
|
411
|
+
(lowerHeader.endsWith("-token") && lowerHeader.startsWith("x-")) ||
|
|
412
|
+
(lowerHeader.includes("-auth-") && lowerHeader.includes("token"))
|
|
413
|
+
) {
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
377
416
|
}
|
|
378
417
|
}
|
|
418
|
+
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Escape single quotes for shell commands by replacing ' with '\''
|
|
424
|
+
*/
|
|
425
|
+
function escapeShellString(str: string): string {
|
|
426
|
+
return str.replace(/'/g, "'\\''");
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Generate cURL command string
|
|
431
|
+
*/
|
|
432
|
+
export function getAsCurlString(yasqe: Yasqe, _config?: Config["requestConfig"]) {
|
|
433
|
+
let ajaxConfig = getAjaxConfig(yasqe, getRequestConfigSettings(yasqe, _config));
|
|
434
|
+
if (!ajaxConfig) return "";
|
|
435
|
+
|
|
436
|
+
let url = normalizeUrl(ajaxConfig.url);
|
|
379
437
|
const segments: string[] = ["curl"];
|
|
380
438
|
|
|
381
439
|
if (ajaxConfig.reqMethod === "GET") {
|
|
382
440
|
url += `?${queryString.stringify(ajaxConfig.args)}`;
|
|
383
|
-
segments.push(url);
|
|
441
|
+
segments.push(`'${escapeShellString(url)}'`);
|
|
384
442
|
} else if (ajaxConfig.reqMethod === "POST") {
|
|
385
|
-
segments.push(url);
|
|
386
|
-
|
|
443
|
+
segments.push(`'${escapeShellString(url)}'`);
|
|
444
|
+
const data = queryString.stringify(ajaxConfig.args);
|
|
445
|
+
segments.push("--data", `'${escapeShellString(data)}'`);
|
|
387
446
|
} else {
|
|
388
|
-
// I don't expect to get here but let's be sure
|
|
389
447
|
console.warn("Unexpected request-method", ajaxConfig.reqMethod);
|
|
390
|
-
segments.push(url);
|
|
448
|
+
segments.push(`'${escapeShellString(url)}'`);
|
|
391
449
|
}
|
|
450
|
+
|
|
392
451
|
segments.push("-X", ajaxConfig.reqMethod);
|
|
452
|
+
|
|
453
|
+
// Add Accept header if present
|
|
454
|
+
if (ajaxConfig.accept) {
|
|
455
|
+
segments.push("-H", `'Accept: ${escapeShellString(ajaxConfig.accept)}'`);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
for (const header in ajaxConfig.headers) {
|
|
459
|
+
segments.push("-H", `'${escapeShellString(header)}: ${escapeShellString(ajaxConfig.headers[header])}'`);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return segments.join(" \\\n ");
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Escape PowerShell string by handling special characters
|
|
467
|
+
*/
|
|
468
|
+
function escapePowerShellString(str: string): string {
|
|
469
|
+
// Escape backtick, double quote, and dollar sign
|
|
470
|
+
return str.replace(/`/g, "``").replace(/"/g, '`"').replace(/\$/g, "`$");
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Generate PowerShell command string
|
|
475
|
+
*/
|
|
476
|
+
export function getAsPowerShellString(yasqe: Yasqe, _config?: Config["requestConfig"]): string {
|
|
477
|
+
let ajaxConfig = getAjaxConfig(yasqe, getRequestConfigSettings(yasqe, _config));
|
|
478
|
+
if (!ajaxConfig) return "";
|
|
479
|
+
|
|
480
|
+
let url = normalizeUrl(ajaxConfig.url);
|
|
481
|
+
const lines: string[] = [];
|
|
482
|
+
|
|
483
|
+
// Determine output file extension based on Accept header
|
|
484
|
+
const acceptHeader = ajaxConfig.accept;
|
|
485
|
+
let fileExtension = "json"; // default
|
|
486
|
+
if (acceptHeader) {
|
|
487
|
+
if (acceptHeader.includes("text/turtle") || acceptHeader.includes("application/x-turtle")) {
|
|
488
|
+
fileExtension = "ttl";
|
|
489
|
+
} else if (acceptHeader.includes("application/rdf+xml")) {
|
|
490
|
+
fileExtension = "xml";
|
|
491
|
+
} else if (acceptHeader.includes("application/n-triples")) {
|
|
492
|
+
fileExtension = "nt";
|
|
493
|
+
} else if (acceptHeader.includes("application/ld+json")) {
|
|
494
|
+
fileExtension = "jsonld";
|
|
495
|
+
} else if (acceptHeader.includes("text/csv")) {
|
|
496
|
+
fileExtension = "csv";
|
|
497
|
+
} else if (acceptHeader.includes("text/tab-separated-values")) {
|
|
498
|
+
fileExtension = "tsv";
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Build headers object, including Accept header
|
|
503
|
+
const headersLines: string[] = [];
|
|
504
|
+
if (acceptHeader) {
|
|
505
|
+
headersLines.push(` "Accept" = "${escapePowerShellString(acceptHeader)}"`);
|
|
506
|
+
}
|
|
507
|
+
for (const header in ajaxConfig.headers) {
|
|
508
|
+
headersLines.push(
|
|
509
|
+
` "${escapePowerShellString(header)}" = "${escapePowerShellString(ajaxConfig.headers[header])}"`,
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (ajaxConfig.reqMethod === "GET") {
|
|
514
|
+
url += `?${queryString.stringify(ajaxConfig.args)}`;
|
|
515
|
+
lines.push("$params = @{");
|
|
516
|
+
lines.push(` Uri = "${escapePowerShellString(url)}"`);
|
|
517
|
+
lines.push(` Method = "Get"`);
|
|
518
|
+
if (headersLines.length > 0) {
|
|
519
|
+
lines.push(" Headers = @{");
|
|
520
|
+
lines.push(headersLines.join("\n"));
|
|
521
|
+
lines.push(" }");
|
|
522
|
+
}
|
|
523
|
+
lines.push(` OutFile = "result.${fileExtension}"`);
|
|
524
|
+
lines.push("}");
|
|
525
|
+
} else if (ajaxConfig.reqMethod === "POST") {
|
|
526
|
+
const body = queryString.stringify(ajaxConfig.args);
|
|
527
|
+
lines.push("$params = @{");
|
|
528
|
+
lines.push(` Uri = "${escapePowerShellString(url)}"`);
|
|
529
|
+
lines.push(` Method = "Post"`);
|
|
530
|
+
if (headersLines.length > 0) {
|
|
531
|
+
lines.push(" Headers = @{");
|
|
532
|
+
lines.push(headersLines.join("\n"));
|
|
533
|
+
lines.push(" }");
|
|
534
|
+
}
|
|
535
|
+
lines.push(` ContentType = "application/x-www-form-urlencoded"`);
|
|
536
|
+
lines.push(` Body = "${escapePowerShellString(body)}"`);
|
|
537
|
+
lines.push(` OutFile = "result.${fileExtension}"`);
|
|
538
|
+
lines.push("}");
|
|
539
|
+
} else {
|
|
540
|
+
// Handle other methods (PUT, DELETE, etc.)
|
|
541
|
+
console.warn("Unexpected request-method for PowerShell", ajaxConfig.reqMethod);
|
|
542
|
+
const body = queryString.stringify(ajaxConfig.args);
|
|
543
|
+
lines.push("$params = @{");
|
|
544
|
+
lines.push(` Uri = "${url}"`);
|
|
545
|
+
lines.push(` Method = "${ajaxConfig.reqMethod}"`);
|
|
546
|
+
if (headersLines.length > 0) {
|
|
547
|
+
lines.push(" Headers = @{");
|
|
548
|
+
lines.push(headersLines.join("\n"));
|
|
549
|
+
lines.push(" }");
|
|
550
|
+
}
|
|
551
|
+
if (body) {
|
|
552
|
+
lines.push(` ContentType = "application/x-www-form-urlencoded"`);
|
|
553
|
+
lines.push(` Body = "${body.replace(/"/g, '`"')}"`);
|
|
554
|
+
}
|
|
555
|
+
lines.push(` OutFile = "result.${fileExtension}"`);
|
|
556
|
+
lines.push("}");
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
lines.push("");
|
|
560
|
+
lines.push("Invoke-WebRequest @params");
|
|
561
|
+
|
|
562
|
+
return lines.join("\n");
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Generate wget command string
|
|
567
|
+
*/
|
|
568
|
+
export function getAsWgetString(yasqe: Yasqe, _config?: Config["requestConfig"]): string {
|
|
569
|
+
let ajaxConfig = getAjaxConfig(yasqe, getRequestConfigSettings(yasqe, _config));
|
|
570
|
+
if (!ajaxConfig) return "";
|
|
571
|
+
|
|
572
|
+
let url = normalizeUrl(ajaxConfig.url);
|
|
573
|
+
const segments: string[] = ["wget"];
|
|
574
|
+
|
|
575
|
+
if (ajaxConfig.reqMethod === "GET") {
|
|
576
|
+
url += `?${queryString.stringify(ajaxConfig.args)}`;
|
|
577
|
+
segments.push(`'${escapeShellString(url)}'`);
|
|
578
|
+
} else if (ajaxConfig.reqMethod === "POST") {
|
|
579
|
+
segments.push(`'${escapeShellString(url)}'`);
|
|
580
|
+
const data = queryString.stringify(ajaxConfig.args);
|
|
581
|
+
segments.push("--post-data", `'${escapeShellString(data)}'`);
|
|
582
|
+
} else {
|
|
583
|
+
// Handle other methods
|
|
584
|
+
console.warn("Unexpected request-method for wget", ajaxConfig.reqMethod);
|
|
585
|
+
segments.push(`'${escapeShellString(url)}'`);
|
|
586
|
+
const data = queryString.stringify(ajaxConfig.args);
|
|
587
|
+
if (data) {
|
|
588
|
+
segments.push("--post-data", `'${escapeShellString(data)}'`);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Only add --method for non-GET requests
|
|
593
|
+
if (ajaxConfig.reqMethod !== "GET") {
|
|
594
|
+
segments.push("--method", ajaxConfig.reqMethod);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// Add Accept header if present
|
|
598
|
+
if (ajaxConfig.accept) {
|
|
599
|
+
segments.push("--header", `'Accept: ${escapeShellString(ajaxConfig.accept)}'`);
|
|
600
|
+
}
|
|
601
|
+
|
|
393
602
|
for (const header in ajaxConfig.headers) {
|
|
394
|
-
segments.push(
|
|
603
|
+
segments.push("--header", `'${escapeShellString(header)}: ${escapeShellString(ajaxConfig.headers[header])}'`);
|
|
395
604
|
}
|
|
396
|
-
|
|
605
|
+
|
|
606
|
+
segments.push("-O -");
|
|
607
|
+
|
|
608
|
+
return segments.join(" \\\n ");
|
|
397
609
|
}
|