@platforma-sdk/tengo-builder 2.3.13 → 2.4.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/dist/compiler/source.cjs +156 -92
- package/dist/compiler/source.cjs.map +1 -1
- package/dist/compiler/source.d.ts +8 -6
- package/dist/compiler/source.d.ts.map +1 -1
- package/dist/compiler/source.js +156 -92
- package/dist/compiler/source.js.map +1 -1
- package/dist/compiler/test.artifacts.d.ts +5 -2
- package/dist/compiler/test.artifacts.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/compiler/source.test.ts +209 -50
- package/src/compiler/source.ts +203 -108
- package/src/compiler/test.artifacts.ts +50 -4
package/src/compiler/source.ts
CHANGED
|
@@ -20,33 +20,37 @@ const functionCallRE = (moduleName: string, fnName: string) => {
|
|
|
20
20
|
`\\b${moduleName}\\.(?<fnCall>(?<fnName>`
|
|
21
21
|
+ fnName
|
|
22
22
|
+ `)\\s*\\(\\s*"(?<templateName>[^"]+)"\\s*\\))`,
|
|
23
|
+
'g',
|
|
23
24
|
);
|
|
24
25
|
};
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const functionCallLikeRE = (moduleName: string, fnName: string) => {
|
|
28
|
+
return new RegExp(
|
|
29
|
+
`\\b${moduleName}\\.(?<fnName>`
|
|
30
|
+
+ fnName
|
|
31
|
+
+ `)\\s*\\(`,
|
|
32
|
+
'g',
|
|
33
|
+
);
|
|
31
34
|
};
|
|
32
35
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
export const newGetTemplateIdRE = (moduleName: string) => functionCallRE(moduleName, 'getTemplateId');
|
|
37
|
+
export const newGetSoftwareInfoRE = (moduleName: string) => functionCallRE(moduleName, 'getSoftwareInfo');
|
|
38
|
+
|
|
39
|
+
const newImportTemplateRE = (moduleName: string) => functionCallRE(moduleName, 'importTemplate');
|
|
40
|
+
const newImportTemplateDetector = (moduleName: string) => functionCallLikeRE(moduleName, 'importTemplate');
|
|
41
|
+
const newImportSoftwareRE = (moduleName: string) => functionCallRE(moduleName, 'importSoftware');
|
|
42
|
+
const newImportSoftwareDetector = (moduleName: string) => functionCallLikeRE(moduleName, 'importSoftware');
|
|
43
|
+
const newImportAssetRE = (moduleName: string) => functionCallRE(moduleName, 'importAsset');
|
|
44
|
+
const newImportAssetDetector = (moduleName: string) => functionCallLikeRE(moduleName, 'importAsset');
|
|
42
45
|
|
|
43
46
|
const emptyLineRE = /^\s*$/;
|
|
44
47
|
const compilerOptionRE = /^\/\/tengo:[\w]/;
|
|
45
48
|
const wrongCompilerOptionRE = /^\s*\/\/\s*tengo:\s*./;
|
|
46
|
-
const inlineCommentRE = /\/\*.*?\*\//g; // .*? = non-greedy search
|
|
47
49
|
const singlelineCommentRE = /^\s*(\/\/)/;
|
|
50
|
+
const singlelineTerminatedCommentRE = /^\s*\/\*.*\*\/\s*$/; // matches '^/* ... */$' comment lines as a special case of singleline comments.
|
|
48
51
|
const multilineCommentStartRE = /^\s*\/\*/;
|
|
49
52
|
const multilineCommentEndRE = /\*\//;
|
|
53
|
+
const multilineStatementRE = /[.,]\s*$/; // it is hard to consistently treat (\n"a"\n) multiline statements, we forbid them for now.
|
|
50
54
|
|
|
51
55
|
// import could only be an assignment in a statement,
|
|
52
56
|
// other ways could break a compilation.
|
|
@@ -163,7 +167,9 @@ function parseSourceData(
|
|
|
163
167
|
let parserContext: sourceParserContext = {
|
|
164
168
|
isInCommentBlock: false,
|
|
165
169
|
canDetectOptions: true,
|
|
166
|
-
|
|
170
|
+
artifactImportREs: new Map<string, [ArtifactType, RegExp][]>(),
|
|
171
|
+
importLikeREs: new Map<string, [ArtifactType, RegExp][]>(),
|
|
172
|
+
multilineStatement: '',
|
|
167
173
|
lineNo: 0,
|
|
168
174
|
};
|
|
169
175
|
|
|
@@ -171,7 +177,7 @@ function parseSourceData(
|
|
|
171
177
|
parserContext.lineNo++;
|
|
172
178
|
|
|
173
179
|
try {
|
|
174
|
-
const { line: processedLine, context: newContext,
|
|
180
|
+
const { line: processedLine, context: newContext, artifacts, option } = parseSingleSourceLine(
|
|
175
181
|
logger,
|
|
176
182
|
line,
|
|
177
183
|
parserContext,
|
|
@@ -181,7 +187,7 @@ function parseSourceData(
|
|
|
181
187
|
processedLines.push(processedLine);
|
|
182
188
|
parserContext = newContext;
|
|
183
189
|
|
|
184
|
-
|
|
190
|
+
for (const artifact of artifacts ?? []) {
|
|
185
191
|
dependencySet.add(artifact);
|
|
186
192
|
}
|
|
187
193
|
if (option) {
|
|
@@ -200,12 +206,21 @@ function parseSourceData(
|
|
|
200
206
|
};
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
|
|
209
|
+
export type sourceParserContext = {
|
|
204
210
|
isInCommentBlock: boolean;
|
|
205
211
|
canDetectOptions: boolean;
|
|
206
|
-
|
|
212
|
+
artifactImportREs: Map<string, [ArtifactType, RegExp][]>;
|
|
213
|
+
importLikeREs: Map<string, [ArtifactType, RegExp][]>;
|
|
214
|
+
multilineStatement: string;
|
|
207
215
|
lineNo: number;
|
|
208
|
-
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export type lineProcessingResult = {
|
|
219
|
+
line: string;
|
|
220
|
+
context: sourceParserContext;
|
|
221
|
+
artifacts: TypedArtifactName[];
|
|
222
|
+
option: CompilerOption | undefined;
|
|
223
|
+
};
|
|
209
224
|
|
|
210
225
|
export function parseSingleSourceLine(
|
|
211
226
|
logger: MiLogger,
|
|
@@ -213,20 +228,12 @@ export function parseSingleSourceLine(
|
|
|
213
228
|
context: sourceParserContext,
|
|
214
229
|
localPackageName: string,
|
|
215
230
|
globalizeImports?: boolean,
|
|
216
|
-
): {
|
|
217
|
-
line: string;
|
|
218
|
-
context: sourceParserContext;
|
|
219
|
-
artifact: TypedArtifactName | undefined;
|
|
220
|
-
option: CompilerOption | undefined;
|
|
221
|
-
} {
|
|
222
|
-
// preprocess line and remove inline comments
|
|
223
|
-
line = line.replaceAll(inlineCommentRE, '');
|
|
224
|
-
|
|
231
|
+
): lineProcessingResult {
|
|
225
232
|
if (context.isInCommentBlock) {
|
|
226
233
|
if (multilineCommentEndRE.exec(line)) {
|
|
227
234
|
context.isInCommentBlock = false;
|
|
228
235
|
}
|
|
229
|
-
return { line: '', context,
|
|
236
|
+
return { line: '', context, artifacts: [], option: undefined };
|
|
230
237
|
}
|
|
231
238
|
|
|
232
239
|
if (compilerOptionRE.exec(line)) {
|
|
@@ -236,127 +243,215 @@ export function parseSingleSourceLine(
|
|
|
236
243
|
);
|
|
237
244
|
throw new Error('tengo compiler options (\'//tengo:\' comments) can be set only in file header');
|
|
238
245
|
}
|
|
239
|
-
return { line, context,
|
|
246
|
+
return { line, context, artifacts: [], option: parseComplierOption(line) };
|
|
240
247
|
}
|
|
241
248
|
|
|
242
249
|
if (wrongCompilerOptionRE.exec(line) && context.canDetectOptions) {
|
|
243
250
|
logger.warn(
|
|
244
251
|
`[line ${context.lineNo}]: text simillar to compiler option ('//tengo:...') was detected, but it has wrong format. Leave it as is, if you did not mean to use a line as compiler option. Or format it to '//tengo:<option>' otherwise (no spaces between '//' and 'tengo', no spaces between ':' and option name)`,
|
|
245
252
|
);
|
|
246
|
-
return { line, context,
|
|
253
|
+
return { line, context, artifacts: [], option: undefined };
|
|
247
254
|
}
|
|
248
255
|
|
|
249
|
-
if (singlelineCommentRE.test(line)) {
|
|
250
|
-
return { line: '', context,
|
|
256
|
+
if (singlelineCommentRE.test(line) || singlelineTerminatedCommentRE.test(line)) {
|
|
257
|
+
return { line: '', context, artifacts: [], option: undefined };
|
|
251
258
|
}
|
|
252
259
|
|
|
253
|
-
|
|
260
|
+
const canBeInlinedComment = line.includes('*/');
|
|
261
|
+
if (multilineCommentStartRE.exec(line) && !canBeInlinedComment) {
|
|
254
262
|
context.isInCommentBlock = true;
|
|
255
|
-
return { line: '', context,
|
|
263
|
+
return { line: '', context, artifacts: [], option: undefined };
|
|
256
264
|
}
|
|
257
265
|
|
|
258
|
-
|
|
259
|
-
|
|
266
|
+
const statement = context.multilineStatement + line.trim();
|
|
267
|
+
|
|
268
|
+
const mayContainAComment = line.includes('//') || line.includes('/*');
|
|
269
|
+
if (multilineStatementRE.test(line) && !mayContainAComment) {
|
|
270
|
+
// We accumulate multiline statements into single line before analyzing them.
|
|
271
|
+
// This dramatically simplifies parsing logic: things like
|
|
272
|
+
//
|
|
273
|
+
// assets.
|
|
274
|
+
// importSoftware("a:b");
|
|
275
|
+
//
|
|
276
|
+
// become simple 'assets.importSoftware("a:b");' for parser checks.
|
|
277
|
+
//
|
|
278
|
+
// For safety reasons, we never consider anything that 'may look like a comment'
|
|
279
|
+
// as a part of multiline statement to prevent joining things like
|
|
280
|
+
//
|
|
281
|
+
// someFnCall() // looks like multiline statement because of dot in the end of a comment.
|
|
282
|
+
//
|
|
283
|
+
// This problem also appears in multiline string literals, but I hope this will not
|
|
284
|
+
// cause problems in real life.
|
|
285
|
+
|
|
286
|
+
// We still try to process each line to globalize imports in case of complex constructions, when
|
|
287
|
+
// statements are stacked one into another:
|
|
288
|
+
// a.
|
|
289
|
+
// use(assets.importSoftware(":soft1")).
|
|
290
|
+
// use(assets.importSoftware(":soft2")).
|
|
291
|
+
// run()
|
|
292
|
+
// It is multiline, and it still requires import globalization mid-way, not just for the last line of statement
|
|
293
|
+
const result = processAssetImport(line, statement, context, localPackageName, globalizeImports);
|
|
294
|
+
context.multilineStatement += result.line.trim(); // accumulate the line after imports globalization.
|
|
295
|
+
return result;
|
|
260
296
|
}
|
|
261
297
|
|
|
262
|
-
|
|
263
|
-
|
|
298
|
+
context.multilineStatement = ''; // reset accumulated multiline statement parts once we reach statement end.
|
|
299
|
+
|
|
300
|
+
if (emptyLineRE.exec(statement)) {
|
|
301
|
+
return { line, context, artifacts: [], option: undefined };
|
|
264
302
|
}
|
|
265
303
|
|
|
266
304
|
// options could be only at the top of the file.
|
|
267
305
|
context.canDetectOptions = false;
|
|
268
306
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (importInstruction) {
|
|
272
|
-
const iInfo = parseImport(line);
|
|
273
|
-
|
|
274
|
-
// If we have plapi, ll or assets, then try to parse
|
|
275
|
-
// getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.
|
|
307
|
+
return processAssetImport(line, statement, context, localPackageName, globalizeImports);
|
|
308
|
+
}
|
|
276
309
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
310
|
+
function processModuleImport(
|
|
311
|
+
importInstruction: RegExpExecArray,
|
|
312
|
+
originalLine: string,
|
|
313
|
+
statement: string,
|
|
314
|
+
context: sourceParserContext,
|
|
315
|
+
localPackageName: string,
|
|
316
|
+
globalizeImports?: boolean,
|
|
317
|
+
): lineProcessingResult {
|
|
318
|
+
const iInfo = parseImport(statement);
|
|
319
|
+
|
|
320
|
+
// If we have plapi, ll or assets, then try to parse
|
|
321
|
+
// getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.
|
|
322
|
+
|
|
323
|
+
if (iInfo.module === 'plapi') {
|
|
324
|
+
if (!context.artifactImportREs.has(iInfo.module)) {
|
|
325
|
+
context.artifactImportREs.set(iInfo.module, [
|
|
326
|
+
['template', newGetTemplateIdRE(iInfo.alias)],
|
|
327
|
+
['software', newGetSoftwareInfoRE(iInfo.alias)],
|
|
328
|
+
]);
|
|
285
329
|
}
|
|
330
|
+
return { line: originalLine, context, artifacts: [], option: undefined };
|
|
331
|
+
}
|
|
286
332
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
333
|
+
if (
|
|
334
|
+
iInfo.module === '@milaboratory/tengo-sdk:ll'
|
|
335
|
+
|| iInfo.module === '@platforma-sdk/workflow-tengo:ll'
|
|
336
|
+
|| ((localPackageName === '@milaboratory/tengo-sdk'
|
|
337
|
+
|| localPackageName === '@platforma-sdk/workflow-tengo')
|
|
338
|
+
&& iInfo.module === ':ll')
|
|
339
|
+
) {
|
|
340
|
+
if (!context.artifactImportREs.has(iInfo.module)) {
|
|
341
|
+
context.artifactImportREs.set(iInfo.module, [
|
|
342
|
+
['template', newImportTemplateRE(iInfo.alias)],
|
|
343
|
+
['software', newImportSoftwareRE(iInfo.alias)],
|
|
344
|
+
]);
|
|
300
345
|
}
|
|
346
|
+
}
|
|
301
347
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
348
|
+
if (
|
|
349
|
+
iInfo.module === '@milaboratory/tengo-sdk:assets'
|
|
350
|
+
|| iInfo.module === '@platforma-sdk/workflow-tengo:assets'
|
|
351
|
+
|| ((localPackageName === '@milaboratory/tengo-sdk'
|
|
352
|
+
|| localPackageName === '@platforma-sdk/workflow-tengo')
|
|
353
|
+
&& iInfo.module === ':assets')
|
|
354
|
+
) {
|
|
355
|
+
if (!context.artifactImportREs.has(iInfo.module)) {
|
|
356
|
+
context.artifactImportREs.set(iInfo.module, [
|
|
357
|
+
['template', newImportTemplateRE(iInfo.alias)],
|
|
358
|
+
['software', newImportSoftwareRE(iInfo.alias)],
|
|
359
|
+
['asset', newImportAssetRE(iInfo.alias)],
|
|
360
|
+
]);
|
|
361
|
+
context.importLikeREs.set(iInfo.module, [
|
|
362
|
+
['template', newImportTemplateDetector(iInfo.alias)],
|
|
363
|
+
['software', newImportSoftwareDetector(iInfo.alias)],
|
|
364
|
+
['asset', newImportAssetDetector(iInfo.alias)],
|
|
365
|
+
]);
|
|
316
366
|
}
|
|
367
|
+
}
|
|
317
368
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
369
|
+
const artifact = parseArtifactName(iInfo.module, 'library', localPackageName);
|
|
370
|
+
if (!artifact) {
|
|
371
|
+
// not a Platforma Tengo library import
|
|
372
|
+
return { line: originalLine, context, artifacts: [], option: undefined };
|
|
373
|
+
}
|
|
323
374
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
375
|
+
if (globalizeImports) {
|
|
376
|
+
originalLine = originalLine.replace(importInstruction[0], ` := import("${artifact.pkg}:${artifact.id}")`);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return { line: originalLine, context, artifacts: [artifact], option: undefined };
|
|
380
|
+
}
|
|
327
381
|
|
|
328
|
-
|
|
382
|
+
function processAssetImport(
|
|
383
|
+
originalLine: string,
|
|
384
|
+
statement: string,
|
|
385
|
+
context: sourceParserContext,
|
|
386
|
+
localPackageName: string,
|
|
387
|
+
globalizeImports?: boolean,
|
|
388
|
+
): lineProcessingResult {
|
|
389
|
+
if (emptyLineRE.exec(statement)) {
|
|
390
|
+
return { line: originalLine, context, artifacts: [], option: undefined };
|
|
329
391
|
}
|
|
330
392
|
|
|
331
|
-
|
|
332
|
-
|
|
393
|
+
// options could be only at the top of the file.
|
|
394
|
+
context.canDetectOptions = false;
|
|
395
|
+
|
|
396
|
+
const importInstruction = importRE.exec(statement);
|
|
397
|
+
|
|
398
|
+
if (importInstruction) {
|
|
399
|
+
return processModuleImport(importInstruction, originalLine, statement, context, localPackageName, globalizeImports);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (context.artifactImportREs.size > 0) {
|
|
403
|
+
for (const [_, artifactRE] of context.artifactImportREs) {
|
|
333
404
|
for (const [artifactType, re] of artifactRE) {
|
|
334
|
-
|
|
335
|
-
|
|
405
|
+
// Find all matches in the statement
|
|
406
|
+
const matches = Array.from(statement.matchAll(re));
|
|
407
|
+
if (matches.length === 0) {
|
|
336
408
|
continue;
|
|
337
409
|
}
|
|
338
410
|
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
411
|
+
const artifacts: TypedArtifactName[] = [];
|
|
412
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
413
|
+
const match = matches[i];
|
|
414
|
+
if (!match || !match.groups) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const { fnCall, templateName, fnName } = match.groups;
|
|
419
|
+
|
|
420
|
+
if (!fnCall || !templateName || !fnName) {
|
|
421
|
+
throw Error(`failed to parse template import statement`);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const artifact = parseArtifactName(templateName, artifactType, localPackageName);
|
|
425
|
+
if (!artifact) {
|
|
426
|
+
throw Error(`failed to parse artifact name in ${fnName} import statement`);
|
|
427
|
+
}
|
|
428
|
+
artifacts.push(artifact);
|
|
429
|
+
|
|
430
|
+
if (globalizeImports) {
|
|
431
|
+
// Replace all occurrences of this fnCall in originalLine
|
|
432
|
+
originalLine = originalLine.replaceAll(fnCall, `${fnName}("${artifact.pkg}:${artifact.id}")`);
|
|
433
|
+
}
|
|
343
434
|
}
|
|
344
435
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
436
|
+
return { line: originalLine, context, artifacts, option: undefined };
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
349
440
|
|
|
350
|
-
|
|
351
|
-
|
|
441
|
+
if (context.importLikeREs.size > 0) {
|
|
442
|
+
for (const [_, artifactRE] of context.importLikeREs) {
|
|
443
|
+
for (const [artifactType, re] of artifactRE) {
|
|
444
|
+
const match = re.exec(statement);
|
|
445
|
+
if (!match || !match.groups) {
|
|
446
|
+
continue;
|
|
352
447
|
}
|
|
353
448
|
|
|
354
|
-
|
|
449
|
+
throw Error(`incorrect '${artifactType}' import statement: use string literal as ID (variables are not allowed) in the same line with brackets (i.e. 'importSoftware("sw:main")').`);
|
|
355
450
|
}
|
|
356
451
|
}
|
|
357
452
|
}
|
|
358
453
|
|
|
359
|
-
return { line, context,
|
|
454
|
+
return { line: originalLine, context, artifacts: [], option: undefined };
|
|
360
455
|
}
|
|
361
456
|
|
|
362
457
|
interface ImportInfo {
|
|
@@ -43,8 +43,10 @@ plapiCustomName := import("plapi" )
|
|
|
43
43
|
|
|
44
44
|
notplapiCustomName.getTemplateId( "some other:parameter")
|
|
45
45
|
|
|
46
|
-
plapiCustomName.getTemplateIdAnother("sss:kkk" )
|
|
47
|
-
plapiCustomName.getSoftwareInfo(":software-1")
|
|
46
|
+
/* inline comment */ plapiCustomName.getTemplateIdAnother("sss:kkk" )
|
|
47
|
+
plapiCustomName.getSoftwareInfo(":software-1") /* inline comment */
|
|
48
|
+
|
|
49
|
+
someCall("comment-like string literal/*")
|
|
48
50
|
|
|
49
51
|
export {
|
|
50
52
|
"some": "value",
|
|
@@ -58,8 +60,10 @@ plapiCustomName := import("plapi" )
|
|
|
58
60
|
|
|
59
61
|
notplapiCustomName.getTemplateId( "some other:parameter")
|
|
60
62
|
|
|
61
|
-
plapiCustomName.getTemplateIdAnother("sss:kkk" )
|
|
62
|
-
plapiCustomName.getSoftwareInfo("current-package:software-1")
|
|
63
|
+
/* inline comment */ plapiCustomName.getTemplateIdAnother("sss:kkk" )
|
|
64
|
+
plapiCustomName.getSoftwareInfo("current-package:software-1") /* inline comment */
|
|
65
|
+
|
|
66
|
+
someCall("comment-like string literal/*")
|
|
63
67
|
|
|
64
68
|
export {
|
|
65
69
|
"some": "value",
|
|
@@ -82,6 +86,24 @@ ll := import("@platforma-sdk/workflow-tengo:assets")
|
|
|
82
86
|
a := import(":non-existent-library")
|
|
83
87
|
*/
|
|
84
88
|
|
|
89
|
+
tplID := ll.importTemplate("package2:template-1")
|
|
90
|
+
softwareID := ll.importSoftware("package2:software-1")
|
|
91
|
+
assetID := ll.importAsset("package2:asset-1")
|
|
92
|
+
|
|
93
|
+
export {
|
|
94
|
+
"some": "value",
|
|
95
|
+
"template1": ll.importTemplate("current-package:local-template-2"),
|
|
96
|
+
"template2": tplID,
|
|
97
|
+
}
|
|
98
|
+
`;
|
|
99
|
+
export const testLocalLib2SrcNormalized = `
|
|
100
|
+
otherLib := import("package1:someid")
|
|
101
|
+
ll := import("@platforma-sdk/workflow-tengo:assets")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
85
107
|
tplID := ll.importTemplate("package2:template-1")
|
|
86
108
|
softwareID := ll.importSoftware("package2:software-1")
|
|
87
109
|
assetID := ll.importAsset("package2:asset-1")
|
|
@@ -269,3 +291,27 @@ export const testPackage2BrokenHash: TestArtifactSource[] = [
|
|
|
269
291
|
src: testLocalTpl3SrcWrongOverride,
|
|
270
292
|
},
|
|
271
293
|
];
|
|
294
|
+
|
|
295
|
+
export const testTrickyCasesSrc = `
|
|
296
|
+
assets := import("@platforma-sdk/workflow-tengo:assets")
|
|
297
|
+
exec := import("@platforma-sdk/workflow-tengo:exec")
|
|
298
|
+
|
|
299
|
+
run := exec.builder().
|
|
300
|
+
processWorkdir("p", assets.importTemplate(":test.wd_processor_1"), {}).
|
|
301
|
+
processWorkdir("q", assets.
|
|
302
|
+
importTemplate(":test.wd_processor_2"),
|
|
303
|
+
{}).
|
|
304
|
+
run()
|
|
305
|
+
`;
|
|
306
|
+
|
|
307
|
+
export const testTrickyCasesNormalized = `
|
|
308
|
+
assets := import("@platforma-sdk/workflow-tengo:assets")
|
|
309
|
+
exec := import("@platforma-sdk/workflow-tengo:exec")
|
|
310
|
+
|
|
311
|
+
run := exec.builder().
|
|
312
|
+
processWorkdir("p", assets.importTemplate("stub-pkg:test.wd_processor_1"), {}).
|
|
313
|
+
processWorkdir("q", assets.
|
|
314
|
+
importTemplate("stub-pkg:test.wd_processor_2"),
|
|
315
|
+
{}).
|
|
316
|
+
run()
|
|
317
|
+
`;
|