@adobe-commerce/aio-toolkit 1.0.1 → 1.0.3
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 +90 -0
- package/README.md +208 -17
- package/dist/index.d.mts +61 -9
- package/dist/index.d.ts +61 -9
- package/dist/index.js +550 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +533 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -2
package/dist/index.mjs
CHANGED
|
@@ -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
|
|
@@ -485,6 +505,143 @@ __name(_FileRepository, "FileRepository");
|
|
|
485
505
|
var FileRepository = _FileRepository;
|
|
486
506
|
var file_repository_default = FileRepository;
|
|
487
507
|
|
|
508
|
+
// src/framework/publish-event/index.ts
|
|
509
|
+
import { Events } from "@adobe/aio-sdk";
|
|
510
|
+
import { CloudEvent } from "cloudevents";
|
|
511
|
+
import { v4 as uuidv4 } from "uuid";
|
|
512
|
+
|
|
513
|
+
// src/framework/custom-logger/index.ts
|
|
514
|
+
var _CustomLogger = class _CustomLogger {
|
|
515
|
+
/**
|
|
516
|
+
* @param logger - External logger instance (can be null)
|
|
517
|
+
*/
|
|
518
|
+
constructor(logger = null) {
|
|
519
|
+
this.logger = logger;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Log debug message if logger is available
|
|
523
|
+
* @param message - Debug message to log
|
|
524
|
+
*/
|
|
525
|
+
debug(message) {
|
|
526
|
+
if (this.logger && typeof this.logger.debug === "function") {
|
|
527
|
+
this.logger.debug(message);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Log info message if logger is available
|
|
532
|
+
* @param message - Info message to log
|
|
533
|
+
*/
|
|
534
|
+
info(message) {
|
|
535
|
+
if (this.logger && typeof this.logger.info === "function") {
|
|
536
|
+
this.logger.info(message);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Log error message if logger is available
|
|
541
|
+
* @param message - Error message to log
|
|
542
|
+
*/
|
|
543
|
+
error(message) {
|
|
544
|
+
if (this.logger && typeof this.logger.error === "function") {
|
|
545
|
+
this.logger.error(message);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Get the underlying logger instance
|
|
550
|
+
* @returns the logger instance or null
|
|
551
|
+
*/
|
|
552
|
+
getLogger() {
|
|
553
|
+
return this.logger;
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
__name(_CustomLogger, "CustomLogger");
|
|
557
|
+
var CustomLogger = _CustomLogger;
|
|
558
|
+
var custom_logger_default = CustomLogger;
|
|
559
|
+
|
|
560
|
+
// src/framework/publish-event/index.ts
|
|
561
|
+
var _PublishEvent = class _PublishEvent {
|
|
562
|
+
/**
|
|
563
|
+
* Creates a new PublishEvent instance
|
|
564
|
+
*
|
|
565
|
+
* @param imsOrgId - Adobe IMS Organization ID
|
|
566
|
+
* @param apiKey - Adobe API Key (Client ID)
|
|
567
|
+
* @param accessToken - Adobe Access Token
|
|
568
|
+
* @param logger - Optional logger instance
|
|
569
|
+
*/
|
|
570
|
+
constructor(imsOrgId, apiKey, accessToken, logger = null) {
|
|
571
|
+
if (!imsOrgId?.trim()) {
|
|
572
|
+
throw new Error("imsOrgId is required and cannot be empty");
|
|
573
|
+
}
|
|
574
|
+
if (!apiKey?.trim()) {
|
|
575
|
+
throw new Error("apiKey is required and cannot be empty");
|
|
576
|
+
}
|
|
577
|
+
if (!accessToken?.trim()) {
|
|
578
|
+
throw new Error("accessToken is required and cannot be empty");
|
|
579
|
+
}
|
|
580
|
+
this.imsOrgId = imsOrgId;
|
|
581
|
+
this.apiKey = apiKey;
|
|
582
|
+
this.accessToken = accessToken;
|
|
583
|
+
this.customLogger = new custom_logger_default(logger);
|
|
584
|
+
this.customLogger.debug("PublishEvent initialized with valid configuration");
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Publishes a CloudEvent to Adobe I/O Events
|
|
588
|
+
*
|
|
589
|
+
* @param providerId - The Adobe I/O Events provider ID
|
|
590
|
+
* @param eventCode - The event type identifier (e.g., 'commerce.order.created')
|
|
591
|
+
* @param payload - The event payload data
|
|
592
|
+
* @param subject - Optional subject for the event
|
|
593
|
+
* @returns Promise<PublishEventResult> - The publish result
|
|
594
|
+
*
|
|
595
|
+
* @throws Error when providerId or eventCode is invalid or publishing fails
|
|
596
|
+
*/
|
|
597
|
+
async execute(providerId, eventCode, payload, subject) {
|
|
598
|
+
try {
|
|
599
|
+
if (!providerId?.trim()) {
|
|
600
|
+
throw new Error("providerId is required and cannot be empty");
|
|
601
|
+
}
|
|
602
|
+
if (!eventCode?.trim()) {
|
|
603
|
+
throw new Error("eventCode is required and cannot be empty");
|
|
604
|
+
}
|
|
605
|
+
if (payload === null || payload === void 0) {
|
|
606
|
+
throw new Error("payload is required");
|
|
607
|
+
}
|
|
608
|
+
this.customLogger.info(`Publishing event to provider: ${providerId}`);
|
|
609
|
+
const eventId = uuidv4();
|
|
610
|
+
const cloudEvent = new CloudEvent({
|
|
611
|
+
id: eventId,
|
|
612
|
+
source: `urn:uuid:${providerId}`,
|
|
613
|
+
datacontenttype: "application/json",
|
|
614
|
+
type: eventCode,
|
|
615
|
+
data: payload,
|
|
616
|
+
...subject && { subject }
|
|
617
|
+
});
|
|
618
|
+
this.customLogger.debug(`Constructed CloudEvent with ID: ${eventId}`);
|
|
619
|
+
const eventsClient = await Events.init(this.imsOrgId, this.apiKey, this.accessToken);
|
|
620
|
+
this.customLogger.debug("Adobe I/O Events client initialized successfully");
|
|
621
|
+
await eventsClient.publishEvent(cloudEvent);
|
|
622
|
+
const publishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
623
|
+
this.customLogger.info(`Event published successfully with ID: ${eventId}`);
|
|
624
|
+
return {
|
|
625
|
+
eventId,
|
|
626
|
+
status: "published",
|
|
627
|
+
publishedAt
|
|
628
|
+
};
|
|
629
|
+
} catch (error) {
|
|
630
|
+
this.customLogger.error(`Failed to publish event: ${error.message}`);
|
|
631
|
+
return {
|
|
632
|
+
eventId: uuidv4(),
|
|
633
|
+
// Generate ID for tracking even failed events
|
|
634
|
+
status: "failed",
|
|
635
|
+
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
636
|
+
error: error.message
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
__name(_PublishEvent, "PublishEvent");
|
|
642
|
+
var PublishEvent = _PublishEvent;
|
|
643
|
+
var publish_event_default = PublishEvent;
|
|
644
|
+
|
|
488
645
|
// src/integration/bearer-token/index.ts
|
|
489
646
|
var _BearerToken = class _BearerToken {
|
|
490
647
|
/**
|
|
@@ -647,13 +804,32 @@ var _RestClient = class _RestClient {
|
|
|
647
804
|
headers
|
|
648
805
|
};
|
|
649
806
|
if (payload !== null) {
|
|
807
|
+
let body;
|
|
808
|
+
let contentType;
|
|
809
|
+
if (payload instanceof URLSearchParams) {
|
|
810
|
+
body = payload.toString();
|
|
811
|
+
contentType = headers["Content-Type"] || "application/x-www-form-urlencoded";
|
|
812
|
+
} else if (typeof FormData !== "undefined" && payload instanceof FormData) {
|
|
813
|
+
body = payload;
|
|
814
|
+
contentType = headers["Content-Type"];
|
|
815
|
+
} else if (typeof payload === "string") {
|
|
816
|
+
body = payload;
|
|
817
|
+
contentType = headers["Content-Type"] || "text/plain";
|
|
818
|
+
} else if (payload instanceof Buffer || payload instanceof ArrayBuffer || typeof Uint8Array !== "undefined" && payload instanceof Uint8Array) {
|
|
819
|
+
body = payload;
|
|
820
|
+
contentType = headers["Content-Type"] || "application/octet-stream";
|
|
821
|
+
} else {
|
|
822
|
+
body = JSON.stringify(payload);
|
|
823
|
+
contentType = headers["Content-Type"] || "application/json";
|
|
824
|
+
}
|
|
825
|
+
const requestHeaders = { ...headers };
|
|
826
|
+
if (contentType) {
|
|
827
|
+
requestHeaders["Content-Type"] = contentType;
|
|
828
|
+
}
|
|
650
829
|
options = {
|
|
651
830
|
...options,
|
|
652
|
-
body
|
|
653
|
-
headers:
|
|
654
|
-
...headers,
|
|
655
|
-
"Content-Type": "application/json"
|
|
656
|
-
}
|
|
831
|
+
body,
|
|
832
|
+
headers: requestHeaders
|
|
657
833
|
};
|
|
658
834
|
}
|
|
659
835
|
return await fetch(endpoint, options);
|
|
@@ -4625,7 +4801,7 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
|
|
|
4625
4801
|
* @return TokenResult | null
|
|
4626
4802
|
*/
|
|
4627
4803
|
async getCommerceToken() {
|
|
4628
|
-
const endpoint = this.
|
|
4804
|
+
const endpoint = this.createTokenEndpoint();
|
|
4629
4805
|
this.logger.debug(`Endpoint: ${endpoint}`);
|
|
4630
4806
|
try {
|
|
4631
4807
|
const restClient = new rest_client_default();
|
|
@@ -4671,6 +4847,19 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
|
|
|
4671
4847
|
return null;
|
|
4672
4848
|
}
|
|
4673
4849
|
}
|
|
4850
|
+
/**
|
|
4851
|
+
* Create the Adobe Commerce integration admin token endpoint.
|
|
4852
|
+
* Handles cases where baseUrl may or may not already include /rest.
|
|
4853
|
+
* @return string
|
|
4854
|
+
*/
|
|
4855
|
+
createTokenEndpoint() {
|
|
4856
|
+
const normalizedBaseUrl = this.baseUrl.replace(/\/+$/, "");
|
|
4857
|
+
if (normalizedBaseUrl.endsWith("/rest")) {
|
|
4858
|
+
return `${normalizedBaseUrl}/V1/integration/admin/token`;
|
|
4859
|
+
} else {
|
|
4860
|
+
return `${normalizedBaseUrl}/rest/V1/integration/admin/token`;
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4674
4863
|
/**
|
|
4675
4864
|
* @param endpoint
|
|
4676
4865
|
* @return string
|
|
@@ -4841,8 +5030,161 @@ __name(_Oauth1aConnection, "Oauth1aConnection");
|
|
|
4841
5030
|
var Oauth1aConnection = _Oauth1aConnection;
|
|
4842
5031
|
var oauth1a_connection_default = Oauth1aConnection;
|
|
4843
5032
|
|
|
5033
|
+
// src/commerce/adobe-commerce-client/ims-connection/generate-ims-token/index.ts
|
|
5034
|
+
import { State as State3 } from "@adobe/aio-sdk";
|
|
5035
|
+
var _GenerateImsToken = class _GenerateImsToken {
|
|
5036
|
+
/**
|
|
5037
|
+
* @param clientId
|
|
5038
|
+
* @param clientSecret
|
|
5039
|
+
* @param technicalAccountId
|
|
5040
|
+
* @param technicalAccountEmail
|
|
5041
|
+
* @param imsOrgId
|
|
5042
|
+
* @param scopes
|
|
5043
|
+
* @param logger
|
|
5044
|
+
*/
|
|
5045
|
+
constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null) {
|
|
5046
|
+
this.key = "adobe_ims_auth_token";
|
|
5047
|
+
this.tokenContext = "adobe-commerce-client";
|
|
5048
|
+
this.clientId = clientId;
|
|
5049
|
+
this.clientSecret = clientSecret;
|
|
5050
|
+
this.technicalAccountId = technicalAccountId;
|
|
5051
|
+
this.technicalAccountEmail = technicalAccountEmail;
|
|
5052
|
+
this.imsOrgId = imsOrgId;
|
|
5053
|
+
this.scopes = scopes;
|
|
5054
|
+
this.customLogger = new custom_logger_default(logger);
|
|
5055
|
+
}
|
|
5056
|
+
/**
|
|
5057
|
+
* @return string | null
|
|
5058
|
+
*/
|
|
5059
|
+
async execute() {
|
|
5060
|
+
try {
|
|
5061
|
+
this.customLogger.info("Starting IMS token generation/retrieval process");
|
|
5062
|
+
const currentValue = await this.getValue();
|
|
5063
|
+
if (currentValue !== null) {
|
|
5064
|
+
this.customLogger.info("Found cached IMS token, returning cached value");
|
|
5065
|
+
return currentValue;
|
|
5066
|
+
}
|
|
5067
|
+
this.customLogger.info("No cached token found, generating new IMS token");
|
|
5068
|
+
let result = {
|
|
5069
|
+
token: null,
|
|
5070
|
+
expire_in: 86399
|
|
5071
|
+
// Default fallback, will be overridden by actual token expiry
|
|
5072
|
+
};
|
|
5073
|
+
const response = await this.getImsToken();
|
|
5074
|
+
if (response !== null) {
|
|
5075
|
+
result = response;
|
|
5076
|
+
}
|
|
5077
|
+
if (result.token !== null) {
|
|
5078
|
+
this.customLogger.info(`Generated new IMS token, caching for ${result.expire_in} seconds`);
|
|
5079
|
+
await this.setValue(result);
|
|
5080
|
+
}
|
|
5081
|
+
return result.token;
|
|
5082
|
+
} catch (error) {
|
|
5083
|
+
this.customLogger.error(`Failed to execute IMS token generation: ${error.message}`);
|
|
5084
|
+
return null;
|
|
5085
|
+
}
|
|
5086
|
+
}
|
|
5087
|
+
/**
|
|
5088
|
+
* @return ImsTokenResult | null
|
|
5089
|
+
*/
|
|
5090
|
+
async getImsToken() {
|
|
5091
|
+
try {
|
|
5092
|
+
this.customLogger.debug(`Calling AdobeAuth.getToken with context: ${this.tokenContext}`);
|
|
5093
|
+
const token = await adobe_auth_default.getToken(
|
|
5094
|
+
this.clientId,
|
|
5095
|
+
this.clientSecret,
|
|
5096
|
+
this.technicalAccountId,
|
|
5097
|
+
this.technicalAccountEmail,
|
|
5098
|
+
this.imsOrgId,
|
|
5099
|
+
this.scopes,
|
|
5100
|
+
this.tokenContext
|
|
5101
|
+
);
|
|
5102
|
+
if (token !== null && token !== void 0) {
|
|
5103
|
+
this.customLogger.debug("Received token from AdobeAuth, parsing with BearerToken.info");
|
|
5104
|
+
const tokenInfo = bearer_token_default.info(token);
|
|
5105
|
+
if (!tokenInfo.isValid) {
|
|
5106
|
+
this.customLogger.error("Received invalid or expired token from IMS");
|
|
5107
|
+
return null;
|
|
5108
|
+
}
|
|
5109
|
+
const expireInSeconds = tokenInfo.timeUntilExpiry ? Math.floor(tokenInfo.timeUntilExpiry / 1e3) : 86399;
|
|
5110
|
+
this.customLogger.debug(`Token expires in ${expireInSeconds} seconds`);
|
|
5111
|
+
return {
|
|
5112
|
+
token,
|
|
5113
|
+
expire_in: expireInSeconds
|
|
5114
|
+
};
|
|
5115
|
+
}
|
|
5116
|
+
this.customLogger.error("Received null or undefined token from IMS");
|
|
5117
|
+
return null;
|
|
5118
|
+
} catch (error) {
|
|
5119
|
+
this.customLogger.error(`Failed to get IMS token: ${error.message}`);
|
|
5120
|
+
return null;
|
|
5121
|
+
}
|
|
5122
|
+
}
|
|
5123
|
+
/**
|
|
5124
|
+
* @param result
|
|
5125
|
+
* @return boolean
|
|
5126
|
+
*/
|
|
5127
|
+
async setValue(result) {
|
|
5128
|
+
try {
|
|
5129
|
+
const state = await this.getState();
|
|
5130
|
+
if (state === null) {
|
|
5131
|
+
this.customLogger.info("State API not available, skipping token caching");
|
|
5132
|
+
return true;
|
|
5133
|
+
}
|
|
5134
|
+
const ttlWithBuffer = Math.max(result.expire_in - 300, 60);
|
|
5135
|
+
this.customLogger.debug(
|
|
5136
|
+
`Caching IMS token with TTL: ${ttlWithBuffer} seconds (original: ${result.expire_in})`
|
|
5137
|
+
);
|
|
5138
|
+
await state.put(this.key, result.token, { ttl: ttlWithBuffer });
|
|
5139
|
+
return true;
|
|
5140
|
+
} catch (error) {
|
|
5141
|
+
this.customLogger.error(`Failed to cache IMS token: ${error.message}`);
|
|
5142
|
+
return true;
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
/**
|
|
5146
|
+
* @return string | null
|
|
5147
|
+
*/
|
|
5148
|
+
async getValue() {
|
|
5149
|
+
try {
|
|
5150
|
+
this.customLogger.debug("Checking for cached IMS token");
|
|
5151
|
+
const state = await this.getState();
|
|
5152
|
+
if (state === null) {
|
|
5153
|
+
this.customLogger.debug("State API not available, cannot retrieve cached token");
|
|
5154
|
+
return null;
|
|
5155
|
+
}
|
|
5156
|
+
const value = await state.get(this.key);
|
|
5157
|
+
if (value !== void 0 && value.value) {
|
|
5158
|
+
this.customLogger.debug("Found cached IMS token");
|
|
5159
|
+
return value.value;
|
|
5160
|
+
}
|
|
5161
|
+
this.customLogger.debug("No cached IMS token found");
|
|
5162
|
+
} catch (error) {
|
|
5163
|
+
this.customLogger.error(`Failed to retrieve cached IMS token: ${error.message}`);
|
|
5164
|
+
}
|
|
5165
|
+
return null;
|
|
5166
|
+
}
|
|
5167
|
+
/**
|
|
5168
|
+
* @return any
|
|
5169
|
+
*/
|
|
5170
|
+
async getState() {
|
|
5171
|
+
if (this.state === void 0) {
|
|
5172
|
+
try {
|
|
5173
|
+
this.customLogger.debug("Initializing State API for token caching");
|
|
5174
|
+
this.state = await State3.init();
|
|
5175
|
+
} catch (error) {
|
|
5176
|
+
this.customLogger.error(`Failed to initialize State API: ${error.message}`);
|
|
5177
|
+
this.state = null;
|
|
5178
|
+
}
|
|
5179
|
+
}
|
|
5180
|
+
return this.state;
|
|
5181
|
+
}
|
|
5182
|
+
};
|
|
5183
|
+
__name(_GenerateImsToken, "GenerateImsToken");
|
|
5184
|
+
var GenerateImsToken = _GenerateImsToken;
|
|
5185
|
+
var generate_ims_token_default = GenerateImsToken;
|
|
5186
|
+
|
|
4844
5187
|
// src/commerce/adobe-commerce-client/ims-connection/index.ts
|
|
4845
|
-
import { Core as Core10 } from "@adobe/aio-sdk";
|
|
4846
5188
|
var _ImsConnection = class _ImsConnection {
|
|
4847
5189
|
/**
|
|
4848
5190
|
* @param clientId
|
|
@@ -4852,38 +5194,35 @@ var _ImsConnection = class _ImsConnection {
|
|
|
4852
5194
|
* @param imsOrgId
|
|
4853
5195
|
* @param scopes
|
|
4854
5196
|
* @param logger
|
|
4855
|
-
* @param currentContext
|
|
4856
5197
|
*/
|
|
4857
|
-
constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null
|
|
5198
|
+
constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null) {
|
|
4858
5199
|
this.clientId = clientId;
|
|
4859
5200
|
this.clientSecret = clientSecret;
|
|
4860
5201
|
this.technicalAccountId = technicalAccountId;
|
|
4861
5202
|
this.technicalAccountEmail = technicalAccountEmail;
|
|
4862
5203
|
this.imsOrgId = imsOrgId;
|
|
4863
5204
|
this.scopes = scopes;
|
|
4864
|
-
this.
|
|
4865
|
-
if (logger === null) {
|
|
4866
|
-
logger = Core10.Logger(currentContext, {
|
|
4867
|
-
level: "debug"
|
|
4868
|
-
});
|
|
4869
|
-
}
|
|
4870
|
-
this.logger = logger;
|
|
5205
|
+
this.customLogger = new custom_logger_default(logger);
|
|
4871
5206
|
}
|
|
4872
5207
|
/**
|
|
4873
5208
|
* @param commerceGot
|
|
4874
5209
|
*/
|
|
4875
5210
|
async extend(commerceGot) {
|
|
4876
|
-
this.
|
|
4877
|
-
const
|
|
5211
|
+
this.customLogger.info("Using Commerce client with IMS authentication");
|
|
5212
|
+
const tokenGenerator = new generate_ims_token_default(
|
|
4878
5213
|
this.clientId,
|
|
4879
5214
|
this.clientSecret,
|
|
4880
5215
|
this.technicalAccountId,
|
|
4881
5216
|
this.technicalAccountEmail,
|
|
4882
5217
|
this.imsOrgId,
|
|
4883
5218
|
this.scopes,
|
|
4884
|
-
this.
|
|
5219
|
+
this.customLogger.getLogger()
|
|
4885
5220
|
);
|
|
4886
|
-
|
|
5221
|
+
const token = await tokenGenerator.execute();
|
|
5222
|
+
if (token === null) {
|
|
5223
|
+
throw new Error("Failed to generate or retrieve IMS token");
|
|
5224
|
+
}
|
|
5225
|
+
this.customLogger.info(`IMS token being extended to header: ${token.substring(0, 10)}...`);
|
|
4887
5226
|
return commerceGot.extend({
|
|
4888
5227
|
headers: {
|
|
4889
5228
|
Authorization: `Bearer ${token}`
|
|
@@ -4894,7 +5233,168 @@ var _ImsConnection = class _ImsConnection {
|
|
|
4894
5233
|
__name(_ImsConnection, "ImsConnection");
|
|
4895
5234
|
var ImsConnection = _ImsConnection;
|
|
4896
5235
|
var ims_connection_default = ImsConnection;
|
|
5236
|
+
|
|
5237
|
+
// src/experience/admin-ui-sdk/index.ts
|
|
5238
|
+
var _AdminUiSdk = class _AdminUiSdk {
|
|
5239
|
+
/**
|
|
5240
|
+
* Creates a new AdminUiSdk instance
|
|
5241
|
+
* @param extensionId - Unique identifier for the extension
|
|
5242
|
+
* @throws {Error} If extensionId is empty or invalid
|
|
5243
|
+
*/
|
|
5244
|
+
constructor(extensionId) {
|
|
5245
|
+
this.menuItems = [];
|
|
5246
|
+
if (!extensionId?.trim()) {
|
|
5247
|
+
throw new Error("Extension ID is required and cannot be empty");
|
|
5248
|
+
}
|
|
5249
|
+
const trimmedId = extensionId.trim();
|
|
5250
|
+
if (!this.isValidExtensionId(trimmedId)) {
|
|
5251
|
+
throw new Error(
|
|
5252
|
+
"Extension ID must be alphanumeric with underscores only (no spaces, hyphens, or special characters)"
|
|
5253
|
+
);
|
|
5254
|
+
}
|
|
5255
|
+
this.extensionId = trimmedId;
|
|
5256
|
+
}
|
|
5257
|
+
/**
|
|
5258
|
+
* Validates that an extension ID contains only alphanumeric characters and underscores
|
|
5259
|
+
* @param id - The extension ID to validate
|
|
5260
|
+
* @returns true if valid, false otherwise
|
|
5261
|
+
*/
|
|
5262
|
+
isValidExtensionId(id) {
|
|
5263
|
+
return /^[a-zA-Z0-9_]+$/.test(id);
|
|
5264
|
+
}
|
|
5265
|
+
/**
|
|
5266
|
+
* Validates that a menu ID is valid (can contain :: separator for namespacing)
|
|
5267
|
+
* @param id - The menu ID to validate
|
|
5268
|
+
* @returns true if valid, false otherwise
|
|
5269
|
+
*/
|
|
5270
|
+
isValidMenuId(id) {
|
|
5271
|
+
return /^[a-zA-Z0-9_:]+$/.test(id);
|
|
5272
|
+
}
|
|
5273
|
+
/**
|
|
5274
|
+
* Adds a menu item to the extension
|
|
5275
|
+
* @param id - Full identifier for the menu item (e.g., 'extensionId::menuItem')
|
|
5276
|
+
* @param title - Display title for the menu item
|
|
5277
|
+
* @param sortOrder - Sort order for menu positioning
|
|
5278
|
+
* @param parent - Parent menu identifier (optional, full ID like 'extensionId::parent')
|
|
5279
|
+
* @throws {Error} If parameters are invalid or ID already exists
|
|
5280
|
+
*/
|
|
5281
|
+
addMenuItem(id, title, sortOrder, parent) {
|
|
5282
|
+
if (!id?.trim()) {
|
|
5283
|
+
throw new Error("Menu item ID is required and cannot be empty");
|
|
5284
|
+
}
|
|
5285
|
+
if (!this.isValidMenuId(id.trim())) {
|
|
5286
|
+
throw new Error(
|
|
5287
|
+
"Menu item ID must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5288
|
+
);
|
|
5289
|
+
}
|
|
5290
|
+
if (!title?.trim()) {
|
|
5291
|
+
throw new Error("Menu item title is required and cannot be empty");
|
|
5292
|
+
}
|
|
5293
|
+
if (parent !== void 0 && !parent?.trim()) {
|
|
5294
|
+
throw new Error("Menu item parent cannot be empty if provided");
|
|
5295
|
+
}
|
|
5296
|
+
if (parent !== void 0 && !this.isValidMenuId(parent.trim())) {
|
|
5297
|
+
throw new Error(
|
|
5298
|
+
"Menu item parent must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5299
|
+
);
|
|
5300
|
+
}
|
|
5301
|
+
if (typeof sortOrder !== "number" || sortOrder < 0) {
|
|
5302
|
+
throw new Error("Menu item sortOrder must be a non-negative number");
|
|
5303
|
+
}
|
|
5304
|
+
const trimmedId = id.trim();
|
|
5305
|
+
if (this.menuItems.some((item) => item.id === trimmedId)) {
|
|
5306
|
+
throw new Error(`Menu item with ID '${trimmedId}' already exists`);
|
|
5307
|
+
}
|
|
5308
|
+
const menuItem = {
|
|
5309
|
+
id: trimmedId,
|
|
5310
|
+
title: title.trim(),
|
|
5311
|
+
sortOrder
|
|
5312
|
+
};
|
|
5313
|
+
if (parent?.trim()) {
|
|
5314
|
+
menuItem.parent = parent.trim();
|
|
5315
|
+
}
|
|
5316
|
+
this.menuItems.push(menuItem);
|
|
5317
|
+
}
|
|
5318
|
+
/**
|
|
5319
|
+
* Adds a menu section to the extension
|
|
5320
|
+
* @param id - Full identifier for the menu section (e.g., 'extensionId::section')
|
|
5321
|
+
* @param title - Display title for the menu section
|
|
5322
|
+
* @param sortOrder - Sort order for section positioning
|
|
5323
|
+
* @param parent - Parent menu identifier (optional, full ID like 'Magento_Backend::system')
|
|
5324
|
+
* @throws {Error} If parameters are invalid or ID already exists
|
|
5325
|
+
*/
|
|
5326
|
+
addMenuSection(id, title, sortOrder, parent) {
|
|
5327
|
+
if (!id?.trim()) {
|
|
5328
|
+
throw new Error("Menu section ID is required and cannot be empty");
|
|
5329
|
+
}
|
|
5330
|
+
if (!this.isValidMenuId(id.trim())) {
|
|
5331
|
+
throw new Error(
|
|
5332
|
+
"Menu section ID must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5333
|
+
);
|
|
5334
|
+
}
|
|
5335
|
+
if (!title?.trim()) {
|
|
5336
|
+
throw new Error("Menu section title is required and cannot be empty");
|
|
5337
|
+
}
|
|
5338
|
+
if (parent !== void 0 && !parent?.trim()) {
|
|
5339
|
+
throw new Error("Menu section parent cannot be empty if provided");
|
|
5340
|
+
}
|
|
5341
|
+
if (parent !== void 0 && !this.isValidMenuId(parent.trim())) {
|
|
5342
|
+
throw new Error(
|
|
5343
|
+
"Menu section parent must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5344
|
+
);
|
|
5345
|
+
}
|
|
5346
|
+
if (typeof sortOrder !== "number" || sortOrder < 0) {
|
|
5347
|
+
throw new Error("Menu section sortOrder must be a non-negative number");
|
|
5348
|
+
}
|
|
5349
|
+
const trimmedId = id.trim();
|
|
5350
|
+
if (this.menuItems.some((item) => item.id === trimmedId)) {
|
|
5351
|
+
throw new Error(`Menu item with ID '${trimmedId}' already exists`);
|
|
5352
|
+
}
|
|
5353
|
+
const menuSection = {
|
|
5354
|
+
id: trimmedId,
|
|
5355
|
+
title: title.trim(),
|
|
5356
|
+
sortOrder,
|
|
5357
|
+
isSection: true
|
|
5358
|
+
};
|
|
5359
|
+
if (parent?.trim()) {
|
|
5360
|
+
menuSection.parent = parent.trim();
|
|
5361
|
+
}
|
|
5362
|
+
this.menuItems.push(menuSection);
|
|
5363
|
+
}
|
|
5364
|
+
/**
|
|
5365
|
+
* Sets the page title for the extension
|
|
5366
|
+
* @param title - The page title
|
|
5367
|
+
* @throws {Error} If title is empty or invalid
|
|
5368
|
+
*/
|
|
5369
|
+
addPage(title) {
|
|
5370
|
+
if (!title?.trim()) {
|
|
5371
|
+
throw new Error("Page title is required and cannot be empty");
|
|
5372
|
+
}
|
|
5373
|
+
this.pageTitle = title.trim();
|
|
5374
|
+
}
|
|
5375
|
+
/**
|
|
5376
|
+
* Gets the complete registration object for the extension
|
|
5377
|
+
* @returns The registration object with optional menu items and page configuration
|
|
5378
|
+
*/
|
|
5379
|
+
getRegistration() {
|
|
5380
|
+
const registration = {};
|
|
5381
|
+
if (this.menuItems.length > 0) {
|
|
5382
|
+
registration.menuItems = [...this.menuItems];
|
|
5383
|
+
}
|
|
5384
|
+
if (this.pageTitle) {
|
|
5385
|
+
registration.page = {
|
|
5386
|
+
title: this.pageTitle
|
|
5387
|
+
};
|
|
5388
|
+
}
|
|
5389
|
+
return {
|
|
5390
|
+
registration
|
|
5391
|
+
};
|
|
5392
|
+
}
|
|
5393
|
+
};
|
|
5394
|
+
__name(_AdminUiSdk, "AdminUiSdk");
|
|
5395
|
+
var AdminUiSdk = _AdminUiSdk;
|
|
4897
5396
|
export {
|
|
5397
|
+
AdminUiSdk,
|
|
4898
5398
|
adobe_auth_default as AdobeAuth,
|
|
4899
5399
|
adobe_commerce_client_default as AdobeCommerceClient,
|
|
4900
5400
|
basic_auth_connection_default as BasicAuthConnection,
|
|
@@ -4918,6 +5418,7 @@ export {
|
|
|
4918
5418
|
openwhisk_action_default as OpenwhiskAction,
|
|
4919
5419
|
parameters_default as Parameters,
|
|
4920
5420
|
provider_default as ProviderManager,
|
|
5421
|
+
publish_event_default as PublishEvent,
|
|
4921
5422
|
registration_default as RegistrationManager,
|
|
4922
5423
|
rest_client_default as RestClient,
|
|
4923
5424
|
runtime_action_default as RuntimeAction,
|