@algorandfoundation/algokit-utils 7.0.0-beta.9 → 8.0.0-beta.1
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/LICENSE +21 -0
- package/README.md +21 -3
- package/account/account.d.ts +4 -1
- package/account/account.js +10 -7
- package/account/account.js.map +1 -1
- package/account/account.mjs +11 -8
- package/account/account.mjs.map +1 -1
- package/account/get-account-config-from-environment.js.map +1 -1
- package/account/get-account-config-from-environment.mjs.map +1 -1
- package/account/get-account.js.map +1 -1
- package/account/get-account.mjs.map +1 -1
- package/account/get-dispenser-account.d.ts +1 -1
- package/account/get-dispenser-account.js.map +1 -1
- package/account/get-dispenser-account.mjs.map +1 -1
- package/account/mnemonic-account.js.map +1 -1
- package/account/mnemonic-account.mjs.map +1 -1
- package/amount.d.ts +1 -0
- package/amount.js +3 -2
- package/amount.js.map +1 -1
- package/amount.mjs +3 -3
- package/amount.mjs.map +1 -1
- package/app-client.d.ts +4 -4
- package/app-client.js +4 -4
- package/app-client.js.map +1 -1
- package/app-client.mjs +4 -4
- package/app-client.mjs.map +1 -1
- package/app-deploy.js +25 -15
- package/app-deploy.js.map +1 -1
- package/app-deploy.mjs +27 -17
- package/app-deploy.mjs.map +1 -1
- package/app.d.ts +2 -2
- package/app.js +9 -6
- package/app.js.map +1 -1
- package/app.mjs +9 -6
- package/app.mjs.map +1 -1
- package/asset.js.map +1 -1
- package/asset.mjs.map +1 -1
- package/debugging/debugging.js.map +1 -1
- package/debugging/debugging.mjs.map +1 -1
- package/dispenser-client.js.map +1 -1
- package/dispenser-client.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +7 -1
- package/index.js.map +1 -1
- package/index.mjs +3 -2
- package/index.mjs.map +1 -1
- package/indexer-lookup.d.ts +10 -8
- package/indexer-lookup.js +14 -10
- package/indexer-lookup.js.map +1 -1
- package/indexer-lookup.mjs +14 -10
- package/indexer-lookup.mjs.map +1 -1
- package/localnet/get-kmd-wallet-account.js.map +1 -1
- package/localnet/get-kmd-wallet-account.mjs.map +1 -1
- package/localnet/get-localnet-dispenser-account.js.map +1 -1
- package/localnet/get-localnet-dispenser-account.mjs.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.js.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.mjs.map +1 -1
- package/localnet/is-localnet.js.map +1 -1
- package/localnet/is-localnet.mjs.map +1 -1
- package/network-client.d.ts +1 -7
- package/network-client.js +2 -9
- package/network-client.js.map +1 -1
- package/network-client.mjs +2 -9
- package/network-client.mjs.map +1 -1
- package/package.json +5 -5
- package/testing/_asset.d.ts +2 -1
- package/testing/account.d.ts +4 -3
- package/testing/account.js +8 -2
- package/testing/account.js.map +1 -1
- package/testing/account.mjs +9 -3
- package/testing/account.mjs.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.mjs.map +1 -1
- package/testing/fixtures/algorand-fixture.js +5 -6
- package/testing/fixtures/algorand-fixture.js.map +1 -1
- package/testing/fixtures/algorand-fixture.mjs +5 -6
- package/testing/fixtures/algorand-fixture.mjs.map +1 -1
- package/testing/indexer.js.map +1 -1
- package/testing/indexer.mjs.map +1 -1
- package/testing/test-logger.js +7 -1
- package/testing/test-logger.js.map +1 -1
- package/testing/test-logger.mjs +7 -1
- package/testing/test-logger.mjs.map +1 -1
- package/testing/transaction-logger.js.map +1 -1
- package/testing/transaction-logger.mjs.map +1 -1
- package/transaction/legacy-bridge.js +2 -2
- package/transaction/legacy-bridge.js.map +1 -1
- package/transaction/legacy-bridge.mjs +3 -3
- package/transaction/legacy-bridge.mjs.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.d.ts +4 -1
- package/transaction/perform-atomic-transaction-composer-simulate.js +14 -9
- package/transaction/perform-atomic-transaction-composer-simulate.js.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.mjs +15 -10
- package/transaction/perform-atomic-transaction-composer-simulate.mjs.map +1 -1
- package/transaction/transaction.d.ts +13 -22
- package/transaction/transaction.js +164 -110
- package/transaction/transaction.js.map +1 -1
- package/transaction/transaction.mjs +163 -109
- package/transaction/transaction.mjs.map +1 -1
- package/transfer/transfer-algos.js.map +1 -1
- package/transfer/transfer-algos.mjs.map +1 -1
- package/transfer/transfer.js +3 -1
- package/transfer/transfer.js.map +1 -1
- package/transfer/transfer.mjs +3 -1
- package/transfer/transfer.mjs.map +1 -1
- package/types/account-manager.d.ts +20 -20
- package/types/account-manager.js +36 -27
- package/types/account-manager.js.map +1 -1
- package/types/account-manager.mjs +38 -29
- package/types/account-manager.mjs.map +1 -1
- package/types/account.d.ts +17 -8
- package/types/account.js +2 -2
- package/types/account.js.map +1 -1
- package/types/account.mjs +3 -3
- package/types/account.mjs.map +1 -1
- package/types/algo-http-client-with-retry.d.ts +1 -2
- package/types/algo-http-client-with-retry.js +33 -3
- package/types/algo-http-client-with-retry.js.map +1 -1
- package/types/algo-http-client-with-retry.mjs +32 -2
- package/types/algo-http-client-with-retry.mjs.map +1 -1
- package/types/algorand-client-interface.d.ts +2 -2
- package/types/algorand-client-transaction-creator.d.ts +16 -14
- package/types/algorand-client-transaction-creator.js +3 -1
- package/types/algorand-client-transaction-creator.js.map +1 -1
- package/types/algorand-client-transaction-creator.mjs +3 -1
- package/types/algorand-client-transaction-creator.mjs.map +1 -1
- package/types/algorand-client-transaction-sender.d.ts +109 -105
- package/types/algorand-client-transaction-sender.js +6 -2
- package/types/algorand-client-transaction-sender.js.map +1 -1
- package/types/algorand-client-transaction-sender.mjs +6 -2
- package/types/algorand-client-transaction-sender.mjs.map +1 -1
- package/types/algorand-client.d.ts +6 -7
- package/types/algorand-client.js +3 -6
- package/types/algorand-client.js.map +1 -1
- package/types/algorand-client.mjs +5 -5
- package/types/algorand-client.mjs.map +1 -1
- package/types/amount.js.map +1 -1
- package/types/amount.mjs.map +1 -1
- package/types/app-arc56.d.ts +31 -20
- package/types/app-arc56.js.map +1 -1
- package/types/app-arc56.mjs.map +1 -1
- package/types/app-client.d.ts +298 -286
- package/types/app-client.js +148 -41
- package/types/app-client.js.map +1 -1
- package/types/app-client.mjs +147 -40
- package/types/app-client.mjs.map +1 -1
- package/types/app-deployer.d.ts +4 -4
- package/types/app-deployer.js +23 -24
- package/types/app-deployer.js.map +1 -1
- package/types/app-deployer.mjs +25 -26
- package/types/app-deployer.mjs.map +1 -1
- package/types/app-factory.d.ts +130 -130
- package/types/app-factory.js +4 -5
- package/types/app-factory.js.map +1 -1
- package/types/app-factory.mjs +5 -6
- package/types/app-factory.mjs.map +1 -1
- package/types/app-manager.d.ts +5 -5
- package/types/app-manager.js +116 -38
- package/types/app-manager.js.map +1 -1
- package/types/app-manager.mjs +117 -39
- package/types/app-manager.mjs.map +1 -1
- package/types/app-spec.js +8 -2
- package/types/app-spec.js.map +1 -1
- package/types/app-spec.mjs +8 -2
- package/types/app-spec.mjs.map +1 -1
- package/types/app.d.ts +12 -11
- package/types/app.js.map +1 -1
- package/types/app.mjs.map +1 -1
- package/types/asset-manager.d.ts +9 -9
- package/types/asset-manager.js +10 -13
- package/types/asset-manager.js.map +1 -1
- package/types/asset-manager.mjs +10 -13
- package/types/asset-manager.mjs.map +1 -1
- package/types/async-event-emitter.d.ts +1 -10
- package/types/async-event-emitter.js +0 -5
- package/types/async-event-emitter.js.map +1 -1
- package/types/async-event-emitter.mjs +1 -6
- package/types/async-event-emitter.mjs.map +1 -1
- package/types/client-manager.d.ts +2 -9
- package/types/client-manager.js +11 -21
- package/types/client-manager.js.map +1 -1
- package/types/client-manager.mjs +11 -21
- package/types/client-manager.mjs.map +1 -1
- package/types/composer.d.ts +58 -46
- package/types/composer.js +154 -105
- package/types/composer.js.map +1 -1
- package/types/composer.mjs +156 -105
- package/types/composer.mjs.map +1 -1
- package/types/config.js.map +1 -1
- package/types/config.mjs.map +1 -1
- package/types/debugging.d.ts +1 -1
- package/types/debugging.js +1 -1
- package/types/debugging.js.map +1 -1
- package/types/debugging.mjs +1 -1
- package/types/debugging.mjs.map +1 -1
- package/types/dispenser-client.d.ts +2 -1
- package/types/dispenser-client.js +5 -1
- package/types/dispenser-client.js.map +1 -1
- package/types/dispenser-client.mjs +5 -1
- package/types/dispenser-client.mjs.map +1 -1
- package/types/indexer.d.ts +74 -755
- package/types/indexer.js.map +1 -1
- package/types/indexer.mjs.map +1 -1
- package/types/kmd-account-manager.d.ts +2 -2
- package/types/kmd-account-manager.js +1 -1
- package/types/kmd-account-manager.js.map +1 -1
- package/types/kmd-account-manager.mjs +2 -2
- package/types/kmd-account-manager.mjs.map +1 -1
- package/types/lifecycle-events.d.ts +10 -0
- package/types/lifecycle-events.js +8 -0
- package/types/lifecycle-events.js.map +1 -0
- package/types/lifecycle-events.mjs +8 -0
- package/types/lifecycle-events.mjs.map +1 -0
- package/types/logging.js.map +1 -1
- package/types/logging.mjs.map +1 -1
- package/types/logic-error.d.ts +2 -3
- package/types/logic-error.js +3 -3
- package/types/logic-error.js.map +1 -1
- package/types/logic-error.mjs +3 -3
- package/types/logic-error.mjs.map +1 -1
- package/types/network-client.d.ts +1 -1
- package/types/network-client.js.map +1 -1
- package/types/network-client.mjs.map +1 -1
- package/types/testing.d.ts +6 -7
- package/util.js.map +1 -1
- package/util.mjs.map +1 -1
- package/types/urlTokenBaseHTTPClient.d.ts +0 -40
- package/types/urlTokenBaseHTTPClient.js +0 -153
- package/types/urlTokenBaseHTTPClient.js.map +0 -1
- package/types/urlTokenBaseHTTPClient.mjs +0 -151
- package/types/urlTokenBaseHTTPClient.mjs.map +0 -1
package/types/app-manager.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var algosdk = require('algosdk');
|
|
4
|
+
var transaction = require('../transaction/transaction.js');
|
|
4
5
|
var types_app = require('./app.js');
|
|
5
6
|
|
|
6
|
-
var modelsv2 = algosdk.modelsv2;
|
|
7
7
|
/** Allows management of application information. */
|
|
8
8
|
class AppManager {
|
|
9
9
|
/**
|
|
@@ -35,7 +35,7 @@ class AppManager {
|
|
|
35
35
|
compiled: compiled.result,
|
|
36
36
|
compiledHash: compiled.hash,
|
|
37
37
|
compiledBase64ToBytes: new Uint8Array(Buffer.from(compiled.result, 'base64')),
|
|
38
|
-
sourceMap: new algosdk.
|
|
38
|
+
sourceMap: new algosdk.ProgramSourceMap(JSON.parse(algosdk.encodeJSON(compiled.sourcemap))),
|
|
39
39
|
};
|
|
40
40
|
this._compilationResults[tealCode] = result;
|
|
41
41
|
return result;
|
|
@@ -83,7 +83,7 @@ class AppManager {
|
|
|
83
83
|
* @returns The app information
|
|
84
84
|
*/
|
|
85
85
|
async getById(appId) {
|
|
86
|
-
const app =
|
|
86
|
+
const app = await this._algod.getApplicationByID(Number(appId)).do();
|
|
87
87
|
return {
|
|
88
88
|
appId: BigInt(app.id),
|
|
89
89
|
appAddress: algosdk.getApplicationAddress(app.id),
|
|
@@ -115,7 +115,7 @@ class AppManager {
|
|
|
115
115
|
* @returns The current local state for the given (app, account) combination
|
|
116
116
|
*/
|
|
117
117
|
async getLocalState(appId, address) {
|
|
118
|
-
const appInfo =
|
|
118
|
+
const appInfo = await this._algod.accountApplicationInformation(address, appId).do();
|
|
119
119
|
if (!appInfo.appLocalState?.keyValue) {
|
|
120
120
|
throw new Error("Couldn't find local state");
|
|
121
121
|
}
|
|
@@ -127,7 +127,7 @@ class AppManager {
|
|
|
127
127
|
* @returns The current box names
|
|
128
128
|
*/
|
|
129
129
|
async getBoxNames(appId) {
|
|
130
|
-
const boxResult = await this._algod.getApplicationBoxes(
|
|
130
|
+
const boxResult = await this._algod.getApplicationBoxes(appId).do();
|
|
131
131
|
return boxResult.boxes.map((b) => {
|
|
132
132
|
return {
|
|
133
133
|
nameRaw: b.name,
|
|
@@ -183,12 +183,8 @@ class AppManager {
|
|
|
183
183
|
static getBoxReference(boxId) {
|
|
184
184
|
const ref = typeof boxId === 'object' && 'appId' in boxId ? boxId : { appId: 0n, name: boxId };
|
|
185
185
|
return {
|
|
186
|
-
appIndex:
|
|
187
|
-
name: typeof ref.name === 'string'
|
|
188
|
-
? new TextEncoder().encode(ref.name)
|
|
189
|
-
: 'length' in ref.name
|
|
190
|
-
? ref.name
|
|
191
|
-
: algosdk.decodeAddress(ref.name.addr).publicKey,
|
|
186
|
+
appIndex: ref.appId,
|
|
187
|
+
name: typeof ref.name === 'string' ? new TextEncoder().encode(ref.name) : 'length' in ref.name ? ref.name : ref.name.addr.publicKey,
|
|
192
188
|
};
|
|
193
189
|
}
|
|
194
190
|
/**
|
|
@@ -201,16 +197,17 @@ class AppManager {
|
|
|
201
197
|
const stateValues = {};
|
|
202
198
|
// Start with empty set
|
|
203
199
|
for (const stateVal of state) {
|
|
204
|
-
const keyBase64 = stateVal.key;
|
|
205
|
-
const keyRaw =
|
|
206
|
-
const key =
|
|
200
|
+
const keyBase64 = Buffer.from(stateVal.key).toString('base64');
|
|
201
|
+
const keyRaw = stateVal.key;
|
|
202
|
+
const key = Buffer.from(stateVal.key).toString('utf-8');
|
|
207
203
|
const tealValue = stateVal.value;
|
|
208
204
|
const dataTypeFlag = 'action' in tealValue ? tealValue.action : tealValue.type;
|
|
209
205
|
let valueBase64;
|
|
210
206
|
let valueRaw;
|
|
211
207
|
switch (dataTypeFlag) {
|
|
212
208
|
case 1:
|
|
213
|
-
valueBase64 =
|
|
209
|
+
valueBase64 =
|
|
210
|
+
typeof tealValue.bytes === 'string' ? tealValue.bytes : tealValue.bytes ? Buffer.from(tealValue.bytes).toString('base64') : '';
|
|
214
211
|
valueRaw = Buffer.from(valueBase64, 'base64');
|
|
215
212
|
stateValues[key] = {
|
|
216
213
|
keyRaw,
|
|
@@ -251,19 +248,7 @@ class AppManager {
|
|
|
251
248
|
method,
|
|
252
249
|
rawReturnValue: new Uint8Array(),
|
|
253
250
|
};
|
|
254
|
-
|
|
255
|
-
return !response.decodeError
|
|
256
|
-
? {
|
|
257
|
-
rawReturnValue: response.rawReturnValue,
|
|
258
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
259
|
-
returnValue: response.returnValue,
|
|
260
|
-
decodeError: undefined,
|
|
261
|
-
}
|
|
262
|
-
: {
|
|
263
|
-
rawReturnValue: undefined,
|
|
264
|
-
returnValue: undefined,
|
|
265
|
-
decodeError: response.decodeError,
|
|
266
|
-
};
|
|
251
|
+
return transaction.getABIReturnValue(algosdk.AtomicTransactionComposer.parseMethodResponse(method, resultDummy, confirmation));
|
|
267
252
|
}
|
|
268
253
|
/**
|
|
269
254
|
* Replaces AlgoKit deploy-time deployment control parameters within the given TEAL template code.
|
|
@@ -283,13 +268,13 @@ class AppManager {
|
|
|
283
268
|
if (!tealTemplateCode.includes(types_app.UPDATABLE_TEMPLATE_NAME)) {
|
|
284
269
|
throw new Error(`Deploy-time updatability control requested for app deployment, but ${types_app.UPDATABLE_TEMPLATE_NAME} not present in TEAL code`);
|
|
285
270
|
}
|
|
286
|
-
tealTemplateCode = tealTemplateCode
|
|
271
|
+
tealTemplateCode = replaceTemplateVariable(tealTemplateCode, types_app.UPDATABLE_TEMPLATE_NAME, (params.updatable ? 1 : 0).toString());
|
|
287
272
|
}
|
|
288
273
|
if (params.deletable !== undefined) {
|
|
289
274
|
if (!tealTemplateCode.includes(types_app.DELETABLE_TEMPLATE_NAME)) {
|
|
290
275
|
throw new Error(`Deploy-time deletability control requested for app deployment, but ${types_app.DELETABLE_TEMPLATE_NAME} not present in TEAL code`);
|
|
291
276
|
}
|
|
292
|
-
tealTemplateCode = tealTemplateCode
|
|
277
|
+
tealTemplateCode = replaceTemplateVariable(tealTemplateCode, types_app.DELETABLE_TEMPLATE_NAME, (params.deletable ? 1 : 0).toString());
|
|
293
278
|
}
|
|
294
279
|
return tealTemplateCode;
|
|
295
280
|
}
|
|
@@ -313,7 +298,7 @@ class AppManager {
|
|
|
313
298
|
tealTemplateCode = tealTemplateCode.replace(new RegExp(`(?<=bytes )${token}`, 'g'), `0x${value.toString(16).padStart(16, '0')}`);
|
|
314
299
|
// We could probably return here since mixing pushint and pushbytes is likely not going to happen, but might as well do both
|
|
315
300
|
}
|
|
316
|
-
tealTemplateCode = tealTemplateCode
|
|
301
|
+
tealTemplateCode = replaceTemplateVariable(tealTemplateCode, token, typeof value === 'string'
|
|
317
302
|
? `0x${Buffer.from(value, 'utf-8').toString('hex')}`
|
|
318
303
|
: ArrayBuffer.isView(value)
|
|
319
304
|
? `0x${Buffer.from(value).toString('hex')}`
|
|
@@ -329,17 +314,110 @@ class AppManager {
|
|
|
329
314
|
* @returns The TEAL without comments
|
|
330
315
|
*/
|
|
331
316
|
static stripTealComments(tealCode) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
317
|
+
const stripCommentFromLine = (line) => {
|
|
318
|
+
const commentIndex = findUnquotedString(line, '//');
|
|
319
|
+
if (commentIndex === undefined) {
|
|
320
|
+
return line;
|
|
321
|
+
}
|
|
322
|
+
return line.slice(0, commentIndex).trimEnd();
|
|
323
|
+
};
|
|
324
|
+
return tealCode
|
|
335
325
|
.split('\n')
|
|
336
|
-
.map((
|
|
337
|
-
return tealCodeLine.split(regex)[0].trim();
|
|
338
|
-
})
|
|
326
|
+
.map((line) => stripCommentFromLine(line))
|
|
339
327
|
.join('\n');
|
|
340
|
-
return tealCode;
|
|
341
328
|
}
|
|
342
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* Find the first string within a line of TEAL. Only matches outside of quotes and base64 are returned.
|
|
332
|
+
* Returns undefined if not found
|
|
333
|
+
*/
|
|
334
|
+
const findUnquotedString = (line, token, startIndex = 0, _endIndex) => {
|
|
335
|
+
const endIndex = _endIndex === undefined ? line.length : _endIndex;
|
|
336
|
+
let index = startIndex;
|
|
337
|
+
let inQuotes = false;
|
|
338
|
+
let inBase64 = false;
|
|
339
|
+
while (index < endIndex) {
|
|
340
|
+
const currentChar = line[index];
|
|
341
|
+
if ((currentChar === ' ' || currentChar === '(') && !inQuotes && lastTokenBase64(line, index)) {
|
|
342
|
+
// enter base64
|
|
343
|
+
inBase64 = true;
|
|
344
|
+
}
|
|
345
|
+
else if ((currentChar === ' ' || currentChar === ')') && !inQuotes && inBase64) {
|
|
346
|
+
// exit base64
|
|
347
|
+
inBase64 = false;
|
|
348
|
+
}
|
|
349
|
+
else if (currentChar === '\\' && inQuotes) {
|
|
350
|
+
// escaped char, skip next character
|
|
351
|
+
index += 1;
|
|
352
|
+
}
|
|
353
|
+
else if (currentChar === '"') {
|
|
354
|
+
// quote boundary
|
|
355
|
+
inQuotes = !inQuotes;
|
|
356
|
+
}
|
|
357
|
+
else if (!inQuotes && !inBase64 && line.startsWith(token, index)) {
|
|
358
|
+
// can test for match
|
|
359
|
+
return index;
|
|
360
|
+
}
|
|
361
|
+
index += 1;
|
|
362
|
+
}
|
|
363
|
+
return undefined;
|
|
364
|
+
};
|
|
365
|
+
const lastTokenBase64 = (line, index) => {
|
|
366
|
+
try {
|
|
367
|
+
const tokens = line.slice(0, index).split(/\s+/);
|
|
368
|
+
const last = tokens[tokens.length - 1];
|
|
369
|
+
return ['base64', 'b64'].includes(last);
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
function replaceTemplateVariable(program, token, replacement) {
|
|
376
|
+
const result = [];
|
|
377
|
+
const tokenIndexOffset = replacement.length - token.length;
|
|
378
|
+
const programLines = program.split('\n');
|
|
379
|
+
for (const line of programLines) {
|
|
380
|
+
const _commentIndex = findUnquotedString(line, '//');
|
|
381
|
+
const commentIndex = _commentIndex === undefined ? line.length : _commentIndex;
|
|
382
|
+
let code = line.substring(0, commentIndex);
|
|
383
|
+
const comment = line.substring(commentIndex);
|
|
384
|
+
let trailingIndex = 0;
|
|
385
|
+
// eslint-disable-next-line no-constant-condition
|
|
386
|
+
while (true) {
|
|
387
|
+
const tokenIndex = findTemplateToken(code, token, trailingIndex);
|
|
388
|
+
if (tokenIndex === undefined) {
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
trailingIndex = tokenIndex + token.length;
|
|
392
|
+
const prefix = code.substring(0, tokenIndex);
|
|
393
|
+
const suffix = code.substring(trailingIndex);
|
|
394
|
+
code = `${prefix}${replacement}${suffix}`;
|
|
395
|
+
trailingIndex += tokenIndexOffset;
|
|
396
|
+
}
|
|
397
|
+
result.push(code + comment);
|
|
398
|
+
}
|
|
399
|
+
return result.join('\n');
|
|
400
|
+
}
|
|
401
|
+
const findTemplateToken = (line, token, startIndex = 0, _endIndex) => {
|
|
402
|
+
const endIndex = line.length ;
|
|
403
|
+
let index = startIndex;
|
|
404
|
+
while (index < endIndex) {
|
|
405
|
+
const tokenIndex = findUnquotedString(line, token, index, endIndex);
|
|
406
|
+
if (tokenIndex === undefined) {
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
const trailingIndex = tokenIndex + token.length;
|
|
410
|
+
if ((tokenIndex === 0 || !isValidTokenCharacter(line[tokenIndex - 1])) &&
|
|
411
|
+
(trailingIndex >= line.length || !isValidTokenCharacter(line[trailingIndex]))) {
|
|
412
|
+
return tokenIndex;
|
|
413
|
+
}
|
|
414
|
+
index = trailingIndex;
|
|
415
|
+
}
|
|
416
|
+
return undefined;
|
|
417
|
+
};
|
|
418
|
+
function isValidTokenCharacter(char) {
|
|
419
|
+
return char.length === 1 && (/\w/.test(char) || char === '_');
|
|
420
|
+
}
|
|
343
421
|
|
|
344
422
|
exports.AppManager = AppManager;
|
|
345
423
|
//# sourceMappingURL=app-manager.js.map
|
package/types/app-manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-manager.js","sources":["../../src/types/app-manager.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { TransactionSignerAccount } from './account'\nimport {\n BoxName,\n DELETABLE_TEMPLATE_NAME,\n UPDATABLE_TEMPLATE_NAME,\n type ABIReturn,\n type AppState,\n type CompiledTeal,\n type TealTemplateParams,\n} from './app'\nimport modelsv2 = algosdk.modelsv2\n\n/** Information about an app. */\nexport interface AppInformation {\n /** The ID of the app. */\n appId: bigint\n /** The escrow address that the app operates with. */\n appAddress: string\n /**\n * Approval program.\n */\n approvalProgram: Uint8Array\n /**\n * Clear state program.\n */\n clearStateProgram: Uint8Array\n /**\n * The address that created this application. This is the address where the\n * parameters and global state for this application can be found.\n */\n creator: string\n /**\n * Current global state values.\n */\n globalState: AppState\n /** The number of allocated ints in per-user local state. */\n localInts: number\n /** The number of allocated byte slices in per-user local state. */\n localByteSlices: number\n /** The number of allocated ints in global state. */\n globalInts: number\n /** The number of allocated byte slices in global state. */\n globalByteSlices: number\n /** Any extra pages that are needed for the smart contract. */\n extraProgramPages?: number\n}\n\n/**\n * Something that identifies an app box name - either a:\n * * `Uint8Array` (the actual binary of the box name)\n * * `string` (that will be encoded to a `Uint8Array`)\n * * `TransactionSignerAccount` (that will be encoded into the\n * public key address of the corresponding account)\n */\nexport type BoxIdentifier = string | Uint8Array | TransactionSignerAccount\n\n/**\n * A grouping of the app ID and name identifier to reference an app box.\n */\nexport interface BoxReference {\n /**\n * A unique application id\n */\n appId: bigint\n /**\n * Identifier for a box name\n */\n name: BoxIdentifier\n}\n\n/**\n * Parameters to get and decode a box value as an ABI type.\n */\nexport interface BoxValueRequestParams {\n /** The ID of the app return box names for */\n appId: bigint\n /** The name of the box to return either as a string, binary array or `BoxName` */\n boxName: BoxIdentifier\n /** The ABI type to decode the value using */\n type: algosdk.ABIType\n}\n\n/**\n * Parameters to get and decode a box value as an ABI type.\n */\nexport interface BoxValuesRequestParams {\n /** The ID of the app return box names for */\n appId: bigint\n /** The names of the boxes to return either as a string, binary array or BoxName` */\n boxNames: BoxIdentifier[]\n /** The ABI type to decode the value using */\n type: algosdk.ABIType\n}\n\n/** Allows management of application information. */\nexport class AppManager {\n private _algod: algosdk.Algodv2\n private _compilationResults: Record<string, CompiledTeal> = {}\n\n /**\n * Creates an `AppManager`\n * @param algod An algod instance\n */\n constructor(algod: algosdk.Algodv2) {\n this._algod = algod\n }\n\n /**\n * Compiles the given TEAL using algod and returns the result, including source map.\n *\n * The result of this compilation is also cached keyed by the TEAL\n * code so it can be retrieved via `getCompilationResult`.\n *\n * This function is re-entrant; it will only compile the same code once.\n *\n * @param tealCode The TEAL code\n * @returns The information about the compiled file\n */\n async compileTeal(tealCode: string): Promise<CompiledTeal> {\n if (this._compilationResults[tealCode]) {\n return this._compilationResults[tealCode]\n }\n\n const compiled = await this._algod.compile(tealCode).sourcemap(true).do()\n const result = {\n teal: tealCode,\n compiled: compiled.result,\n compiledHash: compiled.hash,\n compiledBase64ToBytes: new Uint8Array(Buffer.from(compiled.result, 'base64')),\n sourceMap: new algosdk.SourceMap(compiled['sourcemap']),\n }\n this._compilationResults[tealCode] = result\n\n return result\n }\n\n /**\n * Performs template substitution of a teal template and compiles it, returning the compiled result.\n *\n * Looks for `TMPL_{parameter}` for template replacements and replaces AlgoKit deploy-time control parameters\n * if deployment metadata is specified.\n *\n * * `TMPL_UPDATABLE` for updatability / immutability control\n * * `TMPL_DELETABLE` for deletability / permanence control\n *\n * @param tealTemplateCode The TEAL logic to compile\n * @param templateParams Any parameters to replace in the .teal file before compiling\n * @param deploymentMetadata The deployment metadata the app will be deployed with\n * @returns The information about the compiled code\n */\n async compileTealTemplate(\n tealTemplateCode: string,\n templateParams?: TealTemplateParams,\n deploymentMetadata?: { updatable?: boolean; deletable?: boolean },\n ): Promise<CompiledTeal> {\n let tealCode = AppManager.stripTealComments(tealTemplateCode)\n\n tealCode = AppManager.replaceTealTemplateParams(tealCode, templateParams)\n\n if (deploymentMetadata) {\n tealCode = AppManager.replaceTealTemplateDeployTimeControlParams(tealCode, deploymentMetadata)\n }\n\n return await this.compileTeal(tealCode)\n }\n\n /**\n * Returns a previous compilation result.\n * @param tealCode The TEAL code\n * @returns The information about the previously compiled file\n * or `undefined` if that TEAL code wasn't previously compiled\n */\n getCompilationResult(tealCode: string): CompiledTeal | undefined {\n return this._compilationResults[tealCode]\n }\n\n /**\n * Returns the current app information for the app with the given ID.\n *\n * @example\n * ```typescript\n * const appInfo = await appManager.getById(12353n);\n * ```\n *\n * @param appId The ID of the app\n * @returns The app information\n */\n public async getById(appId: bigint): Promise<AppInformation> {\n const app = modelsv2.Application.from_obj_for_encoding(await this._algod.getApplicationByID(Number(appId)).do())\n return {\n appId: BigInt(app.id),\n appAddress: algosdk.getApplicationAddress(app.id),\n approvalProgram: app.params.approvalProgram,\n clearStateProgram: app.params.clearStateProgram,\n creator: app.params.creator,\n localInts: Number(app.params.localStateSchema?.numUint ?? 0),\n localByteSlices: Number(app.params.localStateSchema?.numByteSlice ?? 0),\n globalInts: Number(app.params.globalStateSchema?.numUint ?? 0),\n globalByteSlices: Number(app.params.globalStateSchema?.numByteSlice ?? 0),\n extraProgramPages: Number(app.params.extraProgramPages ?? 0),\n globalState: AppManager.decodeAppState(app.params.globalState ?? []),\n }\n }\n\n /**\n * Returns the current global state values for the given app ID and account address\n *\n * @param appId The ID of the app to return global state for\n * @returns The current global state for the given app\n */\n public async getGlobalState(appId: bigint) {\n return (await this.getById(appId)).globalState\n }\n\n /**\n * Returns the current local state values for the given app ID and account address\n *\n * @param appId The ID of the app to return local state for\n * @param address The string address of the account to get local state for the given app\n * @returns The current local state for the given (app, account) combination\n */\n public async getLocalState(appId: bigint, address: string) {\n const appInfo = modelsv2.AccountApplicationResponse.from_obj_for_encoding(\n await this._algod.accountApplicationInformation(address, Number(appId)).do(),\n )\n\n if (!appInfo.appLocalState?.keyValue) {\n throw new Error(\"Couldn't find local state\")\n }\n\n return AppManager.decodeAppState(appInfo.appLocalState.keyValue)\n }\n\n /**\n * Returns the names of the current boxes for the given app.\n * @param appId The ID of the app return box names for\n * @returns The current box names\n */\n public async getBoxNames(appId: bigint): Promise<BoxName[]> {\n const boxResult = await this._algod.getApplicationBoxes(Number(appId)).do()\n return boxResult.boxes.map((b) => {\n return {\n nameRaw: b.name,\n nameBase64: Buffer.from(b.name).toString('base64'),\n name: Buffer.from(b.name).toString('utf-8'),\n }\n })\n }\n\n /**\n * Returns the value of the given box name for the given app.\n * @param appId The ID of the app return box names for\n * @param boxName The name of the box to return either as a string, binary array or `BoxName`\n * @returns The current box value as a byte array\n */\n public async getBoxValue(appId: bigint, boxName: BoxIdentifier): Promise<Uint8Array> {\n const name = AppManager.getBoxReference(boxName).name\n const boxResult = await this._algod.getApplicationBoxByName(Number(appId), name).do()\n return boxResult.value\n }\n\n /**\n * Returns the value of the given box names for the given app.\n * @param appId The ID of the app return box names for\n * @param boxNames The names of the boxes to return either as a string, binary array or `BoxName`\n * @returns The current box values as a byte array in the same order as the passed in box names\n */\n public async getBoxValues(appId: bigint, boxNames: BoxIdentifier[]): Promise<Uint8Array[]> {\n return await Promise.all(boxNames.map(async (boxName) => await this.getBoxValue(appId, boxName)))\n }\n\n /**\n * Returns the value of the given box name for the given app decoded based on the given ABI type.\n * @param request The parameters for the box value request\n * @returns The current box value as an ABI value\n */\n public async getBoxValueFromABIType(request: BoxValueRequestParams): Promise<algosdk.ABIValue> {\n const { appId, boxName, type } = request\n const value = await this.getBoxValue(appId, boxName)\n return type.decode(value)\n }\n\n /**\n * Returns the value of the given box names for the given app decoded based on the given ABI type.\n * @param request The parameters for the box value request\n * @returns The current box values as an ABI value in the same order as the passed in box names\n */\n public async getBoxValuesFromABIType(request: BoxValuesRequestParams): Promise<algosdk.ABIValue[]> {\n const { appId, boxNames, type } = request\n return await Promise.all(boxNames.map(async (boxName) => await this.getBoxValueFromABIType({ appId, boxName, type })))\n }\n\n /**\n * Returns a `algosdk.BoxReference` given a `BoxIdentifier` or `BoxReference`.\n * @param boxId The box to return a reference for\n * @returns The box reference ready to pass into a `algosdk.Transaction`\n */\n public static getBoxReference(boxId: BoxIdentifier | BoxReference): algosdk.BoxReference {\n const ref = typeof boxId === 'object' && 'appId' in boxId ? boxId : { appId: 0n, name: boxId }\n return {\n appIndex: Number(ref.appId),\n name:\n typeof ref.name === 'string'\n ? new TextEncoder().encode(ref.name)\n : 'length' in ref.name\n ? ref.name\n : algosdk.decodeAddress(ref.name.addr).publicKey,\n } as algosdk.BoxReference\n }\n\n /**\n * Converts an array of global/local state values from the algod api to a more friendly\n * generic object keyed by the UTF-8 value of the key.\n * @param state A `global-state`, `local-state`, `global-state-deltas` or `local-state-deltas`\n * @returns An object keyeed by the UTF-8 representation of the key with various parsings of the values\n */\n public static decodeAppState(state: { key: string; value: modelsv2.TealValue | modelsv2.EvalDelta }[]): AppState {\n const stateValues = {} as AppState\n\n // Start with empty set\n for (const stateVal of state) {\n const keyBase64 = stateVal.key\n const keyRaw = Buffer.from(keyBase64, 'base64')\n const key = keyRaw.toString('utf-8')\n const tealValue = stateVal.value\n\n const dataTypeFlag = 'action' in tealValue ? tealValue.action : tealValue.type\n let valueBase64: string\n let valueRaw: Buffer\n switch (dataTypeFlag) {\n case 1:\n valueBase64 = tealValue.bytes ?? ''\n valueRaw = Buffer.from(valueBase64, 'base64')\n stateValues[key] = {\n keyRaw,\n keyBase64,\n valueRaw: new Uint8Array(valueRaw),\n valueBase64: valueBase64,\n value: valueRaw.toString('utf-8'),\n }\n break\n case 2: {\n const value = tealValue.uint ?? 0\n stateValues[key] = {\n keyRaw,\n keyBase64,\n value: BigInt(value),\n }\n break\n }\n default:\n throw new Error(`Received unknown state data type of ${dataTypeFlag}`)\n }\n }\n\n return stateValues\n }\n\n /**\n * Returns any ABI return values for the given app call arguments and transaction confirmation.\n * @param confirmation The transaction confirmation from algod\n * @param method The ABI method\n * @returns The return value for the method call\n */\n public static getABIReturn(\n confirmation: modelsv2.PendingTransactionResponse | undefined,\n method: algosdk.ABIMethod | undefined,\n ): ABIReturn | undefined {\n if (!method || !confirmation || method.returns.type === 'void') {\n return undefined\n }\n\n // The parseMethodResponse method mutates the second parameter :(\n const resultDummy: algosdk.ABIResult = {\n txID: '',\n method,\n rawReturnValue: new Uint8Array(),\n }\n const response = algosdk.AtomicTransactionComposer.parseMethodResponse(method, resultDummy, confirmation)\n return !response.decodeError\n ? {\n rawReturnValue: response.rawReturnValue,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n returnValue: response.returnValue!,\n decodeError: undefined,\n }\n : {\n rawReturnValue: undefined,\n returnValue: undefined,\n decodeError: response.decodeError,\n }\n }\n\n /**\n * Replaces AlgoKit deploy-time deployment control parameters within the given TEAL template code.\n *\n * * `TMPL_UPDATABLE` for updatability / immutability control\n * * `TMPL_DELETABLE` for deletability / permanence control\n *\n * Note: If these values are defined, but the corresponding `TMPL_*` value\n * isn't in the teal code it will throw an exception.\n *\n * @param tealTemplateCode The TEAL template code to substitute\n * @param params The deploy-time deployment control parameter value to replace\n * @returns The replaced TEAL code\n */\n static replaceTealTemplateDeployTimeControlParams(tealTemplateCode: string, params: { updatable?: boolean; deletable?: boolean }) {\n if (params.updatable !== undefined) {\n if (!tealTemplateCode.includes(UPDATABLE_TEMPLATE_NAME)) {\n throw new Error(\n `Deploy-time updatability control requested for app deployment, but ${UPDATABLE_TEMPLATE_NAME} not present in TEAL code`,\n )\n }\n tealTemplateCode = tealTemplateCode.replace(new RegExp(UPDATABLE_TEMPLATE_NAME, 'g'), (params.updatable ? 1 : 0).toString())\n }\n\n if (params.deletable !== undefined) {\n if (!tealTemplateCode.includes(DELETABLE_TEMPLATE_NAME)) {\n throw new Error(\n `Deploy-time deletability control requested for app deployment, but ${DELETABLE_TEMPLATE_NAME} not present in TEAL code`,\n )\n }\n tealTemplateCode = tealTemplateCode.replace(new RegExp(DELETABLE_TEMPLATE_NAME, 'g'), (params.deletable ? 1 : 0).toString())\n }\n\n return tealTemplateCode\n }\n\n /**\n * Performs template substitution of a teal file.\n *\n * Looks for `TMPL_{parameter}` for template replacements.\n *\n * @param tealTemplateCode The TEAL template code to make parameter replacements in\n * @param templateParams Any parameters to replace in the teal code\n * @returns The TEAL code with replacements\n */\n static replaceTealTemplateParams(tealTemplateCode: string, templateParams?: TealTemplateParams) {\n if (templateParams !== undefined) {\n for (const key in templateParams) {\n const value = templateParams[key]\n const token = `TMPL_${key.replace(/^TMPL_/, '')}`\n\n // If this is a number, first replace any byte representations of the number\n // These may appear in the TEAL in order to circumvent int compression and preserve PC values\n if (typeof value === 'number' || typeof value === 'bigint') {\n tealTemplateCode = tealTemplateCode.replace(new RegExp(`(?<=bytes )${token}`, 'g'), `0x${value.toString(16).padStart(16, '0')}`)\n\n // We could probably return here since mixing pushint and pushbytes is likely not going to happen, but might as well do both\n }\n\n tealTemplateCode = tealTemplateCode.replace(\n new RegExp(token, 'g'),\n typeof value === 'string'\n ? `0x${Buffer.from(value, 'utf-8').toString('hex')}`\n : ArrayBuffer.isView(value)\n ? `0x${Buffer.from(value).toString('hex')}`\n : value.toString(),\n )\n }\n }\n\n return tealTemplateCode\n }\n\n /**\n * Remove comments from TEAL code (useful to reduce code size before compilation).\n *\n * @param tealCode The TEAL logic to strip\n * @returns The TEAL without comments\n */\n static stripTealComments(tealCode: string) {\n // find // outside quotes, i.e. won't pick up \"//not a comment\"\n const regex = /\\/\\/(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)/\n\n tealCode = tealCode\n .split('\\n')\n .map((tealCodeLine) => {\n return tealCodeLine.split(regex)[0].trim()\n })\n .join('\\n')\n\n return tealCode\n }\n}\n"],"names":["UPDATABLE_TEMPLATE_NAME","DELETABLE_TEMPLATE_NAME"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-manager.js","sources":["../../src/types/app-manager.ts"],"sourcesContent":["import algosdk, { Address, ProgramSourceMap } from 'algosdk'\nimport { getABIReturnValue } from '../transaction/transaction'\nimport { TransactionSignerAccount } from './account'\nimport {\n BoxName,\n DELETABLE_TEMPLATE_NAME,\n UPDATABLE_TEMPLATE_NAME,\n type ABIReturn,\n type AppState,\n type CompiledTeal,\n type TealTemplateParams,\n} from './app'\nimport modelsv2 = algosdk.modelsv2\n\n/** Information about an app. */\nexport interface AppInformation {\n /** The ID of the app. */\n appId: bigint\n /** The escrow address that the app operates with. */\n appAddress: Address\n /**\n * Approval program.\n */\n approvalProgram: Uint8Array\n /**\n * Clear state program.\n */\n clearStateProgram: Uint8Array\n /**\n * The address that created this application. This is the address where the\n * parameters and global state for this application can be found.\n */\n creator: Address\n /**\n * Current global state values.\n */\n globalState: AppState\n /** The number of allocated ints in per-user local state. */\n localInts: number\n /** The number of allocated byte slices in per-user local state. */\n localByteSlices: number\n /** The number of allocated ints in global state. */\n globalInts: number\n /** The number of allocated byte slices in global state. */\n globalByteSlices: number\n /** Any extra pages that are needed for the smart contract. */\n extraProgramPages?: number\n}\n\n/**\n * Something that identifies an app box name - either a:\n * * `Uint8Array` (the actual binary of the box name)\n * * `string` (that will be encoded to a `Uint8Array`)\n * * `TransactionSignerAccount` (that will be encoded into the\n * public key address of the corresponding account)\n */\nexport type BoxIdentifier = string | Uint8Array | TransactionSignerAccount\n\n/**\n * A grouping of the app ID and name identifier to reference an app box.\n */\nexport interface BoxReference {\n /**\n * A unique application id\n */\n appId: bigint\n /**\n * Identifier for a box name\n */\n name: BoxIdentifier\n}\n\n/**\n * Parameters to get and decode a box value as an ABI type.\n */\nexport interface BoxValueRequestParams {\n /** The ID of the app return box names for */\n appId: bigint\n /** The name of the box to return either as a string, binary array or `BoxName` */\n boxName: BoxIdentifier\n /** The ABI type to decode the value using */\n type: algosdk.ABIType\n}\n\n/**\n * Parameters to get and decode a box value as an ABI type.\n */\nexport interface BoxValuesRequestParams {\n /** The ID of the app return box names for */\n appId: bigint\n /** The names of the boxes to return either as a string, binary array or BoxName` */\n boxNames: BoxIdentifier[]\n /** The ABI type to decode the value using */\n type: algosdk.ABIType\n}\n\n/** Allows management of application information. */\nexport class AppManager {\n private _algod: algosdk.Algodv2\n private _compilationResults: Record<string, CompiledTeal> = {}\n\n /**\n * Creates an `AppManager`\n * @param algod An algod instance\n */\n constructor(algod: algosdk.Algodv2) {\n this._algod = algod\n }\n\n /**\n * Compiles the given TEAL using algod and returns the result, including source map.\n *\n * The result of this compilation is also cached keyed by the TEAL\n * code so it can be retrieved via `getCompilationResult`.\n *\n * This function is re-entrant; it will only compile the same code once.\n *\n * @param tealCode The TEAL code\n * @returns The information about the compiled file\n */\n async compileTeal(tealCode: string): Promise<CompiledTeal> {\n if (this._compilationResults[tealCode]) {\n return this._compilationResults[tealCode]\n }\n\n const compiled = await this._algod.compile(tealCode).sourcemap(true).do()\n const result = {\n teal: tealCode,\n compiled: compiled.result,\n compiledHash: compiled.hash,\n compiledBase64ToBytes: new Uint8Array(Buffer.from(compiled.result, 'base64')),\n sourceMap: new ProgramSourceMap(JSON.parse(algosdk.encodeJSON(compiled.sourcemap!))),\n }\n this._compilationResults[tealCode] = result\n\n return result\n }\n\n /**\n * Performs template substitution of a teal template and compiles it, returning the compiled result.\n *\n * Looks for `TMPL_{parameter}` for template replacements and replaces AlgoKit deploy-time control parameters\n * if deployment metadata is specified.\n *\n * * `TMPL_UPDATABLE` for updatability / immutability control\n * * `TMPL_DELETABLE` for deletability / permanence control\n *\n * @param tealTemplateCode The TEAL logic to compile\n * @param templateParams Any parameters to replace in the .teal file before compiling\n * @param deploymentMetadata The deployment metadata the app will be deployed with\n * @returns The information about the compiled code\n */\n async compileTealTemplate(\n tealTemplateCode: string,\n templateParams?: TealTemplateParams,\n deploymentMetadata?: { updatable?: boolean; deletable?: boolean },\n ): Promise<CompiledTeal> {\n let tealCode = AppManager.stripTealComments(tealTemplateCode)\n\n tealCode = AppManager.replaceTealTemplateParams(tealCode, templateParams)\n\n if (deploymentMetadata) {\n tealCode = AppManager.replaceTealTemplateDeployTimeControlParams(tealCode, deploymentMetadata)\n }\n\n return await this.compileTeal(tealCode)\n }\n\n /**\n * Returns a previous compilation result.\n * @param tealCode The TEAL code\n * @returns The information about the previously compiled file\n * or `undefined` if that TEAL code wasn't previously compiled\n */\n getCompilationResult(tealCode: string): CompiledTeal | undefined {\n return this._compilationResults[tealCode]\n }\n\n /**\n * Returns the current app information for the app with the given ID.\n *\n * @example\n * ```typescript\n * const appInfo = await appManager.getById(12353n);\n * ```\n *\n * @param appId The ID of the app\n * @returns The app information\n */\n public async getById(appId: bigint): Promise<AppInformation> {\n const app = await this._algod.getApplicationByID(Number(appId)).do()\n return {\n appId: BigInt(app.id),\n appAddress: algosdk.getApplicationAddress(app.id),\n approvalProgram: app.params.approvalProgram,\n clearStateProgram: app.params.clearStateProgram,\n creator: app.params.creator,\n localInts: Number(app.params.localStateSchema?.numUint ?? 0),\n localByteSlices: Number(app.params.localStateSchema?.numByteSlice ?? 0),\n globalInts: Number(app.params.globalStateSchema?.numUint ?? 0),\n globalByteSlices: Number(app.params.globalStateSchema?.numByteSlice ?? 0),\n extraProgramPages: Number(app.params.extraProgramPages ?? 0),\n globalState: AppManager.decodeAppState(app.params.globalState ?? []),\n }\n }\n\n /**\n * Returns the current global state values for the given app ID and account address\n *\n * @param appId The ID of the app to return global state for\n * @returns The current global state for the given app\n */\n public async getGlobalState(appId: bigint) {\n return (await this.getById(appId)).globalState\n }\n\n /**\n * Returns the current local state values for the given app ID and account address\n *\n * @param appId The ID of the app to return local state for\n * @param address The string address of the account to get local state for the given app\n * @returns The current local state for the given (app, account) combination\n */\n public async getLocalState(appId: bigint, address: Address | string) {\n const appInfo = await this._algod.accountApplicationInformation(address, appId).do()\n\n if (!appInfo.appLocalState?.keyValue) {\n throw new Error(\"Couldn't find local state\")\n }\n\n return AppManager.decodeAppState(appInfo.appLocalState.keyValue)\n }\n\n /**\n * Returns the names of the current boxes for the given app.\n * @param appId The ID of the app return box names for\n * @returns The current box names\n */\n public async getBoxNames(appId: bigint): Promise<BoxName[]> {\n const boxResult = await this._algod.getApplicationBoxes(appId).do()\n return boxResult.boxes.map((b) => {\n return {\n nameRaw: b.name,\n nameBase64: Buffer.from(b.name).toString('base64'),\n name: Buffer.from(b.name).toString('utf-8'),\n }\n })\n }\n\n /**\n * Returns the value of the given box name for the given app.\n * @param appId The ID of the app return box names for\n * @param boxName The name of the box to return either as a string, binary array or `BoxName`\n * @returns The current box value as a byte array\n */\n public async getBoxValue(appId: bigint, boxName: BoxIdentifier): Promise<Uint8Array> {\n const name = AppManager.getBoxReference(boxName).name\n const boxResult = await this._algod.getApplicationBoxByName(Number(appId), name).do()\n return boxResult.value\n }\n\n /**\n * Returns the value of the given box names for the given app.\n * @param appId The ID of the app return box names for\n * @param boxNames The names of the boxes to return either as a string, binary array or `BoxName`\n * @returns The current box values as a byte array in the same order as the passed in box names\n */\n public async getBoxValues(appId: bigint, boxNames: BoxIdentifier[]): Promise<Uint8Array[]> {\n return await Promise.all(boxNames.map(async (boxName) => await this.getBoxValue(appId, boxName)))\n }\n\n /**\n * Returns the value of the given box name for the given app decoded based on the given ABI type.\n * @param request The parameters for the box value request\n * @returns The current box value as an ABI value\n */\n public async getBoxValueFromABIType(request: BoxValueRequestParams): Promise<algosdk.ABIValue> {\n const { appId, boxName, type } = request\n const value = await this.getBoxValue(appId, boxName)\n return type.decode(value)\n }\n\n /**\n * Returns the value of the given box names for the given app decoded based on the given ABI type.\n * @param request The parameters for the box value request\n * @returns The current box values as an ABI value in the same order as the passed in box names\n */\n public async getBoxValuesFromABIType(request: BoxValuesRequestParams): Promise<algosdk.ABIValue[]> {\n const { appId, boxNames, type } = request\n return await Promise.all(boxNames.map(async (boxName) => await this.getBoxValueFromABIType({ appId, boxName, type })))\n }\n\n /**\n * Returns a `algosdk.BoxReference` given a `BoxIdentifier` or `BoxReference`.\n * @param boxId The box to return a reference for\n * @returns The box reference ready to pass into a `algosdk.Transaction`\n */\n public static getBoxReference(boxId: BoxIdentifier | BoxReference): algosdk.BoxReference {\n const ref = typeof boxId === 'object' && 'appId' in boxId ? boxId : { appId: 0n, name: boxId }\n return {\n appIndex: ref.appId,\n name: typeof ref.name === 'string' ? new TextEncoder().encode(ref.name) : 'length' in ref.name ? ref.name : ref.name.addr.publicKey,\n } as algosdk.BoxReference\n }\n\n /**\n * Converts an array of global/local state values from the algod api to a more friendly\n * generic object keyed by the UTF-8 value of the key.\n * @param state A `global-state`, `local-state`, `global-state-deltas` or `local-state-deltas`\n * @returns An object keyeed by the UTF-8 representation of the key with various parsings of the values\n */\n public static decodeAppState(state: { key: Uint8Array; value: modelsv2.TealValue | modelsv2.EvalDelta }[]): AppState {\n const stateValues = {} as AppState\n\n // Start with empty set\n for (const stateVal of state) {\n const keyBase64 = Buffer.from(stateVal.key).toString('base64')\n const keyRaw = stateVal.key\n const key = Buffer.from(stateVal.key).toString('utf-8')\n const tealValue = stateVal.value\n\n const dataTypeFlag = 'action' in tealValue ? tealValue.action : tealValue.type\n let valueBase64: string\n let valueRaw: Buffer\n switch (dataTypeFlag) {\n case 1:\n valueBase64 =\n typeof tealValue.bytes === 'string' ? tealValue.bytes : tealValue.bytes ? Buffer.from(tealValue.bytes).toString('base64') : ''\n valueRaw = Buffer.from(valueBase64, 'base64')\n stateValues[key] = {\n keyRaw,\n keyBase64,\n valueRaw: new Uint8Array(valueRaw),\n valueBase64: valueBase64,\n value: valueRaw.toString('utf-8'),\n }\n break\n case 2: {\n const value = tealValue.uint ?? 0\n stateValues[key] = {\n keyRaw,\n keyBase64,\n value: BigInt(value),\n }\n break\n }\n default:\n throw new Error(`Received unknown state data type of ${dataTypeFlag}`)\n }\n }\n\n return stateValues\n }\n\n /**\n * Returns any ABI return values for the given app call arguments and transaction confirmation.\n * @param confirmation The transaction confirmation from algod\n * @param method The ABI method\n * @returns The return value for the method call\n */\n public static getABIReturn(\n confirmation: modelsv2.PendingTransactionResponse | undefined,\n method: algosdk.ABIMethod | undefined,\n ): ABIReturn | undefined {\n if (!method || !confirmation || method.returns.type === 'void') {\n return undefined\n }\n\n // The parseMethodResponse method mutates the second parameter :(\n const resultDummy: algosdk.ABIResult = {\n txID: '',\n method,\n rawReturnValue: new Uint8Array(),\n }\n return getABIReturnValue(algosdk.AtomicTransactionComposer.parseMethodResponse(method, resultDummy, confirmation))\n }\n\n /**\n * Replaces AlgoKit deploy-time deployment control parameters within the given TEAL template code.\n *\n * * `TMPL_UPDATABLE` for updatability / immutability control\n * * `TMPL_DELETABLE` for deletability / permanence control\n *\n * Note: If these values are defined, but the corresponding `TMPL_*` value\n * isn't in the teal code it will throw an exception.\n *\n * @param tealTemplateCode The TEAL template code to substitute\n * @param params The deploy-time deployment control parameter value to replace\n * @returns The replaced TEAL code\n */\n static replaceTealTemplateDeployTimeControlParams(tealTemplateCode: string, params: { updatable?: boolean; deletable?: boolean }) {\n if (params.updatable !== undefined) {\n if (!tealTemplateCode.includes(UPDATABLE_TEMPLATE_NAME)) {\n throw new Error(\n `Deploy-time updatability control requested for app deployment, but ${UPDATABLE_TEMPLATE_NAME} not present in TEAL code`,\n )\n }\n tealTemplateCode = replaceTemplateVariable(tealTemplateCode, UPDATABLE_TEMPLATE_NAME, (params.updatable ? 1 : 0).toString())\n }\n\n if (params.deletable !== undefined) {\n if (!tealTemplateCode.includes(DELETABLE_TEMPLATE_NAME)) {\n throw new Error(\n `Deploy-time deletability control requested for app deployment, but ${DELETABLE_TEMPLATE_NAME} not present in TEAL code`,\n )\n }\n tealTemplateCode = replaceTemplateVariable(tealTemplateCode, DELETABLE_TEMPLATE_NAME, (params.deletable ? 1 : 0).toString())\n }\n\n return tealTemplateCode\n }\n\n /**\n * Performs template substitution of a teal file.\n *\n * Looks for `TMPL_{parameter}` for template replacements.\n *\n * @param tealTemplateCode The TEAL template code to make parameter replacements in\n * @param templateParams Any parameters to replace in the teal code\n * @returns The TEAL code with replacements\n */\n static replaceTealTemplateParams(tealTemplateCode: string, templateParams?: TealTemplateParams) {\n if (templateParams !== undefined) {\n for (const key in templateParams) {\n const value = templateParams[key]\n const token = `TMPL_${key.replace(/^TMPL_/, '')}`\n\n // If this is a number, first replace any byte representations of the number\n // These may appear in the TEAL in order to circumvent int compression and preserve PC values\n if (typeof value === 'number' || typeof value === 'bigint') {\n tealTemplateCode = tealTemplateCode.replace(new RegExp(`(?<=bytes )${token}`, 'g'), `0x${value.toString(16).padStart(16, '0')}`)\n\n // We could probably return here since mixing pushint and pushbytes is likely not going to happen, but might as well do both\n }\n\n tealTemplateCode = replaceTemplateVariable(\n tealTemplateCode,\n token,\n typeof value === 'string'\n ? `0x${Buffer.from(value, 'utf-8').toString('hex')}`\n : ArrayBuffer.isView(value)\n ? `0x${Buffer.from(value).toString('hex')}`\n : value.toString(),\n )\n }\n }\n\n return tealTemplateCode\n }\n\n /**\n * Remove comments from TEAL code (useful to reduce code size before compilation).\n *\n * @param tealCode The TEAL logic to strip\n * @returns The TEAL without comments\n */\n static stripTealComments(tealCode: string) {\n const stripCommentFromLine = (line: string) => {\n const commentIndex = findUnquotedString(line, '//')\n if (commentIndex === undefined) {\n return line\n }\n return line.slice(0, commentIndex).trimEnd()\n }\n\n return tealCode\n .split('\\n')\n .map((line) => stripCommentFromLine(line))\n .join('\\n')\n }\n}\n\n/**\n * Find the first string within a line of TEAL. Only matches outside of quotes and base64 are returned.\n * Returns undefined if not found\n */\nconst findUnquotedString = (line: string, token: string, startIndex: number = 0, _endIndex?: number): number | undefined => {\n const endIndex = _endIndex === undefined ? line.length : _endIndex\n let index = startIndex\n let inQuotes = false\n let inBase64 = false\n\n while (index < endIndex) {\n const currentChar = line[index]\n if ((currentChar === ' ' || currentChar === '(') && !inQuotes && lastTokenBase64(line, index)) {\n // enter base64\n inBase64 = true\n } else if ((currentChar === ' ' || currentChar === ')') && !inQuotes && inBase64) {\n // exit base64\n inBase64 = false\n } else if (currentChar === '\\\\' && inQuotes) {\n // escaped char, skip next character\n index += 1\n } else if (currentChar === '\"') {\n // quote boundary\n inQuotes = !inQuotes\n } else if (!inQuotes && !inBase64 && line.startsWith(token, index)) {\n // can test for match\n return index\n }\n index += 1\n }\n return undefined\n}\n\nconst lastTokenBase64 = (line: string, index: number): boolean => {\n try {\n const tokens = line.slice(0, index).split(/\\s+/)\n const last = tokens[tokens.length - 1]\n return ['base64', 'b64'].includes(last)\n } catch {\n return false\n }\n}\n\nfunction replaceTemplateVariable(program: string, token: string, replacement: string): string {\n const result: string[] = []\n const tokenIndexOffset = replacement.length - token.length\n\n const programLines = program.split('\\n')\n\n for (const line of programLines) {\n const _commentIndex = findUnquotedString(line, '//')\n const commentIndex = _commentIndex === undefined ? line.length : _commentIndex\n let code = line.substring(0, commentIndex)\n const comment = line.substring(commentIndex)\n let trailingIndex = 0\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const tokenIndex = findTemplateToken(code, token, trailingIndex)\n if (tokenIndex === undefined) {\n break\n }\n trailingIndex = tokenIndex + token.length\n const prefix = code.substring(0, tokenIndex)\n const suffix = code.substring(trailingIndex)\n code = `${prefix}${replacement}${suffix}`\n trailingIndex += tokenIndexOffset\n }\n result.push(code + comment)\n }\n\n return result.join('\\n')\n}\n\nconst findTemplateToken = (line: string, token: string, startIndex: number = 0, _endIndex?: number): number | undefined => {\n const endIndex = _endIndex === undefined ? line.length : _endIndex\n\n let index = startIndex\n while (index < endIndex) {\n const tokenIndex = findUnquotedString(line, token, index, endIndex)\n if (tokenIndex === undefined) {\n break\n }\n const trailingIndex = tokenIndex + token.length\n if (\n (tokenIndex === 0 || !isValidTokenCharacter(line[tokenIndex - 1])) &&\n (trailingIndex >= line.length || !isValidTokenCharacter(line[trailingIndex]))\n ) {\n return tokenIndex\n }\n index = trailingIndex\n }\n return undefined\n}\n\nfunction isValidTokenCharacter(char: string): boolean {\n return char.length === 1 && (/\\w/.test(char) || char === '_')\n}\n"],"names":["ProgramSourceMap","getABIReturnValue","UPDATABLE_TEMPLATE_NAME","DELETABLE_TEMPLATE_NAME"],"mappings":"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"}
|
package/types/app-manager.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import algosdk from 'algosdk';
|
|
1
|
+
import algosdk, { ProgramSourceMap } from 'algosdk';
|
|
2
|
+
import { getABIReturnValue } from '../transaction/transaction.mjs';
|
|
2
3
|
import { UPDATABLE_TEMPLATE_NAME, DELETABLE_TEMPLATE_NAME } from './app.mjs';
|
|
3
4
|
|
|
4
|
-
var modelsv2 = algosdk.modelsv2;
|
|
5
5
|
/** Allows management of application information. */
|
|
6
6
|
class AppManager {
|
|
7
7
|
/**
|
|
@@ -33,7 +33,7 @@ class AppManager {
|
|
|
33
33
|
compiled: compiled.result,
|
|
34
34
|
compiledHash: compiled.hash,
|
|
35
35
|
compiledBase64ToBytes: new Uint8Array(Buffer.from(compiled.result, 'base64')),
|
|
36
|
-
sourceMap: new algosdk.
|
|
36
|
+
sourceMap: new ProgramSourceMap(JSON.parse(algosdk.encodeJSON(compiled.sourcemap))),
|
|
37
37
|
};
|
|
38
38
|
this._compilationResults[tealCode] = result;
|
|
39
39
|
return result;
|
|
@@ -81,7 +81,7 @@ class AppManager {
|
|
|
81
81
|
* @returns The app information
|
|
82
82
|
*/
|
|
83
83
|
async getById(appId) {
|
|
84
|
-
const app =
|
|
84
|
+
const app = await this._algod.getApplicationByID(Number(appId)).do();
|
|
85
85
|
return {
|
|
86
86
|
appId: BigInt(app.id),
|
|
87
87
|
appAddress: algosdk.getApplicationAddress(app.id),
|
|
@@ -113,7 +113,7 @@ class AppManager {
|
|
|
113
113
|
* @returns The current local state for the given (app, account) combination
|
|
114
114
|
*/
|
|
115
115
|
async getLocalState(appId, address) {
|
|
116
|
-
const appInfo =
|
|
116
|
+
const appInfo = await this._algod.accountApplicationInformation(address, appId).do();
|
|
117
117
|
if (!appInfo.appLocalState?.keyValue) {
|
|
118
118
|
throw new Error("Couldn't find local state");
|
|
119
119
|
}
|
|
@@ -125,7 +125,7 @@ class AppManager {
|
|
|
125
125
|
* @returns The current box names
|
|
126
126
|
*/
|
|
127
127
|
async getBoxNames(appId) {
|
|
128
|
-
const boxResult = await this._algod.getApplicationBoxes(
|
|
128
|
+
const boxResult = await this._algod.getApplicationBoxes(appId).do();
|
|
129
129
|
return boxResult.boxes.map((b) => {
|
|
130
130
|
return {
|
|
131
131
|
nameRaw: b.name,
|
|
@@ -181,12 +181,8 @@ class AppManager {
|
|
|
181
181
|
static getBoxReference(boxId) {
|
|
182
182
|
const ref = typeof boxId === 'object' && 'appId' in boxId ? boxId : { appId: 0n, name: boxId };
|
|
183
183
|
return {
|
|
184
|
-
appIndex:
|
|
185
|
-
name: typeof ref.name === 'string'
|
|
186
|
-
? new TextEncoder().encode(ref.name)
|
|
187
|
-
: 'length' in ref.name
|
|
188
|
-
? ref.name
|
|
189
|
-
: algosdk.decodeAddress(ref.name.addr).publicKey,
|
|
184
|
+
appIndex: ref.appId,
|
|
185
|
+
name: typeof ref.name === 'string' ? new TextEncoder().encode(ref.name) : 'length' in ref.name ? ref.name : ref.name.addr.publicKey,
|
|
190
186
|
};
|
|
191
187
|
}
|
|
192
188
|
/**
|
|
@@ -199,16 +195,17 @@ class AppManager {
|
|
|
199
195
|
const stateValues = {};
|
|
200
196
|
// Start with empty set
|
|
201
197
|
for (const stateVal of state) {
|
|
202
|
-
const keyBase64 = stateVal.key;
|
|
203
|
-
const keyRaw =
|
|
204
|
-
const key =
|
|
198
|
+
const keyBase64 = Buffer.from(stateVal.key).toString('base64');
|
|
199
|
+
const keyRaw = stateVal.key;
|
|
200
|
+
const key = Buffer.from(stateVal.key).toString('utf-8');
|
|
205
201
|
const tealValue = stateVal.value;
|
|
206
202
|
const dataTypeFlag = 'action' in tealValue ? tealValue.action : tealValue.type;
|
|
207
203
|
let valueBase64;
|
|
208
204
|
let valueRaw;
|
|
209
205
|
switch (dataTypeFlag) {
|
|
210
206
|
case 1:
|
|
211
|
-
valueBase64 =
|
|
207
|
+
valueBase64 =
|
|
208
|
+
typeof tealValue.bytes === 'string' ? tealValue.bytes : tealValue.bytes ? Buffer.from(tealValue.bytes).toString('base64') : '';
|
|
212
209
|
valueRaw = Buffer.from(valueBase64, 'base64');
|
|
213
210
|
stateValues[key] = {
|
|
214
211
|
keyRaw,
|
|
@@ -249,19 +246,7 @@ class AppManager {
|
|
|
249
246
|
method,
|
|
250
247
|
rawReturnValue: new Uint8Array(),
|
|
251
248
|
};
|
|
252
|
-
|
|
253
|
-
return !response.decodeError
|
|
254
|
-
? {
|
|
255
|
-
rawReturnValue: response.rawReturnValue,
|
|
256
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
257
|
-
returnValue: response.returnValue,
|
|
258
|
-
decodeError: undefined,
|
|
259
|
-
}
|
|
260
|
-
: {
|
|
261
|
-
rawReturnValue: undefined,
|
|
262
|
-
returnValue: undefined,
|
|
263
|
-
decodeError: response.decodeError,
|
|
264
|
-
};
|
|
249
|
+
return getABIReturnValue(algosdk.AtomicTransactionComposer.parseMethodResponse(method, resultDummy, confirmation));
|
|
265
250
|
}
|
|
266
251
|
/**
|
|
267
252
|
* Replaces AlgoKit deploy-time deployment control parameters within the given TEAL template code.
|
|
@@ -281,13 +266,13 @@ class AppManager {
|
|
|
281
266
|
if (!tealTemplateCode.includes(UPDATABLE_TEMPLATE_NAME)) {
|
|
282
267
|
throw new Error(`Deploy-time updatability control requested for app deployment, but ${UPDATABLE_TEMPLATE_NAME} not present in TEAL code`);
|
|
283
268
|
}
|
|
284
|
-
tealTemplateCode = tealTemplateCode
|
|
269
|
+
tealTemplateCode = replaceTemplateVariable(tealTemplateCode, UPDATABLE_TEMPLATE_NAME, (params.updatable ? 1 : 0).toString());
|
|
285
270
|
}
|
|
286
271
|
if (params.deletable !== undefined) {
|
|
287
272
|
if (!tealTemplateCode.includes(DELETABLE_TEMPLATE_NAME)) {
|
|
288
273
|
throw new Error(`Deploy-time deletability control requested for app deployment, but ${DELETABLE_TEMPLATE_NAME} not present in TEAL code`);
|
|
289
274
|
}
|
|
290
|
-
tealTemplateCode = tealTemplateCode
|
|
275
|
+
tealTemplateCode = replaceTemplateVariable(tealTemplateCode, DELETABLE_TEMPLATE_NAME, (params.deletable ? 1 : 0).toString());
|
|
291
276
|
}
|
|
292
277
|
return tealTemplateCode;
|
|
293
278
|
}
|
|
@@ -311,7 +296,7 @@ class AppManager {
|
|
|
311
296
|
tealTemplateCode = tealTemplateCode.replace(new RegExp(`(?<=bytes )${token}`, 'g'), `0x${value.toString(16).padStart(16, '0')}`);
|
|
312
297
|
// We could probably return here since mixing pushint and pushbytes is likely not going to happen, but might as well do both
|
|
313
298
|
}
|
|
314
|
-
tealTemplateCode = tealTemplateCode
|
|
299
|
+
tealTemplateCode = replaceTemplateVariable(tealTemplateCode, token, typeof value === 'string'
|
|
315
300
|
? `0x${Buffer.from(value, 'utf-8').toString('hex')}`
|
|
316
301
|
: ArrayBuffer.isView(value)
|
|
317
302
|
? `0x${Buffer.from(value).toString('hex')}`
|
|
@@ -327,17 +312,110 @@ class AppManager {
|
|
|
327
312
|
* @returns The TEAL without comments
|
|
328
313
|
*/
|
|
329
314
|
static stripTealComments(tealCode) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
315
|
+
const stripCommentFromLine = (line) => {
|
|
316
|
+
const commentIndex = findUnquotedString(line, '//');
|
|
317
|
+
if (commentIndex === undefined) {
|
|
318
|
+
return line;
|
|
319
|
+
}
|
|
320
|
+
return line.slice(0, commentIndex).trimEnd();
|
|
321
|
+
};
|
|
322
|
+
return tealCode
|
|
333
323
|
.split('\n')
|
|
334
|
-
.map((
|
|
335
|
-
return tealCodeLine.split(regex)[0].trim();
|
|
336
|
-
})
|
|
324
|
+
.map((line) => stripCommentFromLine(line))
|
|
337
325
|
.join('\n');
|
|
338
|
-
return tealCode;
|
|
339
326
|
}
|
|
340
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* Find the first string within a line of TEAL. Only matches outside of quotes and base64 are returned.
|
|
330
|
+
* Returns undefined if not found
|
|
331
|
+
*/
|
|
332
|
+
const findUnquotedString = (line, token, startIndex = 0, _endIndex) => {
|
|
333
|
+
const endIndex = _endIndex === undefined ? line.length : _endIndex;
|
|
334
|
+
let index = startIndex;
|
|
335
|
+
let inQuotes = false;
|
|
336
|
+
let inBase64 = false;
|
|
337
|
+
while (index < endIndex) {
|
|
338
|
+
const currentChar = line[index];
|
|
339
|
+
if ((currentChar === ' ' || currentChar === '(') && !inQuotes && lastTokenBase64(line, index)) {
|
|
340
|
+
// enter base64
|
|
341
|
+
inBase64 = true;
|
|
342
|
+
}
|
|
343
|
+
else if ((currentChar === ' ' || currentChar === ')') && !inQuotes && inBase64) {
|
|
344
|
+
// exit base64
|
|
345
|
+
inBase64 = false;
|
|
346
|
+
}
|
|
347
|
+
else if (currentChar === '\\' && inQuotes) {
|
|
348
|
+
// escaped char, skip next character
|
|
349
|
+
index += 1;
|
|
350
|
+
}
|
|
351
|
+
else if (currentChar === '"') {
|
|
352
|
+
// quote boundary
|
|
353
|
+
inQuotes = !inQuotes;
|
|
354
|
+
}
|
|
355
|
+
else if (!inQuotes && !inBase64 && line.startsWith(token, index)) {
|
|
356
|
+
// can test for match
|
|
357
|
+
return index;
|
|
358
|
+
}
|
|
359
|
+
index += 1;
|
|
360
|
+
}
|
|
361
|
+
return undefined;
|
|
362
|
+
};
|
|
363
|
+
const lastTokenBase64 = (line, index) => {
|
|
364
|
+
try {
|
|
365
|
+
const tokens = line.slice(0, index).split(/\s+/);
|
|
366
|
+
const last = tokens[tokens.length - 1];
|
|
367
|
+
return ['base64', 'b64'].includes(last);
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
function replaceTemplateVariable(program, token, replacement) {
|
|
374
|
+
const result = [];
|
|
375
|
+
const tokenIndexOffset = replacement.length - token.length;
|
|
376
|
+
const programLines = program.split('\n');
|
|
377
|
+
for (const line of programLines) {
|
|
378
|
+
const _commentIndex = findUnquotedString(line, '//');
|
|
379
|
+
const commentIndex = _commentIndex === undefined ? line.length : _commentIndex;
|
|
380
|
+
let code = line.substring(0, commentIndex);
|
|
381
|
+
const comment = line.substring(commentIndex);
|
|
382
|
+
let trailingIndex = 0;
|
|
383
|
+
// eslint-disable-next-line no-constant-condition
|
|
384
|
+
while (true) {
|
|
385
|
+
const tokenIndex = findTemplateToken(code, token, trailingIndex);
|
|
386
|
+
if (tokenIndex === undefined) {
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
trailingIndex = tokenIndex + token.length;
|
|
390
|
+
const prefix = code.substring(0, tokenIndex);
|
|
391
|
+
const suffix = code.substring(trailingIndex);
|
|
392
|
+
code = `${prefix}${replacement}${suffix}`;
|
|
393
|
+
trailingIndex += tokenIndexOffset;
|
|
394
|
+
}
|
|
395
|
+
result.push(code + comment);
|
|
396
|
+
}
|
|
397
|
+
return result.join('\n');
|
|
398
|
+
}
|
|
399
|
+
const findTemplateToken = (line, token, startIndex = 0, _endIndex) => {
|
|
400
|
+
const endIndex = line.length ;
|
|
401
|
+
let index = startIndex;
|
|
402
|
+
while (index < endIndex) {
|
|
403
|
+
const tokenIndex = findUnquotedString(line, token, index, endIndex);
|
|
404
|
+
if (tokenIndex === undefined) {
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
const trailingIndex = tokenIndex + token.length;
|
|
408
|
+
if ((tokenIndex === 0 || !isValidTokenCharacter(line[tokenIndex - 1])) &&
|
|
409
|
+
(trailingIndex >= line.length || !isValidTokenCharacter(line[trailingIndex]))) {
|
|
410
|
+
return tokenIndex;
|
|
411
|
+
}
|
|
412
|
+
index = trailingIndex;
|
|
413
|
+
}
|
|
414
|
+
return undefined;
|
|
415
|
+
};
|
|
416
|
+
function isValidTokenCharacter(char) {
|
|
417
|
+
return char.length === 1 && (/\w/.test(char) || char === '_');
|
|
418
|
+
}
|
|
341
419
|
|
|
342
420
|
export { AppManager };
|
|
343
421
|
//# sourceMappingURL=app-manager.mjs.map
|