@adobe/acc-js-sdk 1.1.62 → 1.2.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/.cursor/commands/opsx-apply.md +152 -0
- package/.cursor/commands/opsx-archive.md +157 -0
- package/.cursor/commands/opsx-explore.md +173 -0
- package/.cursor/commands/opsx-propose.md +106 -0
- package/.cursor/skills/openspec-apply-change/SKILL.md +156 -0
- package/.cursor/skills/openspec-archive-change/SKILL.md +114 -0
- package/.cursor/skills/openspec-explore/SKILL.md +288 -0
- package/.cursor/skills/openspec-propose/SKILL.md +110 -0
- package/.eslintrc.js +2 -2
- package/.github/prompts/opsx-apply.prompt.md +149 -0
- package/.github/prompts/opsx-archive.prompt.md +154 -0
- package/.github/prompts/opsx-explore.prompt.md +170 -0
- package/.github/prompts/opsx-propose.prompt.md +103 -0
- package/.github/skills/openspec-apply-change/SKILL.md +156 -0
- package/.github/skills/openspec-archive-change/SKILL.md +114 -0
- package/.github/skills/openspec-explore/SKILL.md +288 -0
- package/.github/skills/openspec-propose/SKILL.md +110 -0
- package/.github/workflows/codeql-analysis.yml +5 -4
- package/.github/workflows/npm-publish.yml +3 -3
- package/AGENTS.md +117 -0
- package/CLAUDE.md +2 -0
- package/MIGRATION.md +10 -0
- package/README.md +6 -2
- package/ai-docs/coding-rules.md +95 -0
- package/ai-docs/tech-stack.md +43 -0
- package/babel.config.js +5 -0
- package/docs/changeLog.html +28 -2
- package/docs/checkList.html +2 -2
- package/docs/quickstart.html +2 -1
- package/docs/release.html +1 -1
- package/openspec/config.yaml +20 -0
- package/package-lock.json +6055 -4036
- package/package.json +9 -7
- package/src/AGENTS.md +98 -0
- package/src/CLAUDE.md +2 -0
- package/src/application.js +637 -637
- package/src/cache.js +133 -133
- package/src/cacheRefresher.js +190 -190
- package/src/campaign.js +532 -532
- package/src/client.js +1539 -1537
- package/src/crypto.js +52 -52
- package/src/domUtil.js +346 -346
- package/src/entityAccessor.js +61 -61
- package/src/index.js +83 -83
- package/src/methodCache.js +69 -69
- package/src/optionCache.js +26 -26
- package/src/soap.js +321 -322
- package/src/testUtil.js +13 -13
- package/src/transport.js +70 -70
- package/src/util.js +147 -147
- package/src/web/bundler.js +5 -5
- package/src/xtkCaster.js +258 -258
- package/src/xtkEntityCache.js +34 -34
- package/src/xtkJob.js +185 -185
- package/test/AGENTS.md +37 -0
- package/test/CLAUDE.md +2 -0
- package/test/cacheRefresher.test.js +7 -0
- package/test/client.test.js +90 -78
- package/test/jest.config.js +6 -0
- package/test/observability.test.js +6 -1
- package/test/xtkJob.test.js +2 -2
package/src/xtkEntityCache.js
CHANGED
|
@@ -10,25 +10,25 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
10
10
|
governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
(function() {
|
|
13
|
-
"use strict";
|
|
13
|
+
"use strict";
|
|
14
14
|
|
|
15
|
-
const DomUtil = require('./domUtil.js').DomUtil;
|
|
16
|
-
const { Cache } = require('./cache.js');
|
|
15
|
+
const DomUtil = require('./domUtil.js').DomUtil;
|
|
16
|
+
const { Cache } = require('./cache.js');
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
/**********************************************************************************
|
|
19
|
+
/**********************************************************************************
|
|
20
20
|
*
|
|
21
21
|
* Caches Xtk Entities (schemas, etc...)
|
|
22
22
|
*
|
|
23
23
|
*********************************************************************************/
|
|
24
24
|
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
26
|
* @private
|
|
27
27
|
* @class
|
|
28
28
|
* @constructor
|
|
29
29
|
* @memberof Campaign
|
|
30
30
|
*/
|
|
31
|
-
class XtkEntityCache extends Cache {
|
|
31
|
+
class XtkEntityCache extends Cache {
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* A in-memory cache for xtk entities. Not intended to be used directly,
|
|
@@ -42,20 +42,20 @@ class XtkEntityCache extends Cache {
|
|
|
42
42
|
* @param {string} rootKey is an optional root key to use for the storage object
|
|
43
43
|
* @param {number} ttl is the TTL for objects in ms. Defaults to 5 mins
|
|
44
44
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
constructor(storage, rootKey, ttl) {
|
|
46
|
+
super(storage, rootKey, ttl, (entityType, entityFullName) => entityType + "|" + entityFullName, (item, serDeser) => {
|
|
47
|
+
if (serDeser) {
|
|
48
|
+
if (!item || !item.value) throw Error(`Cannot serialize falsy cached item`);
|
|
49
|
+
const value = Object.assign({}, item);
|
|
50
|
+
value.value = DomUtil.toXMLString(item.value);
|
|
51
|
+
return JSON.stringify(value);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const json = JSON.parse(item);
|
|
55
|
+
json.value = DomUtil.parse(json.value).documentElement;
|
|
56
|
+
return json;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
@@ -65,7 +65,7 @@ class XtkEntityCache extends Cache {
|
|
|
65
65
|
* @returns {*} the cached entity, or undefined if not found
|
|
66
66
|
*/
|
|
67
67
|
async get(entityType, entityFullName) {
|
|
68
|
-
|
|
68
|
+
return await super.get(entityType, entityFullName);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -75,22 +75,22 @@ class XtkEntityCache extends Cache {
|
|
|
75
75
|
* @param {*} entity is the entity
|
|
76
76
|
*/
|
|
77
77
|
async put(entityType, entityFullName, entity) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
78
|
+
await super.put(entityType, entityFullName, entity);
|
|
79
|
+
// For schemas, cache interfaces
|
|
80
|
+
if (entityType == "xtk:schema") {
|
|
81
|
+
const namespace = entity.getAttribute("namespace");
|
|
82
|
+
var interfaceElement = DomUtil.getFirstChildElement(entity, "interface");
|
|
83
|
+
while (interfaceElement) {
|
|
84
|
+
const name = `${namespace}:${interfaceElement.getAttribute("name")}`;
|
|
85
|
+
await super.put(entityType, name, interfaceElement);
|
|
86
|
+
interfaceElement = DomUtil.getNextSiblingElement(interfaceElement, "interface");
|
|
88
87
|
}
|
|
88
|
+
}
|
|
89
89
|
}
|
|
90
|
-
}
|
|
90
|
+
}
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
// Public exports
|
|
94
|
-
exports.XtkEntityCache = XtkEntityCache;
|
|
93
|
+
// Public exports
|
|
94
|
+
exports.XtkEntityCache = XtkEntityCache;
|
|
95
95
|
|
|
96
96
|
})();
|
package/src/xtkJob.js
CHANGED
|
@@ -10,13 +10,13 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
10
10
|
governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
(function() {
|
|
13
|
-
"use strict";
|
|
13
|
+
"use strict";
|
|
14
14
|
|
|
15
|
-
const { CampaignException } = require("./campaign.js");
|
|
16
|
-
const { DomUtil } = require("./domUtil.js");
|
|
17
|
-
const { XtkCaster } = require("./xtkCaster.js");
|
|
15
|
+
const { CampaignException } = require("./campaign.js");
|
|
16
|
+
const { DomUtil } = require("./domUtil.js");
|
|
17
|
+
const { XtkCaster } = require("./xtkCaster.js");
|
|
18
18
|
|
|
19
|
-
/**
|
|
19
|
+
/**
|
|
20
20
|
* @namespace Campaign
|
|
21
21
|
*
|
|
22
22
|
* @typedef {DOMElement} SoapMethodDefinition
|
|
@@ -25,7 +25,7 @@ const { XtkCaster } = require("./xtkCaster.js");
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
29
|
* The complete Triforce, or one or more components of the Triforce.
|
|
30
30
|
* @typedef {Object} XtkSoapCallSpec
|
|
31
31
|
* @property {string} method - the Soap method name (without any schema information)
|
|
@@ -36,7 +36,7 @@ const { XtkCaster } = require("./xtkCaster.js");
|
|
|
36
36
|
* @memberOf Campaign
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
/**
|
|
39
|
+
/**
|
|
40
40
|
* @typedef {Object} XtkJobLog
|
|
41
41
|
* @property {number} id - the job log id, which can be used for subsequent calls to getStatus
|
|
42
42
|
* @property {number} iRc - the job return code (0 = ok)
|
|
@@ -49,7 +49,7 @@ const { XtkCaster } = require("./xtkCaster.js");
|
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
/**
|
|
52
|
+
/**
|
|
53
53
|
* @typedef {Object} XtkJobStatus
|
|
54
54
|
* @property {number} status - the job status code, as defined in the xtk:job:jobStatus enumeration
|
|
55
55
|
* @property {XtkJobLog[]} logs - the job log messages
|
|
@@ -57,19 +57,19 @@ const { XtkCaster } = require("./xtkCaster.js");
|
|
|
57
57
|
* @memberOf Campaign
|
|
58
58
|
*/
|
|
59
59
|
|
|
60
|
-
/**********************************************************************************
|
|
60
|
+
/**********************************************************************************
|
|
61
61
|
*
|
|
62
62
|
* Job Interface
|
|
63
63
|
* Wraps the xtk:jobInterface interface into convenient JavaScript class
|
|
64
64
|
*
|
|
65
65
|
*********************************************************************************/
|
|
66
|
-
/**
|
|
66
|
+
/**
|
|
67
67
|
* @private
|
|
68
68
|
* @class
|
|
69
69
|
* @constructor
|
|
70
70
|
* @memberof Campaign
|
|
71
71
|
*/
|
|
72
|
-
class XtkJobInterface {
|
|
72
|
+
class XtkJobInterface {
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Create a job interface from a client and a SOAP call definition. This method is not meant to be called directly,
|
|
@@ -78,22 +78,22 @@ class XtkJobInterface {
|
|
|
78
78
|
* @param {Campaign.XtkSoapCallSpec} soapCallSpec the definition of the SOAP call
|
|
79
79
|
*/
|
|
80
80
|
constructor(client, soapCallSpec) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
this._reset();
|
|
82
|
+
this._client = client;
|
|
83
|
+
this._soapCall = soapCallSpec;
|
|
84
|
+
this._maxLogCount = 100; // default fetch size
|
|
85
|
+
this.jobId = soapCallSpec ? soapCallSpec.jobId : undefined;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
// Reset state before executing or submitting a job
|
|
89
89
|
_reset() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
this.jobId = undefined;
|
|
91
|
+
this.status = undefined;
|
|
92
|
+
this.result = undefined;
|
|
93
|
+
this.lastLogId = 0;
|
|
94
|
+
this.iRc = 0;
|
|
95
|
+
this.lastErrorCode = undefined;
|
|
96
|
+
this.firstErrorCode = undefined;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
|
@@ -103,21 +103,21 @@ class XtkJobInterface {
|
|
|
103
103
|
* @returns {string} a job id
|
|
104
104
|
*/
|
|
105
105
|
async execute() {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
106
|
+
this._reset();
|
|
107
|
+
const methodName = this._soapCall.method;
|
|
108
|
+
const entitySchemaId = this._soapCall.xtkschema ? this._soapCall.xtkschema : (this._soapCall.object ? this._soapCall.object.xtkschema : undefined);
|
|
109
|
+
if (!entitySchemaId)
|
|
110
|
+
throw CampaignException.SOAP_UNKNOWN_METHOD(entitySchemaId, methodName, `No schema was provided in soap call or object`);
|
|
111
|
+
const callContext = {
|
|
112
|
+
client: this._client,
|
|
113
|
+
object: this._soapCall.object,
|
|
114
|
+
schemaId: 'xtk:jobInterface',
|
|
115
|
+
entitySchemaId: entitySchemaId,
|
|
116
|
+
headers: this._client._connectionParameters._options.extraHttpHeaders
|
|
117
|
+
};
|
|
118
|
+
var jobId = await callContext.client._callMethod("Execute", callContext, [ methodName ]);
|
|
119
|
+
this.jobId = jobId;
|
|
120
|
+
return jobId;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
@@ -126,22 +126,22 @@ class XtkJobInterface {
|
|
|
126
126
|
* Static methods are not supported
|
|
127
127
|
* @returns {string} a job id
|
|
128
128
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
129
|
+
async submit() {
|
|
130
|
+
this._reset();
|
|
131
|
+
const methodName = this._soapCall.method;
|
|
132
|
+
const entitySchemaId = this._soapCall.xtkschema ? this._soapCall.xtkschema : (this._soapCall.object ? this._soapCall.object.xtkschema : undefined);
|
|
133
|
+
if (!entitySchemaId)
|
|
134
|
+
throw CampaignException.SOAP_UNKNOWN_METHOD(entitySchemaId, methodName, `No schema was provided in soap call or object`);
|
|
135
|
+
const callContext = {
|
|
136
|
+
client: this._client,
|
|
137
|
+
object: this._soapCall.object,
|
|
138
|
+
schemaId: 'xtk:jobInterface',
|
|
139
|
+
entitySchemaId: entitySchemaId,
|
|
140
|
+
headers: this._client._connectionParameters._options.extraHttpHeaders
|
|
141
|
+
};
|
|
142
|
+
var jobId = await callContext.client._callMethod("Submit", callContext, [ this._soapCall.method ]);
|
|
143
|
+
this.jobId = jobId;
|
|
144
|
+
return jobId;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
/**
|
|
@@ -150,58 +150,58 @@ class XtkJobInterface {
|
|
|
150
150
|
* Static methods are not supported
|
|
151
151
|
* @returns {string} a job id
|
|
152
152
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
153
|
+
async submitSoapCall() {
|
|
154
|
+
this._reset();
|
|
155
|
+
const entitySchemaId = this._soapCall.xtkschema ? this._soapCall.xtkschema : (this._soapCall.object ? this._soapCall.object.xtkschema : undefined);
|
|
156
|
+
const callContext = {
|
|
157
|
+
client: this._client,
|
|
158
|
+
object: this._soapCall.object,
|
|
159
|
+
schemaId: 'xtk:jobInterface',
|
|
160
|
+
entitySchemaId: entitySchemaId,
|
|
161
|
+
headers: this._client._connectionParameters._options.extraHttpHeaders
|
|
162
|
+
};
|
|
163
|
+
const methodName = this._soapCall.method;
|
|
164
|
+
var schema = await this._client.getSchema(entitySchemaId, "xml", true);
|
|
165
|
+
if (!schema)
|
|
166
|
+
throw CampaignException.SOAP_UNKNOWN_METHOD(entitySchemaId, methodName, `Schema '${entitySchemaId}' not found`);
|
|
167
|
+
var method = await this._client._methodCache.get(entitySchemaId, methodName);
|
|
168
|
+
if (!method)
|
|
169
|
+
throw CampaignException.SOAP_UNKNOWN_METHOD(entitySchemaId, methodName, `Method '${methodName}' of schema '${entitySchemaId}' not found`);
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
const isStatic = DomUtil.getAttributeAsBoolean(method, "static");
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
173
|
+
var jobId = null;
|
|
174
|
+
if ( !isStatic)
|
|
175
|
+
jobId = await callContext.client._callMethod("SubmitSoapCall", callContext, [ {
|
|
176
|
+
name: this._soapCall.method,
|
|
177
|
+
service: this._soapCall.xtkschema,
|
|
178
|
+
param: [
|
|
179
|
+
{ name:"this", type:"DOMDocument", value: this._soapCall.object },
|
|
180
|
+
{ name:"bStart", type:"boolean", value:"false" },
|
|
181
|
+
]
|
|
182
|
+
} ]);
|
|
183
|
+
else {
|
|
184
|
+
// for non-persistant job, override object to intialize job properties
|
|
185
|
+
callContext.object = {
|
|
186
|
+
doNotPersist: "true",
|
|
187
|
+
xtkschema: this._soapCall.xtkschema,
|
|
188
|
+
id: this._soapCall.jobId,
|
|
189
|
+
properties: {
|
|
190
|
+
warning: false,
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
// SubmitSoapCall now supports static method
|
|
194
|
+
// no need parameter type as it's already present in API definition
|
|
195
|
+
jobId = await callContext.client._callMethod("SubmitSoapCall", callContext,
|
|
196
|
+
{
|
|
197
|
+
name: this._soapCall.method,
|
|
198
|
+
service: this._soapCall.xtkschema,
|
|
199
|
+
param : this._soapCall.args
|
|
200
|
+
},
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
this.jobId = jobId;
|
|
204
|
+
return jobId;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
/**
|
|
@@ -213,32 +213,32 @@ class XtkJobInterface {
|
|
|
213
213
|
* @returns {Campaign.XtkJobStatus} an object containing the job status, all logs fetched so for, and job properties
|
|
214
214
|
*/
|
|
215
215
|
async getStatus(lastLogId, maxLogCount) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
216
|
+
if (lastLogId === undefined) lastLogId = this.lastLogId;
|
|
217
|
+
if (maxLogCount === null || maxLogCount === undefined) maxLogCount = this._maxLogCount;
|
|
218
|
+
var status = await this._client.NLWS.xtkJob.getStatus(this.jobId, lastLogId, maxLogCount);
|
|
219
|
+
if (this._client._representation === "xml") {
|
|
220
|
+
status[1] = this._client._toRepresentation(status[1], "SimpleJson");
|
|
221
|
+
status[2] = this._client._toRepresentation(status[2], "SimpleJson");
|
|
222
|
+
}
|
|
223
|
+
status = this._makeJobStatus(status);
|
|
224
|
+
this._updateStatus(status);
|
|
225
|
+
return status;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// Aggregate new status with previously fetched status
|
|
229
229
|
_updateStatus(status) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
230
|
+
for (var i=0; i<status.logs.length; i++) {
|
|
231
|
+
if (status.logs[i].id > this.lastLogId)
|
|
232
|
+
this.lastLogId = status.logs[i].id;
|
|
233
|
+
}
|
|
234
|
+
if (this.status === undefined) {
|
|
235
|
+
this.status = status;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
const oldLogs = this.status.logs;
|
|
239
|
+
this.status = status;
|
|
240
|
+
this.status.logs = oldLogs.concat(this.status.logs);
|
|
241
|
+
}
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
/**
|
|
@@ -246,9 +246,9 @@ class XtkJobInterface {
|
|
|
246
246
|
* @returns {number} the current job progress as a percentage value
|
|
247
247
|
*/
|
|
248
248
|
getProgress() {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
if (!this.status || !this.status.properties || !this.status.properties.progress) return 0;
|
|
250
|
+
if (!this.status.properties.progress.max) return 0;
|
|
251
|
+
return this.status.properties.progress.current / this.status.properties.progress.max;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
/**
|
|
@@ -257,104 +257,104 @@ class XtkJobInterface {
|
|
|
257
257
|
* @returns {*} the job result
|
|
258
258
|
*/
|
|
259
259
|
async getResult() {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
260
|
+
var result = await this._client.NLWS.xtkJob.getResult(this.jobId);
|
|
261
|
+
result = this._makeJobResult(result);
|
|
262
|
+
this.result = result;
|
|
263
|
+
return result;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
// Convert the job result into a typed object
|
|
267
267
|
_makeJobResult(rawResult) {
|
|
268
|
-
|
|
268
|
+
return rawResult;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
// Convert job logs into a type object
|
|
272
272
|
_makeLogs(rawLogs) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
rawLog.id = XtkCaster.asLong(rawLog.id);
|
|
287
|
-
rawLog.iRc = XtkCaster.asLong(rawLog.iRc);
|
|
288
|
-
rawLog.logDate = XtkCaster.asDatetime(rawLog.logDate);
|
|
289
|
-
rawLog.logType = XtkCaster.asLong(rawLog.logType);
|
|
290
|
-
rawLog.message = message;
|
|
291
|
-
rawLog.object = XtkCaster.asString(rawLog.object);
|
|
292
|
-
rawLog.errorCode = errorCode;
|
|
293
|
-
logs.push(rawLog);
|
|
294
|
-
|
|
295
|
-
if (errorCode)
|
|
296
|
-
this.lastErrorCode = errorCode;
|
|
297
|
-
if (errorCode && !this.firstErrorCode)
|
|
298
|
-
this.firstErrorCode = errorCode;
|
|
299
|
-
if (rawLog.iRc != 0)
|
|
300
|
-
this.iRc = rawLog.iRc;
|
|
273
|
+
const logs = [];
|
|
274
|
+
rawLogs = rawLogs || {};
|
|
275
|
+
rawLogs = XtkCaster.asArray(rawLogs.log);
|
|
276
|
+
for (var i=0; i<rawLogs.length; i++) {
|
|
277
|
+
const rawLog = rawLogs[i];
|
|
278
|
+
var message = XtkCaster.asString(rawLog.message);
|
|
279
|
+
const match = message.match(/(\w{3}-\d{6})(.*)/);
|
|
280
|
+
var errorCode = undefined;
|
|
281
|
+
if (match && match.length >= 2) {
|
|
282
|
+
errorCode = match[1];
|
|
283
|
+
message = match[2] || "";
|
|
284
|
+
message = message.trim();
|
|
301
285
|
}
|
|
302
|
-
|
|
286
|
+
rawLog.id = XtkCaster.asLong(rawLog.id);
|
|
287
|
+
rawLog.iRc = XtkCaster.asLong(rawLog.iRc);
|
|
288
|
+
rawLog.logDate = XtkCaster.asDatetime(rawLog.logDate);
|
|
289
|
+
rawLog.logType = XtkCaster.asLong(rawLog.logType);
|
|
290
|
+
rawLog.message = message;
|
|
291
|
+
rawLog.object = XtkCaster.asString(rawLog.object);
|
|
292
|
+
rawLog.errorCode = errorCode;
|
|
293
|
+
logs.push(rawLog);
|
|
294
|
+
|
|
295
|
+
if (errorCode)
|
|
296
|
+
this.lastErrorCode = errorCode;
|
|
297
|
+
if (errorCode && !this.firstErrorCode)
|
|
298
|
+
this.firstErrorCode = errorCode;
|
|
299
|
+
if (rawLog.iRc != 0)
|
|
300
|
+
this.iRc = rawLog.iRc;
|
|
301
|
+
}
|
|
302
|
+
return logs;
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
// Convert job properties into a typed object
|
|
306
306
|
_makeProperties(rawProperties) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
307
|
+
rawProperties = rawProperties || {};
|
|
308
|
+
rawProperties.warning = XtkCaster.asBoolean(rawProperties.warning);
|
|
309
|
+
if (!rawProperties.progress) rawProperties.progress = {};
|
|
310
|
+
rawProperties.progress.current = XtkCaster.asLong(rawProperties.progress.current);
|
|
311
|
+
rawProperties.progress.max = XtkCaster.asLong(rawProperties.progress.max);
|
|
312
|
+
return rawProperties;
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
// Parse the result of GetStatus API. The result is an array of 3 object. The first is the status code,
|
|
316
316
|
// followed by the the logs, and finally the properties
|
|
317
317
|
_makeJobStatus(rawStatus) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
318
|
+
if (!rawStatus) rawStatus = [];
|
|
319
|
+
return {
|
|
320
|
+
status: XtkCaster.asLong(rawStatus[0]),
|
|
321
|
+
logs: this._makeLogs(rawStatus[1]),
|
|
322
|
+
properties: this._makeProperties(rawStatus[2])
|
|
323
|
+
};
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
/**
|
|
327
327
|
* Cancel a preciously submitted job
|
|
328
328
|
*/
|
|
329
|
-
|
|
330
|
-
|
|
329
|
+
async cancel() {
|
|
330
|
+
await this._client.NLWS.xtkJob.cancel(this.jobId);
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
/**
|
|
334
334
|
* Pause a preciously submitted job
|
|
335
335
|
*/
|
|
336
336
|
async pause() {
|
|
337
|
-
|
|
337
|
+
await this._client.NLWS.xtkJob.pause(this.jobId);
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
/**
|
|
341
341
|
* Waits until a job is actually cancelled
|
|
342
342
|
* @param {number} timeoutSeconds in seconds
|
|
343
343
|
*/
|
|
344
|
-
|
|
345
|
-
|
|
344
|
+
async waitJobCancelled(timeoutSeconds) {
|
|
345
|
+
await this._client.NLWS.xtkJob.waitJobCancelled(this.jobId, timeoutSeconds);
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
/**
|
|
349
349
|
* Queries if warnings or errors have been generated for this job
|
|
350
350
|
* @return {boolean} Returns 'true' if there has been at least one warning or error message
|
|
351
351
|
*/
|
|
352
|
-
|
|
353
|
-
|
|
352
|
+
async hasWarning() {
|
|
353
|
+
return XtkCaster.asBoolean(await this._client.NLWS.xtkJob.hasWarning(this.jobId));
|
|
354
354
|
}
|
|
355
|
-
}
|
|
355
|
+
}
|
|
356
356
|
|
|
357
|
-
// Public exports
|
|
358
|
-
exports.XtkJobInterface = XtkJobInterface;
|
|
357
|
+
// Public exports
|
|
358
|
+
exports.XtkJobInterface = XtkJobInterface;
|
|
359
359
|
|
|
360
360
|
})();
|
package/test/AGENTS.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
last_compiled_date: 2026-04-04
|
|
3
|
+
version: 1.0
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# test/AGENTS.md
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
- Unit tests for all `src/` modules with 100% coverage enforcement (branches, lines, statements)
|
|
11
|
+
- Transport-level mocking via `mock.js` — no real HTTP calls
|
|
12
|
+
|
|
13
|
+
## Key Files
|
|
14
|
+
|
|
15
|
+
- `mock.js` (shared) — `Mock.makeClient()`, `Mock.withMockConsole()`, and pre-built SOAP response constants (`LOGON_RESPONSE`, `LOGOFF_RESPONSE`, `R_TEST`, etc.)
|
|
16
|
+
- `jest.config.js` (config) — Coverage thresholds, Babel transform, `transformIgnorePatterns` for ESM packages
|
|
17
|
+
- `client.test.js` (largest) — 5000+ lines covering NLWS proxy, SOAP dispatch, session management
|
|
18
|
+
|
|
19
|
+
## Patterns
|
|
20
|
+
|
|
21
|
+
### Adding a New Test File
|
|
22
|
+
|
|
23
|
+
1. Create `test/<module>.test.js` mirroring `src/<module>.js`
|
|
24
|
+
2. Import the module under test and `Mock` from `./mock.js`:
|
|
25
|
+
```js
|
|
26
|
+
const sdk = require('../src/index.js');
|
|
27
|
+
const Mock = require('./mock.js').Mock;
|
|
28
|
+
```
|
|
29
|
+
3. Create client: `const client = await Mock.makeClient();`
|
|
30
|
+
4. Mock transport responses: `client._transport.mockReturnValueOnce(Promise.resolve(xmlString));`
|
|
31
|
+
5. Run: `npm run unit-tests`
|
|
32
|
+
6. Coverage must remain at 100% — add tests for every branch
|
|
33
|
+
|
|
34
|
+
## Related
|
|
35
|
+
|
|
36
|
+
- `src/` — source modules under test
|
|
37
|
+
- `mock.js` — shared mock utilities and SOAP response fixtures
|