@adobe-commerce/aio-toolkit 1.0.0 → 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/CHANGELOG.md +134 -16
- package/README.md +203 -98
- package/dist/index.d.mts +21 -17
- package/dist/index.d.ts +21 -17
- package/dist/index.js +185 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +185 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -12
package/dist/index.mjs
CHANGED
|
@@ -15,13 +15,13 @@ var HttpStatus = /* @__PURE__ */ ((HttpStatus2) => {
|
|
|
15
15
|
return HttpStatus2;
|
|
16
16
|
})(HttpStatus || {});
|
|
17
17
|
var HttpMethod = /* @__PURE__ */ ((HttpMethod3) => {
|
|
18
|
-
HttpMethod3["GET"] = "
|
|
19
|
-
HttpMethod3["POST"] = "
|
|
20
|
-
HttpMethod3["PUT"] = "
|
|
21
|
-
HttpMethod3["DELETE"] = "
|
|
22
|
-
HttpMethod3["PATCH"] = "
|
|
23
|
-
HttpMethod3["HEAD"] = "
|
|
24
|
-
HttpMethod3["OPTIONS"] = "
|
|
18
|
+
HttpMethod3["GET"] = "GET";
|
|
19
|
+
HttpMethod3["POST"] = "POST";
|
|
20
|
+
HttpMethod3["PUT"] = "PUT";
|
|
21
|
+
HttpMethod3["DELETE"] = "DELETE";
|
|
22
|
+
HttpMethod3["PATCH"] = "PATCH";
|
|
23
|
+
HttpMethod3["HEAD"] = "HEAD";
|
|
24
|
+
HttpMethod3["OPTIONS"] = "OPTIONS";
|
|
25
25
|
return HttpMethod3;
|
|
26
26
|
})(HttpMethod || {});
|
|
27
27
|
|
|
@@ -195,9 +195,9 @@ var _RuntimeAction = class _RuntimeAction {
|
|
|
195
195
|
if (errorMessage) {
|
|
196
196
|
return response_default.error(400 /* BAD_REQUEST */, errorMessage);
|
|
197
197
|
}
|
|
198
|
-
const requestMethod = params.__ow_method;
|
|
198
|
+
const requestMethod = params.__ow_method?.toUpperCase();
|
|
199
199
|
if (httpMethods.length > 0 && !httpMethods.includes(requestMethod)) {
|
|
200
|
-
const errorMessage2 = `Invalid HTTP method: ${
|
|
200
|
+
const errorMessage2 = `Invalid HTTP method: ${params.__ow_method}. Allowed methods are: ${httpMethods.join(", ")}`;
|
|
201
201
|
logger.error(errorMessage2);
|
|
202
202
|
return response_default.error(405 /* METHOD_NOT_ALLOWED */, errorMessage2);
|
|
203
203
|
}
|
|
@@ -258,7 +258,7 @@ var _GraphQlAction = class _GraphQlAction {
|
|
|
258
258
|
}, name = "main", disableIntrospection = false) {
|
|
259
259
|
return runtime_action_default.execute(
|
|
260
260
|
`graphql-${name}`,
|
|
261
|
-
["
|
|
261
|
+
["GET" /* GET */, "POST" /* POST */],
|
|
262
262
|
["query"],
|
|
263
263
|
[],
|
|
264
264
|
async (params, ctx) => {
|
|
@@ -423,39 +423,44 @@ var _FileRepository = class _FileRepository {
|
|
|
423
423
|
/**
|
|
424
424
|
* Saves a file record to the repository
|
|
425
425
|
* @param payload - The data to save
|
|
426
|
-
* @
|
|
426
|
+
* @param id - Optional ID for the file (sanitized to alphanumeric + underscore, takes precedence over payload.id)
|
|
427
|
+
* @returns Promise<string | null> The filename on success, null on failure
|
|
427
428
|
*/
|
|
428
|
-
async save(payload = {}) {
|
|
429
|
+
async save(payload = {}, id) {
|
|
429
430
|
try {
|
|
430
431
|
const filesLib = await this.getFiles();
|
|
431
|
-
let
|
|
432
|
-
if (
|
|
433
|
-
|
|
432
|
+
let fileId;
|
|
433
|
+
if (id) {
|
|
434
|
+
fileId = this.sanitizeFileId(id);
|
|
435
|
+
} else if ("id" in payload && payload.id !== void 0) {
|
|
436
|
+
fileId = String(payload.id);
|
|
437
|
+
} else {
|
|
438
|
+
fileId = String((/* @__PURE__ */ new Date()).getTime());
|
|
434
439
|
}
|
|
435
|
-
const filepath = `${this.filepath}/${
|
|
440
|
+
const filepath = `${this.filepath}/${fileId}.json`;
|
|
436
441
|
const existingFile = await filesLib.list(filepath);
|
|
437
442
|
if (existingFile.length) {
|
|
438
443
|
const buffer = await filesLib.read(filepath);
|
|
439
444
|
const existingData = JSON.parse(buffer.toString());
|
|
440
445
|
payload = {
|
|
441
446
|
...payload,
|
|
442
|
-
|
|
447
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
443
448
|
};
|
|
444
449
|
payload = { ...existingData, ...payload };
|
|
445
450
|
await filesLib.delete(filepath);
|
|
446
451
|
} else {
|
|
447
452
|
payload = {
|
|
448
453
|
...payload,
|
|
449
|
-
id:
|
|
450
|
-
|
|
451
|
-
|
|
454
|
+
id: fileId,
|
|
455
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
456
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
452
457
|
};
|
|
453
458
|
}
|
|
454
459
|
await filesLib.write(filepath, JSON.stringify(payload));
|
|
455
|
-
return
|
|
460
|
+
return fileId;
|
|
456
461
|
} catch (error) {
|
|
457
462
|
console.error("Error saving file:", error);
|
|
458
|
-
return
|
|
463
|
+
return null;
|
|
459
464
|
}
|
|
460
465
|
}
|
|
461
466
|
/**
|
|
@@ -470,6 +475,21 @@ var _FileRepository = class _FileRepository {
|
|
|
470
475
|
}
|
|
471
476
|
return await this.list();
|
|
472
477
|
}
|
|
478
|
+
/**
|
|
479
|
+
* Sanitizes the file ID to contain only alphanumeric characters and underscores
|
|
480
|
+
* @param id - The ID to sanitize
|
|
481
|
+
* @returns Sanitized ID with invalid characters replaced by underscores
|
|
482
|
+
*/
|
|
483
|
+
sanitizeFileId(id) {
|
|
484
|
+
if (!id || typeof id !== "string") {
|
|
485
|
+
return String((/* @__PURE__ */ new Date()).getTime());
|
|
486
|
+
}
|
|
487
|
+
const sanitized = id.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
488
|
+
if (!sanitized || /^_+$/.test(sanitized)) {
|
|
489
|
+
return String((/* @__PURE__ */ new Date()).getTime());
|
|
490
|
+
}
|
|
491
|
+
return sanitized;
|
|
492
|
+
}
|
|
473
493
|
/**
|
|
474
494
|
* Initializes and returns the Files library instance
|
|
475
495
|
* @returns Promise<any> Initialized Files library instance
|
|
@@ -488,21 +508,31 @@ var file_repository_default = FileRepository;
|
|
|
488
508
|
// src/integration/bearer-token/index.ts
|
|
489
509
|
var _BearerToken = class _BearerToken {
|
|
490
510
|
/**
|
|
491
|
-
* Extracts the Bearer token from
|
|
492
|
-
*
|
|
493
|
-
* after the "Bearer " prefix.
|
|
511
|
+
* Extracts the Bearer token from HTTP request headers and returns detailed token information.
|
|
512
|
+
* Supports both standard HTTP headers and OpenWhisk action parameter formats.
|
|
494
513
|
*
|
|
495
|
-
* @param
|
|
514
|
+
* @param headersOrParams - Either a standard headers object or OpenWhisk action parameters
|
|
496
515
|
* @returns Detailed token information object
|
|
497
516
|
*
|
|
498
517
|
* @example
|
|
518
|
+
* // Standard HTTP headers approach
|
|
519
|
+
* const headers = {
|
|
520
|
+
* authorization: 'Bearer abc123token'
|
|
521
|
+
* };
|
|
522
|
+
* const tokenInfo = BearerToken.extract(headers);
|
|
523
|
+
*
|
|
524
|
+
* @example
|
|
525
|
+
* // OpenWhisk action parameters (backward compatibility)
|
|
499
526
|
* const params = {
|
|
500
527
|
* __ow_headers: {
|
|
501
528
|
* authorization: 'Bearer abc123token'
|
|
502
529
|
* }
|
|
503
530
|
* };
|
|
504
531
|
* const tokenInfo = BearerToken.extract(params);
|
|
505
|
-
*
|
|
532
|
+
*
|
|
533
|
+
* @example
|
|
534
|
+
* // Both return the same result:
|
|
535
|
+
* // {
|
|
506
536
|
* // token: 'abc123token',
|
|
507
537
|
* // tokenLength: 11,
|
|
508
538
|
* // isValid: true,
|
|
@@ -510,26 +540,54 @@ var _BearerToken = class _BearerToken {
|
|
|
510
540
|
* // timeUntilExpiry: 3600000
|
|
511
541
|
* // }
|
|
512
542
|
*/
|
|
513
|
-
static extract(
|
|
543
|
+
static extract(headersOrParams) {
|
|
514
544
|
let token = null;
|
|
515
|
-
if (
|
|
516
|
-
token =
|
|
545
|
+
if (headersOrParams.authorization?.startsWith("Bearer ")) {
|
|
546
|
+
token = headersOrParams.authorization.substring("Bearer ".length);
|
|
547
|
+
} else if (headersOrParams.__ow_headers?.authorization?.startsWith("Bearer ")) {
|
|
548
|
+
token = headersOrParams.__ow_headers.authorization.substring("Bearer ".length);
|
|
517
549
|
}
|
|
518
550
|
return _BearerToken.info(token);
|
|
519
551
|
}
|
|
520
552
|
/**
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
553
|
+
* Analyzes a Bearer token and returns detailed information including validity and expiry.
|
|
554
|
+
* Supports both JWT tokens (with automatic expiry detection) and plain tokens (24h default expiry).
|
|
555
|
+
*
|
|
556
|
+
* @param token - The Bearer token string (or null). Can be JWT or plain token.
|
|
557
|
+
* @returns Detailed token information object
|
|
524
558
|
*
|
|
525
559
|
* @example
|
|
526
|
-
*
|
|
560
|
+
* // Plain token (gets 24h default expiry)
|
|
561
|
+
* const plainTokenInfo = BearerToken.info('abc123token');
|
|
527
562
|
* // returns: {
|
|
528
563
|
* // token: 'abc123token',
|
|
529
564
|
* // tokenLength: 11,
|
|
530
565
|
* // isValid: true,
|
|
531
|
-
* // expiry: '2024-01-
|
|
532
|
-
* // timeUntilExpiry:
|
|
566
|
+
* // expiry: '2024-01-02T12:00:00.000Z', // 24h from now
|
|
567
|
+
* // timeUntilExpiry: 86400000 // milliseconds until expiry
|
|
568
|
+
* // }
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* // JWT token (automatic expiry detection from 'exp' or 'expires_in' claims)
|
|
572
|
+
* const jwtToken = 'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDQ0Njc2MDB9.signature';
|
|
573
|
+
* const jwtTokenInfo = BearerToken.info(jwtToken);
|
|
574
|
+
* // returns: {
|
|
575
|
+
* // token: 'eyJhbGciOiJIUzI1NiJ9...',
|
|
576
|
+
* // tokenLength: 45,
|
|
577
|
+
* // isValid: true, // false if expired
|
|
578
|
+
* // expiry: '2024-01-05T12:00:00.000Z', // from JWT exp claim
|
|
579
|
+
* // timeUntilExpiry: 172800000 // actual time until expiry
|
|
580
|
+
* // }
|
|
581
|
+
*
|
|
582
|
+
* @example
|
|
583
|
+
* // Null or invalid token
|
|
584
|
+
* const nullTokenInfo = BearerToken.info(null);
|
|
585
|
+
* // returns: {
|
|
586
|
+
* // token: null,
|
|
587
|
+
* // tokenLength: 0,
|
|
588
|
+
* // isValid: false,
|
|
589
|
+
* // expiry: null,
|
|
590
|
+
* // timeUntilExpiry: null
|
|
533
591
|
* // }
|
|
534
592
|
*/
|
|
535
593
|
static info(token) {
|
|
@@ -595,14 +653,86 @@ var bearer_token_default = BearerToken;
|
|
|
595
653
|
import fetch from "node-fetch";
|
|
596
654
|
var _RestClient = class _RestClient {
|
|
597
655
|
/**
|
|
598
|
-
* A
|
|
656
|
+
* A completely raw method to make HTTP requests
|
|
599
657
|
*
|
|
600
658
|
* @param endpoint
|
|
659
|
+
* @param method
|
|
601
660
|
* @param headers
|
|
661
|
+
* @param payload
|
|
662
|
+
* @returns {Promise<Response>}
|
|
663
|
+
*/
|
|
664
|
+
async makeRequest(endpoint, method = "GET", headers = {}, payload = null) {
|
|
665
|
+
let options = {
|
|
666
|
+
method,
|
|
667
|
+
headers
|
|
668
|
+
};
|
|
669
|
+
if (payload !== null) {
|
|
670
|
+
let body;
|
|
671
|
+
let contentType;
|
|
672
|
+
if (payload instanceof URLSearchParams) {
|
|
673
|
+
body = payload.toString();
|
|
674
|
+
contentType = headers["Content-Type"] || "application/x-www-form-urlencoded";
|
|
675
|
+
} else if (typeof FormData !== "undefined" && payload instanceof FormData) {
|
|
676
|
+
body = payload;
|
|
677
|
+
contentType = headers["Content-Type"];
|
|
678
|
+
} else if (typeof payload === "string") {
|
|
679
|
+
body = payload;
|
|
680
|
+
contentType = headers["Content-Type"] || "text/plain";
|
|
681
|
+
} else if (payload instanceof Buffer || payload instanceof ArrayBuffer || typeof Uint8Array !== "undefined" && payload instanceof Uint8Array) {
|
|
682
|
+
body = payload;
|
|
683
|
+
contentType = headers["Content-Type"] || "application/octet-stream";
|
|
684
|
+
} else {
|
|
685
|
+
body = JSON.stringify(payload);
|
|
686
|
+
contentType = headers["Content-Type"] || "application/json";
|
|
687
|
+
}
|
|
688
|
+
const requestHeaders = { ...headers };
|
|
689
|
+
if (contentType) {
|
|
690
|
+
requestHeaders["Content-Type"] = contentType;
|
|
691
|
+
}
|
|
692
|
+
options = {
|
|
693
|
+
...options,
|
|
694
|
+
body,
|
|
695
|
+
headers: requestHeaders
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
return await fetch(endpoint, options);
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* A method to parse HTTP response
|
|
702
|
+
*
|
|
703
|
+
* @param response
|
|
602
704
|
* @returns {Promise<any>}
|
|
603
705
|
*/
|
|
604
|
-
async
|
|
605
|
-
|
|
706
|
+
async parseResponse(response) {
|
|
707
|
+
if (!response.ok) {
|
|
708
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
709
|
+
}
|
|
710
|
+
if (response.status === 204 || response.headers?.get("content-length") === "0") {
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
if (typeof response.json === "function") {
|
|
714
|
+
const contentType = response.headers?.get("content-type");
|
|
715
|
+
if (!contentType || contentType.includes("application/json") || contentType.includes("application/hal+json")) {
|
|
716
|
+
return await response.json();
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
if (typeof response.text === "function") {
|
|
720
|
+
const text = await response.text();
|
|
721
|
+
return text;
|
|
722
|
+
}
|
|
723
|
+
return null;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* A generic method to make GET rest call
|
|
727
|
+
*
|
|
728
|
+
* @param endpoint
|
|
729
|
+
* @param headers
|
|
730
|
+
* @param parsed
|
|
731
|
+
* @returns {Promise<Response | any>}
|
|
732
|
+
*/
|
|
733
|
+
async get(endpoint, headers = {}, parsed = true) {
|
|
734
|
+
const response = await this.makeRequest(endpoint, "GET", headers);
|
|
735
|
+
return parsed ? await this.parseResponse(response) : response;
|
|
606
736
|
}
|
|
607
737
|
/**
|
|
608
738
|
* A generic method to make POST rest call
|
|
@@ -610,10 +740,12 @@ var _RestClient = class _RestClient {
|
|
|
610
740
|
* @param endpoint
|
|
611
741
|
* @param headers
|
|
612
742
|
* @param payload
|
|
613
|
-
* @
|
|
743
|
+
* @param parsed
|
|
744
|
+
* @returns {Promise<Response | any>}
|
|
614
745
|
*/
|
|
615
|
-
async post(endpoint, headers = {}, payload = null) {
|
|
616
|
-
|
|
746
|
+
async post(endpoint, headers = {}, payload = null, parsed = true) {
|
|
747
|
+
const response = await this.makeRequest(endpoint, "POST", headers, payload);
|
|
748
|
+
return parsed ? await this.parseResponse(response) : response;
|
|
617
749
|
}
|
|
618
750
|
/**
|
|
619
751
|
* A generic method to make PUT rest call
|
|
@@ -621,20 +753,24 @@ var _RestClient = class _RestClient {
|
|
|
621
753
|
* @param endpoint
|
|
622
754
|
* @param headers
|
|
623
755
|
* @param payload
|
|
624
|
-
* @
|
|
756
|
+
* @param parsed
|
|
757
|
+
* @returns {Promise<Response | any>}
|
|
625
758
|
*/
|
|
626
|
-
async put(endpoint, headers = {}, payload = null) {
|
|
627
|
-
|
|
759
|
+
async put(endpoint, headers = {}, payload = null, parsed = true) {
|
|
760
|
+
const response = await this.makeRequest(endpoint, "PUT", headers, payload);
|
|
761
|
+
return parsed ? await this.parseResponse(response) : response;
|
|
628
762
|
}
|
|
629
763
|
/**
|
|
630
764
|
* A generic method to make DELETE rest call
|
|
631
765
|
*
|
|
632
766
|
* @param endpoint
|
|
633
767
|
* @param headers
|
|
634
|
-
* @
|
|
768
|
+
* @param parsed
|
|
769
|
+
* @returns {Promise<Response | any>}
|
|
635
770
|
*/
|
|
636
|
-
async delete(endpoint, headers = {}) {
|
|
637
|
-
|
|
771
|
+
async delete(endpoint, headers = {}, parsed = true) {
|
|
772
|
+
const response = await this.makeRequest(endpoint, "DELETE", headers);
|
|
773
|
+
return parsed ? await this.parseResponse(response) : response;
|
|
638
774
|
}
|
|
639
775
|
/**
|
|
640
776
|
* A generic method to make rest call
|
|
@@ -644,6 +780,7 @@ var _RestClient = class _RestClient {
|
|
|
644
780
|
* @param headers
|
|
645
781
|
* @param payload
|
|
646
782
|
* @returns {Promise<any>}
|
|
783
|
+
* @deprecated Use makeRequest() and parseResponse() methods instead
|
|
647
784
|
*/
|
|
648
785
|
async apiCall(endpoint, method = "POST", headers = {}, payload = null) {
|
|
649
786
|
let options = {
|