@adobe/acc-js-sdk 1.1.61 → 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 +34 -0
- package/docs/checkList.html +2 -2
- package/docs/connectionParameters.html +5 -0
- package/docs/quickstart.html +2 -1
- package/docs/release.html +1 -1
- package/openspec/config.yaml +20 -0
- package/package-lock.json +7437 -3924
- 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 -1532
- 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 +123 -81
- package/test/jest.config.js +6 -0
- package/test/observability.test.js +6 -1
- package/test/xtkJob.test.js +2 -2
package/src/cache.js
CHANGED
|
@@ -10,37 +10,37 @@ 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 { Util } = require("./util.js");
|
|
15
|
+
const { Util } = require("./util.js");
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
/**********************************************************************************
|
|
18
|
+
/**********************************************************************************
|
|
19
19
|
*
|
|
20
20
|
* Cache utilities
|
|
21
21
|
*
|
|
22
22
|
*********************************************************************************/
|
|
23
23
|
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
25
|
* @namespace Utils
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
/**********************************************************************************
|
|
29
|
+
/**********************************************************************************
|
|
30
30
|
*
|
|
31
31
|
* A simple cache for XtkEntities, options, etc.
|
|
32
32
|
*
|
|
33
33
|
*********************************************************************************/
|
|
34
34
|
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
36
|
* @private
|
|
37
37
|
* @class
|
|
38
38
|
* @constructor
|
|
39
39
|
* @memberof Utils
|
|
40
40
|
*/
|
|
41
|
-
class SafeStorage {
|
|
41
|
+
class SafeStorage {
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
/**
|
|
44
44
|
* A wrapper to the Storage interface (LocalStorage, etc.) which is "safe", i.e.
|
|
45
45
|
*
|
|
46
46
|
* - it will never throw / support local stroage to be undefined or not accessible
|
|
@@ -56,87 +56,87 @@ class SafeStorage {
|
|
|
56
56
|
* @param {function} serDeser serializarion & deserialization function. First parameter is the object or value to serialize
|
|
57
57
|
* or deserialize, and second parameter is true for serialization or false for deserialization
|
|
58
58
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
59
|
+
constructor(delegate, rootKey, serDeser) {
|
|
60
|
+
if (!serDeser)
|
|
61
|
+
serDeser = (item, serDeser) => {
|
|
62
|
+
if (serDeser) {
|
|
63
|
+
if (!item) throw Error(`Cannot serialize falsy cached item`);
|
|
64
|
+
if (typeof item !== "object") throw Error(`Cannot serialize non-object`);
|
|
65
|
+
return JSON.stringify(item);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
if (!item) throw Error(`Cannot deserialize falsy cached item`);
|
|
69
|
+
return JSON.parse(item);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
this._delegate = delegate;
|
|
73
|
+
this._rootKey = rootKey ? `${rootKey}$` : "";
|
|
74
|
+
this._serDeser = serDeser;
|
|
75
|
+
}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
/**
|
|
78
78
|
* Get an item from storage
|
|
79
79
|
* @param {string} key the item key (relative to the root key)
|
|
80
80
|
* @returns {Utils.CachedObject} the cached object, or undefined if not found.
|
|
81
81
|
* The storage serDeser fucntion will be used to deserialize the cached value
|
|
82
82
|
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
async getItem(key) {
|
|
84
|
+
if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
|
|
85
|
+
return;
|
|
86
|
+
const itemKey = `${this._rootKey}${key}`;
|
|
87
|
+
const raw = await Util.asPromise(this._delegate.getItem(itemKey));
|
|
88
|
+
if (!raw)
|
|
89
|
+
return undefined;
|
|
90
|
+
try {
|
|
91
|
+
return this._serDeser(raw, false);
|
|
92
|
+
} catch(ex) {
|
|
93
|
+
this.removeItem(key);
|
|
94
|
+
}
|
|
94
95
|
}
|
|
95
|
-
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
/**
|
|
98
98
|
* Put an item into storage
|
|
99
99
|
* @param {string} key the item key (relative to the root key)
|
|
100
100
|
* @param {Utils.CachedObject} json the object to cache
|
|
101
101
|
* The storage serDeser fucntion will be used to serialize the cached value
|
|
102
102
|
*/
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
async setItem(key, json) {
|
|
104
|
+
if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
|
|
105
|
+
return;
|
|
106
|
+
try {
|
|
107
107
|
//if (json && typeof json === "object") {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
const raw = this._serDeser(json, true);
|
|
109
|
+
await Util.asPromise(this._delegate.setItem(`${this._rootKey}${key}`, raw));
|
|
110
|
+
return;
|
|
111
|
+
} catch(ex) { /* Ignore errors in safe class */
|
|
112
|
+
await this.removeItem(key);
|
|
113
|
+
}
|
|
113
114
|
}
|
|
114
|
-
}
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
/**
|
|
117
117
|
* Removes an item from the storage
|
|
118
118
|
* @param {string} key the item key (relative to the root key)
|
|
119
119
|
*/
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+
async removeItem(key) {
|
|
121
|
+
if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
|
|
122
|
+
return;
|
|
123
|
+
try {
|
|
124
|
+
await this._delegate.removeItem(`${this._rootKey}${key}`);
|
|
125
|
+
} catch(ex) { /* Ignore errors in safe class */
|
|
126
|
+
}
|
|
126
127
|
}
|
|
127
|
-
}
|
|
128
128
|
|
|
129
|
-
}
|
|
129
|
+
}
|
|
130
130
|
|
|
131
|
-
/**
|
|
131
|
+
/**
|
|
132
132
|
* @private
|
|
133
133
|
* @class
|
|
134
134
|
* @constructor
|
|
135
135
|
* @memberof Utils
|
|
136
136
|
*/
|
|
137
|
-
class CachedObject {
|
|
137
|
+
class CachedObject {
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
/**
|
|
140
140
|
* An object in the cache, i.e. a wrapped to a cached value and additional metadata to manage the cache.
|
|
141
141
|
* Do not create such objects directly, they are 100% managed by the Cache object
|
|
142
142
|
*
|
|
@@ -144,22 +144,22 @@ class CachedObject {
|
|
|
144
144
|
* @param {number} cachedAt the timestamp at which the value was cached
|
|
145
145
|
* @param {number} expiresAt the timestamp at which the cached value expires
|
|
146
146
|
*/
|
|
147
|
-
|
|
147
|
+
constructor(value, cachedAt, expiresAt) {
|
|
148
148
|
this.value = value;
|
|
149
149
|
this.cachedAt = cachedAt;
|
|
150
150
|
this.expiresAt = expiresAt;
|
|
151
|
+
}
|
|
151
152
|
}
|
|
152
|
-
}
|
|
153
153
|
|
|
154
|
-
/**
|
|
154
|
+
/**
|
|
155
155
|
* @private
|
|
156
156
|
* @class
|
|
157
157
|
* @constructor
|
|
158
158
|
* @memberof Utils
|
|
159
159
|
*/
|
|
160
|
-
class Cache {
|
|
160
|
+
class Cache {
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
/**
|
|
163
163
|
* A general purpose in-memory cache with TTL. In addition to caching in memory, the cache has the ability to delegate the caching
|
|
164
164
|
* to a persistent cache, such as the browser localStorage. The interface is 100% synchronous.
|
|
165
165
|
*
|
|
@@ -174,7 +174,7 @@ class Cache {
|
|
|
174
174
|
* @param {function} serDeser serializarion & deserialization function. First parameter is the object or value to serialize
|
|
175
175
|
* or deserialize, and second parameter is true for serialization or false for deserialization
|
|
176
176
|
*/
|
|
177
|
-
|
|
177
|
+
constructor(storage, rootKey, ttl, makeKeyFn, serDeser) {
|
|
178
178
|
this._storage = new SafeStorage(storage, rootKey, serDeser);
|
|
179
179
|
this._ttl = ttl || 1000*300;
|
|
180
180
|
this._makeKeyFn = makeKeyFn || ((x) => x);
|
|
@@ -196,86 +196,86 @@ class Cache {
|
|
|
196
196
|
loads: 0,
|
|
197
197
|
saves: 0,
|
|
198
198
|
};
|
|
199
|
-
|
|
199
|
+
}
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
// Load timestamp at which the cache was last cleared
|
|
202
|
+
async _loadLastCleared() {
|
|
203
|
+
const json = await this._storage.getItem("lastCleared");
|
|
204
|
+
return json ? json.timestamp : undefined;
|
|
205
|
+
}
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
207
|
+
async _saveLastCleared() {
|
|
208
|
+
const now = Date.now();
|
|
209
|
+
this._lastCleared = now;
|
|
210
|
+
await this._storage.setItem("lastCleared", { timestamp: now});
|
|
211
|
+
}
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
213
|
+
// Load from local storage
|
|
214
|
+
async _load(key) {
|
|
215
|
+
this._stats.loads = this._stats.loads + 1;
|
|
216
|
+
// A null value here indicates that we have not yet loaded the
|
|
217
|
+
// timestamp at which the cache was cleared last
|
|
218
|
+
if (this._lastCleared === null)
|
|
219
|
+
this._lastCleared = await this._loadLastCleared();
|
|
220
|
+
const json = await this._storage.getItem(key);
|
|
221
|
+
if (!json || !json.cachedAt || json.cachedAt <= this._lastCleared) {
|
|
222
|
+
await this._storage.removeItem(key);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
return json;
|
|
224
226
|
}
|
|
225
|
-
return json;
|
|
226
|
-
}
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
228
|
+
// Save to local storage
|
|
229
|
+
async _save(key, cached) {
|
|
230
|
+
this._stats.saves = this._stats.saves + 1;
|
|
231
|
+
await this._storage.setItem(key, cached);
|
|
232
|
+
}
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
// Remove from local storage
|
|
235
|
+
async _remove(key) {
|
|
236
|
+
await this._storage.removeItem(key);
|
|
237
|
+
}
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
async _getIfActive(key) {
|
|
240
240
|
// In memory cache?
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
241
|
+
var cached = this._cache[key];
|
|
242
|
+
var memoryHit = !!cached;
|
|
243
|
+
// Local storage ?
|
|
244
|
+
if (!cached) {
|
|
245
|
+
cached = await this._load(key);
|
|
246
|
+
this._cache[key] = cached;
|
|
247
|
+
}
|
|
248
|
+
if (!cached)
|
|
249
|
+
return undefined;
|
|
250
|
+
if (cached.expiresAt <= Date.now()) {
|
|
251
|
+
delete this._cache[key];
|
|
252
|
+
await this._remove(key);
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
this._stats.memoryHits = this._stats.memoryHits + 1;
|
|
256
|
+
if (!memoryHit) this._stats.storageHits = this._stats.storageHits + 1;
|
|
257
|
+
return cached.value;
|
|
254
258
|
}
|
|
255
|
-
this._stats.memoryHits = this._stats.memoryHits + 1;
|
|
256
|
-
if (!memoryHit) this._stats.storageHits = this._stats.storageHits + 1;
|
|
257
|
-
return cached.value;
|
|
258
|
-
}
|
|
259
259
|
|
|
260
|
-
|
|
260
|
+
/**
|
|
261
261
|
* Get a value from the cache
|
|
262
262
|
* @param {*} key the key or keys of the value to retreive
|
|
263
263
|
* @returns {*} the cached value, or undefined if not found
|
|
264
264
|
*/
|
|
265
|
-
|
|
265
|
+
async get() {
|
|
266
266
|
this._stats.reads = this._stats.reads + 1;
|
|
267
267
|
const key = this._makeKeyFn.apply(this, arguments);
|
|
268
268
|
const cached = await this._getIfActive(key);
|
|
269
269
|
return cached;
|
|
270
|
-
|
|
270
|
+
}
|
|
271
271
|
|
|
272
|
-
|
|
272
|
+
/**
|
|
273
273
|
* Put a value from the cache
|
|
274
274
|
* @param {*} key the key or keys of the value to retrieve
|
|
275
275
|
* @param {*} value the value to cache
|
|
276
276
|
* @returns {CachedObject} a cached object containing the cached value
|
|
277
277
|
*/
|
|
278
|
-
|
|
278
|
+
async put() {
|
|
279
279
|
this._stats.writes = this._stats.writes + 1;
|
|
280
280
|
const value = arguments[arguments.length -1];
|
|
281
281
|
const key = this._makeKeyFn.apply(this, arguments);
|
|
@@ -285,31 +285,31 @@ class Cache {
|
|
|
285
285
|
this._cache[key] = cached;
|
|
286
286
|
await this._save(key, cached);
|
|
287
287
|
return cached;
|
|
288
|
-
|
|
288
|
+
}
|
|
289
289
|
|
|
290
|
-
|
|
290
|
+
/**
|
|
291
291
|
* Removes everything from the cache. It does not directly removes data from persistent storage if there is, but it marks the cache
|
|
292
292
|
* as cleared so that subsequent get operation will not actually return any data cached in persistent storage
|
|
293
293
|
*/
|
|
294
|
-
|
|
294
|
+
async clear() {
|
|
295
295
|
this._stats.clears = this._stats.clears + 1;
|
|
296
296
|
this._cache = {};
|
|
297
297
|
await this._saveLastCleared();
|
|
298
|
-
|
|
298
|
+
}
|
|
299
299
|
|
|
300
|
-
|
|
300
|
+
/**
|
|
301
301
|
* Remove a key from the cache
|
|
302
302
|
* @param {string} key the key to remove
|
|
303
303
|
*/
|
|
304
|
-
|
|
304
|
+
async remove(key) {
|
|
305
305
|
this._stats.removals = this._stats.removals + 1;
|
|
306
306
|
delete this._cache[key];
|
|
307
307
|
await this._remove(key);
|
|
308
|
+
}
|
|
308
309
|
}
|
|
309
|
-
}
|
|
310
310
|
|
|
311
|
-
// Public expots
|
|
312
|
-
exports.SafeStorage = SafeStorage;
|
|
313
|
-
exports.Cache = Cache;
|
|
311
|
+
// Public expots
|
|
312
|
+
exports.SafeStorage = SafeStorage;
|
|
313
|
+
exports.Cache = Cache;
|
|
314
314
|
|
|
315
315
|
})();
|