deepline 0.1.155 → 0.1.157
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/bundling-sources/apps/play-runner-workers/src/entry.ts +146 -14
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +53 -1
- package/dist/bundling-sources/sdk/src/play.ts +4 -2
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-contract.ts +8 -4
- package/dist/bundling-sources/shared_libs/play-runtime/execution-plan.ts +159 -42
- package/dist/bundling-sources/shared_libs/play-runtime/map-chunk-limits.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +0 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +19 -3
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +464 -226
- package/dist/cli/index.js +76 -29
- package/dist/cli/index.mjs +100 -49
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/plays/bundle-play-file.mjs +318 -181
- package/package.json +3 -1
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
resolve,
|
|
13
13
|
} from 'node:path';
|
|
14
14
|
import { builtinModules } from 'node:module';
|
|
15
|
-
import {
|
|
15
|
+
import { Parser } from 'acorn';
|
|
16
|
+
import { tsPlugin } from 'acorn-typescript';
|
|
17
|
+
import { build, transformSync, type Message, type Plugin } from 'esbuild';
|
|
16
18
|
import {
|
|
17
19
|
PLAY_ARTIFACT_KINDS,
|
|
18
20
|
type PlayArtifactKind,
|
|
@@ -438,30 +440,6 @@ function findSourceImportReferences(
|
|
|
438
440
|
);
|
|
439
441
|
}
|
|
440
442
|
|
|
441
|
-
function unquoteStringLiteral(literal: string): string | null {
|
|
442
|
-
const trimmed = literal.trim();
|
|
443
|
-
const quote = trimmed[0];
|
|
444
|
-
if (
|
|
445
|
-
(quote !== '"' && quote !== "'" && quote !== '`') ||
|
|
446
|
-
trimmed[trimmed.length - 1] !== quote
|
|
447
|
-
) {
|
|
448
|
-
return null;
|
|
449
|
-
}
|
|
450
|
-
if (quote === '`') {
|
|
451
|
-
const value = trimmed.slice(1, -1);
|
|
452
|
-
return value.includes('${') ? null : value;
|
|
453
|
-
}
|
|
454
|
-
try {
|
|
455
|
-
return JSON.parse(
|
|
456
|
-
quote === '"'
|
|
457
|
-
? trimmed
|
|
458
|
-
: `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`,
|
|
459
|
-
);
|
|
460
|
-
} catch {
|
|
461
|
-
return trimmed.slice(1, -1);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
443
|
function findMatchingBrace(source: string, openIndex: number): number {
|
|
466
444
|
const structuralSource = maskSourceForStructure(source);
|
|
467
445
|
let depth = 0;
|
|
@@ -476,262 +454,522 @@ function findMatchingBrace(source: string, openIndex: number): number {
|
|
|
476
454
|
return -1;
|
|
477
455
|
}
|
|
478
456
|
|
|
479
|
-
function findMatchingParen(source: string, openIndex: number): number {
|
|
480
|
-
const structuralSource = maskSourceForStructure(source);
|
|
481
|
-
let depth = 0;
|
|
482
|
-
for (let index = openIndex; index < structuralSource.length; index += 1) {
|
|
483
|
-
const char = structuralSource[index]!;
|
|
484
|
-
if (char === '(') depth += 1;
|
|
485
|
-
if (char === ')') {
|
|
486
|
-
depth -= 1;
|
|
487
|
-
if (depth === 0) return index;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
return -1;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
function splitTopLevelArguments(source: string): string[] {
|
|
494
|
-
const args: string[] = [];
|
|
495
|
-
const structuralSource = maskSourceForStructure(source);
|
|
496
|
-
let start = 0;
|
|
497
|
-
let parenDepth = 0;
|
|
498
|
-
let braceDepth = 0;
|
|
499
|
-
let bracketDepth = 0;
|
|
500
|
-
for (let index = 0; index < structuralSource.length; index += 1) {
|
|
501
|
-
const char = structuralSource[index]!;
|
|
502
|
-
if (char === '(') parenDepth += 1;
|
|
503
|
-
if (char === ')') parenDepth -= 1;
|
|
504
|
-
if (char === '{') braceDepth += 1;
|
|
505
|
-
if (char === '}') braceDepth -= 1;
|
|
506
|
-
if (char === '[') bracketDepth += 1;
|
|
507
|
-
if (char === ']') bracketDepth -= 1;
|
|
508
|
-
if (
|
|
509
|
-
char === ',' &&
|
|
510
|
-
parenDepth === 0 &&
|
|
511
|
-
braceDepth === 0 &&
|
|
512
|
-
bracketDepth === 0
|
|
513
|
-
) {
|
|
514
|
-
args.push(source.slice(start, index).trim());
|
|
515
|
-
start = index + 1;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
const finalArg = source.slice(start).trim();
|
|
519
|
-
if (finalArg) args.push(finalArg);
|
|
520
|
-
return args;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
function extractStringProperty(
|
|
524
|
-
objectSource: string,
|
|
525
|
-
propertyName: string,
|
|
526
|
-
): string | null {
|
|
527
|
-
for (const entry of splitTopLevelArguments(objectSource)) {
|
|
528
|
-
const structuralEntry = stripCommentsToSpaces(entry).trim();
|
|
529
|
-
const match = structuralEntry.match(
|
|
530
|
-
new RegExp(
|
|
531
|
-
`^(?:${propertyName}|['"]${propertyName}['"])\\s*:\\s*((['"\`])(?:\\\\.|(?!\\2)[\\s\\S])*\\2)\\s*$`,
|
|
532
|
-
),
|
|
533
|
-
);
|
|
534
|
-
const value = match?.[1] ? unquoteStringLiteral(match[1]) : null;
|
|
535
|
-
if (value?.trim()) return value.trim();
|
|
536
|
-
}
|
|
537
|
-
return null;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
457
|
export function extractDefinedPlayName(sourceCode: string): string | null {
|
|
541
|
-
|
|
542
|
-
const name = nameFromDefinePlayArguments(sourceCode, call.arguments);
|
|
543
|
-
if (name) return name;
|
|
544
|
-
}
|
|
545
|
-
return null;
|
|
458
|
+
return extractDefinedPlayMetadata(sourceCode, null)?.name ?? null;
|
|
546
459
|
}
|
|
547
460
|
|
|
548
461
|
export function extractDefinedPlayNameForExport(
|
|
549
462
|
sourceCode: string,
|
|
550
463
|
exportName: string,
|
|
551
464
|
): string | null {
|
|
552
|
-
return
|
|
553
|
-
sourceCode,
|
|
554
|
-
exportName,
|
|
555
|
-
nameFromDefinePlayArguments,
|
|
556
|
-
);
|
|
465
|
+
return extractDefinedPlayMetadata(sourceCode, exportName)?.name ?? null;
|
|
557
466
|
}
|
|
558
467
|
|
|
559
468
|
export function extractDefinedPlayDescription(
|
|
560
469
|
sourceCode: string,
|
|
561
470
|
): string | null {
|
|
562
|
-
return
|
|
563
|
-
sourceCode,
|
|
564
|
-
null,
|
|
565
|
-
descriptionFromDefinePlayArguments,
|
|
566
|
-
);
|
|
471
|
+
return extractDefinedPlayMetadata(sourceCode, null)?.description ?? null;
|
|
567
472
|
}
|
|
568
473
|
|
|
569
474
|
export function extractDefinedPlayDescriptionForExport(
|
|
570
475
|
sourceCode: string,
|
|
571
476
|
exportName: string,
|
|
572
477
|
): string | null {
|
|
573
|
-
return
|
|
574
|
-
sourceCode,
|
|
575
|
-
exportName,
|
|
576
|
-
descriptionFromDefinePlayArguments,
|
|
577
|
-
);
|
|
478
|
+
return extractDefinedPlayMetadata(sourceCode, exportName)?.description ?? null;
|
|
578
479
|
}
|
|
579
480
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
481
|
+
type AstNode = {
|
|
482
|
+
type: string;
|
|
483
|
+
[key: string]: unknown;
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
type PlayMetadataExtractionContext = {
|
|
487
|
+
declarations: Map<string, AstNode | null>;
|
|
488
|
+
namedExports: Map<string, string>;
|
|
489
|
+
commonJsExports: Map<string, AstNode>;
|
|
490
|
+
defaultExport: AstNode | null;
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
type ExtractedPlayMetadata = {
|
|
494
|
+
name: string | null;
|
|
495
|
+
description: string | null;
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
const TypeScriptParser = Parser.extend(
|
|
499
|
+
tsPlugin({
|
|
500
|
+
allowSatisfies: true,
|
|
501
|
+
jsx: {
|
|
502
|
+
allowNamespaces: true,
|
|
503
|
+
allowNamespacedObjects: true,
|
|
504
|
+
},
|
|
505
|
+
}) as unknown as (BaseParser: typeof Parser) => typeof Parser,
|
|
506
|
+
);
|
|
507
|
+
|
|
508
|
+
function parsePlaySourceAst(sourceCode: string): AstNode | null {
|
|
509
|
+
try {
|
|
510
|
+
return TypeScriptParser.parse(sourceCode, {
|
|
511
|
+
ecmaVersion: 'latest',
|
|
512
|
+
sourceType: 'module',
|
|
513
|
+
allowHashBang: true,
|
|
514
|
+
}) as unknown as AstNode;
|
|
515
|
+
} catch {
|
|
516
|
+
try {
|
|
517
|
+
const transformed = transformSync(sourceCode, {
|
|
518
|
+
loader: 'ts',
|
|
519
|
+
format: 'esm',
|
|
520
|
+
target: 'esnext',
|
|
521
|
+
legalComments: 'none',
|
|
522
|
+
sourcemap: false,
|
|
523
|
+
}).code;
|
|
524
|
+
return Parser.parse(transformed, {
|
|
525
|
+
ecmaVersion: 'latest',
|
|
526
|
+
sourceType: 'module',
|
|
527
|
+
allowHashBang: true,
|
|
528
|
+
}) as unknown as AstNode;
|
|
529
|
+
} catch {
|
|
530
|
+
return null;
|
|
592
531
|
}
|
|
593
|
-
const value = getMetadata(sourceCode, call.arguments);
|
|
594
|
-
if (value) return value;
|
|
595
532
|
}
|
|
596
|
-
return null;
|
|
597
533
|
}
|
|
598
534
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
535
|
+
function getIdentifierName(node: unknown): string | null {
|
|
536
|
+
return isAstNode(node) && node.type === 'Identifier'
|
|
537
|
+
? typeof node.name === 'string'
|
|
538
|
+
? node.name
|
|
539
|
+
: null
|
|
540
|
+
: null;
|
|
541
|
+
}
|
|
603
542
|
|
|
604
|
-
function
|
|
605
|
-
|
|
606
|
-
const callPattern =
|
|
607
|
-
/(?:\b[A-Za-z_$][\w$]*\s*\.\s*)?\b(?:definePlay|defineWorkflow)\s*\(/g;
|
|
608
|
-
const calls: DefinePlayCallMetadata[] = [];
|
|
609
|
-
for (const match of source.matchAll(callPattern)) {
|
|
610
|
-
const callStart = match.index!;
|
|
611
|
-
const openParen = callStart + match[0].length - 1;
|
|
612
|
-
const closeParen = findMatchingParen(sourceCode, openParen);
|
|
613
|
-
if (closeParen < 0) continue;
|
|
614
|
-
calls.push({
|
|
615
|
-
arguments: splitTopLevelArguments(
|
|
616
|
-
sourceCode.slice(openParen + 1, closeParen),
|
|
617
|
-
),
|
|
618
|
-
exportName: exportNameForDefinePlayCall(sourceCode, callStart),
|
|
619
|
-
});
|
|
620
|
-
}
|
|
621
|
-
return calls;
|
|
543
|
+
function isAstNode(value: unknown): value is AstNode {
|
|
544
|
+
return value !== null && typeof value === 'object' && 'type' in value;
|
|
622
545
|
}
|
|
623
546
|
|
|
624
|
-
function
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
547
|
+
function astArray(value: unknown): AstNode[] {
|
|
548
|
+
return Array.isArray(value) ? value.filter(isAstNode) : [];
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function memberExpressionPath(node: AstNode | null | undefined): string[] | null {
|
|
552
|
+
const expression = unwrapStaticExpression(node);
|
|
553
|
+
if (!expression) return null;
|
|
554
|
+
if (expression.type === 'Identifier' && typeof expression.name === 'string') {
|
|
555
|
+
return [expression.name];
|
|
556
|
+
}
|
|
557
|
+
if (expression.type !== 'MemberExpression') return null;
|
|
558
|
+
const objectPath = memberExpressionPath(
|
|
559
|
+
isAstNode(expression.object) ? expression.object : null,
|
|
560
|
+
);
|
|
561
|
+
if (!objectPath) return null;
|
|
562
|
+
const property = isAstNode(expression.property) ? expression.property : null;
|
|
563
|
+
if (!property) return null;
|
|
564
|
+
if (!expression.computed && property.type === 'Identifier') {
|
|
565
|
+
return typeof property.name === 'string'
|
|
566
|
+
? [...objectPath, property.name]
|
|
567
|
+
: null;
|
|
568
|
+
}
|
|
569
|
+
if (expression.computed && property.type === 'Literal') {
|
|
570
|
+
return typeof property.value === 'string'
|
|
571
|
+
? [...objectPath, property.value]
|
|
572
|
+
: null;
|
|
631
573
|
}
|
|
632
574
|
return null;
|
|
633
575
|
}
|
|
634
576
|
|
|
635
|
-
function
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
if (
|
|
642
|
-
return
|
|
643
|
-
|
|
644
|
-
if (
|
|
645
|
-
return
|
|
577
|
+
function commonJsExportName(left: AstNode | null | undefined): string | null {
|
|
578
|
+
const path = memberExpressionPath(left);
|
|
579
|
+
if (!path) return null;
|
|
580
|
+
if (path.length === 2 && path[0] === 'module' && path[1] === 'exports') {
|
|
581
|
+
return 'default';
|
|
582
|
+
}
|
|
583
|
+
if (path.length === 3 && path[0] === 'module' && path[1] === 'exports') {
|
|
584
|
+
return path[2] || null;
|
|
585
|
+
}
|
|
586
|
+
if (path.length === 2 && path[0] === 'exports') {
|
|
587
|
+
return path[1] || null;
|
|
646
588
|
}
|
|
647
589
|
return null;
|
|
648
590
|
}
|
|
649
591
|
|
|
650
|
-
function
|
|
651
|
-
|
|
652
|
-
|
|
592
|
+
function isDefinePlayCallExpression(node: AstNode | null | undefined): boolean {
|
|
593
|
+
if (!node || node.type !== 'CallExpression') return false;
|
|
594
|
+
const callee = isAstNode(node.callee) ? node.callee : null;
|
|
595
|
+
if (!callee) return false;
|
|
596
|
+
if (callee.type === 'Identifier') {
|
|
597
|
+
return callee.name === 'definePlay' || callee.name === 'defineWorkflow';
|
|
598
|
+
}
|
|
599
|
+
if (callee.type === 'MemberExpression' && isAstNode(callee.property)) {
|
|
600
|
+
const property = callee.property;
|
|
601
|
+
return (
|
|
602
|
+
!callee.computed &&
|
|
603
|
+
property.type === 'Identifier' &&
|
|
604
|
+
(property.name === 'definePlay' || property.name === 'defineWorkflow')
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function canResolveDeclarationInitializer(
|
|
611
|
+
declarationKind: unknown,
|
|
612
|
+
initializer: AstNode | null,
|
|
613
|
+
): boolean {
|
|
614
|
+
return declarationKind === 'const' || isDefinePlayCallExpression(initializer);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
function buildPlayMetadataContext(ast: AstNode): PlayMetadataExtractionContext {
|
|
618
|
+
const declarations = new Map<string, AstNode | null>();
|
|
619
|
+
const namedExports = new Map<string, string>();
|
|
620
|
+
const commonJsExports = new Map<string, AstNode>();
|
|
621
|
+
let defaultExport: AstNode | null = null;
|
|
622
|
+
|
|
623
|
+
for (const statement of astArray(ast.body)) {
|
|
624
|
+
if (statement.type === 'VariableDeclaration') {
|
|
625
|
+
for (const declaration of astArray(statement.declarations)) {
|
|
626
|
+
const name = getIdentifierName(declaration.id);
|
|
627
|
+
if (!name) continue;
|
|
628
|
+
const initializer = isAstNode(declaration.init)
|
|
629
|
+
? declaration.init
|
|
630
|
+
: null;
|
|
631
|
+
declarations.set(
|
|
632
|
+
name,
|
|
633
|
+
canResolveDeclarationInitializer(statement.kind, initializer)
|
|
634
|
+
? initializer
|
|
635
|
+
: null,
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
if (statement.type === 'ExportDefaultDeclaration') {
|
|
642
|
+
defaultExport = isAstNode(statement.declaration)
|
|
643
|
+
? statement.declaration
|
|
644
|
+
: null;
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
if (statement.type === 'TSExportAssignment') {
|
|
649
|
+
defaultExport = isAstNode(statement.expression)
|
|
650
|
+
? statement.expression
|
|
651
|
+
: null;
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
if (statement.type === 'ExportNamedDeclaration') {
|
|
656
|
+
if (
|
|
657
|
+
isAstNode(statement.declaration) &&
|
|
658
|
+
statement.declaration.type === 'VariableDeclaration'
|
|
659
|
+
) {
|
|
660
|
+
for (const declaration of astArray(statement.declaration.declarations)) {
|
|
661
|
+
const name = getIdentifierName(declaration.id);
|
|
662
|
+
if (!name) continue;
|
|
663
|
+
const initializer = isAstNode(declaration.init)
|
|
664
|
+
? declaration.init
|
|
665
|
+
: null;
|
|
666
|
+
declarations.set(
|
|
667
|
+
name,
|
|
668
|
+
canResolveDeclarationInitializer(
|
|
669
|
+
statement.declaration.kind,
|
|
670
|
+
initializer,
|
|
671
|
+
)
|
|
672
|
+
? initializer
|
|
673
|
+
: null,
|
|
674
|
+
);
|
|
675
|
+
namedExports.set(name, name);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
for (const specifier of astArray(statement.specifiers)) {
|
|
680
|
+
const localName = getIdentifierName(specifier.local);
|
|
681
|
+
const exportedName =
|
|
682
|
+
getIdentifierName(specifier.exported) ??
|
|
683
|
+
(isAstNode(specifier.exported) &&
|
|
684
|
+
specifier.exported.type === 'Literal' &&
|
|
685
|
+
typeof specifier.exported.value === 'string'
|
|
686
|
+
? specifier.exported.value
|
|
687
|
+
: null);
|
|
688
|
+
if (localName && exportedName) {
|
|
689
|
+
namedExports.set(exportedName, localName);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if (
|
|
695
|
+
statement.type === 'ExpressionStatement' &&
|
|
696
|
+
isAstNode(statement.expression) &&
|
|
697
|
+
statement.expression.type === 'AssignmentExpression'
|
|
698
|
+
) {
|
|
699
|
+
const exportName = commonJsExportName(
|
|
700
|
+
isAstNode(statement.expression.left) ? statement.expression.left : null,
|
|
701
|
+
);
|
|
702
|
+
if (exportName && isAstNode(statement.expression.right)) {
|
|
703
|
+
commonJsExports.set(exportName, statement.expression.right);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
return { declarations, namedExports, commonJsExports, defaultExport };
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
function unwrapStaticExpression(node: AstNode | null | undefined): AstNode | null {
|
|
712
|
+
let current = node ?? null;
|
|
713
|
+
while (
|
|
714
|
+
current &&
|
|
715
|
+
(current.type === 'TSAsExpression' ||
|
|
716
|
+
current.type === 'TSSatisfiesExpression' ||
|
|
717
|
+
current.type === 'TSTypeAssertion' ||
|
|
718
|
+
current.type === 'TSNonNullExpression' ||
|
|
719
|
+
current.type === 'ParenthesizedExpression')
|
|
720
|
+
) {
|
|
721
|
+
current = isAstNode(current.expression) ? current.expression : null;
|
|
722
|
+
}
|
|
723
|
+
return current;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
function staticStringFromExpression(
|
|
727
|
+
node: AstNode | null | undefined,
|
|
728
|
+
context: PlayMetadataExtractionContext,
|
|
729
|
+
seen = new Set<string>(),
|
|
653
730
|
): string | null {
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
731
|
+
const expression = unwrapStaticExpression(node);
|
|
732
|
+
if (!expression) return null;
|
|
733
|
+
|
|
734
|
+
if (expression.type === 'Literal') {
|
|
735
|
+
const value = expression.value;
|
|
736
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
if (
|
|
740
|
+
expression.type === 'TemplateLiteral' &&
|
|
741
|
+
astArray(expression.expressions).length === 0
|
|
742
|
+
) {
|
|
743
|
+
const firstQuasi = astArray(expression.quasis)[0];
|
|
744
|
+
const cooked =
|
|
745
|
+
firstQuasi && typeof firstQuasi.value === 'object'
|
|
746
|
+
? (firstQuasi.value as { cooked?: unknown }).cooked
|
|
747
|
+
: null;
|
|
748
|
+
return typeof cooked === 'string' && cooked.trim()
|
|
749
|
+
? cooked.trim()
|
|
750
|
+
: null;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const identifier = getIdentifierName(expression);
|
|
754
|
+
if (!identifier || seen.has(identifier)) return null;
|
|
755
|
+
seen.add(identifier);
|
|
756
|
+
return staticStringFromExpression(
|
|
757
|
+
context.declarations.get(identifier),
|
|
758
|
+
context,
|
|
759
|
+
seen,
|
|
657
760
|
);
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
function propertyNameFromKey(property: AstNode): string | null {
|
|
764
|
+
if (property.computed) return null;
|
|
765
|
+
const key = isAstNode(property.key) ? property.key : null;
|
|
766
|
+
if (!key) return null;
|
|
767
|
+
if (key.type === 'Identifier' && typeof key.name === 'string') {
|
|
768
|
+
return key.name;
|
|
769
|
+
}
|
|
770
|
+
if (key.type === 'Literal' && typeof key.value === 'string') {
|
|
771
|
+
return key.value;
|
|
665
772
|
}
|
|
666
773
|
return null;
|
|
667
774
|
}
|
|
668
775
|
|
|
669
|
-
function
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
if (
|
|
677
|
-
|
|
776
|
+
function objectExpressionFromNode(
|
|
777
|
+
node: AstNode | null | undefined,
|
|
778
|
+
context: PlayMetadataExtractionContext,
|
|
779
|
+
seen = new Set<string>(),
|
|
780
|
+
): AstNode | null {
|
|
781
|
+
const expression = unwrapStaticExpression(node);
|
|
782
|
+
if (!expression) return null;
|
|
783
|
+
if (expression.type === 'ObjectExpression') return expression;
|
|
784
|
+
|
|
785
|
+
const identifier = getIdentifierName(expression);
|
|
786
|
+
if (!identifier || seen.has(identifier)) return null;
|
|
787
|
+
seen.add(identifier);
|
|
788
|
+
return objectExpressionFromNode(
|
|
789
|
+
context.declarations.get(identifier),
|
|
790
|
+
context,
|
|
791
|
+
seen,
|
|
792
|
+
);
|
|
678
793
|
}
|
|
679
794
|
|
|
680
|
-
function
|
|
681
|
-
|
|
682
|
-
|
|
795
|
+
function stringPropertyFromObjectExpression(
|
|
796
|
+
node: AstNode | null | undefined,
|
|
797
|
+
propertyName: string,
|
|
798
|
+
context: PlayMetadataExtractionContext,
|
|
799
|
+
seenObjects = new Set<AstNode>(),
|
|
683
800
|
): string | null {
|
|
684
|
-
const
|
|
685
|
-
if (
|
|
686
|
-
|
|
687
|
-
|
|
801
|
+
const object = objectExpressionFromNode(node, context);
|
|
802
|
+
if (!object || seenObjects.has(object)) return null;
|
|
803
|
+
seenObjects.add(object);
|
|
804
|
+
|
|
805
|
+
let value: string | null = null;
|
|
806
|
+
for (const property of astArray(object.properties)) {
|
|
807
|
+
if (property.type === 'SpreadElement') {
|
|
808
|
+
const spreadValue = stringPropertyFromObjectExpression(
|
|
809
|
+
isAstNode(property.argument) ? property.argument : null,
|
|
810
|
+
propertyName,
|
|
811
|
+
context,
|
|
812
|
+
seenObjects,
|
|
813
|
+
);
|
|
814
|
+
if (spreadValue) value = spreadValue;
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
if (property.type !== 'Property') continue;
|
|
819
|
+
if (propertyNameFromKey(property) !== propertyName) continue;
|
|
820
|
+
const propertyValue = property.shorthand
|
|
821
|
+
? property.key
|
|
822
|
+
: property.value;
|
|
823
|
+
value = staticStringFromExpression(
|
|
824
|
+
isAstNode(propertyValue) ? propertyValue : null,
|
|
825
|
+
context,
|
|
826
|
+
);
|
|
688
827
|
}
|
|
689
|
-
|
|
690
|
-
return findTopLevelObjectLiteralBody(sourceCode, trimmed);
|
|
828
|
+
return value;
|
|
691
829
|
}
|
|
692
830
|
|
|
693
|
-
function
|
|
694
|
-
|
|
831
|
+
function isDefinePlayCallee(node: AstNode | null | undefined): boolean {
|
|
832
|
+
const callee = unwrapStaticExpression(node);
|
|
833
|
+
if (!callee) return false;
|
|
834
|
+
if (
|
|
835
|
+
callee.type === 'Identifier' &&
|
|
836
|
+
(callee.name === 'definePlay' || callee.name === 'defineWorkflow')
|
|
837
|
+
) {
|
|
838
|
+
return true;
|
|
839
|
+
}
|
|
840
|
+
if (callee.type === 'MemberExpression' && isAstNode(callee.property)) {
|
|
841
|
+
const property = callee.property;
|
|
842
|
+
return (
|
|
843
|
+
!callee.computed &&
|
|
844
|
+
property.type === 'Identifier' &&
|
|
845
|
+
(property.name === 'definePlay' || property.name === 'defineWorkflow')
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
return false;
|
|
695
849
|
}
|
|
696
850
|
|
|
697
|
-
function
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
):
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
851
|
+
function playMetadataFromDefinePlayCall(
|
|
852
|
+
node: AstNode | null | undefined,
|
|
853
|
+
context: PlayMetadataExtractionContext,
|
|
854
|
+
): ExtractedPlayMetadata | null {
|
|
855
|
+
const expression = unwrapStaticExpression(node);
|
|
856
|
+
if (
|
|
857
|
+
!expression ||
|
|
858
|
+
expression.type !== 'CallExpression' ||
|
|
859
|
+
!isDefinePlayCallee(isAstNode(expression.callee) ? expression.callee : null)
|
|
860
|
+
) {
|
|
861
|
+
return null;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
const args = astArray(expression.arguments);
|
|
865
|
+
const firstArg = args[0] ?? null;
|
|
866
|
+
const objectName = stringPropertyFromObjectExpression(firstArg, 'id', context);
|
|
867
|
+
const name = objectName ?? staticStringFromExpression(firstArg, context);
|
|
868
|
+
|
|
869
|
+
let description =
|
|
870
|
+
stringPropertyFromObjectExpression(firstArg, 'description', context) ?? null;
|
|
871
|
+
for (let index = args.length - 1; !description && index >= 2; index -= 1) {
|
|
872
|
+
description = stringPropertyFromObjectExpression(
|
|
873
|
+
args[index],
|
|
874
|
+
'description',
|
|
875
|
+
context,
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (!name && !description) return null;
|
|
880
|
+
return { name, description };
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
function resolveExportExpression(
|
|
884
|
+
exportName: string | null,
|
|
885
|
+
context: PlayMetadataExtractionContext,
|
|
886
|
+
): AstNode | null {
|
|
887
|
+
if (exportName === 'default') {
|
|
888
|
+
const commonJsDefault = context.commonJsExports.get('default');
|
|
889
|
+
if (commonJsDefault) {
|
|
890
|
+
const commonJsDefaultIdentifier = getIdentifierName(
|
|
891
|
+
unwrapStaticExpression(commonJsDefault),
|
|
892
|
+
);
|
|
893
|
+
return commonJsDefaultIdentifier
|
|
894
|
+
? (context.declarations.get(commonJsDefaultIdentifier) ??
|
|
895
|
+
commonJsDefault)
|
|
896
|
+
: commonJsDefault;
|
|
897
|
+
}
|
|
898
|
+
const defaultExpression = unwrapStaticExpression(context.defaultExport);
|
|
899
|
+
const defaultIdentifier = getIdentifierName(defaultExpression);
|
|
900
|
+
if (!defaultIdentifier) {
|
|
901
|
+
const defaultExportName = context.namedExports.get('default');
|
|
902
|
+
return defaultExportName
|
|
903
|
+
? (context.declarations.get(defaultExportName) ?? null)
|
|
904
|
+
: defaultExpression;
|
|
905
|
+
}
|
|
906
|
+
return defaultIdentifier
|
|
907
|
+
? (context.declarations.get(defaultIdentifier) ?? context.defaultExport)
|
|
908
|
+
: context.defaultExport;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
if (exportName) {
|
|
912
|
+
const commonJsExport = context.commonJsExports.get(exportName);
|
|
913
|
+
if (commonJsExport) {
|
|
914
|
+
const commonJsExportIdentifier = getIdentifierName(
|
|
915
|
+
unwrapStaticExpression(commonJsExport),
|
|
916
|
+
);
|
|
917
|
+
return commonJsExportIdentifier
|
|
918
|
+
? (context.declarations.get(commonJsExportIdentifier) ?? commonJsExport)
|
|
919
|
+
: commonJsExport;
|
|
920
|
+
}
|
|
921
|
+
const localName = context.namedExports.get(exportName) ?? exportName;
|
|
922
|
+
return context.declarations.get(localName) ?? null;
|
|
714
923
|
}
|
|
924
|
+
|
|
715
925
|
return null;
|
|
716
926
|
}
|
|
717
927
|
|
|
718
|
-
function
|
|
928
|
+
function extractDefinedPlayMetadata(
|
|
719
929
|
sourceCode: string,
|
|
720
|
-
|
|
721
|
-
):
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
const
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
if (variableMatch?.[1]) return variableMatch[1];
|
|
731
|
-
const localVariableMatch = structuralPrefix.match(
|
|
732
|
-
/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)(?:\s*:[^=;]+)?\s*=\s*$/,
|
|
930
|
+
exportName: string | null,
|
|
931
|
+
): ExtractedPlayMetadata | null {
|
|
932
|
+
const ast = parsePlaySourceAst(sourceCode);
|
|
933
|
+
if (!ast) return null;
|
|
934
|
+
const context = buildPlayMetadataContext(ast);
|
|
935
|
+
|
|
936
|
+
const exportedExpression = resolveExportExpression(exportName, context);
|
|
937
|
+
const exportedMetadata = playMetadataFromDefinePlayCall(
|
|
938
|
+
exportedExpression,
|
|
939
|
+
context,
|
|
733
940
|
);
|
|
734
|
-
|
|
941
|
+
if (exportedMetadata) return exportedMetadata;
|
|
942
|
+
|
|
943
|
+
if (exportName) return null;
|
|
944
|
+
|
|
945
|
+
if (context.defaultExport) {
|
|
946
|
+
const directDefaultMetadata = playMetadataFromDefinePlayCall(
|
|
947
|
+
context.defaultExport,
|
|
948
|
+
context,
|
|
949
|
+
);
|
|
950
|
+
if (directDefaultMetadata) return directDefaultMetadata;
|
|
951
|
+
|
|
952
|
+
const defaultIdentifier = getIdentifierName(context.defaultExport);
|
|
953
|
+
if (defaultIdentifier) {
|
|
954
|
+
const defaultMetadata = playMetadataFromDefinePlayCall(
|
|
955
|
+
context.declarations.get(defaultIdentifier),
|
|
956
|
+
context,
|
|
957
|
+
);
|
|
958
|
+
if (defaultMetadata) return defaultMetadata;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
for (const expression of context.declarations.values()) {
|
|
963
|
+
const metadata = playMetadataFromDefinePlayCall(expression, context);
|
|
964
|
+
if (metadata) return metadata;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
for (const expression of context.commonJsExports.values()) {
|
|
968
|
+
const metadata = playMetadataFromDefinePlayCall(expression, context);
|
|
969
|
+
if (metadata) return metadata;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
return null;
|
|
735
973
|
}
|
|
736
974
|
|
|
737
975
|
function canonicalizeRootPlayNameForWorkersRuntimeHash(
|