deepline 0.3.293 → 0.3.295
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/sdk/src/compat.ts +35 -7
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +269 -267
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +3 -4
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +14 -1
- package/dist/cli/auth-EDTRERZP.mjs +31 -0
- package/dist/cli/auth-TDHKB277.js +31 -0
- package/dist/cli/billing-ELIDPILY.js +1749 -0
- package/dist/cli/billing-EXGXJVAU.mjs +1749 -0
- package/dist/cli/chunk-2S5Y3TZP.js +5688 -0
- package/dist/cli/chunk-3KC45UVF.js +150 -0
- package/dist/cli/chunk-3XX5TEA4.js +15 -0
- package/dist/cli/chunk-4MBOJQPL.mjs +0 -0
- package/dist/cli/chunk-4NEFYBF7.js +2240 -0
- package/dist/cli/chunk-5JLQPVNX.js +3056 -0
- package/dist/cli/chunk-5KDKFHZI.js +1269 -0
- package/dist/cli/chunk-6A3TJUWC.js +76 -0
- package/dist/cli/chunk-6O5YZOVN.mjs +890 -0
- package/dist/cli/chunk-7P5AA3SN.js +344 -0
- package/dist/cli/chunk-AYHLUHE5.js +52 -0
- package/dist/cli/chunk-CBVIJSHF.mjs +560 -0
- package/dist/cli/chunk-CFVVCN4A.js +735 -0
- package/dist/cli/chunk-COGTRVWW.js +30 -0
- package/dist/cli/chunk-D4AZUZO4.js +190 -0
- package/dist/cli/chunk-DLIRSHV6.mjs +28 -0
- package/dist/cli/chunk-EACVZI6N.mjs +1995 -0
- package/dist/cli/chunk-EDWJY6T4.mjs +3056 -0
- package/dist/cli/chunk-EXMLR72R.mjs +0 -0
- package/dist/cli/chunk-F35VOIQL.js +890 -0
- package/dist/cli/chunk-GAMFK2ZP.mjs +148 -0
- package/dist/cli/chunk-GHRQQPW2.mjs +2240 -0
- package/dist/cli/chunk-GONRLVV3.js +3440 -0
- package/dist/cli/chunk-GVUJJJ5G.mjs +76 -0
- package/dist/cli/chunk-H7HIDGZ7.mjs +150 -0
- package/dist/cli/chunk-HUZXWOSK.mjs +503 -0
- package/dist/cli/chunk-I5YZLGMG.js +1 -0
- package/dist/cli/chunk-ITOFSXIU.mjs +15 -0
- package/dist/cli/chunk-J5NA2TTX.js +503 -0
- package/dist/cli/chunk-JCS5TPNY.mjs +3440 -0
- package/dist/cli/chunk-JNNOCMQY.js +47 -0
- package/dist/cli/chunk-KRD6H754.mjs +30 -0
- package/dist/cli/chunk-LA46MMTL.js +560 -0
- package/dist/cli/chunk-LDWT7RJK.mjs +190 -0
- package/dist/cli/chunk-M2V26OR5.js +499 -0
- package/dist/cli/chunk-MIMASXO4.mjs +389 -0
- package/dist/cli/chunk-MROPCKW2.mjs +190 -0
- package/dist/cli/chunk-NXDRDJ4K.js +389 -0
- package/dist/cli/chunk-NXGCO4JB.mjs +344 -0
- package/dist/cli/chunk-OG64RBAC.js +6 -0
- package/dist/cli/chunk-OQYEC4GL.mjs +34 -0
- package/dist/cli/chunk-OWJZUE3Y.mjs +103 -0
- package/dist/cli/chunk-SDK3ZA2C.js +103 -0
- package/dist/cli/chunk-SFLARO4Y.mjs +47 -0
- package/dist/cli/chunk-SVIIIYIQ.js +923 -0
- package/dist/cli/chunk-TAC3JIFE.mjs +354 -0
- package/dist/cli/chunk-U3PI7HBM.js +34 -0
- package/dist/cli/chunk-UFS752TU.mjs +52 -0
- package/dist/cli/chunk-UI37DQE7.mjs +499 -0
- package/dist/cli/chunk-UNEMDKXN.js +1 -0
- package/dist/cli/chunk-WB6Z2Q44.mjs +1622 -0
- package/dist/cli/chunk-WJYPBHTE.js +148 -0
- package/dist/cli/chunk-WOHBA5PV.js +354 -0
- package/dist/cli/chunk-WQICC2B3.js +190 -0
- package/dist/cli/chunk-WZYKRD7T.mjs +6 -0
- package/dist/cli/chunk-XL2FO6CW.mjs +5688 -0
- package/dist/cli/chunk-XNYIZMNQ.js +28 -0
- package/dist/cli/chunk-XRK2TZT5.js +1995 -0
- package/dist/cli/chunk-YJYPL5OK.mjs +1269 -0
- package/dist/cli/chunk-YWNDYCXR.mjs +735 -0
- package/dist/cli/chunk-YWWAF7KZ.mjs +923 -0
- package/dist/cli/chunk-ZDO3TO3M.js +1622 -0
- package/dist/cli/client-4JVOYVC5.js +20 -0
- package/dist/cli/client-EEN2IJN2.mjs +20 -0
- package/dist/cli/csv-BOHBEP2I.mjs +585 -0
- package/dist/cli/csv-S5NYRUEX.js +585 -0
- package/dist/cli/db-CLODWCOB.mjs +486 -0
- package/dist/cli/db-F6PKFOOV.js +486 -0
- package/dist/cli/executions-5TQAKLJU.js +28 -0
- package/dist/cli/executions-MAKW6QOY.mjs +28 -0
- package/dist/cli/feedback-GV4QJFEN.js +107 -0
- package/dist/cli/feedback-XY24TW7H.mjs +107 -0
- package/dist/cli/getting-started.js +18 -76
- package/dist/cli/getting-started.mjs +10 -37
- package/dist/cli/git-6S2C22T5.js +23 -0
- package/dist/cli/git-OZLBD5HH.mjs +23 -0
- package/dist/cli/index.js +291 -54294
- package/dist/cli/index.mjs +209 -54352
- package/dist/cli/legacy-noops-LLCGDPQE.js +157 -0
- package/dist/cli/legacy-noops-TYH3TW2D.mjs +157 -0
- package/dist/cli/monitors-CABMB4DW.js +3251 -0
- package/dist/cli/monitors-TTD55HMK.mjs +3251 -0
- package/dist/cli/org-MSF3RG76.js +849 -0
- package/dist/cli/org-SFJ77MWY.mjs +849 -0
- package/dist/cli/play-NXHJSCKL.mjs +18439 -0
- package/dist/cli/play-OKSFNNO4.js +18439 -0
- package/dist/cli/providers-QC2ERERL.js +95 -0
- package/dist/cli/providers-TIIAZEUA.mjs +95 -0
- package/dist/cli/proxy-env-EBANZHPV.js +161 -0
- package/dist/cli/proxy-env-M4ZHXHRL.mjs +161 -0
- package/dist/cli/quickstart-ICANHLMI.js +69 -0
- package/dist/cli/quickstart-KWUOP3FI.mjs +69 -0
- package/dist/cli/search-U5H2FDOO.mjs +18 -0
- package/dist/cli/search-XQRQOLWS.js +18 -0
- package/dist/cli/secrets-3J6YTWFA.mjs +400 -0
- package/dist/cli/secrets-YNMNZNOM.js +400 -0
- package/dist/cli/sessions-CLEES4L6.mjs +15 -0
- package/dist/cli/sessions-J6VR47FG.js +15 -0
- package/dist/cli/settings-EEKZMTY4.js +846 -0
- package/dist/cli/settings-UVLOQZRH.mjs +846 -0
- package/dist/cli/setup-DLMDXPGJ.mjs +1257 -0
- package/dist/cli/setup-HC4Q7QM4.js +1257 -0
- package/dist/cli/skills-33PHFBSB.mjs +28 -0
- package/dist/cli/skills-LFRY3KPX.js +28 -0
- package/dist/cli/tools-3COEPKML.mjs +2955 -0
- package/dist/cli/tools-QXEVCN45.js +2955 -0
- package/dist/cli/update-LSAC4FF5.mjs +28 -0
- package/dist/cli/update-NXHSPYXA.js +28 -0
- package/dist/cli/workflow-7S44OECF.mjs +1936 -0
- package/dist/cli/workflow-QPZWYSZE.js +1936 -0
- package/dist/helpers.js +6 -32
- package/dist/helpers.mjs +2 -0
- package/dist/index.js +1972 -12825
- package/dist/index.mjs +1910 -12672
- package/dist/install-integrity.json +110 -0
- package/dist/monitor-fleet-contract.js +31 -730
- package/dist/monitor-fleet-contract.mjs +18 -667
- package/dist/monitor-input-contract.js +10 -390
- package/dist/monitor-input-contract.mjs +7 -348
- package/dist/plays/bundle-play-file.mjs +13 -5178
- package/dist/plays/csv-data-input.js +5 -3132
- package/dist/plays/csv-data-input.mjs +5 -3105
- package/dist/plays/run-request.js +56 -664
- package/dist/plays/run-request.mjs +30 -588
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +5 -212
- package/dist/release.mjs +5 -185
- package/package.json +1 -1
|
@@ -0,0 +1,3440 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunk3KC45UVFjs = require('./chunk-3KC45UVF.js');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkZDO3TO3Mjs = require('./chunk-ZDO3TO3M.js');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var _chunk6A3TJUWCjs = require('./chunk-6A3TJUWC.js');
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
var _chunk7P5AA3SNjs = require('./chunk-7P5AA3SN.js');
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
var _chunkOG64RBACjs = require('./chunk-OG64RBAC.js');
|
|
20
|
+
|
|
21
|
+
// src/plays/bundle-play-file.ts
|
|
22
|
+
var _os = require('os');
|
|
23
|
+
var _path = require('path');
|
|
24
|
+
var _url = require('url');
|
|
25
|
+
var _fs = require('fs');
|
|
26
|
+
var _promises = require('fs/promises');
|
|
27
|
+
|
|
28
|
+
// ../plays/bundling/index.ts
|
|
29
|
+
var _crypto = require('crypto');
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
var _module = require('module');
|
|
44
|
+
var _acorn = require('acorn');
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
var _esbuild = require('esbuild');
|
|
49
|
+
|
|
50
|
+
// ../plays/contracts.ts
|
|
51
|
+
var PLAY_ARTIFACT_VERSION = _chunkOG64RBACjs.CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION;
|
|
52
|
+
function buildPlayContractCompatibility(input) {
|
|
53
|
+
return {
|
|
54
|
+
artifactVersion: PLAY_ARTIFACT_VERSION,
|
|
55
|
+
runtimeBackend: _nullishCoalesce(_optionalChain([input, 'optionalAccess', _ => _.runtimeBackend]), () => ( null)),
|
|
56
|
+
toolErrorSchemaVersion: _nullishCoalesce(_optionalChain([input, 'optionalAccess', _2 => _2.toolErrorSchemaVersion]), () => ( _chunk7P5AA3SNjs.TOOL_EXECUTION_ERROR_SCHEMA_VERSION)),
|
|
57
|
+
authoringContractEdition: _nullishCoalesce(_optionalChain([input, 'optionalAccess', _3 => _3.authoringContractEdition]), () => ( _chunkZDO3TO3Mjs.PLAY_AUTHORING_CONTRACT_EDITION)),
|
|
58
|
+
toolResponseContract: _nullishCoalesce(_optionalChain([input, 'optionalAccess', _4 => _4.toolResponseContract]), () => ( _chunk6A3TJUWCjs.RAW_V2_TOOL_RESPONSE_CONTRACT)),
|
|
59
|
+
toolResponseReceiptRevision: _chunk6A3TJUWCjs.normalizeToolResponseReceiptRevision.call(void 0,
|
|
60
|
+
_nullishCoalesce(_optionalChain([input, 'optionalAccess', _5 => _5.toolResponseReceiptRevision]), () => ( _chunk6A3TJUWCjs.RAW_V2_TOOL_RESPONSE_RECEIPT_REVISION))
|
|
61
|
+
)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ../plays/ts-ast.ts
|
|
66
|
+
|
|
67
|
+
var _acorntypescript = require('acorn-typescript');
|
|
68
|
+
var TypeScriptParser = _acorn.Parser.extend(
|
|
69
|
+
_acorntypescript.tsPlugin.call(void 0, {
|
|
70
|
+
allowSatisfies: true,
|
|
71
|
+
jsx: {
|
|
72
|
+
allowNamespaces: true,
|
|
73
|
+
allowNamespacedObjects: true
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
function isAstNode(value) {
|
|
78
|
+
return value !== null && typeof value === "object" && "type" in value;
|
|
79
|
+
}
|
|
80
|
+
function astArray(value) {
|
|
81
|
+
return Array.isArray(value) ? value.filter(isAstNode) : [];
|
|
82
|
+
}
|
|
83
|
+
function parsePlaySourceForAnalysis(sourceCode) {
|
|
84
|
+
try {
|
|
85
|
+
return TypeScriptParser.parse(sourceCode, {
|
|
86
|
+
ecmaVersion: "latest",
|
|
87
|
+
sourceType: "module",
|
|
88
|
+
allowHashBang: true
|
|
89
|
+
});
|
|
90
|
+
} catch (e) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ../plays/play-exports.ts
|
|
96
|
+
var PLAY_DEFAULT_EXPORT = "default";
|
|
97
|
+
function getIdentifierName(node) {
|
|
98
|
+
return isAstNode(node) && node.type === "Identifier" ? typeof node.name === "string" ? node.name : null : null;
|
|
99
|
+
}
|
|
100
|
+
function unwrapStaticExpression(node) {
|
|
101
|
+
let current = node;
|
|
102
|
+
while (current && (current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression" || current.type === "ParenthesizedExpression")) {
|
|
103
|
+
current = isAstNode(current.expression) ? current.expression : null;
|
|
104
|
+
}
|
|
105
|
+
return current;
|
|
106
|
+
}
|
|
107
|
+
function isDefinePlayCall(node) {
|
|
108
|
+
const expression = unwrapStaticExpression(node);
|
|
109
|
+
if (!expression || expression.type !== "CallExpression") return false;
|
|
110
|
+
const callee = isAstNode(expression.callee) ? expression.callee : null;
|
|
111
|
+
if (!callee) return false;
|
|
112
|
+
if (callee.type === "Identifier") {
|
|
113
|
+
return callee.name === "definePlay" || callee.name === "defineWorkflow";
|
|
114
|
+
}
|
|
115
|
+
if (callee.type === "MemberExpression" && !callee.computed && isAstNode(callee.property) && callee.property.type === "Identifier") {
|
|
116
|
+
return callee.property.name === "definePlay" || callee.property.name === "defineWorkflow";
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
function stringLiteralValue(node) {
|
|
121
|
+
const expression = unwrapStaticExpression(node);
|
|
122
|
+
return _optionalChain([expression, 'optionalAccess', _6 => _6.type]) === "Literal" && typeof expression.value === "string" ? expression.value : null;
|
|
123
|
+
}
|
|
124
|
+
function definePlayName(node) {
|
|
125
|
+
const expression = unwrapStaticExpression(node);
|
|
126
|
+
if (!expression || expression.type !== "CallExpression") return null;
|
|
127
|
+
const first = unwrapStaticExpression(
|
|
128
|
+
_nullishCoalesce(astArray(expression.arguments)[0], () => ( null))
|
|
129
|
+
);
|
|
130
|
+
if (_optionalChain([first, 'optionalAccess', _7 => _7.type]) !== "ObjectExpression") return stringLiteralValue(first);
|
|
131
|
+
let id = null;
|
|
132
|
+
for (const property of astArray(first.properties)) {
|
|
133
|
+
if (property.type !== "Property" || property.computed) continue;
|
|
134
|
+
const key = isAstNode(property.key) ? property.key : null;
|
|
135
|
+
const keyName = _nullishCoalesce(getIdentifierName(key), () => ( (_optionalChain([key, 'optionalAccess', _8 => _8.type]) === "Literal" && typeof key.value === "string" ? key.value : null)));
|
|
136
|
+
if (keyName !== "id") continue;
|
|
137
|
+
id = stringLiteralValue(isAstNode(property.value) ? property.value : null);
|
|
138
|
+
}
|
|
139
|
+
return id;
|
|
140
|
+
}
|
|
141
|
+
function listPlayFileExports(sourceCode) {
|
|
142
|
+
const ast = parsePlaySourceForAnalysis(sourceCode);
|
|
143
|
+
if (!ast) return null;
|
|
144
|
+
const declarations = /* @__PURE__ */ new Map();
|
|
145
|
+
const namedExports = /* @__PURE__ */ new Map();
|
|
146
|
+
let defaultExpression = null;
|
|
147
|
+
const recordDeclarations = (declaration, exported) => {
|
|
148
|
+
for (const declarator of astArray(declaration.declarations)) {
|
|
149
|
+
const name = getIdentifierName(declarator.id);
|
|
150
|
+
if (!name) continue;
|
|
151
|
+
declarations.set(
|
|
152
|
+
name,
|
|
153
|
+
isAstNode(declarator.init) ? declarator.init : null
|
|
154
|
+
);
|
|
155
|
+
if (exported) namedExports.set(name, name);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
for (const statement of astArray(ast.body)) {
|
|
159
|
+
if (statement.type === "VariableDeclaration") {
|
|
160
|
+
recordDeclarations(statement, false);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
164
|
+
defaultExpression = isAstNode(statement.declaration) ? statement.declaration : null;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (statement.type === "TSExportAssignment") {
|
|
168
|
+
defaultExpression = isAstNode(statement.expression) ? statement.expression : null;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (statement.type !== "ExportNamedDeclaration") continue;
|
|
172
|
+
if (isAstNode(statement.declaration) && statement.declaration.type === "VariableDeclaration") {
|
|
173
|
+
recordDeclarations(statement.declaration, true);
|
|
174
|
+
}
|
|
175
|
+
for (const specifier of astArray(statement.specifiers)) {
|
|
176
|
+
const localName = getIdentifierName(specifier.local);
|
|
177
|
+
const exportedName = getIdentifierName(specifier.exported);
|
|
178
|
+
if (localName && exportedName) namedExports.set(exportedName, localName);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const defaultLocalName = getIdentifierName(
|
|
182
|
+
unwrapStaticExpression(defaultExpression)
|
|
183
|
+
);
|
|
184
|
+
const defaultIsPlay = defaultLocalName ? isDefinePlayCall(_nullishCoalesce(declarations.get(defaultLocalName), () => ( null))) : isDefinePlayCall(defaultExpression);
|
|
185
|
+
const exports = [];
|
|
186
|
+
const aliasedLocals = /* @__PURE__ */ new Set();
|
|
187
|
+
if (defaultIsPlay) {
|
|
188
|
+
const aliases = defaultLocalName ? [...namedExports.entries()].filter(([, local]) => local === defaultLocalName).map(([exported]) => exported) : [];
|
|
189
|
+
if (defaultLocalName) aliasedLocals.add(defaultLocalName);
|
|
190
|
+
exports.push({
|
|
191
|
+
name: PLAY_DEFAULT_EXPORT,
|
|
192
|
+
aliases,
|
|
193
|
+
playName: definePlayName(
|
|
194
|
+
defaultLocalName ? _nullishCoalesce(declarations.get(defaultLocalName), () => ( null)) : defaultExpression
|
|
195
|
+
)
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
for (const [exportedName, localName] of namedExports) {
|
|
199
|
+
if (exportedName === PLAY_DEFAULT_EXPORT) continue;
|
|
200
|
+
if (aliasedLocals.has(localName)) continue;
|
|
201
|
+
const declaration = _nullishCoalesce(declarations.get(localName), () => ( null));
|
|
202
|
+
if (!isDefinePlayCall(declaration)) continue;
|
|
203
|
+
exports.push({
|
|
204
|
+
name: exportedName,
|
|
205
|
+
aliases: [],
|
|
206
|
+
playName: definePlayName(declaration)
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return exports;
|
|
210
|
+
}
|
|
211
|
+
function canonicalPlayExportName(exportName, exports) {
|
|
212
|
+
const requested = _optionalChain([exportName, 'optionalAccess', _9 => _9.trim, 'call', _10 => _10()]) || PLAY_DEFAULT_EXPORT;
|
|
213
|
+
for (const entry of exports) {
|
|
214
|
+
if (entry.name === requested || entry.aliases.includes(requested)) {
|
|
215
|
+
return entry.name;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
for (const entry of exports) {
|
|
219
|
+
if (entry.playName === requested) return entry.name;
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
function playExportNamesForMessage(exports) {
|
|
224
|
+
return exports.flatMap((entry) => [
|
|
225
|
+
...entry.playName ? [entry.playName] : [],
|
|
226
|
+
entry.name,
|
|
227
|
+
...entry.aliases
|
|
228
|
+
]);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ../plays/docflow.ts
|
|
232
|
+
var PLAY_DOCFLOW_NODE_KINDS = [
|
|
233
|
+
"action",
|
|
234
|
+
"decision",
|
|
235
|
+
"dataset",
|
|
236
|
+
"play",
|
|
237
|
+
"conceptual"
|
|
238
|
+
];
|
|
239
|
+
var PLAY_DOCFLOW_ARMS = [
|
|
240
|
+
"run",
|
|
241
|
+
"else"
|
|
242
|
+
];
|
|
243
|
+
var FLOW_START = /^\s*(?:flowchart|graph)\s+(LR|RL|TB|TD|BT)\s*$/i;
|
|
244
|
+
var MERMAID_NODE = /^\s*\/\/\s*@mermaid-node\s+([A-Za-z][\w-]*)(?:\s+(.*))?$/;
|
|
245
|
+
var MERMAID_NODE_HINT = /@mermaid-node/;
|
|
246
|
+
var ATTRIBUTE = /([A-Za-z][\w-]*)\s*:\s*"([^"\n]*)"/y;
|
|
247
|
+
var MERMAID_NODE_ATTRIBUTES = ["label", "type", "in", "out", "arm"];
|
|
248
|
+
var MERMAID_NODE_ID = /^[A-Za-z][\w-]*/;
|
|
249
|
+
var SKETCH_CLASS = /^\s*class\s+([A-Za-z][\w-]*(?:\s*,\s*[A-Za-z][\w-]*)*)\s+sketch\s*;?\s*$/;
|
|
250
|
+
var MERMAID_NODE_SHAPES = [
|
|
251
|
+
["[[", "]]"],
|
|
252
|
+
["[(", ")]"],
|
|
253
|
+
["([", "])"],
|
|
254
|
+
["{{", "}}"],
|
|
255
|
+
["((", "))"],
|
|
256
|
+
["[/", "/]"],
|
|
257
|
+
["[\\", "\\]"],
|
|
258
|
+
["[/", "\\]"],
|
|
259
|
+
["[\\", "/]"],
|
|
260
|
+
["[", "]"],
|
|
261
|
+
["{", "}"],
|
|
262
|
+
["(", ")"],
|
|
263
|
+
[">", "]"]
|
|
264
|
+
];
|
|
265
|
+
var SUBGRAPH_OPEN = /^\s*subgraph\s+([A-Za-z][\w-]*)\s*(?:\[(.*)\])?\s*$/i;
|
|
266
|
+
var SUBGRAPH_END = /^\s*end\s*$/i;
|
|
267
|
+
var MERMAID_EDGE_CONNECTOR = /^\s*(?:-->|-\.->|==>|---)(?:\|([^|]+)\|)?/;
|
|
268
|
+
var DOCFLOW_PATH = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/;
|
|
269
|
+
var IDENTIFIER = /[A-Za-z_$][\w$]*/g;
|
|
270
|
+
var JS_WORDS = /* @__PURE__ */ new Set([
|
|
271
|
+
"async",
|
|
272
|
+
"await",
|
|
273
|
+
"const",
|
|
274
|
+
"else",
|
|
275
|
+
"false",
|
|
276
|
+
"if",
|
|
277
|
+
"let",
|
|
278
|
+
"new",
|
|
279
|
+
"null",
|
|
280
|
+
"return",
|
|
281
|
+
"true",
|
|
282
|
+
"undefined",
|
|
283
|
+
"var"
|
|
284
|
+
]);
|
|
285
|
+
function parseAttributes(source, line, errors) {
|
|
286
|
+
const attributes = {};
|
|
287
|
+
const validAttributes = MERMAID_NODE_ATTRIBUTES;
|
|
288
|
+
let cursor = 0;
|
|
289
|
+
while (cursor < source.length) {
|
|
290
|
+
cursor += _nullishCoalesce(_optionalChain([/^\s*/, 'access', _11 => _11.exec, 'call', _12 => _12(source.slice(cursor)), 'optionalAccess', _13 => _13[0], 'access', _14 => _14.length]), () => ( 0));
|
|
291
|
+
if (cursor >= source.length) break;
|
|
292
|
+
ATTRIBUTE.lastIndex = cursor;
|
|
293
|
+
const match = ATTRIBUTE.exec(source);
|
|
294
|
+
if (!match) {
|
|
295
|
+
const fragment = _nullishCoalesce(source.slice(cursor).split(/\s+/)[0], () => ( source.slice(cursor)));
|
|
296
|
+
errors.push(
|
|
297
|
+
`Docflow \`// @mermaid-node\` annotation on line ${line} has malformed attribute ${JSON.stringify(fragment)}. Use key:"value" pairs. Valid attributes: ${validAttributes.map((name2) => `"${name2}"`).join(", ")}.`
|
|
298
|
+
);
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const name = match[1];
|
|
302
|
+
if (!validAttributes.includes(name)) {
|
|
303
|
+
errors.push(
|
|
304
|
+
`Docflow \`// @mermaid-node\` annotation on line ${line} has unknown attribute "${name}". Valid attributes: ${validAttributes.map((option) => `"${option}"`).join(", ")}.`
|
|
305
|
+
);
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
if (Object.prototype.hasOwnProperty.call(attributes, name)) {
|
|
309
|
+
errors.push(
|
|
310
|
+
`Docflow \`// @mermaid-node\` annotation on line ${line} repeats attribute "${name}". Write each attribute once.`
|
|
311
|
+
);
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
attributes[name] = match[2];
|
|
315
|
+
cursor = ATTRIBUTE.lastIndex;
|
|
316
|
+
}
|
|
317
|
+
return attributes;
|
|
318
|
+
}
|
|
319
|
+
function nodeKind(value) {
|
|
320
|
+
if (!value) return void 0;
|
|
321
|
+
return PLAY_DOCFLOW_NODE_KINDS.includes(value) ? value : null;
|
|
322
|
+
}
|
|
323
|
+
function nodeArm(value) {
|
|
324
|
+
if (!value) return void 0;
|
|
325
|
+
return PLAY_DOCFLOW_ARMS.includes(value) ? value : null;
|
|
326
|
+
}
|
|
327
|
+
var SHAPE_KINDS = {
|
|
328
|
+
"{": "decision",
|
|
329
|
+
"[[": "play"
|
|
330
|
+
};
|
|
331
|
+
var MERMAID_LABEL_LOOKS_LIKE_SOURCE = /^(?:\[|\{|\(|>)/;
|
|
332
|
+
function parseMermaidNodeAtStart(source) {
|
|
333
|
+
const leadingWhitespace = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _15 => _15.exec, 'call', _16 => _16(source), 'optionalAccess', _17 => _17[0], 'access', _18 => _18.length]), () => ( 0));
|
|
334
|
+
const idMatch = MERMAID_NODE_ID.exec(source.slice(leadingWhitespace));
|
|
335
|
+
if (!idMatch) return null;
|
|
336
|
+
const id = idMatch[0];
|
|
337
|
+
let cursor = leadingWhitespace + id.length;
|
|
338
|
+
cursor += _nullishCoalesce(_optionalChain([/^\s*/, 'access', _19 => _19.exec, 'call', _20 => _20(source.slice(cursor)), 'optionalAccess', _21 => _21[0], 'access', _22 => _22.length]), () => ( 0));
|
|
339
|
+
const shape = MERMAID_NODE_SHAPES.find(
|
|
340
|
+
([open2]) => source.startsWith(open2, cursor)
|
|
341
|
+
);
|
|
342
|
+
if (!shape) {
|
|
343
|
+
return { id, label: id, kind: "action", length: cursor, shaped: false };
|
|
344
|
+
}
|
|
345
|
+
const [open, close] = shape;
|
|
346
|
+
const labelStart = cursor + open.length;
|
|
347
|
+
const openingQuote = source[labelStart];
|
|
348
|
+
let labelEnd = -1;
|
|
349
|
+
if (openingQuote === '"' || openingQuote === "'") {
|
|
350
|
+
for (let index = labelStart + 1; index < source.length; index += 1) {
|
|
351
|
+
if (source[index] === "\\") {
|
|
352
|
+
index += 1;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (source[index] !== openingQuote) continue;
|
|
356
|
+
const whitespace = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _23 => _23.exec, 'call', _24 => _24(source.slice(index + 1)), 'optionalAccess', _25 => _25[0], 'access', _26 => _26.length]), () => ( 0));
|
|
357
|
+
const candidate = index + 1 + whitespace;
|
|
358
|
+
if (source.startsWith(close, candidate)) {
|
|
359
|
+
labelEnd = candidate;
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
364
|
+
labelEnd = source.indexOf(close, labelStart);
|
|
365
|
+
}
|
|
366
|
+
if (labelEnd < 0) {
|
|
367
|
+
return {
|
|
368
|
+
id,
|
|
369
|
+
label: id,
|
|
370
|
+
kind: "action",
|
|
371
|
+
length: cursor + open.length,
|
|
372
|
+
shaped: false,
|
|
373
|
+
unterminated: { open, close }
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
const rawLabel = source.slice(labelStart, labelEnd).trim();
|
|
377
|
+
const label = rawLabel.length >= 2 && (rawLabel.startsWith('"') && rawLabel.endsWith('"') || rawLabel.startsWith("'") && rawLabel.endsWith("'")) ? rawLabel.slice(1, -1) : rawLabel;
|
|
378
|
+
return {
|
|
379
|
+
id,
|
|
380
|
+
label: label || id,
|
|
381
|
+
kind: _nullishCoalesce(SHAPE_KINDS[open], () => ( "action")),
|
|
382
|
+
length: labelEnd + close.length,
|
|
383
|
+
shaped: true
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function parseShapedMermaidNodes(fragment) {
|
|
387
|
+
const nodes = [];
|
|
388
|
+
let cursor = 0;
|
|
389
|
+
while (cursor < fragment.length) {
|
|
390
|
+
const identifier = /[A-Za-z][\w-]*/.exec(fragment.slice(cursor));
|
|
391
|
+
if (!identifier) break;
|
|
392
|
+
const start = cursor + (_nullishCoalesce(identifier.index, () => ( 0)));
|
|
393
|
+
const parsed = parseMermaidNodeAtStart(fragment.slice(start));
|
|
394
|
+
if (_optionalChain([parsed, 'optionalAccess', _27 => _27.shaped]) || _optionalChain([parsed, 'optionalAccess', _28 => _28.unterminated])) nodes.push(parsed);
|
|
395
|
+
cursor = start + Math.max(_nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _29 => _29.length]), () => ( identifier[0].length)), 1);
|
|
396
|
+
}
|
|
397
|
+
return nodes;
|
|
398
|
+
}
|
|
399
|
+
function parseEdgeChain(line) {
|
|
400
|
+
let remaining = line;
|
|
401
|
+
const first = parseMermaidNodeAtStart(remaining);
|
|
402
|
+
if (!first) return null;
|
|
403
|
+
const nodes = [first];
|
|
404
|
+
const labels = [];
|
|
405
|
+
remaining = remaining.slice(first.length);
|
|
406
|
+
while (remaining.trim()) {
|
|
407
|
+
const connector = MERMAID_EDGE_CONNECTOR.exec(remaining);
|
|
408
|
+
if (!connector) return null;
|
|
409
|
+
remaining = remaining.slice(connector[0].length);
|
|
410
|
+
const next = parseMermaidNodeAtStart(remaining);
|
|
411
|
+
if (!next) return null;
|
|
412
|
+
labels.push(_optionalChain([connector, 'access', _30 => _30[1], 'optionalAccess', _31 => _31.trim, 'call', _32 => _32()]) || void 0);
|
|
413
|
+
nodes.push(next);
|
|
414
|
+
remaining = remaining.slice(next.length);
|
|
415
|
+
}
|
|
416
|
+
return nodes.length > 1 ? { nodes, labels } : null;
|
|
417
|
+
}
|
|
418
|
+
function parseContractPaths(value, attribute, nodeId, line, errors) {
|
|
419
|
+
if (value === void 0) return void 0;
|
|
420
|
+
const paths = value.split(",").map((path) => path.trim()).filter(Boolean);
|
|
421
|
+
if (paths.some((path) => !DOCFLOW_PATH.test(path))) {
|
|
422
|
+
errors.push(
|
|
423
|
+
`Docflow annotation "${nodeId}" on line ${line} has an invalid ${attribute}:"\u2026" contract. Use comma-separated identifiers or property paths only \u2014 e.g. the assigned const name (out:"result"). Prose labels belong in the diagram box, not here.`
|
|
424
|
+
);
|
|
425
|
+
return void 0;
|
|
426
|
+
}
|
|
427
|
+
return [...new Set(paths)];
|
|
428
|
+
}
|
|
429
|
+
function inferBindingIo(statement) {
|
|
430
|
+
const returned = /^return\s+(.+?);?\s*$/.exec(statement.trim());
|
|
431
|
+
if (returned) {
|
|
432
|
+
const inputs2 = /* @__PURE__ */ new Set();
|
|
433
|
+
const expression2 = returned[1].replace(/(['"`])(?:\\.|(?!\1).)*\1/g, "");
|
|
434
|
+
IDENTIFIER.lastIndex = 0;
|
|
435
|
+
for (const match of expression2.matchAll(IDENTIFIER)) {
|
|
436
|
+
const identifier = match[0];
|
|
437
|
+
const index = _nullishCoalesce(match.index, () => ( 0));
|
|
438
|
+
if (JS_WORDS.has(identifier) || expression2[index - 1] === ".") continue;
|
|
439
|
+
inputs2.add(identifier);
|
|
440
|
+
}
|
|
441
|
+
return {
|
|
442
|
+
inputs: [...inputs2],
|
|
443
|
+
ioConfidence: "inferred"
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
const assignment = /^(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*([^;]+);?\s*$/.exec(
|
|
447
|
+
statement.trim()
|
|
448
|
+
);
|
|
449
|
+
if (!assignment || assignment[2].includes("await")) {
|
|
450
|
+
return { ioConfidence: "ambiguous" };
|
|
451
|
+
}
|
|
452
|
+
const output = assignment[1];
|
|
453
|
+
const expression = assignment[2];
|
|
454
|
+
const inputs = /* @__PURE__ */ new Set();
|
|
455
|
+
IDENTIFIER.lastIndex = 0;
|
|
456
|
+
for (const match of expression.matchAll(IDENTIFIER)) {
|
|
457
|
+
const identifier = match[0];
|
|
458
|
+
const index = _nullishCoalesce(match.index, () => ( 0));
|
|
459
|
+
const previous = _nullishCoalesce(expression[index - 1], () => ( ""));
|
|
460
|
+
const next = _nullishCoalesce(expression[index + identifier.length], () => ( ""));
|
|
461
|
+
if (JS_WORDS.has(identifier) || identifier === output || previous === "." || next === ":" || /^\s*\(/.test(expression.slice(index + identifier.length))) {
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
inputs.add(identifier);
|
|
465
|
+
}
|
|
466
|
+
return {
|
|
467
|
+
inputs: [...inputs],
|
|
468
|
+
outputs: [output],
|
|
469
|
+
ioConfidence: "inferred"
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
var JSDOC_BLOCK = /\/\*\*([\s\S]*?)\*\//g;
|
|
473
|
+
var BLOCK_EXPORT_HEADER = /^[A-Za-z_$][\w$-]*$/;
|
|
474
|
+
function cleanBlockBody(raw) {
|
|
475
|
+
return raw.split(/\r?\n/).map((line) => /^\s*\*/.test(line) ? line.replace(/^\s*\* ?/, "") : line).join("\n").trim();
|
|
476
|
+
}
|
|
477
|
+
function splitBlockExportHeader(body) {
|
|
478
|
+
const newlineIndex = body.indexOf("\n");
|
|
479
|
+
const firstLine = (newlineIndex < 0 ? body : body.slice(0, newlineIndex)).trim();
|
|
480
|
+
if (!BLOCK_EXPORT_HEADER.test(firstLine) || /^(?:flowchart|graph)$/i.test(firstLine)) {
|
|
481
|
+
return { exportName: null, diagram: body };
|
|
482
|
+
}
|
|
483
|
+
return {
|
|
484
|
+
exportName: firstLine,
|
|
485
|
+
diagram: newlineIndex < 0 ? "" : body.slice(newlineIndex + 1).trim()
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
function blockLabel(block) {
|
|
489
|
+
return block.authoredExportName ? `@mermaid ${block.authoredExportName}` : "@mermaid";
|
|
490
|
+
}
|
|
491
|
+
function parseDocflowBlockGraph(mermaidSource, errors) {
|
|
492
|
+
const docLines = mermaidSource.split(/\r?\n/).filter((line) => line.trim() && !line.trim().startsWith("%%"));
|
|
493
|
+
const direction = _optionalChain([FLOW_START, 'access', _33 => _33.exec, 'call', _34 => _34(_nullishCoalesce(docLines[0], () => ( ""))), 'optionalAccess', _35 => _35[1], 'optionalAccess', _36 => _36.toUpperCase, 'call', _37 => _37()]);
|
|
494
|
+
if (!direction) {
|
|
495
|
+
errors.push(
|
|
496
|
+
"Docflow must start with `flowchart` or `graph` and direction `LR`, `RL`, `TB`, `TD`, or `BT`."
|
|
497
|
+
);
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
501
|
+
const edges = [];
|
|
502
|
+
const subgraphs = /* @__PURE__ */ new Map();
|
|
503
|
+
const ignoredDirectives = [];
|
|
504
|
+
const sketchIds = /* @__PURE__ */ new Set();
|
|
505
|
+
const subgraphStack = [];
|
|
506
|
+
const subgraphIds = /* @__PURE__ */ new Set();
|
|
507
|
+
for (const line of docLines.slice(1)) {
|
|
508
|
+
const opened = SUBGRAPH_OPEN.exec(line);
|
|
509
|
+
if (opened) subgraphIds.add(opened[1]);
|
|
510
|
+
}
|
|
511
|
+
const declaredIds = /* @__PURE__ */ new Set();
|
|
512
|
+
const addNodes = (fragment, line) => {
|
|
513
|
+
let sawDeclaration = false;
|
|
514
|
+
for (const node of parseShapedMermaidNodes(fragment)) {
|
|
515
|
+
const { id, label, kind } = node;
|
|
516
|
+
if (node.unterminated) {
|
|
517
|
+
sawDeclaration = true;
|
|
518
|
+
errors.push(
|
|
519
|
+
`Docflow node "${id}" opens with \`${node.unterminated.open}\` but never closes with \`${node.unterminated.close}\`: ${line.trim()}`
|
|
520
|
+
);
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
sawDeclaration = true;
|
|
524
|
+
if (subgraphIds.has(id)) {
|
|
525
|
+
errors.push(
|
|
526
|
+
`Docflow subgraph "${id}" collides with a node of the same id.`
|
|
527
|
+
);
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
if (MERMAID_LABEL_LOOKS_LIKE_SOURCE.test(label)) {
|
|
531
|
+
errors.push(
|
|
532
|
+
`Docflow node "${id}" has an unreadable label \`${label}\` \u2014 the shape around it is not one this parser knows, so its own syntax became the label. Supported shapes: ${MERMAID_NODE_SHAPES.map(([open, close]) => `${open}\u2026${close}`).join(", ")}. Line: ${line.trim()}`
|
|
533
|
+
);
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
declaredIds.add(id);
|
|
537
|
+
const existing = nodes.get(id);
|
|
538
|
+
if (existing && existing.label === existing.id && label !== id) {
|
|
539
|
+
existing.label = label;
|
|
540
|
+
existing.kind = kind;
|
|
541
|
+
for (const subgraph of subgraphs.values()) {
|
|
542
|
+
const at = subgraph.memberIds.indexOf(id);
|
|
543
|
+
if (at !== -1) subgraph.memberIds.splice(at, 1);
|
|
544
|
+
}
|
|
545
|
+
_optionalChain([subgraphStack, 'access', _38 => _38[subgraphStack.length - 1], 'optionalAccess', _39 => _39.memberIds, 'access', _40 => _40.push, 'call', _41 => _41(id)]);
|
|
546
|
+
} else if (existing && existing.label !== label) {
|
|
547
|
+
errors.push(`Docflow node "${id}" has conflicting labels.`);
|
|
548
|
+
} else if (!existing) {
|
|
549
|
+
nodes.set(id, { id, label, kind });
|
|
550
|
+
_optionalChain([subgraphStack, 'access', _42 => _42[subgraphStack.length - 1], 'optionalAccess', _43 => _43.memberIds, 'access', _44 => _44.push, 'call', _45 => _45(id)]);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
return sawDeclaration;
|
|
554
|
+
};
|
|
555
|
+
for (const line of docLines.slice(1)) {
|
|
556
|
+
const opened = SUBGRAPH_OPEN.exec(line);
|
|
557
|
+
if (opened) {
|
|
558
|
+
const id = opened[1];
|
|
559
|
+
const rawLabel = _nullishCoalesce(_optionalChain([opened, 'access', _46 => _46[2], 'optionalAccess', _47 => _47.trim, 'call', _48 => _48()]), () => ( ""));
|
|
560
|
+
const label = rawLabel.length >= 2 && (rawLabel.startsWith('"') && rawLabel.endsWith('"') || rawLabel.startsWith("'") && rawLabel.endsWith("'")) ? rawLabel.slice(1, -1) : rawLabel;
|
|
561
|
+
const parent = subgraphStack[subgraphStack.length - 1];
|
|
562
|
+
const subgraph = {
|
|
563
|
+
id,
|
|
564
|
+
label: label || id,
|
|
565
|
+
memberIds: [],
|
|
566
|
+
...parent ? { parentId: parent.id } : {}
|
|
567
|
+
};
|
|
568
|
+
subgraphs.set(id, subgraph);
|
|
569
|
+
subgraphStack.push(subgraph);
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
if (SUBGRAPH_END.test(line)) {
|
|
573
|
+
if (subgraphStack.length === 0) {
|
|
574
|
+
errors.push(
|
|
575
|
+
"Docflow has an `end` with no open `subgraph` above it. Every `end` closes exactly one `subgraph`."
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
subgraphStack.pop();
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
let declaredOnThisLine = false;
|
|
582
|
+
const isDirective = /^\s*(?:direction|classDef|class|style|linkStyle|click)\b/i.test(line);
|
|
583
|
+
if (isDirective) {
|
|
584
|
+
const sketch = SKETCH_CLASS.exec(line);
|
|
585
|
+
if (sketch) {
|
|
586
|
+
for (const id of sketch[1].split(",")) {
|
|
587
|
+
const trimmed = id.trim();
|
|
588
|
+
if (trimmed) sketchIds.add(trimmed);
|
|
589
|
+
}
|
|
590
|
+
} else {
|
|
591
|
+
ignoredDirectives.push(line.trim());
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
if (!isDirective) {
|
|
595
|
+
declaredOnThisLine = addNodes(line, line);
|
|
596
|
+
}
|
|
597
|
+
const chain = parseEdgeChain(line);
|
|
598
|
+
if (!chain) {
|
|
599
|
+
if (!isDirective && !declaredOnThisLine) {
|
|
600
|
+
errors.push(
|
|
601
|
+
`Docflow line is not an edge, a node declaration, or a directive this parser understands: ${line.trim()}`
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
addNodes(line, line);
|
|
607
|
+
for (const node of chain.nodes) {
|
|
608
|
+
if (subgraphIds.has(node.id)) continue;
|
|
609
|
+
const existing = nodes.get(node.id);
|
|
610
|
+
if (!existing) {
|
|
611
|
+
nodes.set(node.id, node);
|
|
612
|
+
_optionalChain([subgraphStack, 'access', _49 => _49[subgraphStack.length - 1], 'optionalAccess', _50 => _50.memberIds, 'access', _51 => _51.push, 'call', _52 => _52(node.id)]);
|
|
613
|
+
} else if (existing.label === existing.id && node.label !== node.id) {
|
|
614
|
+
existing.label = node.label;
|
|
615
|
+
existing.kind = node.kind;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
for (let index = 0; index < chain.nodes.length - 1; index += 1) {
|
|
619
|
+
edges.push({
|
|
620
|
+
from: chain.nodes[index].id,
|
|
621
|
+
to: chain.nodes[index + 1].id,
|
|
622
|
+
...chain.labels[index] ? { label: chain.labels[index] } : {}
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (subgraphStack.length > 0) {
|
|
627
|
+
errors.push(
|
|
628
|
+
`Docflow subgraph${subgraphStack.length === 1 ? "" : "s"} ${subgraphStack.map((subgraph) => `"${subgraph.id}"`).join(
|
|
629
|
+
", "
|
|
630
|
+
)} ${subgraphStack.length === 1 ? "is" : "are"} never closed with \`end\`. Everything below an unclosed subgraph is silently drawn inside it.`
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
for (const node of nodes.values()) {
|
|
634
|
+
if (declaredIds.has(node.id) || subgraphIds.has(node.id)) continue;
|
|
635
|
+
errors.push(
|
|
636
|
+
`Docflow node "${node.id}" is referenced by an edge but never declared with a shape and label, so the canvas would show its id. Declare it once, e.g. \`${node.id}["What this step does"]\`.`
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
for (const id of sketchIds) {
|
|
640
|
+
const node = nodes.get(id);
|
|
641
|
+
if (!node) {
|
|
642
|
+
errors.push(
|
|
643
|
+
subgraphs.has(id) ? `Docflow \`class ${id} sketch\` names a subgraph. A subgraph is a region, not a box, and never binds code \u2014 drop it from the class line.` : `Docflow \`class ${id} sketch\` names "${id}", which this diagram does not draw.`
|
|
644
|
+
);
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
node.sketch = true;
|
|
648
|
+
}
|
|
649
|
+
return { direction, nodes, edges, subgraphs, ignoredDirectives, sketchIds };
|
|
650
|
+
}
|
|
651
|
+
function materializeDocflow(block) {
|
|
652
|
+
return {
|
|
653
|
+
direction: block.direction,
|
|
654
|
+
nodes: [...block.nodes.values()],
|
|
655
|
+
edges: block.edges,
|
|
656
|
+
bindings: block.bindings,
|
|
657
|
+
syntax: block.syntax,
|
|
658
|
+
mermaidSource: block.mermaidSource,
|
|
659
|
+
...block.subgraphs.size ? { subgraphs: [...block.subgraphs.values()] } : {},
|
|
660
|
+
...block.ignoredDirectives.length ? { ignoredDirectives: block.ignoredDirectives } : {}
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
function parsePlayDocflowFile(sourceCode, moduleSources) {
|
|
664
|
+
const errors = [];
|
|
665
|
+
const rawBlocks = [];
|
|
666
|
+
JSDOC_BLOCK.lastIndex = 0;
|
|
667
|
+
for (const match of sourceCode.matchAll(JSDOC_BLOCK)) {
|
|
668
|
+
const cleanedBody = cleanBlockBody(match[1]);
|
|
669
|
+
const mermaid = /^@mermaid(?:[ \t]+|\r?\n|$)([\s\S]*)$/.exec(cleanedBody);
|
|
670
|
+
if (!mermaid) continue;
|
|
671
|
+
rawBlocks.push({ syntax: "mermaid", body: mermaid[1].trim() });
|
|
672
|
+
}
|
|
673
|
+
if (rawBlocks.length === 0) return { blocks: [], bindings: [], errors };
|
|
674
|
+
const rejectedNodeIds = /* @__PURE__ */ new Set();
|
|
675
|
+
const annotationSources = [{ sourceCode }];
|
|
676
|
+
for (const [sourcePath, moduleCode] of _nullishCoalesce(moduleSources, () => ( []))) {
|
|
677
|
+
if (!MERMAID_NODE_HINT.test(moduleCode)) continue;
|
|
678
|
+
annotationSources.push({ sourceCode: moduleCode, sourcePath });
|
|
679
|
+
}
|
|
680
|
+
const bindings = parseDocflowBindings(
|
|
681
|
+
annotationSources,
|
|
682
|
+
errors,
|
|
683
|
+
rejectedNodeIds
|
|
684
|
+
);
|
|
685
|
+
const parsedBlocks = [];
|
|
686
|
+
for (const raw of rawBlocks) {
|
|
687
|
+
const { exportName, diagram } = splitBlockExportHeader(raw.body);
|
|
688
|
+
const graph = parseDocflowBlockGraph(diagram, errors);
|
|
689
|
+
if (!graph) continue;
|
|
690
|
+
parsedBlocks.push({
|
|
691
|
+
...graph,
|
|
692
|
+
authoredExportName: exportName,
|
|
693
|
+
exportName: null,
|
|
694
|
+
syntax: raw.syntax,
|
|
695
|
+
mermaidSource: diagram,
|
|
696
|
+
bindings: []
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
resolveBlockExports(sourceCode, parsedBlocks, errors);
|
|
700
|
+
attachBindingsToBlocks(
|
|
701
|
+
sourceCode,
|
|
702
|
+
parsedBlocks,
|
|
703
|
+
bindings,
|
|
704
|
+
errors,
|
|
705
|
+
rejectedNodeIds
|
|
706
|
+
);
|
|
707
|
+
return {
|
|
708
|
+
blocks: parsedBlocks.filter((block) => block.exportName !== null).map((block) => ({
|
|
709
|
+
exportName: block.exportName,
|
|
710
|
+
docflow: materializeDocflow(block)
|
|
711
|
+
})),
|
|
712
|
+
bindings,
|
|
713
|
+
errors
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
function resolveBlockExports(sourceCode, blocks, errors) {
|
|
717
|
+
const fileExports = blocks.some((block) => block.authoredExportName !== null) ? listPlayFileExports(sourceCode) : null;
|
|
718
|
+
const claimed = /* @__PURE__ */ new Map();
|
|
719
|
+
for (const block of blocks) {
|
|
720
|
+
if (block.authoredExportName === null) {
|
|
721
|
+
block.exportName = PLAY_DEFAULT_EXPORT;
|
|
722
|
+
} else if (fileExports === null) {
|
|
723
|
+
block.exportName = block.authoredExportName;
|
|
724
|
+
} else {
|
|
725
|
+
const canonical = canonicalPlayExportName(
|
|
726
|
+
block.authoredExportName,
|
|
727
|
+
fileExports
|
|
728
|
+
);
|
|
729
|
+
if (!canonical) {
|
|
730
|
+
const available = playExportNamesForMessage(fileExports);
|
|
731
|
+
errors.push(
|
|
732
|
+
`Docflow block \`${blockLabel(block)}\` names an export this file does not define. ` + (available.length ? `Exported plays: ${available.map((name) => `"${name}"`).join(", ")}.` : "This file exports no play.")
|
|
733
|
+
);
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
block.exportName = canonical;
|
|
737
|
+
}
|
|
738
|
+
const existing = claimed.get(block.exportName);
|
|
739
|
+
if (existing) {
|
|
740
|
+
errors.push(
|
|
741
|
+
`Docflow blocks \`${blockLabel(existing)}\` and \`${blockLabel(block)}\` both describe export "${block.exportName}". One diagram per export.`
|
|
742
|
+
);
|
|
743
|
+
block.exportName = null;
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
claimed.set(block.exportName, block);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
function unwrapExportExpression(node) {
|
|
750
|
+
let current = node;
|
|
751
|
+
while (current && (current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression" || current.type === "ParenthesizedExpression")) {
|
|
752
|
+
current = isAstNode(current.expression) ? current.expression : null;
|
|
753
|
+
}
|
|
754
|
+
return current;
|
|
755
|
+
}
|
|
756
|
+
function playExportSourceRanges(sourceCode) {
|
|
757
|
+
const ast = parsePlaySourceForAnalysis(sourceCode);
|
|
758
|
+
const fileExports = listPlayFileExports(sourceCode);
|
|
759
|
+
if (!ast || !fileExports) return [];
|
|
760
|
+
const declarations = /* @__PURE__ */ new Map();
|
|
761
|
+
const namedExports = /* @__PURE__ */ new Map();
|
|
762
|
+
let defaultExpression = null;
|
|
763
|
+
for (const statement of astArray(ast.body)) {
|
|
764
|
+
const recordDeclarations = (declaration, exported) => {
|
|
765
|
+
for (const declarator of astArray(declaration.declarations)) {
|
|
766
|
+
const id = isAstNode(declarator.id) ? declarator.id : null;
|
|
767
|
+
const name = _optionalChain([id, 'optionalAccess', _53 => _53.type]) === "Identifier" && typeof id.name === "string" ? id.name : null;
|
|
768
|
+
if (!name) continue;
|
|
769
|
+
declarations.set(
|
|
770
|
+
name,
|
|
771
|
+
isAstNode(declarator.init) ? declarator.init : null
|
|
772
|
+
);
|
|
773
|
+
if (exported) namedExports.set(name, name);
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
if (statement.type === "VariableDeclaration") {
|
|
777
|
+
recordDeclarations(statement, false);
|
|
778
|
+
} else if (statement.type === "ExportDefaultDeclaration") {
|
|
779
|
+
defaultExpression = isAstNode(statement.declaration) ? statement.declaration : null;
|
|
780
|
+
} else if (statement.type === "TSExportAssignment") {
|
|
781
|
+
defaultExpression = isAstNode(statement.expression) ? statement.expression : null;
|
|
782
|
+
} else if (statement.type === "ExportNamedDeclaration") {
|
|
783
|
+
if (isAstNode(statement.declaration) && statement.declaration.type === "VariableDeclaration") {
|
|
784
|
+
recordDeclarations(statement.declaration, true);
|
|
785
|
+
}
|
|
786
|
+
for (const specifier of astArray(statement.specifiers)) {
|
|
787
|
+
const local = isAstNode(specifier.local) ? specifier.local : null;
|
|
788
|
+
const exported = isAstNode(specifier.exported) ? specifier.exported : null;
|
|
789
|
+
if (_optionalChain([local, 'optionalAccess', _54 => _54.type]) === "Identifier" && typeof local.name === "string" && _optionalChain([exported, 'optionalAccess', _55 => _55.type]) === "Identifier" && typeof exported.name === "string") {
|
|
790
|
+
namedExports.set(exported.name, local.name);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
const resolveCall = (expression, seen = /* @__PURE__ */ new Set()) => {
|
|
796
|
+
const unwrapped = unwrapExportExpression(expression);
|
|
797
|
+
if (!unwrapped) return null;
|
|
798
|
+
if (isDefinePlayCall(unwrapped)) return unwrapped;
|
|
799
|
+
if (unwrapped.type !== "Identifier" || typeof unwrapped.name !== "string" || seen.has(unwrapped.name)) {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
seen.add(unwrapped.name);
|
|
803
|
+
return resolveCall(_nullishCoalesce(declarations.get(unwrapped.name), () => ( null)), seen);
|
|
804
|
+
};
|
|
805
|
+
const defaultCall = resolveCall(defaultExpression);
|
|
806
|
+
const ranges = [];
|
|
807
|
+
for (const fileExport of fileExports) {
|
|
808
|
+
const call = fileExport.name === PLAY_DEFAULT_EXPORT ? defaultCall : resolveCall(
|
|
809
|
+
_nullishCoalesce(declarations.get(_nullishCoalesce(namedExports.get(fileExport.name), () => ( ""))), () => ( null))
|
|
810
|
+
);
|
|
811
|
+
if (call && typeof call.start === "number" && typeof call.end === "number") {
|
|
812
|
+
ranges.push({
|
|
813
|
+
exportName: fileExport.name,
|
|
814
|
+
start: call.start,
|
|
815
|
+
end: call.end
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
return ranges;
|
|
820
|
+
}
|
|
821
|
+
function projectRecordedArms(block, errors) {
|
|
822
|
+
const declaredBy = /* @__PURE__ */ new Map();
|
|
823
|
+
for (const binding of block.bindings) {
|
|
824
|
+
if (!binding.arm) continue;
|
|
825
|
+
const incoming = block.edges.filter(
|
|
826
|
+
(edge2) => edge2.to === binding.nodeId && _optionalChain([block, 'access', _56 => _56.nodes, 'access', _57 => _57.get, 'call', _58 => _58(edge2.from), 'optionalAccess', _59 => _59.kind]) === "decision"
|
|
827
|
+
);
|
|
828
|
+
if (incoming.length === 0) {
|
|
829
|
+
errors.push(
|
|
830
|
+
`Docflow annotation "${binding.nodeId}" declares arm:"${binding.arm}" but no decision points at it. Put arm:"\u2026" on the node a decision's labelled edge leads to.`
|
|
831
|
+
);
|
|
832
|
+
continue;
|
|
833
|
+
}
|
|
834
|
+
if (incoming.length > 1) {
|
|
835
|
+
errors.push(
|
|
836
|
+
`Docflow annotation "${binding.nodeId}" declares arm:"${binding.arm}" but ${incoming.length} decisions point at it, so the arm names no single edge. Give each decision its own arm node.`
|
|
837
|
+
);
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
const edge = incoming[0];
|
|
841
|
+
const key = `${edge.from}\0${binding.arm}`;
|
|
842
|
+
const already = declaredBy.get(key);
|
|
843
|
+
if (already !== void 0) {
|
|
844
|
+
errors.push(
|
|
845
|
+
`Decision "${edge.from}" has two arms declaring arm:"${binding.arm}" ("${already}" and "${binding.nodeId}"). A conditional has one run arm and one else arm.`
|
|
846
|
+
);
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
declaredBy.set(key, binding.nodeId);
|
|
850
|
+
edge.arm = binding.arm;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
function attachBindingsToBlocks(sourceCode, blocks, bindings, errors, rejectedNodeIds) {
|
|
854
|
+
const lineStarts = sourceLineStartsForDocflow(sourceCode);
|
|
855
|
+
const exportRanges = playExportSourceRanges(sourceCode);
|
|
856
|
+
for (const binding of bindings) {
|
|
857
|
+
let owners = blocks.filter((block) => block.nodes.has(binding.nodeId));
|
|
858
|
+
if (owners.length === 0) {
|
|
859
|
+
errors.push(
|
|
860
|
+
`Docflow annotation "${binding.nodeId}" does not name a graph node.`
|
|
861
|
+
);
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
if (owners.length > 1) {
|
|
865
|
+
const lineStart = lineStarts[binding.line - 1];
|
|
866
|
+
if (lineStart !== void 0) {
|
|
867
|
+
const scoped = owners.filter(
|
|
868
|
+
(owner2) => exportRanges.some(
|
|
869
|
+
(range) => range.exportName === owner2.exportName && lineStart >= range.start && lineStart < range.end
|
|
870
|
+
)
|
|
871
|
+
);
|
|
872
|
+
if (scoped.length === 1) owners = scoped;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
if (owners.length > 1) {
|
|
876
|
+
errors.push(
|
|
877
|
+
`Docflow annotation "${binding.nodeId}" names a node in ${owners.map((owner2) => `\`${blockLabel(owner2)}\``).join(" and ")}, and its enclosing play could not identify one owner. Put the annotation inside the definePlay handler for the export it describes.`
|
|
878
|
+
);
|
|
879
|
+
continue;
|
|
880
|
+
}
|
|
881
|
+
const owner = owners[0];
|
|
882
|
+
if (owner.bindings.some((candidate) => candidate.nodeId === binding.nodeId)) {
|
|
883
|
+
errors.push(
|
|
884
|
+
`Docflow node "${binding.nodeId}" has more than one code binding.`
|
|
885
|
+
);
|
|
886
|
+
continue;
|
|
887
|
+
}
|
|
888
|
+
owner.bindings.push(binding);
|
|
889
|
+
}
|
|
890
|
+
for (const block of blocks) {
|
|
891
|
+
for (const binding of block.bindings) {
|
|
892
|
+
const node = block.nodes.get(binding.nodeId);
|
|
893
|
+
if (binding.label) node.label = binding.label;
|
|
894
|
+
if (block.sketchIds.has(binding.nodeId)) {
|
|
895
|
+
errors.push(
|
|
896
|
+
`Docflow box "${binding.nodeId}" is declared \`class ${binding.nodeId} sketch\` and also bound by \`// @mermaid-node ${binding.nodeId}\` on line ${binding.line}. It is one or the other: drop it from the class line, or drop the annotation.`
|
|
897
|
+
);
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
if (binding.kind) node.kind = binding.kind;
|
|
901
|
+
}
|
|
902
|
+
projectRecordedArms(block, errors);
|
|
903
|
+
const bound = new Set(block.bindings.map((binding) => binding.nodeId));
|
|
904
|
+
for (const node of block.nodes.values()) {
|
|
905
|
+
if (node.sketch || node.kind === "conceptual" || bound.has(node.id) || rejectedNodeIds.has(node.id))
|
|
906
|
+
continue;
|
|
907
|
+
errors.push(
|
|
908
|
+
`Docflow box "${node.id}" in \`${blockLabel(block)}\` points at nothing, so the canvas can only draw it and say nothing about it. Either put \`// @mermaid-node ${node.id}\` above the statement it runs, or \u2014 if this play has no such statement, because the work happens in another module or inside a loop \u2014 add it to a \`class ${node.id} sketch\` line in the block to declare it a sketch.`
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
function sourceLineStartsForDocflow(sourceCode) {
|
|
914
|
+
const starts = [0];
|
|
915
|
+
for (let index = 0; index < sourceCode.length; index += 1) {
|
|
916
|
+
if (sourceCode[index] === "\n") starts.push(index + 1);
|
|
917
|
+
}
|
|
918
|
+
return starts;
|
|
919
|
+
}
|
|
920
|
+
function parseDocflowBindings(sources, errors, rejectedNodeIds) {
|
|
921
|
+
const bindings = [];
|
|
922
|
+
for (const source of sources) {
|
|
923
|
+
bindings.push(
|
|
924
|
+
...parseDocflowBindingsInSource(source, errors, rejectedNodeIds)
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
return bindings;
|
|
928
|
+
}
|
|
929
|
+
function parseDocflowBindingsInSource(source, errors, rejectedNodeIds) {
|
|
930
|
+
const { sourceCode, sourcePath } = source;
|
|
931
|
+
const lines = sourceCode.split(/\r?\n/);
|
|
932
|
+
const bindings = [];
|
|
933
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
934
|
+
MERMAID_NODE.lastIndex = 0;
|
|
935
|
+
const mermaidMatch = _nullishCoalesce(MERMAID_NODE.exec(lines[index]), () => ( null));
|
|
936
|
+
if (!mermaidMatch) continue;
|
|
937
|
+
const annotatedId = _optionalChain([mermaidMatch, 'access', _60 => _60[1], 'optionalAccess', _61 => _61.trim, 'call', _62 => _62()]);
|
|
938
|
+
if (annotatedId) rejectedNodeIds.add(annotatedId);
|
|
939
|
+
const attributes = parseAttributes(
|
|
940
|
+
_nullishCoalesce(mermaidMatch[2], () => ( "")),
|
|
941
|
+
index + 1,
|
|
942
|
+
errors
|
|
943
|
+
);
|
|
944
|
+
if (!attributes) continue;
|
|
945
|
+
const id = _optionalChain([(_nullishCoalesce(annotatedId, () => ( attributes.id))), 'optionalAccess', _63 => _63.trim, 'call', _64 => _64()]);
|
|
946
|
+
if (!id) {
|
|
947
|
+
errors.push(`Docflow annotation on line ${index + 1} requires id:"\u2026".`);
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
rejectedNodeIds.add(id);
|
|
951
|
+
const kind = nodeKind(attributes.type);
|
|
952
|
+
if (attributes.type && !kind) {
|
|
953
|
+
errors.push(
|
|
954
|
+
`Docflow annotation "${id}" has unsupported type "${attributes.type}". Valid types: ${PLAY_DOCFLOW_NODE_KINDS.map((nodeType) => `"${nodeType}"`).join(", ")}.`
|
|
955
|
+
);
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
const arm = nodeArm(attributes.arm);
|
|
959
|
+
if (attributes.arm && !arm) {
|
|
960
|
+
errors.push(
|
|
961
|
+
`Docflow annotation "${id}" has unsupported arm "${attributes.arm}". Valid arms: ${PLAY_DOCFLOW_ARMS.map((token) => `"${token}"`).join(", ")}. The arm names which side of the conditional this node is, not what the edge is labelled.`
|
|
962
|
+
);
|
|
963
|
+
continue;
|
|
964
|
+
}
|
|
965
|
+
let nextLine = index + 1;
|
|
966
|
+
while (nextLine < lines.length && (!lines[nextLine].trim() || lines[nextLine].trim().startsWith("//")))
|
|
967
|
+
nextLine += 1;
|
|
968
|
+
if (nextLine === lines.length) {
|
|
969
|
+
errors.push(
|
|
970
|
+
`Docflow annotation "${id}" must be followed by executable code.`
|
|
971
|
+
);
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
const inputs = parseContractPaths(
|
|
975
|
+
attributes.in,
|
|
976
|
+
"in",
|
|
977
|
+
id,
|
|
978
|
+
index + 1,
|
|
979
|
+
errors
|
|
980
|
+
);
|
|
981
|
+
const outputs = parseContractPaths(
|
|
982
|
+
attributes.out,
|
|
983
|
+
"out",
|
|
984
|
+
id,
|
|
985
|
+
index + 1,
|
|
986
|
+
errors
|
|
987
|
+
);
|
|
988
|
+
if (attributes.in !== void 0 && !inputs || attributes.out !== void 0 && !outputs) {
|
|
989
|
+
continue;
|
|
990
|
+
}
|
|
991
|
+
const inferred = inputs || outputs ? {
|
|
992
|
+
...inputs ? { inputs } : {},
|
|
993
|
+
...outputs ? { outputs } : {},
|
|
994
|
+
ioConfidence: "explicit"
|
|
995
|
+
} : inferBindingIo(lines[nextLine]);
|
|
996
|
+
rejectedNodeIds.delete(id);
|
|
997
|
+
bindings.push({
|
|
998
|
+
nodeId: id,
|
|
999
|
+
line: nextLine + 1,
|
|
1000
|
+
...sourcePath ? { sourcePath } : {},
|
|
1001
|
+
...attributes.label ? { label: attributes.label } : {},
|
|
1002
|
+
...kind ? { kind } : {},
|
|
1003
|
+
// Spread, never `arm: arm ?? undefined` — see `PlayDocflowEdge.arm`. An
|
|
1004
|
+
// explicit `undefined` key survives `JSON.stringify` round-trips in some
|
|
1005
|
+
// callers and would reintroduce the hash drift this omission avoids.
|
|
1006
|
+
...arm ? { arm } : {},
|
|
1007
|
+
...inferred
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
return bindings;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
// ../plays/docflow-binding.ts
|
|
1014
|
+
function sourceLineStarts(sourceCode) {
|
|
1015
|
+
const starts = [0];
|
|
1016
|
+
for (let index = 0; index < sourceCode.length; index += 1) {
|
|
1017
|
+
if (sourceCode[index] === "\n") starts.push(index + 1);
|
|
1018
|
+
}
|
|
1019
|
+
return starts;
|
|
1020
|
+
}
|
|
1021
|
+
function astNodeBounds(node) {
|
|
1022
|
+
return typeof node.start === "number" && typeof node.end === "number" ? { start: node.start, end: node.end } : null;
|
|
1023
|
+
}
|
|
1024
|
+
function findDocflowBoundStatement(ast, line, lineStarts) {
|
|
1025
|
+
const lineStart = lineStarts[line - 1];
|
|
1026
|
+
const lineEnd = _nullishCoalesce(lineStarts[line], () => ( Number.POSITIVE_INFINITY));
|
|
1027
|
+
if (lineStart === void 0) return null;
|
|
1028
|
+
let match = null;
|
|
1029
|
+
const pending = [ast];
|
|
1030
|
+
const statementTypes = /* @__PURE__ */ new Set([
|
|
1031
|
+
"ExpressionStatement",
|
|
1032
|
+
"IfStatement",
|
|
1033
|
+
"ReturnStatement",
|
|
1034
|
+
"ThrowStatement",
|
|
1035
|
+
"VariableDeclaration"
|
|
1036
|
+
]);
|
|
1037
|
+
while (pending.length > 0) {
|
|
1038
|
+
const node = pending.pop();
|
|
1039
|
+
const bounds = astNodeBounds(node);
|
|
1040
|
+
if (bounds && bounds.start < lineEnd && bounds.end > lineStart && statementTypes.has(node.type)) {
|
|
1041
|
+
if (!match || bounds.end - bounds.start < (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _65 => _65(match), 'optionalAccess', _66 => _66.end]), () => ( 0))) - (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _67 => _67(match), 'optionalAccess', _68 => _68.start]), () => ( 0)))) {
|
|
1042
|
+
match = node;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
for (const child of Object.values(node)) {
|
|
1046
|
+
if (Array.isArray(child)) pending.push(...child.filter(isAstNode));
|
|
1047
|
+
else if (isAstNode(child)) pending.push(child);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return match;
|
|
1051
|
+
}
|
|
1052
|
+
var DOCFLOW_STATEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
1053
|
+
"ExpressionStatement",
|
|
1054
|
+
"IfStatement",
|
|
1055
|
+
"ReturnStatement",
|
|
1056
|
+
"ThrowStatement",
|
|
1057
|
+
"VariableDeclaration"
|
|
1058
|
+
]);
|
|
1059
|
+
function docflowOutputRoot(binding) {
|
|
1060
|
+
const first = _optionalChain([binding, 'access', _69 => _69.outputs, 'optionalAccess', _70 => _70[0]]);
|
|
1061
|
+
if (!first) return null;
|
|
1062
|
+
const root = first.split(".")[0];
|
|
1063
|
+
if (!root || root === "$output") return null;
|
|
1064
|
+
return root;
|
|
1065
|
+
}
|
|
1066
|
+
function buildDocflowParentIndex(ast) {
|
|
1067
|
+
const parents = /* @__PURE__ */ new Map();
|
|
1068
|
+
const pending = [ast];
|
|
1069
|
+
while (pending.length > 0) {
|
|
1070
|
+
const node = pending.pop();
|
|
1071
|
+
for (const child of Object.values(node)) {
|
|
1072
|
+
const children = Array.isArray(child) ? child.filter(isAstNode) : isAstNode(child) ? [child] : [];
|
|
1073
|
+
for (const nested of children) {
|
|
1074
|
+
parents.set(nested, node);
|
|
1075
|
+
pending.push(nested);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
return parents;
|
|
1080
|
+
}
|
|
1081
|
+
function enclosingDocflowStatement(node, parents) {
|
|
1082
|
+
let current = node;
|
|
1083
|
+
while (current) {
|
|
1084
|
+
if (DOCFLOW_STATEMENT_TYPES.has(current.type)) return current;
|
|
1085
|
+
current = _nullishCoalesce(parents.get(current), () => ( null));
|
|
1086
|
+
}
|
|
1087
|
+
return null;
|
|
1088
|
+
}
|
|
1089
|
+
function isWithColumnCallForName(node, columnName) {
|
|
1090
|
+
if (node.type !== "CallExpression") return false;
|
|
1091
|
+
const callee = isAstNode(node.callee) ? node.callee : null;
|
|
1092
|
+
if (!callee || callee.type !== "MemberExpression" || callee.computed || !isAstNode(callee.property) || callee.property.type !== "Identifier" || callee.property.name !== "withColumn") {
|
|
1093
|
+
return false;
|
|
1094
|
+
}
|
|
1095
|
+
const firstArg = astArray(node.arguments)[0];
|
|
1096
|
+
return Boolean(
|
|
1097
|
+
firstArg && firstArg.type === "Literal" && typeof firstArg.value === "string" && firstArg.value === columnName
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
function isDocflowStepCallForName(node, stepName) {
|
|
1101
|
+
if (node.type !== "CallExpression") return false;
|
|
1102
|
+
const callee = isAstNode(node.callee) ? node.callee : null;
|
|
1103
|
+
if (!callee || callee.type !== "MemberExpression" || callee.computed || !isAstNode(callee.property) || callee.property.type !== "Identifier" || callee.property.name !== "step") {
|
|
1104
|
+
return false;
|
|
1105
|
+
}
|
|
1106
|
+
const firstArg = astArray(node.arguments)[0];
|
|
1107
|
+
return Boolean(
|
|
1108
|
+
firstArg && firstArg.type === "Literal" && typeof firstArg.value === "string" && firstArg.value === stepName
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
function docflowExpressionWrapsStepBuilder(expression, stepName) {
|
|
1112
|
+
const unwrapped = expression.type === "AwaitExpression" && isAstNode(expression.argument) ? expression.argument : expression;
|
|
1113
|
+
if (isDocflowStepCallForName(unwrapped, stepName)) return false;
|
|
1114
|
+
const pending = [unwrapped];
|
|
1115
|
+
while (pending.length > 0) {
|
|
1116
|
+
const node = pending.pop();
|
|
1117
|
+
if (node !== unwrapped && isDocflowStepCallForName(node, stepName)) {
|
|
1118
|
+
return true;
|
|
1119
|
+
}
|
|
1120
|
+
for (const child of Object.values(node)) {
|
|
1121
|
+
if (Array.isArray(child)) pending.push(...child.filter(isAstNode));
|
|
1122
|
+
else if (isAstNode(child)) pending.push(child);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
function getIdentifierName2(node) {
|
|
1128
|
+
return isAstNode(node) && node.type === "Identifier" ? typeof node.name === "string" ? node.name : null : null;
|
|
1129
|
+
}
|
|
1130
|
+
function enclosingDefinePlayCall(ast, line, lineStarts) {
|
|
1131
|
+
const lineStart = lineStarts[line - 1];
|
|
1132
|
+
const lineEnd = _nullishCoalesce(lineStarts[line], () => ( Number.POSITIVE_INFINITY));
|
|
1133
|
+
if (lineStart === void 0) return null;
|
|
1134
|
+
let match = null;
|
|
1135
|
+
const pending = [ast];
|
|
1136
|
+
while (pending.length > 0) {
|
|
1137
|
+
const node = pending.pop();
|
|
1138
|
+
const bounds = astNodeBounds(node);
|
|
1139
|
+
if (bounds && bounds.start < lineEnd && bounds.end > lineStart && isDefinePlayCall(node)) {
|
|
1140
|
+
const matchBounds = match ? astNodeBounds(match) : null;
|
|
1141
|
+
if (!match || !matchBounds || bounds.end - bounds.start < matchBounds.end - matchBounds.start) {
|
|
1142
|
+
match = node;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
for (const child of Object.values(node)) {
|
|
1146
|
+
if (Array.isArray(child)) pending.push(...child.filter(isAstNode));
|
|
1147
|
+
else if (isAstNode(child)) pending.push(child);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
return match;
|
|
1151
|
+
}
|
|
1152
|
+
function isVariableDeclarationForName(node, name) {
|
|
1153
|
+
if (node.type !== "VariableDeclaration") return false;
|
|
1154
|
+
return astArray(node.declarations).some(
|
|
1155
|
+
(declarator) => getIdentifierName2(declarator.id) === name
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
function resolveDocflowBindingSymbol(ast, binding, lineStarts, parents) {
|
|
1159
|
+
const root = docflowOutputRoot(binding);
|
|
1160
|
+
if (!root) return { kind: "abstain" };
|
|
1161
|
+
const parentIndex = _nullishCoalesce(parents, () => ( buildDocflowParentIndex(ast)));
|
|
1162
|
+
const scope = _nullishCoalesce(enclosingDefinePlayCall(ast, binding.line, lineStarts), () => ( ast));
|
|
1163
|
+
const inScope = (node) => {
|
|
1164
|
+
if (scope === ast) return true;
|
|
1165
|
+
const bounds = astNodeBounds(node);
|
|
1166
|
+
const scopeBounds = astNodeBounds(scope);
|
|
1167
|
+
return Boolean(
|
|
1168
|
+
bounds && scopeBounds && bounds.start >= scopeBounds.start && bounds.end <= scopeBounds.end
|
|
1169
|
+
);
|
|
1170
|
+
};
|
|
1171
|
+
const matchesColumn = (node) => isWithColumnCallForName(node, root) && inScope(node);
|
|
1172
|
+
const matchesStep = (node) => isDocflowStepCallForName(node, root) && inScope(node);
|
|
1173
|
+
const matchesVariable = (node) => isVariableDeclarationForName(node, root) && inScope(node);
|
|
1174
|
+
const collectStatements = (predicate) => {
|
|
1175
|
+
const statements = /* @__PURE__ */ new Map();
|
|
1176
|
+
const pending = [scope];
|
|
1177
|
+
while (pending.length > 0) {
|
|
1178
|
+
const node = pending.pop();
|
|
1179
|
+
if (predicate(node)) {
|
|
1180
|
+
const statement = enclosingDocflowStatement(node, parentIndex);
|
|
1181
|
+
const kind = matchesColumn(node) ? "declaredColumn" : matchesStep(node) ? "declaredStep" : "variable";
|
|
1182
|
+
if (statement && (!statements.has(statement) || kind === "declaredColumn")) {
|
|
1183
|
+
statements.set(statement, kind);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
for (const child of Object.values(node)) {
|
|
1187
|
+
if (Array.isArray(child)) pending.push(...child.filter(isAstNode));
|
|
1188
|
+
else if (isAstNode(child)) pending.push(child);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
return statements;
|
|
1192
|
+
};
|
|
1193
|
+
let candidates = collectStatements(
|
|
1194
|
+
(node) => matchesColumn(node) || matchesStep(node)
|
|
1195
|
+
);
|
|
1196
|
+
if (candidates.size === 0) candidates = collectStatements(matchesVariable);
|
|
1197
|
+
if (candidates.size === 0) return { kind: "abstain" };
|
|
1198
|
+
const resolved = (statement) => ({
|
|
1199
|
+
kind: "resolved",
|
|
1200
|
+
statement,
|
|
1201
|
+
symbolKind: _nullishCoalesce(candidates.get(statement), () => ( "variable"))
|
|
1202
|
+
});
|
|
1203
|
+
const lineStart = lineStarts[binding.line - 1];
|
|
1204
|
+
const lineEnd = _nullishCoalesce(lineStarts[binding.line], () => ( Number.POSITIVE_INFINITY));
|
|
1205
|
+
if (lineStart !== void 0) {
|
|
1206
|
+
const containing = [...candidates.keys()].filter((statement) => {
|
|
1207
|
+
const bounds = astNodeBounds(statement);
|
|
1208
|
+
return bounds && bounds.start < lineEnd && bounds.end > lineStart;
|
|
1209
|
+
});
|
|
1210
|
+
if (containing.length === 1) return resolved(containing[0]);
|
|
1211
|
+
if (containing.length > 1) {
|
|
1212
|
+
return { kind: "ambiguous", candidates: containing };
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
if (candidates.size === 1) {
|
|
1216
|
+
return resolved([...candidates.keys()][0]);
|
|
1217
|
+
}
|
|
1218
|
+
return { kind: "ambiguous", candidates: [...candidates.keys()] };
|
|
1219
|
+
}
|
|
1220
|
+
function statementLine(statement, lineStarts) {
|
|
1221
|
+
const bounds = statement ? astNodeBounds(statement) : null;
|
|
1222
|
+
if (!bounds) return null;
|
|
1223
|
+
let line = 1;
|
|
1224
|
+
for (let index = 0; index < lineStarts.length; index += 1) {
|
|
1225
|
+
if (lineStarts[index] > bounds.start) break;
|
|
1226
|
+
line = index + 1;
|
|
1227
|
+
}
|
|
1228
|
+
return line;
|
|
1229
|
+
}
|
|
1230
|
+
function resolveDocflowBinding(ast, binding, lineStarts, parents) {
|
|
1231
|
+
const positional = findDocflowBoundStatement(ast, binding.line, lineStarts);
|
|
1232
|
+
const symbol = resolveDocflowBindingSymbol(ast, binding, lineStarts, parents);
|
|
1233
|
+
const root = docflowOutputRoot(binding);
|
|
1234
|
+
if (symbol.kind === "ambiguous") {
|
|
1235
|
+
return {
|
|
1236
|
+
binding,
|
|
1237
|
+
statement: positional,
|
|
1238
|
+
symbolKind: null,
|
|
1239
|
+
drift: {
|
|
1240
|
+
binding,
|
|
1241
|
+
symbol: _nullishCoalesce(root, () => ( "")),
|
|
1242
|
+
annotatedLine: statementLine(positional, lineStarts),
|
|
1243
|
+
symbolLine: statementLine(_nullishCoalesce(symbol.candidates[0], () => ( null)), lineStarts),
|
|
1244
|
+
ambiguous: true
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
if (symbol.kind === "resolved") {
|
|
1249
|
+
const drift = positional && positional !== symbol.statement ? {
|
|
1250
|
+
binding,
|
|
1251
|
+
symbol: _nullishCoalesce(root, () => ( "")),
|
|
1252
|
+
annotatedLine: statementLine(positional, lineStarts),
|
|
1253
|
+
symbolLine: statementLine(symbol.statement, lineStarts),
|
|
1254
|
+
ambiguous: false
|
|
1255
|
+
} : null;
|
|
1256
|
+
return {
|
|
1257
|
+
binding,
|
|
1258
|
+
statement: symbol.statement,
|
|
1259
|
+
symbolKind: symbol.symbolKind,
|
|
1260
|
+
drift
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
return { binding, statement: positional, symbolKind: null, drift: null };
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
// ../plays/bundling/limits.ts
|
|
1267
|
+
var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
|
|
1268
|
+
|
|
1269
|
+
// ../plays/bundling/index.ts
|
|
1270
|
+
var PLAY_BUNDLE_CACHE_NAMESPACE = "deepline-play-artifacts-docflow-jsdoc";
|
|
1271
|
+
var PLAY_ARTIFACT_CACHE_DIR = _path.join.call(void 0, _os.tmpdir.call(void 0, ), PLAY_BUNDLE_CACHE_NAMESPACE);
|
|
1272
|
+
var PLAY_PROXY_NAMESPACE = "deepline-play-runtime-ref";
|
|
1273
|
+
var SOURCE_EXTENSIONS = [
|
|
1274
|
+
".ts",
|
|
1275
|
+
".tsx",
|
|
1276
|
+
".mts",
|
|
1277
|
+
".cts",
|
|
1278
|
+
".js",
|
|
1279
|
+
".jsx",
|
|
1280
|
+
".mjs",
|
|
1281
|
+
".cjs",
|
|
1282
|
+
".json"
|
|
1283
|
+
];
|
|
1284
|
+
var PLAY_SOURCE_FILE_PATTERN = /\.play\.(?:[cm]?[jt]sx?)$/i;
|
|
1285
|
+
var TEXT_IMPORT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt"]);
|
|
1286
|
+
var EXPLICIT_IMPORT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
1287
|
+
...SOURCE_EXTENSIONS,
|
|
1288
|
+
...TEXT_IMPORT_EXTENSIONS
|
|
1289
|
+
]);
|
|
1290
|
+
var NODE_BUILTIN_SET = new Set(
|
|
1291
|
+
_module.builtinModules.flatMap(
|
|
1292
|
+
(name) => name.startsWith("node:") ? [name, name.slice(5)] : [name, `node:${name}`]
|
|
1293
|
+
)
|
|
1294
|
+
);
|
|
1295
|
+
var defaultPathRelationshipApi = {
|
|
1296
|
+
relative: _path.relative,
|
|
1297
|
+
isAbsolute: _path.isAbsolute,
|
|
1298
|
+
sep: _path.sep
|
|
1299
|
+
};
|
|
1300
|
+
function assertValidExportName(exportName) {
|
|
1301
|
+
if (exportName === "default") return;
|
|
1302
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(exportName)) {
|
|
1303
|
+
throw new Error(
|
|
1304
|
+
`Invalid play export name "${exportName}". Named prebuilt exports must be valid JavaScript identifiers.`
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
function sha256(value) {
|
|
1309
|
+
return _crypto.createHash.call(void 0, "sha256").update(value).digest("hex");
|
|
1310
|
+
}
|
|
1311
|
+
function sourceIdentityPath(filePath, sourceIdentityRoot) {
|
|
1312
|
+
if (!sourceIdentityRoot) return filePath;
|
|
1313
|
+
const identityRoot = _path.resolve.call(void 0, sourceIdentityRoot);
|
|
1314
|
+
const resolvedFilePath = _path.resolve.call(void 0, filePath);
|
|
1315
|
+
const logicalPath = _path.relative.call(void 0, identityRoot, resolvedFilePath);
|
|
1316
|
+
if (!logicalPath) {
|
|
1317
|
+
return _path.basename.call(void 0, resolvedFilePath);
|
|
1318
|
+
}
|
|
1319
|
+
if (logicalPath === ".." || logicalPath.startsWith(`..${_path.sep}`) || _path.isAbsolute.call(void 0, logicalPath)) {
|
|
1320
|
+
return filePath;
|
|
1321
|
+
}
|
|
1322
|
+
return logicalPath.split(/[\\/]+/).join("/");
|
|
1323
|
+
}
|
|
1324
|
+
function formatEsbuildMessage(message) {
|
|
1325
|
+
const location = message.location ? `${message.location.file}:${message.location.line}:${message.location.column}` : null;
|
|
1326
|
+
return location ? `${location} ${message.text}` : message.text;
|
|
1327
|
+
}
|
|
1328
|
+
function isLocalSpecifier(specifier) {
|
|
1329
|
+
return specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:");
|
|
1330
|
+
}
|
|
1331
|
+
async function normalizeLocalPath(filePath) {
|
|
1332
|
+
try {
|
|
1333
|
+
return await _promises.realpath.call(void 0, filePath);
|
|
1334
|
+
} catch (e2) {
|
|
1335
|
+
return _path.resolve.call(void 0, filePath);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
function createPlayWorkspace(entryFile) {
|
|
1339
|
+
return {
|
|
1340
|
+
entryFile,
|
|
1341
|
+
rootDir: _path.dirname.call(void 0, entryFile)
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
function isPathInsideDirectory(filePath, directory, pathApi = defaultPathRelationshipApi) {
|
|
1345
|
+
const relationship = pathApi.relative(directory, filePath);
|
|
1346
|
+
return relationship === "" || relationship !== ".." && !relationship.startsWith(`..${pathApi.sep}`) && !pathApi.isAbsolute(relationship);
|
|
1347
|
+
}
|
|
1348
|
+
function assertWithinPlayWorkspace(input) {
|
|
1349
|
+
if (isPathInsideDirectory(input.resolvedPath, input.workspace.rootDir)) {
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
throw new Error(
|
|
1353
|
+
`${input.importer}:${input.line}:${input.column} Local play imports must stay inside the play workspace (${input.workspace.rootDir}). Import "${input.specifier}" resolved to ${input.resolvedPath}, which crosses into app/backend code. Use the public SDK/API surface or move shared helpers into the play workspace.`
|
|
1354
|
+
);
|
|
1355
|
+
}
|
|
1356
|
+
function getPackageName(specifier) {
|
|
1357
|
+
if (specifier.startsWith("@")) {
|
|
1358
|
+
const [scope, name] = specifier.split("/");
|
|
1359
|
+
return scope && name ? `${scope}/${name}` : specifier;
|
|
1360
|
+
}
|
|
1361
|
+
return _nullishCoalesce(specifier.split("/")[0], () => ( specifier));
|
|
1362
|
+
}
|
|
1363
|
+
function isPlaySourceFile(filePath) {
|
|
1364
|
+
return PLAY_SOURCE_FILE_PATTERN.test(filePath);
|
|
1365
|
+
}
|
|
1366
|
+
function stripCommentsToSpaces(source) {
|
|
1367
|
+
return source.replace(/\/\*[\s\S]*?\*\//g, (match) => match.replace(/[^\n]/g, " ")).replace(
|
|
1368
|
+
/(^|[^:])\/\/.*$/gm,
|
|
1369
|
+
(match, prefix) => prefix + " ".repeat(Math.max(0, match.length - prefix.length))
|
|
1370
|
+
);
|
|
1371
|
+
}
|
|
1372
|
+
function lineAndColumnAt(source, index) {
|
|
1373
|
+
const prefix = source.slice(0, index);
|
|
1374
|
+
const lines = prefix.split("\n");
|
|
1375
|
+
return { line: lines.length, column: lines[lines.length - 1].length + 1 };
|
|
1376
|
+
}
|
|
1377
|
+
function findSourceImportReferences(sourceCode) {
|
|
1378
|
+
const source = stripCommentsToSpaces(sourceCode);
|
|
1379
|
+
const references = [];
|
|
1380
|
+
const addReference = (specifier, specifierIndex, kind) => {
|
|
1381
|
+
if (!specifier) return;
|
|
1382
|
+
const position = lineAndColumnAt(sourceCode, specifierIndex);
|
|
1383
|
+
references.push({
|
|
1384
|
+
specifier,
|
|
1385
|
+
line: position.line,
|
|
1386
|
+
column: position.column,
|
|
1387
|
+
kind
|
|
1388
|
+
});
|
|
1389
|
+
};
|
|
1390
|
+
const staticImportPattern = /\b(?:import|export)\s+(?!type\b)(?:[\s\S]*?\s+from\s*)?(['"])([^'"\n]+)\1/g;
|
|
1391
|
+
for (const match of source.matchAll(staticImportPattern)) {
|
|
1392
|
+
addReference(
|
|
1393
|
+
match[2],
|
|
1394
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
1395
|
+
"static"
|
|
1396
|
+
);
|
|
1397
|
+
}
|
|
1398
|
+
const dynamicImportPattern = /\bimport\s*\(\s*(['"])([^'"\n]+)\1/g;
|
|
1399
|
+
for (const match of source.matchAll(dynamicImportPattern)) {
|
|
1400
|
+
addReference(
|
|
1401
|
+
match[2],
|
|
1402
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
1403
|
+
"dynamic-import"
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1406
|
+
const requirePattern = /\brequire\s*\(\s*(['"])([^'"\n]+)\1/g;
|
|
1407
|
+
for (const match of source.matchAll(requirePattern)) {
|
|
1408
|
+
addReference(
|
|
1409
|
+
match[2],
|
|
1410
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
1411
|
+
"require"
|
|
1412
|
+
);
|
|
1413
|
+
}
|
|
1414
|
+
const literalDynamicImportIndexes = new Set(
|
|
1415
|
+
[...source.matchAll(dynamicImportPattern)].map((match) => match.index)
|
|
1416
|
+
);
|
|
1417
|
+
for (const match of source.matchAll(/\bimport\s*\(/g)) {
|
|
1418
|
+
if (literalDynamicImportIndexes.has(match.index)) continue;
|
|
1419
|
+
const position = lineAndColumnAt(sourceCode, match.index);
|
|
1420
|
+
throw new Error(
|
|
1421
|
+
`:${position.line}:${position.column} Dynamic import() is not allowed in plays. Use static imports instead.`
|
|
1422
|
+
);
|
|
1423
|
+
}
|
|
1424
|
+
const literalRequireIndexes = new Set(
|
|
1425
|
+
[...source.matchAll(requirePattern)].map((match) => match.index)
|
|
1426
|
+
);
|
|
1427
|
+
for (const match of source.matchAll(/\brequire\s*\(/g)) {
|
|
1428
|
+
if (literalRequireIndexes.has(match.index)) continue;
|
|
1429
|
+
const position = lineAndColumnAt(sourceCode, match.index);
|
|
1430
|
+
throw new Error(
|
|
1431
|
+
`:${position.line}:${position.column} Dynamic require() is not allowed in plays. Use static imports or require("literal") only.`
|
|
1432
|
+
);
|
|
1433
|
+
}
|
|
1434
|
+
return references.sort(
|
|
1435
|
+
(left, right) => left.line === right.line ? left.column - right.column : left.line - right.line
|
|
1436
|
+
);
|
|
1437
|
+
}
|
|
1438
|
+
function extractDefinedPlayName(sourceCode) {
|
|
1439
|
+
return _nullishCoalesce(_optionalChain([extractDefinedPlayMetadata, 'call', _71 => _71(sourceCode, null), 'optionalAccess', _72 => _72.name]), () => ( null));
|
|
1440
|
+
}
|
|
1441
|
+
function parsePlaySourceAst(sourceCode) {
|
|
1442
|
+
try {
|
|
1443
|
+
return TypeScriptParser.parse(sourceCode, {
|
|
1444
|
+
ecmaVersion: "latest",
|
|
1445
|
+
sourceType: "module",
|
|
1446
|
+
allowHashBang: true
|
|
1447
|
+
});
|
|
1448
|
+
} catch (e3) {
|
|
1449
|
+
try {
|
|
1450
|
+
const transformed = _esbuild.transformSync.call(void 0, sourceCode, {
|
|
1451
|
+
loader: "ts",
|
|
1452
|
+
format: "esm",
|
|
1453
|
+
target: "esnext",
|
|
1454
|
+
legalComments: "none",
|
|
1455
|
+
sourcemap: false
|
|
1456
|
+
}).code;
|
|
1457
|
+
return _acorn.Parser.parse(transformed, {
|
|
1458
|
+
ecmaVersion: "latest",
|
|
1459
|
+
sourceType: "module",
|
|
1460
|
+
allowHashBang: true
|
|
1461
|
+
});
|
|
1462
|
+
} catch (e4) {
|
|
1463
|
+
return null;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
function getIdentifierName3(node) {
|
|
1468
|
+
return isAstNode(node) && node.type === "Identifier" ? typeof node.name === "string" ? node.name : null : null;
|
|
1469
|
+
}
|
|
1470
|
+
function memberExpressionPath(node) {
|
|
1471
|
+
const expression = unwrapStaticExpression2(node);
|
|
1472
|
+
if (!expression) return null;
|
|
1473
|
+
if (expression.type === "Identifier" && typeof expression.name === "string") {
|
|
1474
|
+
return [expression.name];
|
|
1475
|
+
}
|
|
1476
|
+
if (expression.type !== "MemberExpression") return null;
|
|
1477
|
+
const objectPath = memberExpressionPath(
|
|
1478
|
+
isAstNode(expression.object) ? expression.object : null
|
|
1479
|
+
);
|
|
1480
|
+
if (!objectPath) return null;
|
|
1481
|
+
const property = isAstNode(expression.property) ? expression.property : null;
|
|
1482
|
+
if (!property) return null;
|
|
1483
|
+
if (!expression.computed && property.type === "Identifier") {
|
|
1484
|
+
return typeof property.name === "string" ? [...objectPath, property.name] : null;
|
|
1485
|
+
}
|
|
1486
|
+
if (expression.computed && property.type === "Literal") {
|
|
1487
|
+
return typeof property.value === "string" ? [...objectPath, property.value] : null;
|
|
1488
|
+
}
|
|
1489
|
+
return null;
|
|
1490
|
+
}
|
|
1491
|
+
function commonJsExportName(left) {
|
|
1492
|
+
const path = memberExpressionPath(left);
|
|
1493
|
+
if (!path) return null;
|
|
1494
|
+
if (path.length === 2 && path[0] === "module" && path[1] === "exports") {
|
|
1495
|
+
return "default";
|
|
1496
|
+
}
|
|
1497
|
+
if (path.length === 3 && path[0] === "module" && path[1] === "exports") {
|
|
1498
|
+
return path[2] || null;
|
|
1499
|
+
}
|
|
1500
|
+
if (path.length === 2 && path[0] === "exports") {
|
|
1501
|
+
return path[1] || null;
|
|
1502
|
+
}
|
|
1503
|
+
return null;
|
|
1504
|
+
}
|
|
1505
|
+
function isDefinePlayCallExpression(node) {
|
|
1506
|
+
if (!node || node.type !== "CallExpression") return false;
|
|
1507
|
+
const callee = isAstNode(node.callee) ? node.callee : null;
|
|
1508
|
+
if (!callee) return false;
|
|
1509
|
+
if (callee.type === "Identifier") {
|
|
1510
|
+
return callee.name === "definePlay" || callee.name === "defineWorkflow";
|
|
1511
|
+
}
|
|
1512
|
+
if (callee.type === "MemberExpression" && isAstNode(callee.property)) {
|
|
1513
|
+
const property = callee.property;
|
|
1514
|
+
return !callee.computed && property.type === "Identifier" && (property.name === "definePlay" || property.name === "defineWorkflow");
|
|
1515
|
+
}
|
|
1516
|
+
return false;
|
|
1517
|
+
}
|
|
1518
|
+
function canResolveDeclarationInitializer(declarationKind, initializer) {
|
|
1519
|
+
return declarationKind === "const" || isDefinePlayCallExpression(initializer);
|
|
1520
|
+
}
|
|
1521
|
+
function buildPlayMetadataContext(ast) {
|
|
1522
|
+
const declarations = /* @__PURE__ */ new Map();
|
|
1523
|
+
const namedExports = /* @__PURE__ */ new Map();
|
|
1524
|
+
const commonJsExports = /* @__PURE__ */ new Map();
|
|
1525
|
+
let defaultExport = null;
|
|
1526
|
+
for (const statement of astArray(ast.body)) {
|
|
1527
|
+
if (statement.type === "VariableDeclaration") {
|
|
1528
|
+
for (const declaration of astArray(statement.declarations)) {
|
|
1529
|
+
const name = getIdentifierName3(declaration.id);
|
|
1530
|
+
if (!name) continue;
|
|
1531
|
+
const initializer = isAstNode(declaration.init) ? declaration.init : null;
|
|
1532
|
+
declarations.set(
|
|
1533
|
+
name,
|
|
1534
|
+
canResolveDeclarationInitializer(statement.kind, initializer) ? initializer : null
|
|
1535
|
+
);
|
|
1536
|
+
}
|
|
1537
|
+
continue;
|
|
1538
|
+
}
|
|
1539
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
1540
|
+
defaultExport = isAstNode(statement.declaration) ? statement.declaration : null;
|
|
1541
|
+
continue;
|
|
1542
|
+
}
|
|
1543
|
+
if (statement.type === "TSExportAssignment") {
|
|
1544
|
+
defaultExport = isAstNode(statement.expression) ? statement.expression : null;
|
|
1545
|
+
continue;
|
|
1546
|
+
}
|
|
1547
|
+
if (statement.type === "ExportNamedDeclaration") {
|
|
1548
|
+
if (isAstNode(statement.declaration) && statement.declaration.type === "VariableDeclaration") {
|
|
1549
|
+
for (const declaration of astArray(
|
|
1550
|
+
statement.declaration.declarations
|
|
1551
|
+
)) {
|
|
1552
|
+
const name = getIdentifierName3(declaration.id);
|
|
1553
|
+
if (!name) continue;
|
|
1554
|
+
const initializer = isAstNode(declaration.init) ? declaration.init : null;
|
|
1555
|
+
declarations.set(
|
|
1556
|
+
name,
|
|
1557
|
+
canResolveDeclarationInitializer(
|
|
1558
|
+
statement.declaration.kind,
|
|
1559
|
+
initializer
|
|
1560
|
+
) ? initializer : null
|
|
1561
|
+
);
|
|
1562
|
+
namedExports.set(name, name);
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
for (const specifier of astArray(statement.specifiers)) {
|
|
1566
|
+
const localName = getIdentifierName3(specifier.local);
|
|
1567
|
+
const exportedName = _nullishCoalesce(getIdentifierName3(specifier.exported), () => ( (isAstNode(specifier.exported) && specifier.exported.type === "Literal" && typeof specifier.exported.value === "string" ? specifier.exported.value : null)));
|
|
1568
|
+
if (localName && exportedName) {
|
|
1569
|
+
namedExports.set(exportedName, localName);
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
if (statement.type === "ExpressionStatement" && isAstNode(statement.expression) && statement.expression.type === "AssignmentExpression") {
|
|
1574
|
+
const exportName = commonJsExportName(
|
|
1575
|
+
isAstNode(statement.expression.left) ? statement.expression.left : null
|
|
1576
|
+
);
|
|
1577
|
+
if (exportName && isAstNode(statement.expression.right)) {
|
|
1578
|
+
commonJsExports.set(exportName, statement.expression.right);
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
return { declarations, namedExports, commonJsExports, defaultExport };
|
|
1583
|
+
}
|
|
1584
|
+
function unwrapStaticExpression2(node) {
|
|
1585
|
+
let current = _nullishCoalesce(node, () => ( null));
|
|
1586
|
+
while (current && (current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression" || current.type === "ParenthesizedExpression")) {
|
|
1587
|
+
current = isAstNode(current.expression) ? current.expression : null;
|
|
1588
|
+
}
|
|
1589
|
+
return current;
|
|
1590
|
+
}
|
|
1591
|
+
function staticStringFromExpression(node, context, seen = /* @__PURE__ */ new Set(), trimResult = true) {
|
|
1592
|
+
const expression = unwrapStaticExpression2(node);
|
|
1593
|
+
if (!expression) return null;
|
|
1594
|
+
if (expression.type === "Literal") {
|
|
1595
|
+
const value = expression.value;
|
|
1596
|
+
if (typeof value !== "string" || !value.trim()) return null;
|
|
1597
|
+
return trimResult ? value.trim() : value;
|
|
1598
|
+
}
|
|
1599
|
+
if (expression.type === "TemplateLiteral" && astArray(expression.expressions).length === 0) {
|
|
1600
|
+
const firstQuasi = astArray(expression.quasis)[0];
|
|
1601
|
+
const cooked = firstQuasi && typeof firstQuasi.value === "object" ? firstQuasi.value.cooked : null;
|
|
1602
|
+
if (typeof cooked !== "string" || !cooked.trim()) return null;
|
|
1603
|
+
return trimResult ? cooked.trim() : cooked;
|
|
1604
|
+
}
|
|
1605
|
+
if (expression.type === "BinaryExpression" && expression.operator === "+") {
|
|
1606
|
+
const left = staticStringFromExpression(
|
|
1607
|
+
isAstNode(expression.left) ? expression.left : null,
|
|
1608
|
+
context,
|
|
1609
|
+
new Set(seen),
|
|
1610
|
+
false
|
|
1611
|
+
);
|
|
1612
|
+
const right = staticStringFromExpression(
|
|
1613
|
+
isAstNode(expression.right) ? expression.right : null,
|
|
1614
|
+
context,
|
|
1615
|
+
new Set(seen),
|
|
1616
|
+
false
|
|
1617
|
+
);
|
|
1618
|
+
const value = left !== null && right !== null ? `${left}${right}` : null;
|
|
1619
|
+
if (!_optionalChain([value, 'optionalAccess', _73 => _73.trim, 'call', _74 => _74()])) return null;
|
|
1620
|
+
return trimResult ? value.trim() : value;
|
|
1621
|
+
}
|
|
1622
|
+
const identifier = getIdentifierName3(expression);
|
|
1623
|
+
if (!identifier || seen.has(identifier)) return null;
|
|
1624
|
+
seen.add(identifier);
|
|
1625
|
+
return staticStringFromExpression(
|
|
1626
|
+
context.declarations.get(identifier),
|
|
1627
|
+
context,
|
|
1628
|
+
seen,
|
|
1629
|
+
trimResult
|
|
1630
|
+
);
|
|
1631
|
+
}
|
|
1632
|
+
function propertyNameFromKey(property) {
|
|
1633
|
+
const key = isAstNode(property.key) ? property.key : null;
|
|
1634
|
+
if (!key) return null;
|
|
1635
|
+
if (property.computed) {
|
|
1636
|
+
return key.type === "Literal" && typeof key.value === "string" ? key.value : null;
|
|
1637
|
+
}
|
|
1638
|
+
if (key.type === "Identifier" && typeof key.name === "string") {
|
|
1639
|
+
return key.name;
|
|
1640
|
+
}
|
|
1641
|
+
if (key.type === "Literal" && typeof key.value === "string") {
|
|
1642
|
+
return key.value;
|
|
1643
|
+
}
|
|
1644
|
+
return null;
|
|
1645
|
+
}
|
|
1646
|
+
function objectExpressionFromNode(node, context, seen = /* @__PURE__ */ new Set()) {
|
|
1647
|
+
const expression = unwrapStaticExpression2(node);
|
|
1648
|
+
if (!expression) return null;
|
|
1649
|
+
if (expression.type === "ObjectExpression") return expression;
|
|
1650
|
+
const identifier = getIdentifierName3(expression);
|
|
1651
|
+
if (!identifier || seen.has(identifier)) return null;
|
|
1652
|
+
seen.add(identifier);
|
|
1653
|
+
return objectExpressionFromNode(
|
|
1654
|
+
context.declarations.get(identifier),
|
|
1655
|
+
context,
|
|
1656
|
+
seen
|
|
1657
|
+
);
|
|
1658
|
+
}
|
|
1659
|
+
function resolveStaticProperty(node, propertyName, context, ancestors = /* @__PURE__ */ new Set()) {
|
|
1660
|
+
if (!node) return { kind: "absent" };
|
|
1661
|
+
const object = objectExpressionFromNode(node, context);
|
|
1662
|
+
if (!object) return { kind: "unknown" };
|
|
1663
|
+
if (ancestors.has(object)) return { kind: "unknown" };
|
|
1664
|
+
const nextAncestors = new Set(ancestors).add(object);
|
|
1665
|
+
let resolution = { kind: "absent" };
|
|
1666
|
+
for (const property of astArray(object.properties)) {
|
|
1667
|
+
if (property.type === "SpreadElement") {
|
|
1668
|
+
const spreadResolution = resolveStaticProperty(
|
|
1669
|
+
isAstNode(property.argument) ? property.argument : null,
|
|
1670
|
+
propertyName,
|
|
1671
|
+
context,
|
|
1672
|
+
nextAncestors
|
|
1673
|
+
);
|
|
1674
|
+
if (spreadResolution.kind !== "absent") {
|
|
1675
|
+
resolution = spreadResolution;
|
|
1676
|
+
}
|
|
1677
|
+
continue;
|
|
1678
|
+
}
|
|
1679
|
+
if (property.type !== "Property") continue;
|
|
1680
|
+
const resolvedPropertyName = propertyNameFromKey(property);
|
|
1681
|
+
if (resolvedPropertyName !== propertyName) {
|
|
1682
|
+
if (property.computed && resolvedPropertyName === null) {
|
|
1683
|
+
resolution = { kind: "unknown" };
|
|
1684
|
+
}
|
|
1685
|
+
continue;
|
|
1686
|
+
}
|
|
1687
|
+
const propertyValue = property.shorthand ? property.key : property.value;
|
|
1688
|
+
resolution = isAstNode(propertyValue) ? { kind: "found", value: propertyValue } : { kind: "unknown" };
|
|
1689
|
+
}
|
|
1690
|
+
return resolution;
|
|
1691
|
+
}
|
|
1692
|
+
function staticPropertyNames(node, context, ancestors = /* @__PURE__ */ new Set()) {
|
|
1693
|
+
if (!node) return /* @__PURE__ */ new Set();
|
|
1694
|
+
const object = objectExpressionFromNode(node, context);
|
|
1695
|
+
if (!object || ancestors.has(object)) return null;
|
|
1696
|
+
const nextAncestors = new Set(ancestors).add(object);
|
|
1697
|
+
const names = /* @__PURE__ */ new Set();
|
|
1698
|
+
for (const property of astArray(object.properties)) {
|
|
1699
|
+
if (property.type === "SpreadElement") {
|
|
1700
|
+
const spreadNames = staticPropertyNames(
|
|
1701
|
+
isAstNode(property.argument) ? property.argument : null,
|
|
1702
|
+
context,
|
|
1703
|
+
nextAncestors
|
|
1704
|
+
);
|
|
1705
|
+
if (!spreadNames) return null;
|
|
1706
|
+
for (const name2 of spreadNames) names.add(name2);
|
|
1707
|
+
continue;
|
|
1708
|
+
}
|
|
1709
|
+
if (property.type !== "Property") return null;
|
|
1710
|
+
const name = propertyNameFromKey(property);
|
|
1711
|
+
if (name === null) return null;
|
|
1712
|
+
names.add(name);
|
|
1713
|
+
}
|
|
1714
|
+
return names;
|
|
1715
|
+
}
|
|
1716
|
+
function staticNumberFromExpression(node, context, seen = /* @__PURE__ */ new Set()) {
|
|
1717
|
+
const expression = unwrapStaticExpression2(node);
|
|
1718
|
+
if (!expression) return null;
|
|
1719
|
+
if (expression.type === "Literal" && typeof expression.value === "number") {
|
|
1720
|
+
return expression.value;
|
|
1721
|
+
}
|
|
1722
|
+
const identifier = getIdentifierName3(expression);
|
|
1723
|
+
if (!identifier || seen.has(identifier)) return null;
|
|
1724
|
+
seen.add(identifier);
|
|
1725
|
+
return staticNumberFromExpression(
|
|
1726
|
+
context.declarations.get(identifier),
|
|
1727
|
+
context,
|
|
1728
|
+
seen
|
|
1729
|
+
);
|
|
1730
|
+
}
|
|
1731
|
+
function toolErrorSchemaVersionFromOptions(node, context) {
|
|
1732
|
+
const directCompatibility = resolveStaticProperty(
|
|
1733
|
+
node,
|
|
1734
|
+
"compatibility",
|
|
1735
|
+
context
|
|
1736
|
+
);
|
|
1737
|
+
if (directCompatibility.kind === "unknown") return null;
|
|
1738
|
+
const bindings = resolveStaticProperty(node, "bindings", context);
|
|
1739
|
+
if (bindings.kind === "unknown") return null;
|
|
1740
|
+
const bindingCompatibility = bindings.kind === "found" ? resolveStaticProperty(bindings.value, "compatibility", context) : { kind: "absent" };
|
|
1741
|
+
if (bindingCompatibility.kind === "unknown") return null;
|
|
1742
|
+
const compatibility = directCompatibility.kind === "found" ? directCompatibility : bindingCompatibility;
|
|
1743
|
+
if (compatibility.kind === "absent") return void 0;
|
|
1744
|
+
const schema = resolveStaticProperty(
|
|
1745
|
+
compatibility.value,
|
|
1746
|
+
"toolErrorSchemaVersion",
|
|
1747
|
+
context
|
|
1748
|
+
);
|
|
1749
|
+
if (schema.kind === "absent") return void 0;
|
|
1750
|
+
if (schema.kind !== "found") return null;
|
|
1751
|
+
const schemaVersion = staticNumberFromExpression(schema.value, context);
|
|
1752
|
+
if (schemaVersion === 0 || schemaVersion === 1) return schemaVersion;
|
|
1753
|
+
return null;
|
|
1754
|
+
}
|
|
1755
|
+
function toolResponseReceiptRevisionFromOptions(node, context) {
|
|
1756
|
+
const directCompatibility = resolveStaticProperty(
|
|
1757
|
+
node,
|
|
1758
|
+
"compatibility",
|
|
1759
|
+
context
|
|
1760
|
+
);
|
|
1761
|
+
if (directCompatibility.kind === "unknown") return null;
|
|
1762
|
+
const bindings = resolveStaticProperty(node, "bindings", context);
|
|
1763
|
+
if (bindings.kind === "unknown") return null;
|
|
1764
|
+
const bindingCompatibility = bindings.kind === "found" ? resolveStaticProperty(bindings.value, "compatibility", context) : { kind: "absent" };
|
|
1765
|
+
if (bindingCompatibility.kind === "unknown") return null;
|
|
1766
|
+
const compatibility = directCompatibility.kind === "found" ? directCompatibility : bindingCompatibility;
|
|
1767
|
+
if (compatibility.kind === "absent") return void 0;
|
|
1768
|
+
const revision = resolveStaticProperty(
|
|
1769
|
+
compatibility.value,
|
|
1770
|
+
"toolResponseReceiptRevision",
|
|
1771
|
+
context
|
|
1772
|
+
);
|
|
1773
|
+
if (revision.kind === "absent") return void 0;
|
|
1774
|
+
if (revision.kind !== "found") return null;
|
|
1775
|
+
return staticStringFromExpression(revision.value, context);
|
|
1776
|
+
}
|
|
1777
|
+
function sandboxRuntimeDeclarationFromOptions(node, context) {
|
|
1778
|
+
const directRuntime = resolveStaticProperty(node, "runtime", context);
|
|
1779
|
+
const bindings = resolveStaticProperty(node, "bindings", context);
|
|
1780
|
+
const bindingRuntime = bindings.kind === "found" ? resolveStaticProperty(bindings.value, "runtime", context) : { kind: "absent" };
|
|
1781
|
+
const runtime = directRuntime.kind === "found" ? directRuntime : bindingRuntime;
|
|
1782
|
+
if (runtime.kind !== "found") return null;
|
|
1783
|
+
const propertyNames = staticPropertyNames(runtime.value, context);
|
|
1784
|
+
const unsupportedProperties = propertyNames ? [...propertyNames].filter(
|
|
1785
|
+
(propertyName) => propertyName !== "timeout" && propertyName !== "size"
|
|
1786
|
+
) : [];
|
|
1787
|
+
if (unsupportedProperties.length > 0) {
|
|
1788
|
+
throw new Error(
|
|
1789
|
+
`Unsupported runtime sandbox option${unsupportedProperties.length === 1 ? "" : "s"} "${unsupportedProperties.join('", "')}". Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard".`
|
|
1790
|
+
);
|
|
1791
|
+
}
|
|
1792
|
+
const timeout = resolveStaticProperty(runtime.value, "timeout", context);
|
|
1793
|
+
const size = resolveStaticProperty(runtime.value, "size", context);
|
|
1794
|
+
const declaration = {};
|
|
1795
|
+
if (timeout.kind === "found") {
|
|
1796
|
+
const value = staticStringFromExpression(timeout.value, context);
|
|
1797
|
+
if (value === null) return null;
|
|
1798
|
+
declaration.timeout = value;
|
|
1799
|
+
}
|
|
1800
|
+
if (size.kind === "found") {
|
|
1801
|
+
const value = staticStringFromExpression(size.value, context);
|
|
1802
|
+
if (value === null) return null;
|
|
1803
|
+
declaration.size = value;
|
|
1804
|
+
}
|
|
1805
|
+
return declaration;
|
|
1806
|
+
}
|
|
1807
|
+
function stringPropertyFromObjectExpression(node, propertyName, context, seenObjects = /* @__PURE__ */ new Set()) {
|
|
1808
|
+
const object = objectExpressionFromNode(node, context);
|
|
1809
|
+
if (!object || seenObjects.has(object)) return null;
|
|
1810
|
+
seenObjects.add(object);
|
|
1811
|
+
let value = null;
|
|
1812
|
+
for (const property of astArray(object.properties)) {
|
|
1813
|
+
if (property.type === "SpreadElement") {
|
|
1814
|
+
const spreadValue = stringPropertyFromObjectExpression(
|
|
1815
|
+
isAstNode(property.argument) ? property.argument : null,
|
|
1816
|
+
propertyName,
|
|
1817
|
+
context,
|
|
1818
|
+
seenObjects
|
|
1819
|
+
);
|
|
1820
|
+
if (spreadValue) value = spreadValue;
|
|
1821
|
+
continue;
|
|
1822
|
+
}
|
|
1823
|
+
if (property.type !== "Property") continue;
|
|
1824
|
+
if (propertyNameFromKey(property) !== propertyName) continue;
|
|
1825
|
+
const propertyValue = property.shorthand ? property.key : property.value;
|
|
1826
|
+
value = staticStringFromExpression(
|
|
1827
|
+
isAstNode(propertyValue) ? propertyValue : null,
|
|
1828
|
+
context
|
|
1829
|
+
);
|
|
1830
|
+
}
|
|
1831
|
+
return value;
|
|
1832
|
+
}
|
|
1833
|
+
function isDefinePlayCallee(node) {
|
|
1834
|
+
const callee = unwrapStaticExpression2(node);
|
|
1835
|
+
if (!callee) return false;
|
|
1836
|
+
if (callee.type === "Identifier" && (callee.name === "definePlay" || callee.name === "defineWorkflow")) {
|
|
1837
|
+
return true;
|
|
1838
|
+
}
|
|
1839
|
+
if (callee.type === "MemberExpression" && isAstNode(callee.property)) {
|
|
1840
|
+
const property = callee.property;
|
|
1841
|
+
return !callee.computed && property.type === "Identifier" && (property.name === "definePlay" || property.name === "defineWorkflow");
|
|
1842
|
+
}
|
|
1843
|
+
return false;
|
|
1844
|
+
}
|
|
1845
|
+
function playMetadataFromDefinePlayCall(node, context) {
|
|
1846
|
+
const expression = unwrapStaticExpression2(node);
|
|
1847
|
+
if (!expression || expression.type !== "CallExpression" || !isDefinePlayCallee(isAstNode(expression.callee) ? expression.callee : null)) {
|
|
1848
|
+
return null;
|
|
1849
|
+
}
|
|
1850
|
+
const args = astArray(expression.arguments);
|
|
1851
|
+
const firstArg = _nullishCoalesce(args[0], () => ( null));
|
|
1852
|
+
const isObjectForm = args.length === 1 || objectExpressionFromNode(firstArg, context) !== null;
|
|
1853
|
+
const objectName = stringPropertyFromObjectExpression(
|
|
1854
|
+
firstArg,
|
|
1855
|
+
"id",
|
|
1856
|
+
context
|
|
1857
|
+
);
|
|
1858
|
+
const name = isObjectForm ? objectName : staticStringFromExpression(firstArg, context);
|
|
1859
|
+
let description = _nullishCoalesce(stringPropertyFromObjectExpression(firstArg, "description", context), () => ( null));
|
|
1860
|
+
for (let index = args.length - 1; !description && index >= 2; index -= 1) {
|
|
1861
|
+
description = stringPropertyFromObjectExpression(
|
|
1862
|
+
args[index],
|
|
1863
|
+
"description",
|
|
1864
|
+
context
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
const options = isObjectForm ? firstArg : _nullishCoalesce(args[2], () => ( null));
|
|
1868
|
+
const sandboxRuntimeDeclaration = sandboxRuntimeDeclarationFromOptions(
|
|
1869
|
+
options,
|
|
1870
|
+
context
|
|
1871
|
+
);
|
|
1872
|
+
const toolErrorSchemaVersion = toolErrorSchemaVersionFromOptions(
|
|
1873
|
+
options,
|
|
1874
|
+
context
|
|
1875
|
+
);
|
|
1876
|
+
const toolErrorSchemaVersionUnknown = toolErrorSchemaVersion === null;
|
|
1877
|
+
const toolResponseReceiptRevision = toolResponseReceiptRevisionFromOptions(
|
|
1878
|
+
options,
|
|
1879
|
+
context
|
|
1880
|
+
);
|
|
1881
|
+
const toolResponseReceiptRevisionUnknown = toolResponseReceiptRevision === null;
|
|
1882
|
+
if (!name && !description && toolErrorSchemaVersion === void 0 && !toolErrorSchemaVersionUnknown && toolResponseReceiptRevision === void 0 && !toolResponseReceiptRevisionUnknown) {
|
|
1883
|
+
return null;
|
|
1884
|
+
}
|
|
1885
|
+
return {
|
|
1886
|
+
name,
|
|
1887
|
+
description,
|
|
1888
|
+
sandboxRuntimeDeclaration,
|
|
1889
|
+
toolErrorSchemaVersion: _nullishCoalesce(toolErrorSchemaVersion, () => ( null)),
|
|
1890
|
+
toolErrorSchemaVersionUnknown,
|
|
1891
|
+
toolResponseReceiptRevision: _nullishCoalesce(toolResponseReceiptRevision, () => ( null)),
|
|
1892
|
+
toolResponseReceiptRevisionUnknown
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
function resolveExportExpression(exportName, context) {
|
|
1896
|
+
if (exportName === "default") {
|
|
1897
|
+
const commonJsDefault = context.commonJsExports.get("default");
|
|
1898
|
+
if (commonJsDefault) {
|
|
1899
|
+
const commonJsDefaultIdentifier = getIdentifierName3(
|
|
1900
|
+
unwrapStaticExpression2(commonJsDefault)
|
|
1901
|
+
);
|
|
1902
|
+
return commonJsDefaultIdentifier ? _nullishCoalesce(context.declarations.get(commonJsDefaultIdentifier), () => ( commonJsDefault)) : commonJsDefault;
|
|
1903
|
+
}
|
|
1904
|
+
const defaultExpression = unwrapStaticExpression2(context.defaultExport);
|
|
1905
|
+
const defaultIdentifier = getIdentifierName3(defaultExpression);
|
|
1906
|
+
if (!defaultIdentifier) {
|
|
1907
|
+
const defaultExportName = context.namedExports.get("default");
|
|
1908
|
+
return defaultExportName ? _nullishCoalesce(context.declarations.get(defaultExportName), () => ( null)) : defaultExpression;
|
|
1909
|
+
}
|
|
1910
|
+
return defaultIdentifier ? _nullishCoalesce(context.declarations.get(defaultIdentifier), () => ( context.defaultExport)) : context.defaultExport;
|
|
1911
|
+
}
|
|
1912
|
+
if (exportName) {
|
|
1913
|
+
const commonJsExport = context.commonJsExports.get(exportName);
|
|
1914
|
+
if (commonJsExport) {
|
|
1915
|
+
const commonJsExportIdentifier = getIdentifierName3(
|
|
1916
|
+
unwrapStaticExpression2(commonJsExport)
|
|
1917
|
+
);
|
|
1918
|
+
return commonJsExportIdentifier ? _nullishCoalesce(context.declarations.get(commonJsExportIdentifier), () => ( commonJsExport)) : commonJsExport;
|
|
1919
|
+
}
|
|
1920
|
+
const localName = _nullishCoalesce(context.namedExports.get(exportName), () => ( exportName));
|
|
1921
|
+
return _nullishCoalesce(context.declarations.get(localName), () => ( null));
|
|
1922
|
+
}
|
|
1923
|
+
return null;
|
|
1924
|
+
}
|
|
1925
|
+
function extractDefinedPlayMetadata(sourceCode, exportName) {
|
|
1926
|
+
const ast = parsePlaySourceAst(sourceCode);
|
|
1927
|
+
if (!ast) return null;
|
|
1928
|
+
const context = buildPlayMetadataContext(ast);
|
|
1929
|
+
const exportedExpression = resolveExportExpression(exportName, context);
|
|
1930
|
+
const exportedMetadata = playMetadataFromDefinePlayCall(
|
|
1931
|
+
exportedExpression,
|
|
1932
|
+
context
|
|
1933
|
+
);
|
|
1934
|
+
if (exportedMetadata) return exportedMetadata;
|
|
1935
|
+
if (exportName) return null;
|
|
1936
|
+
if (context.defaultExport) {
|
|
1937
|
+
const directDefaultMetadata = playMetadataFromDefinePlayCall(
|
|
1938
|
+
context.defaultExport,
|
|
1939
|
+
context
|
|
1940
|
+
);
|
|
1941
|
+
if (directDefaultMetadata) return directDefaultMetadata;
|
|
1942
|
+
const defaultIdentifier = getIdentifierName3(context.defaultExport);
|
|
1943
|
+
if (defaultIdentifier) {
|
|
1944
|
+
const defaultMetadata = playMetadataFromDefinePlayCall(
|
|
1945
|
+
context.declarations.get(defaultIdentifier),
|
|
1946
|
+
context
|
|
1947
|
+
);
|
|
1948
|
+
if (defaultMetadata) return defaultMetadata;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
for (const expression of context.declarations.values()) {
|
|
1952
|
+
const metadata = playMetadataFromDefinePlayCall(expression, context);
|
|
1953
|
+
if (metadata) return metadata;
|
|
1954
|
+
}
|
|
1955
|
+
for (const expression of context.commonJsExports.values()) {
|
|
1956
|
+
const metadata = playMetadataFromDefinePlayCall(expression, context);
|
|
1957
|
+
if (metadata) return metadata;
|
|
1958
|
+
}
|
|
1959
|
+
return null;
|
|
1960
|
+
}
|
|
1961
|
+
function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
|
|
1962
|
+
try {
|
|
1963
|
+
const packageJson = JSON.parse(_fs.readFileSync.call(void 0, packageJsonPath, "utf-8"));
|
|
1964
|
+
if (packageJson.name === packageName && typeof packageJson.version === "string") {
|
|
1965
|
+
return packageJson.version;
|
|
1966
|
+
}
|
|
1967
|
+
} catch (e5) {
|
|
1968
|
+
return null;
|
|
1969
|
+
}
|
|
1970
|
+
return null;
|
|
1971
|
+
}
|
|
1972
|
+
function findPackageJsonPathFrom(startDir, packageName) {
|
|
1973
|
+
if (!_path.isAbsolute.call(void 0, startDir)) {
|
|
1974
|
+
throw new Error(
|
|
1975
|
+
`Package resolution requires an absolute start directory, got ${startDir}`
|
|
1976
|
+
);
|
|
1977
|
+
}
|
|
1978
|
+
let current = startDir;
|
|
1979
|
+
while (true) {
|
|
1980
|
+
const packageJsonPath = _path.join.call(void 0,
|
|
1981
|
+
current,
|
|
1982
|
+
"node_modules",
|
|
1983
|
+
packageName,
|
|
1984
|
+
"package.json"
|
|
1985
|
+
);
|
|
1986
|
+
if (_fs.existsSync.call(void 0, packageJsonPath)) {
|
|
1987
|
+
return packageJsonPath;
|
|
1988
|
+
}
|
|
1989
|
+
const parent = _path.dirname.call(void 0, current);
|
|
1990
|
+
if (parent === current) {
|
|
1991
|
+
return null;
|
|
1992
|
+
}
|
|
1993
|
+
current = parent;
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
function findPackageJsonPath(packageName, fromFile, adapter) {
|
|
1997
|
+
const startDirs = [
|
|
1998
|
+
_path.resolve.call(void 0, _path.dirname.call(void 0, fromFile)),
|
|
1999
|
+
_path.resolve.call(void 0, adapter.projectRoot),
|
|
2000
|
+
_path.resolve.call(void 0, _path.dirname.call(void 0, adapter.sdkPackageJson))
|
|
2001
|
+
];
|
|
2002
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2003
|
+
for (const startDir of startDirs) {
|
|
2004
|
+
if (seen.has(startDir)) continue;
|
|
2005
|
+
seen.add(startDir);
|
|
2006
|
+
const packageJsonPath = findPackageJsonPathFrom(startDir, packageName);
|
|
2007
|
+
if (packageJsonPath) return packageJsonPath;
|
|
2008
|
+
}
|
|
2009
|
+
const adapterNodeModulesPackageJson = _path.join.call(void 0,
|
|
2010
|
+
adapter.nodeModulesDir,
|
|
2011
|
+
packageName,
|
|
2012
|
+
"package.json"
|
|
2013
|
+
);
|
|
2014
|
+
return _fs.existsSync.call(void 0, adapterNodeModulesPackageJson) ? adapterNodeModulesPackageJson : null;
|
|
2015
|
+
}
|
|
2016
|
+
function localSdkAliasPlugin(adapter) {
|
|
2017
|
+
const entryFile = adapter.sdkEntryFile;
|
|
2018
|
+
if (!_fs.existsSync.call(void 0, entryFile)) {
|
|
2019
|
+
return null;
|
|
2020
|
+
}
|
|
2021
|
+
return {
|
|
2022
|
+
name: "deepline-sdk-local-alias",
|
|
2023
|
+
setup(buildContext) {
|
|
2024
|
+
buildContext.onResolve({ filter: /^deepline$/ }, () => ({
|
|
2025
|
+
path: entryFile
|
|
2026
|
+
}));
|
|
2027
|
+
buildContext.onResolve({ filter: /^deepline\/helpers$/ }, () => ({
|
|
2028
|
+
path: _path.join.call(void 0, adapter.sdkSourceRoot, "helpers.ts")
|
|
2029
|
+
}));
|
|
2030
|
+
}
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
2033
|
+
function isTextImportFile(path) {
|
|
2034
|
+
return TEXT_IMPORT_EXTENSIONS.has(_path.extname.call(void 0, path));
|
|
2035
|
+
}
|
|
2036
|
+
function sourceLoaderForPath(path) {
|
|
2037
|
+
const rawExtension = _path.extname.call(void 0, path);
|
|
2038
|
+
if (TEXT_IMPORT_EXTENSIONS.has(rawExtension)) return "text";
|
|
2039
|
+
const extension = rawExtension.toLowerCase();
|
|
2040
|
+
if (extension === ".tsx") return "tsx";
|
|
2041
|
+
if (extension === ".jsx") return "jsx";
|
|
2042
|
+
if (extension === ".js" || extension === ".mjs" || extension === ".cjs") {
|
|
2043
|
+
return "js";
|
|
2044
|
+
}
|
|
2045
|
+
return "ts";
|
|
2046
|
+
}
|
|
2047
|
+
function isFunctionNode(node) {
|
|
2048
|
+
return !!node && (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression");
|
|
2049
|
+
}
|
|
2050
|
+
function definePlayRunFunction(call) {
|
|
2051
|
+
if (!isDefinePlayCallExpression(call)) return null;
|
|
2052
|
+
const args = astArray(call.arguments);
|
|
2053
|
+
const positional = args.find((argument) => isFunctionNode(argument));
|
|
2054
|
+
if (positional) return positional;
|
|
2055
|
+
const config = unwrapStaticExpression2(_nullishCoalesce(args[0], () => ( null)));
|
|
2056
|
+
if (!config || config.type !== "ObjectExpression") return null;
|
|
2057
|
+
let run = null;
|
|
2058
|
+
for (const property of astArray(config.properties)) {
|
|
2059
|
+
if (property.type !== "Property") continue;
|
|
2060
|
+
if (propertyNameFromKey(property) !== "run") continue;
|
|
2061
|
+
const value = unwrapStaticExpression2(
|
|
2062
|
+
isAstNode(property.value) ? property.value : null
|
|
2063
|
+
);
|
|
2064
|
+
run = isFunctionNode(value) ? value : null;
|
|
2065
|
+
}
|
|
2066
|
+
return run;
|
|
2067
|
+
}
|
|
2068
|
+
var DOCFLOW_INJECTED_CONTEXT_NAME = "__deeplineDocflowContext";
|
|
2069
|
+
function docflowContextFromCall(call, sourceCode) {
|
|
2070
|
+
if (!isDefinePlayCallExpression(call)) return null;
|
|
2071
|
+
const run = definePlayRunFunction(call);
|
|
2072
|
+
if (!run) {
|
|
2073
|
+
return {
|
|
2074
|
+
kind: "unsupported",
|
|
2075
|
+
reason: "its definePlay call does not declare the run function inline (pass `definePlay(name, async (ctx, input) => \u2026)` or `definePlay({ id, run: async (ctx, input) => \u2026 })`)"
|
|
2076
|
+
};
|
|
2077
|
+
}
|
|
2078
|
+
const params = astArray(run.params);
|
|
2079
|
+
const first = params[0];
|
|
2080
|
+
if (first) {
|
|
2081
|
+
const name = getIdentifierName3(first);
|
|
2082
|
+
return name ? { kind: "named", name } : {
|
|
2083
|
+
kind: "unsupported",
|
|
2084
|
+
reason: `its run function's first parameter is not a plain identifier (found ${first.type}; declare the context as \`ctx\` and destructure inside the body)`
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
const runBounds = astNodeBounds(run);
|
|
2088
|
+
const body = isAstNode(run.body) ? astNodeBounds(run.body) : null;
|
|
2089
|
+
if (!runBounds || !body) {
|
|
2090
|
+
return {
|
|
2091
|
+
kind: "unsupported",
|
|
2092
|
+
reason: "its run function has no source span"
|
|
2093
|
+
};
|
|
2094
|
+
}
|
|
2095
|
+
const signature = sourceCode.slice(runBounds.start, body.start);
|
|
2096
|
+
const emptyParams = /\(\s*\)/.exec(signature);
|
|
2097
|
+
if (!emptyParams) {
|
|
2098
|
+
return {
|
|
2099
|
+
kind: "unsupported",
|
|
2100
|
+
reason: "its parameterless run function has no `()` parameter list"
|
|
2101
|
+
};
|
|
2102
|
+
}
|
|
2103
|
+
return {
|
|
2104
|
+
kind: "inject",
|
|
2105
|
+
name: DOCFLOW_INJECTED_CONTEXT_NAME,
|
|
2106
|
+
at: runBounds.start + emptyParams.index + 1
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
2109
|
+
function findDocflowContext(input) {
|
|
2110
|
+
let owner = input.statement;
|
|
2111
|
+
while (owner) {
|
|
2112
|
+
const context = docflowContextFromCall(owner, input.sourceCode);
|
|
2113
|
+
if (context) return context;
|
|
2114
|
+
owner = _nullishCoalesce(input.parents.get(owner), () => ( null));
|
|
2115
|
+
}
|
|
2116
|
+
const lineStart = input.lineStarts[input.bindingLine - 1];
|
|
2117
|
+
const lineEnd = _nullishCoalesce(input.lineStarts[input.bindingLine], () => ( Number.POSITIVE_INFINITY));
|
|
2118
|
+
if (lineStart === void 0) return null;
|
|
2119
|
+
let best = null;
|
|
2120
|
+
const pending = [input.ast];
|
|
2121
|
+
while (pending.length > 0) {
|
|
2122
|
+
const value = pending.pop();
|
|
2123
|
+
if (!isAstNode(value)) continue;
|
|
2124
|
+
if (isDefinePlayCallExpression(value)) {
|
|
2125
|
+
const bounds = astNodeBounds(value);
|
|
2126
|
+
if (bounds && bounds.start < lineEnd && bounds.end > lineStart && (!best || bounds.end - bounds.start < (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _75 => _75(best), 'optionalAccess', _76 => _76.end]), () => ( 0))) - (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _77 => _77(best), 'optionalAccess', _78 => _78.start]), () => ( 0))))) {
|
|
2127
|
+
best = value;
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
for (const child of Object.values(value)) {
|
|
2131
|
+
if (Array.isArray(child)) pending.push(...child);
|
|
2132
|
+
else if (isAstNode(child)) pending.push(child);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
return best ? docflowContextFromCall(best, input.sourceCode) : null;
|
|
2136
|
+
}
|
|
2137
|
+
function docflowInputCaptureSource(paths) {
|
|
2138
|
+
return `[${paths.map((path) => {
|
|
2139
|
+
const [root, ...properties] = path.split(".");
|
|
2140
|
+
return `{path:${JSON.stringify(path)},readRoot:()=>${root},properties:${JSON.stringify(properties)}}`;
|
|
2141
|
+
}).join(",")}]`;
|
|
2142
|
+
}
|
|
2143
|
+
function docflowObservationTarget(statement) {
|
|
2144
|
+
if (!statement) return null;
|
|
2145
|
+
let expression = null;
|
|
2146
|
+
if (statement.type === "VariableDeclaration") {
|
|
2147
|
+
const declarations = astArray(statement.declarations);
|
|
2148
|
+
if (declarations.length === 1 && isAstNode(declarations[0].init)) {
|
|
2149
|
+
expression = declarations[0].init;
|
|
2150
|
+
}
|
|
2151
|
+
} else if (statement.type === "ReturnStatement" && isAstNode(statement.argument)) {
|
|
2152
|
+
expression = statement.argument;
|
|
2153
|
+
} else if (statement.type === "ExpressionStatement" && isAstNode(statement.expression)) {
|
|
2154
|
+
expression = statement.expression;
|
|
2155
|
+
} else if (statement.type === "IfStatement" && isAstNode(statement.test)) {
|
|
2156
|
+
expression = statement.test;
|
|
2157
|
+
} else if (statement.type === "ThrowStatement" && isAstNode(statement.argument)) {
|
|
2158
|
+
expression = statement.argument;
|
|
2159
|
+
}
|
|
2160
|
+
if (!expression) return null;
|
|
2161
|
+
const bounds = astNodeBounds(expression);
|
|
2162
|
+
if (!bounds) return null;
|
|
2163
|
+
return {
|
|
2164
|
+
...bounds,
|
|
2165
|
+
awaitsResult: expressionContainsTopLevelAwait(expression),
|
|
2166
|
+
expression,
|
|
2167
|
+
throws: statement.type === "ThrowStatement"
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2170
|
+
function docflowObservedExpression(input) {
|
|
2171
|
+
const body = input.throws ? `{throw (${input.expression})}` : `(${input.expression})`;
|
|
2172
|
+
const callback = input.awaitsResult ? `async()=>${body}` : `()=>${body}`;
|
|
2173
|
+
const observation = `((runtimeContext,inputCaptures,execute)=>typeof runtimeContext.__deeplineObserveDocflowNode==="function"?runtimeContext.__deeplineObserveDocflowNode(${JSON.stringify(input.nodeId)},inputCaptures,${JSON.stringify(input.outputs)},execute):execute())(${input.contextName},${docflowInputCaptureSource(input.inputs)},${callback})`;
|
|
2174
|
+
return input.awaitsResult ? `(await ${observation})` : observation;
|
|
2175
|
+
}
|
|
2176
|
+
function expressionContainsTopLevelAwait(expression) {
|
|
2177
|
+
const pending = [expression];
|
|
2178
|
+
while (pending.length > 0) {
|
|
2179
|
+
const node = pending.pop();
|
|
2180
|
+
if (node.type === "AwaitExpression") return true;
|
|
2181
|
+
if (node !== expression && (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression" || node.type === "FunctionDeclaration")) {
|
|
2182
|
+
continue;
|
|
2183
|
+
}
|
|
2184
|
+
for (const child of Object.values(node)) {
|
|
2185
|
+
if (Array.isArray(child)) pending.push(...child.filter(isAstNode));
|
|
2186
|
+
else if (isAstNode(child)) pending.push(child);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
return false;
|
|
2190
|
+
}
|
|
2191
|
+
function instrumentPlayDocflowRuntimeHits(sourceCode) {
|
|
2192
|
+
const parsed = parsePlayDocflowFile(sourceCode);
|
|
2193
|
+
if (parsed.blocks.length === 0 || parsed.errors.length > 0) return sourceCode;
|
|
2194
|
+
const ast = parsePlaySourceAst(sourceCode);
|
|
2195
|
+
if (!ast) return sourceCode;
|
|
2196
|
+
const lineStarts = sourceLineStarts(sourceCode);
|
|
2197
|
+
const replacements = [];
|
|
2198
|
+
const targets = [];
|
|
2199
|
+
const injectedContextAt = /* @__PURE__ */ new Set();
|
|
2200
|
+
const parents = buildDocflowParentIndex(ast);
|
|
2201
|
+
for (const binding of parsed.bindings) {
|
|
2202
|
+
const resolution = resolveDocflowBinding(ast, binding, lineStarts, parents);
|
|
2203
|
+
const context = findDocflowContext({
|
|
2204
|
+
ast,
|
|
2205
|
+
sourceCode,
|
|
2206
|
+
statement: resolution.statement,
|
|
2207
|
+
bindingLine: binding.line,
|
|
2208
|
+
lineStarts,
|
|
2209
|
+
parents
|
|
2210
|
+
});
|
|
2211
|
+
if (!context) continue;
|
|
2212
|
+
if (context.kind === "unsupported") {
|
|
2213
|
+
throw new Error(
|
|
2214
|
+
`@mermaid-node ${binding.nodeId} (line ${binding.line}) cannot be observed at runtime: ${context.reason}.`
|
|
2215
|
+
);
|
|
2216
|
+
}
|
|
2217
|
+
if (context.kind === "inject") injectedContextAt.add(context.at);
|
|
2218
|
+
const contextName = context.kind === "inject" ? `(${context.name}??{})` : context.name;
|
|
2219
|
+
const target = docflowObservationTarget(resolution.statement);
|
|
2220
|
+
const observedRoot = docflowOutputRoot(binding);
|
|
2221
|
+
if (target && observedRoot && docflowExpressionWrapsStepBuilder(target.expression, observedRoot)) {
|
|
2222
|
+
continue;
|
|
2223
|
+
}
|
|
2224
|
+
if (target) {
|
|
2225
|
+
targets.push({ ...target, contextName, binding });
|
|
2226
|
+
continue;
|
|
2227
|
+
}
|
|
2228
|
+
const lineStart = lineStarts[binding.line - 1];
|
|
2229
|
+
if (lineStart !== void 0) {
|
|
2230
|
+
const indentationLength = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _79 => _79.exec, 'call', _80 => _80(sourceCode.slice(lineStart)), 'optionalAccess', _81 => _81[0], 'access', _82 => _82.length]), () => ( 0));
|
|
2231
|
+
replacements.push({
|
|
2232
|
+
start: lineStart + indentationLength,
|
|
2233
|
+
end: lineStart + indentationLength,
|
|
2234
|
+
value: `await (typeof ${contextName}.__deeplineDocflowHit==="function"?${contextName}.__deeplineDocflowHit(${JSON.stringify(binding.nodeId)}):void 0); `
|
|
2235
|
+
});
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
targets.sort(
|
|
2239
|
+
(left, right) => left.start - right.start || right.end - left.end
|
|
2240
|
+
);
|
|
2241
|
+
const groups = [];
|
|
2242
|
+
for (const target of targets) {
|
|
2243
|
+
const open = groups[groups.length - 1];
|
|
2244
|
+
if (open && target.start < open.end) {
|
|
2245
|
+
open.bindings.push(target.binding);
|
|
2246
|
+
} else {
|
|
2247
|
+
groups.push({
|
|
2248
|
+
start: target.start,
|
|
2249
|
+
end: target.end,
|
|
2250
|
+
awaitsResult: target.awaitsResult,
|
|
2251
|
+
throws: target.throws,
|
|
2252
|
+
contextName: target.contextName,
|
|
2253
|
+
bindings: [target.binding]
|
|
2254
|
+
});
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
for (const group of groups) {
|
|
2258
|
+
let expression = sourceCode.slice(group.start, group.end);
|
|
2259
|
+
let innermost = true;
|
|
2260
|
+
for (const binding of [...group.bindings].reverse()) {
|
|
2261
|
+
expression = docflowObservedExpression({
|
|
2262
|
+
contextName: group.contextName,
|
|
2263
|
+
nodeId: binding.nodeId,
|
|
2264
|
+
inputs: _nullishCoalesce(binding.inputs, () => ( [])),
|
|
2265
|
+
outputs: _nullishCoalesce(binding.outputs, () => ( [])),
|
|
2266
|
+
expression,
|
|
2267
|
+
awaitsResult: group.awaitsResult,
|
|
2268
|
+
throws: group.throws && innermost
|
|
2269
|
+
});
|
|
2270
|
+
innermost = false;
|
|
2271
|
+
}
|
|
2272
|
+
replacements.push({
|
|
2273
|
+
start: group.start,
|
|
2274
|
+
end: group.end,
|
|
2275
|
+
value: expression
|
|
2276
|
+
});
|
|
2277
|
+
}
|
|
2278
|
+
for (const at of injectedContextAt) {
|
|
2279
|
+
replacements.push({
|
|
2280
|
+
start: at,
|
|
2281
|
+
end: at,
|
|
2282
|
+
value: DOCFLOW_INJECTED_CONTEXT_NAME
|
|
2283
|
+
});
|
|
2284
|
+
}
|
|
2285
|
+
return replacements.sort((left, right) => right.start - left.start).reduce(
|
|
2286
|
+
(source, replacement) => `${source.slice(0, replacement.start)}${replacement.value}${source.slice(replacement.end)}`,
|
|
2287
|
+
sourceCode
|
|
2288
|
+
);
|
|
2289
|
+
}
|
|
2290
|
+
function docflowRuntimeInstrumentationPlugin(customerSourceFilePaths) {
|
|
2291
|
+
const customerSourceFiles = new Set(
|
|
2292
|
+
customerSourceFilePaths.filter((path) => _path.extname.call(void 0, path).toLowerCase() !== ".json").map((path) => _path.resolve.call(void 0, path))
|
|
2293
|
+
);
|
|
2294
|
+
return {
|
|
2295
|
+
name: "deepline-docflow-runtime-instrumentation",
|
|
2296
|
+
setup(buildContext) {
|
|
2297
|
+
buildContext.onLoad({ filter: /./ }, (args) => {
|
|
2298
|
+
if (!customerSourceFiles.has(_path.resolve.call(void 0, args.path))) return void 0;
|
|
2299
|
+
if (isTextImportFile(args.path)) {
|
|
2300
|
+
return {
|
|
2301
|
+
contents: _fs.readFileSync.call(void 0, args.path, "utf8"),
|
|
2302
|
+
loader: "text",
|
|
2303
|
+
resolveDir: _path.dirname.call(void 0, args.path)
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
return {
|
|
2307
|
+
contents: instrumentPlayDocflowRuntimeHits(
|
|
2308
|
+
_fs.readFileSync.call(void 0, args.path, "utf8")
|
|
2309
|
+
),
|
|
2310
|
+
loader: sourceLoaderForPath(args.path),
|
|
2311
|
+
resolveDir: _path.dirname.call(void 0, args.path)
|
|
2312
|
+
};
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
function buildImportedPlayProxyModule(playName) {
|
|
2318
|
+
const serializedName = JSON.stringify(playName);
|
|
2319
|
+
return `
|
|
2320
|
+
const PLAY_METADATA_SYMBOL = Symbol.for('deepline.play.metadata');
|
|
2321
|
+
const importedPlayRef = async function importedPlayRef(ctx, input) {
|
|
2322
|
+
return ctx.runPlay(${JSON.stringify(`imported_${playName.replace(/[^A-Za-z0-9_]+/g, "_")}`)}, importedPlayRef, input, {
|
|
2323
|
+
description: 'Run the imported Deepline play dependency.',
|
|
2324
|
+
});
|
|
2325
|
+
};
|
|
2326
|
+
Object.defineProperty(importedPlayRef, 'playName', {
|
|
2327
|
+
value: ${serializedName},
|
|
2328
|
+
enumerable: true,
|
|
2329
|
+
configurable: false,
|
|
2330
|
+
writable: false,
|
|
2331
|
+
});
|
|
2332
|
+
Object.defineProperty(importedPlayRef, PLAY_METADATA_SYMBOL, {
|
|
2333
|
+
value: { name: ${serializedName} },
|
|
2334
|
+
enumerable: false,
|
|
2335
|
+
configurable: false,
|
|
2336
|
+
writable: false,
|
|
2337
|
+
});
|
|
2338
|
+
export const playName = ${serializedName};
|
|
2339
|
+
export const name = ${serializedName};
|
|
2340
|
+
export default importedPlayRef;
|
|
2341
|
+
`;
|
|
2342
|
+
}
|
|
2343
|
+
function importedPlayProxyPlugin(importedPlayDependencies) {
|
|
2344
|
+
if (importedPlayDependencies.length === 0) {
|
|
2345
|
+
return null;
|
|
2346
|
+
}
|
|
2347
|
+
const dependenciesByPath = new Map(
|
|
2348
|
+
importedPlayDependencies.map((dependency) => [
|
|
2349
|
+
dependency.filePath,
|
|
2350
|
+
dependency
|
|
2351
|
+
])
|
|
2352
|
+
);
|
|
2353
|
+
return {
|
|
2354
|
+
name: "deepline-imported-play-proxy",
|
|
2355
|
+
setup(buildContext) {
|
|
2356
|
+
buildContext.onResolve({ filter: /.*/ }, async (args) => {
|
|
2357
|
+
if (!args.importer || !isLocalSpecifier(args.path) || args.importer.split(/[\\/]+/).includes("node_modules")) {
|
|
2358
|
+
return null;
|
|
2359
|
+
}
|
|
2360
|
+
const resolvedPath = await resolveLocalImport(args.importer, args.path);
|
|
2361
|
+
const dependency = dependenciesByPath.get(resolvedPath);
|
|
2362
|
+
if (!dependency) {
|
|
2363
|
+
return null;
|
|
2364
|
+
}
|
|
2365
|
+
return {
|
|
2366
|
+
path: dependency.filePath,
|
|
2367
|
+
namespace: PLAY_PROXY_NAMESPACE,
|
|
2368
|
+
pluginData: dependency
|
|
2369
|
+
};
|
|
2370
|
+
});
|
|
2371
|
+
buildContext.onLoad(
|
|
2372
|
+
{ filter: /.*/, namespace: PLAY_PROXY_NAMESPACE },
|
|
2373
|
+
async (args) => {
|
|
2374
|
+
const dependency = _nullishCoalesce(args.pluginData, () => ( dependenciesByPath.get(args.path)));
|
|
2375
|
+
if (!dependency) {
|
|
2376
|
+
return null;
|
|
2377
|
+
}
|
|
2378
|
+
return {
|
|
2379
|
+
contents: buildImportedPlayProxyModule(dependency.playName),
|
|
2380
|
+
loader: "ts",
|
|
2381
|
+
resolveDir: _path.dirname.call(void 0, args.path)
|
|
2382
|
+
};
|
|
2383
|
+
}
|
|
2384
|
+
);
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2388
|
+
async function fileExists(filePath) {
|
|
2389
|
+
try {
|
|
2390
|
+
await _promises.stat.call(void 0, filePath);
|
|
2391
|
+
return true;
|
|
2392
|
+
} catch (e6) {
|
|
2393
|
+
return false;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
async function resolveLocalImport(fromFile, specifier) {
|
|
2397
|
+
if (specifier.startsWith("file:")) {
|
|
2398
|
+
return normalizeLocalPath(new URL(specifier).pathname);
|
|
2399
|
+
}
|
|
2400
|
+
const base = _path.isAbsolute.call(void 0, specifier) ? _path.resolve.call(void 0, specifier) : _path.resolve.call(void 0, _path.dirname.call(void 0, fromFile), specifier);
|
|
2401
|
+
const candidates = [base];
|
|
2402
|
+
const explicitExtension = _path.extname.call(void 0, base).toLowerCase();
|
|
2403
|
+
if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
|
|
2404
|
+
const stem = base.slice(0, -explicitExtension.length);
|
|
2405
|
+
candidates.push(
|
|
2406
|
+
...SOURCE_EXTENSIONS.map((extension) => `${stem}${extension}`)
|
|
2407
|
+
);
|
|
2408
|
+
} else if (!EXPLICIT_IMPORT_EXTENSIONS.has(explicitExtension)) {
|
|
2409
|
+
candidates.push(
|
|
2410
|
+
...SOURCE_EXTENSIONS.map((extension) => `${base}${extension}`)
|
|
2411
|
+
);
|
|
2412
|
+
candidates.push(
|
|
2413
|
+
...SOURCE_EXTENSIONS.map((extension) => _path.join.call(void 0, base, `index${extension}`))
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
for (const candidate of candidates) {
|
|
2417
|
+
if (await fileExists(candidate)) {
|
|
2418
|
+
return normalizeLocalPath(candidate);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
throw new Error(
|
|
2422
|
+
`Could not resolve local import "${specifier}" from ${fromFile}`
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
function resolvePackageImport(specifier, fromFile, adapter) {
|
|
2426
|
+
const packageName = getPackageName(specifier);
|
|
2427
|
+
if (packageName === "deepline" && _fs.existsSync.call(void 0, adapter.sdkPackageJson)) {
|
|
2428
|
+
const packageJson = JSON.parse(
|
|
2429
|
+
_fs.readFileSync.call(void 0, adapter.sdkPackageJson, "utf-8")
|
|
2430
|
+
);
|
|
2431
|
+
return {
|
|
2432
|
+
name: "deepline",
|
|
2433
|
+
version: _nullishCoalesce(packageJson.version, () => ( null))
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
const packageJsonPath = findPackageJsonPath(packageName, fromFile, adapter);
|
|
2437
|
+
if (!packageJsonPath) {
|
|
2438
|
+
throw new Error(`Could not resolve "${specifier}" from ${fromFile}`);
|
|
2439
|
+
}
|
|
2440
|
+
return {
|
|
2441
|
+
name: packageName,
|
|
2442
|
+
version: readPackageVersionFromPackageJson(packageJsonPath, packageName)
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
async function analyzeSourceGraph(entryFile, adapter, exportName) {
|
|
2446
|
+
const absoluteEntryFile = await normalizeLocalPath(entryFile);
|
|
2447
|
+
const workspace = createPlayWorkspace(absoluteEntryFile);
|
|
2448
|
+
const sourceIdentityRoot = adapter.sourceIdentityRoot ? await normalizeLocalPath(adapter.sourceIdentityRoot) : void 0;
|
|
2449
|
+
const localFiles = /* @__PURE__ */ new Map();
|
|
2450
|
+
const nodeBuiltins = /* @__PURE__ */ new Set();
|
|
2451
|
+
const packages = /* @__PURE__ */ new Map();
|
|
2452
|
+
const importedPlayDependencies = /* @__PURE__ */ new Map();
|
|
2453
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2454
|
+
const visitFile = async (filePath) => {
|
|
2455
|
+
const absolutePath = await normalizeLocalPath(filePath);
|
|
2456
|
+
if (visited.has(absolutePath)) {
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2459
|
+
visited.add(absolutePath);
|
|
2460
|
+
const sourceCode2 = await _promises.readFile.call(void 0,
|
|
2461
|
+
/* turbopackIgnore: true */
|
|
2462
|
+
absolutePath,
|
|
2463
|
+
"utf-8"
|
|
2464
|
+
);
|
|
2465
|
+
localFiles.set(absolutePath, sourceCode2);
|
|
2466
|
+
if (_path.extname.call(void 0, absolutePath).toLowerCase() === ".json" || isTextImportFile(absolutePath)) {
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
2469
|
+
const handleSpecifier = async (specifier, line, column, kind) => {
|
|
2470
|
+
if (kind === "dynamic-import") {
|
|
2471
|
+
throw new Error(
|
|
2472
|
+
`${absolutePath}:${line}:${column} Dynamic import() is not allowed in plays. Use static imports instead.`
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
if (NODE_BUILTIN_SET.has(specifier)) {
|
|
2476
|
+
nodeBuiltins.add(
|
|
2477
|
+
specifier.startsWith("node:") ? specifier : `node:${specifier}`
|
|
2478
|
+
);
|
|
2479
|
+
return;
|
|
2480
|
+
}
|
|
2481
|
+
if (isLocalSpecifier(specifier)) {
|
|
2482
|
+
const resolved = await resolveLocalImport(absolutePath, specifier);
|
|
2483
|
+
assertWithinPlayWorkspace({
|
|
2484
|
+
importer: absolutePath,
|
|
2485
|
+
specifier,
|
|
2486
|
+
resolvedPath: resolved,
|
|
2487
|
+
workspace,
|
|
2488
|
+
line,
|
|
2489
|
+
column
|
|
2490
|
+
});
|
|
2491
|
+
if (resolved !== absoluteEntryFile && isPlaySourceFile(resolved)) {
|
|
2492
|
+
const importedSource = await _promises.readFile.call(void 0,
|
|
2493
|
+
/* turbopackIgnore: true */
|
|
2494
|
+
resolved,
|
|
2495
|
+
"utf-8"
|
|
2496
|
+
);
|
|
2497
|
+
const importedPlayName = extractDefinedPlayName(importedSource);
|
|
2498
|
+
if (!importedPlayName) {
|
|
2499
|
+
throw new Error(
|
|
2500
|
+
`${absolutePath}:${line}:${column} Imported play file "${specifier}" must export definePlay(...) so it can be runtime-composed.`
|
|
2501
|
+
);
|
|
2502
|
+
}
|
|
2503
|
+
importedPlayDependencies.set(resolved, {
|
|
2504
|
+
filePath: resolved,
|
|
2505
|
+
playName: importedPlayName
|
|
2506
|
+
});
|
|
2507
|
+
return;
|
|
2508
|
+
}
|
|
2509
|
+
await visitFile(resolved);
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
if (specifier.includes(":")) {
|
|
2513
|
+
throw new Error(
|
|
2514
|
+
`${absolutePath}:${line}:${column} Unsupported import specifier "${specifier}". Allowed imports are relative files, Node builtins, and installed packages.`
|
|
2515
|
+
);
|
|
2516
|
+
}
|
|
2517
|
+
const packageImport = resolvePackageImport(
|
|
2518
|
+
specifier,
|
|
2519
|
+
absolutePath,
|
|
2520
|
+
adapter
|
|
2521
|
+
);
|
|
2522
|
+
packages.set(packageImport.name, packageImport.version);
|
|
2523
|
+
};
|
|
2524
|
+
try {
|
|
2525
|
+
for (const reference of findSourceImportReferences(sourceCode2)) {
|
|
2526
|
+
await handleSpecifier(
|
|
2527
|
+
reference.specifier,
|
|
2528
|
+
reference.line,
|
|
2529
|
+
reference.column,
|
|
2530
|
+
reference.kind
|
|
2531
|
+
);
|
|
2532
|
+
}
|
|
2533
|
+
} catch (error) {
|
|
2534
|
+
if (error instanceof Error && error.message.startsWith(":")) {
|
|
2535
|
+
throw new Error(`${absolutePath}${error.message}`);
|
|
2536
|
+
}
|
|
2537
|
+
throw error;
|
|
2538
|
+
}
|
|
2539
|
+
};
|
|
2540
|
+
await visitFile(absoluteEntryFile);
|
|
2541
|
+
const sourceCode = _nullishCoalesce(localFiles.get(absoluteEntryFile), () => ( ""));
|
|
2542
|
+
const sourceHash = sha256(sourceCode);
|
|
2543
|
+
const graphHash = sha256(
|
|
2544
|
+
JSON.stringify({
|
|
2545
|
+
entryFile: sourceIdentityPath(absoluteEntryFile, sourceIdentityRoot),
|
|
2546
|
+
localFiles: [...localFiles.entries()].map(([filePath, contents]) => ({
|
|
2547
|
+
filePath: sourceIdentityPath(filePath, sourceIdentityRoot),
|
|
2548
|
+
hash: sha256(contents)
|
|
2549
|
+
})).sort((left, right) => left.filePath.localeCompare(right.filePath)),
|
|
2550
|
+
nodeBuiltins: [...nodeBuiltins].sort(),
|
|
2551
|
+
packages: [...packages.entries()].map(([name, version]) => ({ name, version })).sort((left, right) => left.name.localeCompare(right.name)),
|
|
2552
|
+
importedPlayDependencies: [...importedPlayDependencies.values()].map((dependency) => ({
|
|
2553
|
+
filePath: sourceIdentityPath(dependency.filePath, sourceIdentityRoot),
|
|
2554
|
+
playName: dependency.playName
|
|
2555
|
+
})).sort((left, right) => left.filePath.localeCompare(right.filePath))
|
|
2556
|
+
})
|
|
2557
|
+
);
|
|
2558
|
+
const metadata = _nullishCoalesce(extractDefinedPlayMetadata(sourceCode, exportName), () => ( (exportName === "default" ? extractDefinedPlayMetadata(sourceCode, null) : null)));
|
|
2559
|
+
if (_optionalChain([metadata, 'optionalAccess', _83 => _83.toolErrorSchemaVersionUnknown])) {
|
|
2560
|
+
throw new Error(
|
|
2561
|
+
"definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1."
|
|
2562
|
+
);
|
|
2563
|
+
}
|
|
2564
|
+
if (_optionalChain([metadata, 'optionalAccess', _84 => _84.toolResponseReceiptRevisionUnknown])) {
|
|
2565
|
+
throw new Error(
|
|
2566
|
+
"definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string."
|
|
2567
|
+
);
|
|
2568
|
+
}
|
|
2569
|
+
const playName = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _85 => _85.name]), () => ( null));
|
|
2570
|
+
const playDescription = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _86 => _86.description]), () => ( null));
|
|
2571
|
+
const sandboxRuntimeDeclaration = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _87 => _87.sandboxRuntimeDeclaration]), () => ( null));
|
|
2572
|
+
return {
|
|
2573
|
+
sourceCode,
|
|
2574
|
+
sourceFiles: Object.fromEntries(
|
|
2575
|
+
[...localFiles.entries()].sort(
|
|
2576
|
+
(left, right) => left[0].localeCompare(right[0])
|
|
2577
|
+
)
|
|
2578
|
+
),
|
|
2579
|
+
sourceHash,
|
|
2580
|
+
graphHash,
|
|
2581
|
+
importPolicy: {
|
|
2582
|
+
localFiles: [...localFiles.keys()].sort(),
|
|
2583
|
+
nodeBuiltins: [...nodeBuiltins].sort(),
|
|
2584
|
+
packages: [...packages.entries()].map(([name, version]) => ({ name, version })).sort((left, right) => left.name.localeCompare(right.name))
|
|
2585
|
+
},
|
|
2586
|
+
playName,
|
|
2587
|
+
playDescription,
|
|
2588
|
+
sandboxRuntimeDeclaration,
|
|
2589
|
+
toolErrorSchemaVersion: _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _88 => _88.toolErrorSchemaVersion]), () => ( null)),
|
|
2590
|
+
toolResponseReceiptRevision: _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _89 => _89.toolResponseReceiptRevision]), () => ( null)),
|
|
2591
|
+
importedPlayDependencies: [...importedPlayDependencies.values()].sort(
|
|
2592
|
+
(left, right) => left.filePath.localeCompare(right.filePath)
|
|
2593
|
+
)
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
function artifactCachePath(graphHash, artifactKind, adapter) {
|
|
2597
|
+
return _path.join.call(void 0,
|
|
2598
|
+
/* turbopackIgnore: true */
|
|
2599
|
+
_nullishCoalesce(adapter.cacheDir, () => ( PLAY_ARTIFACT_CACHE_DIR)),
|
|
2600
|
+
`${graphHash}.${artifactKind}.json`
|
|
2601
|
+
);
|
|
2602
|
+
}
|
|
2603
|
+
async function readArtifactCache(graphHash, artifactKind, adapter) {
|
|
2604
|
+
if (adapter.cacheDir === null) return null;
|
|
2605
|
+
try {
|
|
2606
|
+
const serialized = await _promises.readFile.call(void 0,
|
|
2607
|
+
/* turbopackIgnore: true */
|
|
2608
|
+
artifactCachePath(
|
|
2609
|
+
graphHash,
|
|
2610
|
+
artifactKind,
|
|
2611
|
+
adapter
|
|
2612
|
+
),
|
|
2613
|
+
"utf-8"
|
|
2614
|
+
);
|
|
2615
|
+
return JSON.parse(serialized);
|
|
2616
|
+
} catch (e7) {
|
|
2617
|
+
return null;
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
async function writeArtifactCache(artifact, adapter) {
|
|
2621
|
+
if (adapter.cacheDir === null) return;
|
|
2622
|
+
const cacheDir = _nullishCoalesce(adapter.cacheDir, () => ( PLAY_ARTIFACT_CACHE_DIR));
|
|
2623
|
+
await _promises.mkdir.call(void 0,
|
|
2624
|
+
/* turbopackIgnore: true */
|
|
2625
|
+
cacheDir,
|
|
2626
|
+
{ recursive: true }
|
|
2627
|
+
);
|
|
2628
|
+
await _promises.writeFile.call(void 0,
|
|
2629
|
+
/* turbopackIgnore: true */
|
|
2630
|
+
artifactCachePath(
|
|
2631
|
+
artifact.graphHash,
|
|
2632
|
+
_nullishCoalesce(artifact.artifactKind, () => ( _chunk6A3TJUWCjs.PLAY_ARTIFACT_KINDS.cjsNode20)),
|
|
2633
|
+
adapter
|
|
2634
|
+
),
|
|
2635
|
+
JSON.stringify(artifact),
|
|
2636
|
+
"utf-8"
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2639
|
+
function normalizeSourceMapForRuntime(sourceMapText, projectRoot) {
|
|
2640
|
+
const parsed = JSON.parse(sourceMapText);
|
|
2641
|
+
parsed.sources = (_nullishCoalesce(parsed.sources, () => ( []))).map((sourcePath) => {
|
|
2642
|
+
if (sourcePath.startsWith("data:") || sourcePath.startsWith("node:") || sourcePath.startsWith("/") || /^[a-zA-Z]+:\/\//.test(sourcePath)) {
|
|
2643
|
+
return sourcePath;
|
|
2644
|
+
}
|
|
2645
|
+
return _path.join.call(void 0, projectRoot, sourcePath);
|
|
2646
|
+
});
|
|
2647
|
+
parsed.sourceRoot = void 0;
|
|
2648
|
+
return JSON.stringify(parsed);
|
|
2649
|
+
}
|
|
2650
|
+
function getBundleSizeErrorForBytes(filePath, bundleBytes, _artifactKind) {
|
|
2651
|
+
if (bundleBytes > MAX_PLAY_BUNDLE_BYTES) {
|
|
2652
|
+
return `${filePath} Play bundle exceeds the 30 MiB limit (${bundleBytes} bytes > ${MAX_PLAY_BUNDLE_BYTES} bytes).`;
|
|
2653
|
+
}
|
|
2654
|
+
return null;
|
|
2655
|
+
}
|
|
2656
|
+
function getBundleSizeError(filePath, bundledCode, artifactKind) {
|
|
2657
|
+
return getBundleSizeErrorForBytes(
|
|
2658
|
+
filePath,
|
|
2659
|
+
Buffer.byteLength(bundledCode, "utf8"),
|
|
2660
|
+
artifactKind
|
|
2661
|
+
);
|
|
2662
|
+
}
|
|
2663
|
+
async function runEsbuildForCjsNode(entryFile, customerSourceFilePaths, importedPlayDependencies, adapter, exportName, bundleRoot) {
|
|
2664
|
+
const sdkAliasPlugin = localSdkAliasPlugin(adapter);
|
|
2665
|
+
const playProxyPlugin = importedPlayProxyPlugin(importedPlayDependencies);
|
|
2666
|
+
const docflowPlugin = docflowRuntimeInstrumentationPlugin([
|
|
2667
|
+
entryFile,
|
|
2668
|
+
...customerSourceFilePaths
|
|
2669
|
+
]);
|
|
2670
|
+
const namedExportShim = exportName === "default" ? null : `export { ${exportName} as default } from ${JSON.stringify(entryFile)};
|
|
2671
|
+
`;
|
|
2672
|
+
const result = await _esbuild.build.call(void 0, {
|
|
2673
|
+
...namedExportShim ? {
|
|
2674
|
+
stdin: {
|
|
2675
|
+
contents: namedExportShim,
|
|
2676
|
+
resolveDir: _path.dirname.call(void 0, entryFile),
|
|
2677
|
+
sourcefile: `${_path.basename.call(void 0, entryFile)}.${exportName}.entry.ts`,
|
|
2678
|
+
loader: "ts"
|
|
2679
|
+
}
|
|
2680
|
+
} : { entryPoints: [entryFile] },
|
|
2681
|
+
// esbuild writes `// <path relative to absWorkingDir>` above every module
|
|
2682
|
+
// it inlines, and artifactHash is sha256 of those bytes. Rooting the build
|
|
2683
|
+
// at the identity root keeps the customer's own files repo-relative, so a
|
|
2684
|
+
// deploy worker building the same commit in a fresh temp directory each
|
|
2685
|
+
// time produces the same bytes. Files outside the root (the SDK on the
|
|
2686
|
+
// worker image) come out as a `..`-prefixed path whose shape depends only
|
|
2687
|
+
// on the image's layout, which is fixed, not on the build's name.
|
|
2688
|
+
absWorkingDir: bundleRoot,
|
|
2689
|
+
bundle: true,
|
|
2690
|
+
format: "cjs",
|
|
2691
|
+
nodePaths: [adapter.nodeModulesDir],
|
|
2692
|
+
platform: "node",
|
|
2693
|
+
target: ["node20"],
|
|
2694
|
+
outfile: "play-artifact.cjs",
|
|
2695
|
+
write: false,
|
|
2696
|
+
sourcemap: "external",
|
|
2697
|
+
sourcesContent: false,
|
|
2698
|
+
logLevel: "silent",
|
|
2699
|
+
legalComments: "none",
|
|
2700
|
+
plugins: [docflowPlugin, sdkAliasPlugin, playProxyPlugin].filter(
|
|
2701
|
+
(plugin) => plugin != null
|
|
2702
|
+
)
|
|
2703
|
+
});
|
|
2704
|
+
const codeFile = _optionalChain([result, 'access', _90 => _90.outputFiles, 'optionalAccess', _91 => _91.find, 'call', _92 => _92((f) => f.path.endsWith(".cjs"))]);
|
|
2705
|
+
const mapFile = _optionalChain([result, 'access', _93 => _93.outputFiles, 'optionalAccess', _94 => _94.find, 'call', _95 => _95((f) => f.path.endsWith(".cjs.map"))]);
|
|
2706
|
+
if (!_optionalChain([codeFile, 'optionalAccess', _96 => _96.text]) || !_optionalChain([mapFile, 'optionalAccess', _97 => _97.text])) {
|
|
2707
|
+
return ["Play bundling produced incomplete output."];
|
|
2708
|
+
}
|
|
2709
|
+
return {
|
|
2710
|
+
bundledCode: codeFile.text,
|
|
2711
|
+
sourceMapText: mapFile.text,
|
|
2712
|
+
outputExtension: "cjs"
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
async function bundlePlayFile(filePath, options) {
|
|
2716
|
+
const adapter = options.adapter;
|
|
2717
|
+
const target = _nullishCoalesce(options.target, () => ( _chunk6A3TJUWCjs.PLAY_ARTIFACT_KINDS.cjsNode20));
|
|
2718
|
+
const exportName = _optionalChain([options, 'access', _98 => _98.exportName, 'optionalAccess', _99 => _99.trim, 'call', _100 => _100()]) || "default";
|
|
2719
|
+
assertValidExportName(exportName);
|
|
2720
|
+
const absolutePath = await normalizeLocalPath(filePath);
|
|
2721
|
+
const sourceIdentityRoot = adapter.sourceIdentityRoot;
|
|
2722
|
+
_optionalChain([adapter, 'access', _101 => _101.warnAboutNonDevelopmentBundling, 'optionalCall', _102 => _102(absolutePath)]);
|
|
2723
|
+
try {
|
|
2724
|
+
const analysis = await analyzeSourceGraph(
|
|
2725
|
+
absolutePath,
|
|
2726
|
+
adapter,
|
|
2727
|
+
exportName
|
|
2728
|
+
);
|
|
2729
|
+
analysis.graphHash = sha256(
|
|
2730
|
+
`${analysis.graphHash}
|
|
2731
|
+
entry-export:${exportName}
|
|
2732
|
+
authoring-contract-edition:${_chunkZDO3TO3Mjs.PLAY_AUTHORING_CONTRACT_EDITION}`
|
|
2733
|
+
);
|
|
2734
|
+
const sourceFiles = Object.fromEntries(
|
|
2735
|
+
Object.entries(analysis.sourceFiles).map(([sourcePath, sourceCode]) => [
|
|
2736
|
+
sourceIdentityPath(sourcePath, sourceIdentityRoot),
|
|
2737
|
+
sourceCode
|
|
2738
|
+
])
|
|
2739
|
+
);
|
|
2740
|
+
const importPolicy = {
|
|
2741
|
+
...analysis.importPolicy,
|
|
2742
|
+
localFiles: analysis.importPolicy.localFiles.map(
|
|
2743
|
+
(sourcePath) => sourceIdentityPath(sourcePath, sourceIdentityRoot)
|
|
2744
|
+
)
|
|
2745
|
+
};
|
|
2746
|
+
const entryFile = sourceIdentityPath(absolutePath, sourceIdentityRoot);
|
|
2747
|
+
try {
|
|
2748
|
+
_chunk3KC45UVFjs.validatePlaySourceFilesHaveNoInlineSecrets.call(void 0, analysis.sourceFiles);
|
|
2749
|
+
} catch (error) {
|
|
2750
|
+
return {
|
|
2751
|
+
success: false,
|
|
2752
|
+
filePath: absolutePath,
|
|
2753
|
+
errors: [error instanceof Error ? error.message : String(error)]
|
|
2754
|
+
};
|
|
2755
|
+
}
|
|
2756
|
+
const typecheckErrors = [
|
|
2757
|
+
...await _asyncNullishCoalesce(await _optionalChain([adapter, 'access', _103 => _103.typecheckPlaySource, 'optionalCall', _104 => _104({
|
|
2758
|
+
sourceCode: analysis.sourceCode,
|
|
2759
|
+
sourcePath: absolutePath,
|
|
2760
|
+
importedFilePaths: [
|
|
2761
|
+
...analysis.importPolicy.localFiles,
|
|
2762
|
+
...analysis.importedPlayDependencies.map(
|
|
2763
|
+
(dependency) => dependency.filePath
|
|
2764
|
+
)
|
|
2765
|
+
]
|
|
2766
|
+
})]), async () => ( []))
|
|
2767
|
+
];
|
|
2768
|
+
if (typecheckErrors.length > 0) {
|
|
2769
|
+
return {
|
|
2770
|
+
success: false,
|
|
2771
|
+
filePath: absolutePath,
|
|
2772
|
+
errors: typecheckErrors
|
|
2773
|
+
};
|
|
2774
|
+
}
|
|
2775
|
+
const cachedArtifact = await readArtifactCache(
|
|
2776
|
+
analysis.graphHash,
|
|
2777
|
+
target,
|
|
2778
|
+
adapter
|
|
2779
|
+
);
|
|
2780
|
+
const discoveredFiles = await adapter.discoverPackagedLocalFiles(absolutePath);
|
|
2781
|
+
if (cachedArtifact) {
|
|
2782
|
+
const cachedArtifactSizeError = getBundleSizeError(
|
|
2783
|
+
absolutePath,
|
|
2784
|
+
cachedArtifact.bundledCode,
|
|
2785
|
+
target
|
|
2786
|
+
);
|
|
2787
|
+
if (cachedArtifactSizeError) {
|
|
2788
|
+
return {
|
|
2789
|
+
success: false,
|
|
2790
|
+
filePath: absolutePath,
|
|
2791
|
+
errors: [cachedArtifactSizeError]
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
return {
|
|
2795
|
+
success: true,
|
|
2796
|
+
artifact: {
|
|
2797
|
+
...cachedArtifact,
|
|
2798
|
+
entryFile,
|
|
2799
|
+
sourceHash: analysis.sourceHash,
|
|
2800
|
+
importPolicy,
|
|
2801
|
+
compatibility: buildPlayContractCompatibility({
|
|
2802
|
+
toolErrorSchemaVersion: _nullishCoalesce(analysis.toolErrorSchemaVersion, () => ( void 0)),
|
|
2803
|
+
toolResponseReceiptRevision: _nullishCoalesce(analysis.toolResponseReceiptRevision, () => ( void 0))
|
|
2804
|
+
}),
|
|
2805
|
+
cacheHit: true
|
|
2806
|
+
},
|
|
2807
|
+
sourceCode: analysis.sourceCode,
|
|
2808
|
+
sourceFiles,
|
|
2809
|
+
filePath: absolutePath,
|
|
2810
|
+
playName: analysis.playName,
|
|
2811
|
+
playDescription: analysis.playDescription,
|
|
2812
|
+
sandboxRuntimeDeclaration: analysis.sandboxRuntimeDeclaration,
|
|
2813
|
+
packagedFiles: discoveredFiles.files,
|
|
2814
|
+
unresolvedFileReferences: discoveredFiles.unresolved,
|
|
2815
|
+
importedPlayDependencies: analysis.importedPlayDependencies
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
const bundleRoot = _path.resolve.call(void 0, _nullishCoalesce(sourceIdentityRoot, () => ( adapter.projectRoot)));
|
|
2819
|
+
const buildOutcome = await runEsbuildForCjsNode(
|
|
2820
|
+
absolutePath,
|
|
2821
|
+
analysis.importPolicy.localFiles,
|
|
2822
|
+
analysis.importedPlayDependencies,
|
|
2823
|
+
adapter,
|
|
2824
|
+
exportName,
|
|
2825
|
+
bundleRoot
|
|
2826
|
+
);
|
|
2827
|
+
if (Array.isArray(buildOutcome)) {
|
|
2828
|
+
return {
|
|
2829
|
+
success: false,
|
|
2830
|
+
filePath: absolutePath,
|
|
2831
|
+
errors: buildOutcome
|
|
2832
|
+
};
|
|
2833
|
+
}
|
|
2834
|
+
const { bundledCode, sourceMapText, outputExtension } = buildOutcome;
|
|
2835
|
+
const normalizedSourceMap = normalizeSourceMapForRuntime(
|
|
2836
|
+
sourceMapText,
|
|
2837
|
+
bundleRoot
|
|
2838
|
+
);
|
|
2839
|
+
const virtualBaseName = exportName === "default" ? _path.basename.call(void 0, absolutePath).replace(/\.[^.]+$/, "") : `${_path.basename.call(void 0, absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
|
|
2840
|
+
const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
|
|
2841
|
+
const executableCode = `${bundledCode}
|
|
2842
|
+
//# sourceMappingURL=${_path.basename.call(void 0, virtualFilename)}.map
|
|
2843
|
+
`;
|
|
2844
|
+
const bundleSizeError = getBundleSizeError(
|
|
2845
|
+
absolutePath,
|
|
2846
|
+
executableCode,
|
|
2847
|
+
target
|
|
2848
|
+
);
|
|
2849
|
+
if (bundleSizeError) {
|
|
2850
|
+
return {
|
|
2851
|
+
success: false,
|
|
2852
|
+
filePath: absolutePath,
|
|
2853
|
+
errors: [bundleSizeError]
|
|
2854
|
+
};
|
|
2855
|
+
}
|
|
2856
|
+
const artifact = {
|
|
2857
|
+
codeFormat: "cjs_module",
|
|
2858
|
+
artifactKind: target,
|
|
2859
|
+
entryFile,
|
|
2860
|
+
virtualFilename,
|
|
2861
|
+
sourceHash: analysis.sourceHash,
|
|
2862
|
+
graphHash: analysis.graphHash,
|
|
2863
|
+
artifactHash: sha256(executableCode),
|
|
2864
|
+
sourceMapHash: sha256(normalizedSourceMap),
|
|
2865
|
+
bundledCode: executableCode,
|
|
2866
|
+
sourceMap: normalizedSourceMap,
|
|
2867
|
+
importPolicy,
|
|
2868
|
+
compatibility: buildPlayContractCompatibility({
|
|
2869
|
+
toolErrorSchemaVersion: _nullishCoalesce(analysis.toolErrorSchemaVersion, () => ( void 0)),
|
|
2870
|
+
toolResponseReceiptRevision: _nullishCoalesce(analysis.toolResponseReceiptRevision, () => ( void 0))
|
|
2871
|
+
}),
|
|
2872
|
+
generatedAt: Date.now(),
|
|
2873
|
+
cacheHit: false
|
|
2874
|
+
};
|
|
2875
|
+
try {
|
|
2876
|
+
await writeArtifactCache(artifact, adapter);
|
|
2877
|
+
} catch (error) {
|
|
2878
|
+
console.warn(
|
|
2879
|
+
"Play artifact cache write failed; continuing without a disk cache.",
|
|
2880
|
+
error
|
|
2881
|
+
);
|
|
2882
|
+
}
|
|
2883
|
+
return {
|
|
2884
|
+
success: true,
|
|
2885
|
+
artifact,
|
|
2886
|
+
sourceCode: analysis.sourceCode,
|
|
2887
|
+
sourceFiles,
|
|
2888
|
+
filePath: absolutePath,
|
|
2889
|
+
playName: analysis.playName,
|
|
2890
|
+
playDescription: analysis.playDescription,
|
|
2891
|
+
sandboxRuntimeDeclaration: analysis.sandboxRuntimeDeclaration,
|
|
2892
|
+
packagedFiles: discoveredFiles.files,
|
|
2893
|
+
unresolvedFileReferences: discoveredFiles.unresolved,
|
|
2894
|
+
importedPlayDependencies: analysis.importedPlayDependencies
|
|
2895
|
+
};
|
|
2896
|
+
} catch (error) {
|
|
2897
|
+
if (error && typeof error === "object" && "errors" in error) {
|
|
2898
|
+
const errors = Array.isArray(error.errors) ? error.errors.map(formatEsbuildMessage) : ["Play bundling failed."];
|
|
2899
|
+
return {
|
|
2900
|
+
success: false,
|
|
2901
|
+
filePath: absolutePath,
|
|
2902
|
+
errors
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2905
|
+
return {
|
|
2906
|
+
success: false,
|
|
2907
|
+
filePath: absolutePath,
|
|
2908
|
+
errors: [error instanceof Error ? error.message : String(error)]
|
|
2909
|
+
};
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
// ../play-runtime/scheduler-backend.ts
|
|
2914
|
+
var PLAY_SCHEDULER_BACKENDS = {
|
|
2915
|
+
/**
|
|
2916
|
+
* Postgres-native durable-execution scheduler (vendored Absurd engine). Runs
|
|
2917
|
+
* on the battle-tested run-state store without an external workflow engine.
|
|
2918
|
+
* Selected explicitly by the `absurd` profile.
|
|
2919
|
+
*/
|
|
2920
|
+
absurd: "absurd",
|
|
2921
|
+
inProcess: "in-process"
|
|
2922
|
+
};
|
|
2923
|
+
|
|
2924
|
+
// ../play-runtime/providers.ts
|
|
2925
|
+
var PLAY_RUNTIME_PROVIDER_IDS = {
|
|
2926
|
+
absurd: "absurd"
|
|
2927
|
+
};
|
|
2928
|
+
var PLAY_RUNTIME_PROVIDERS = {
|
|
2929
|
+
absurd: {
|
|
2930
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.absurd,
|
|
2931
|
+
scheduler: PLAY_SCHEDULER_BACKENDS.absurd,
|
|
2932
|
+
// Server runs execute on Daytona; the local-dev/test shape swaps the runner
|
|
2933
|
+
// axis to local_process (same as the local profile) via an explicit
|
|
2934
|
+
// runtimeBackend override at submit while tests drive local_process.
|
|
2935
|
+
runner: _chunk6A3TJUWCjs.PLAY_RUNTIME_BACKENDS.daytona,
|
|
2936
|
+
artifactKind: _chunk6A3TJUWCjs.PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
2937
|
+
label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner"
|
|
2938
|
+
}
|
|
2939
|
+
};
|
|
2940
|
+
function defaultPlayRuntimeProvider() {
|
|
2941
|
+
return PLAY_RUNTIME_PROVIDERS.absurd;
|
|
2942
|
+
}
|
|
2943
|
+
function resolvePlayRuntimeProvider(override) {
|
|
2944
|
+
if (_optionalChain([override, 'optionalAccess', _105 => _105.trim, 'call', _106 => _106()])) {
|
|
2945
|
+
const id = override.trim();
|
|
2946
|
+
if (id in PLAY_RUNTIME_PROVIDERS) {
|
|
2947
|
+
return PLAY_RUNTIME_PROVIDERS[id];
|
|
2948
|
+
}
|
|
2949
|
+
throw new Error(
|
|
2950
|
+
`Unsupported play runtime provider "${id}". Expected one of: ${Object.keys(
|
|
2951
|
+
PLAY_RUNTIME_PROVIDERS
|
|
2952
|
+
).join(", ")}.`
|
|
2953
|
+
);
|
|
2954
|
+
}
|
|
2955
|
+
return defaultPlayRuntimeProvider();
|
|
2956
|
+
}
|
|
2957
|
+
function resolveEnabledPlayRuntimeProvider(override) {
|
|
2958
|
+
return resolvePlayRuntimeProvider(override);
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
// ../play-runtime/profiles.ts
|
|
2962
|
+
var PLAY_EXECUTION_PROFILE_IDS = {
|
|
2963
|
+
...PLAY_RUNTIME_PROVIDER_IDS
|
|
2964
|
+
};
|
|
2965
|
+
var PLAY_EXECUTION_PROFILES = PLAY_RUNTIME_PROVIDERS;
|
|
2966
|
+
function resolveExecutionProfile(override) {
|
|
2967
|
+
try {
|
|
2968
|
+
return resolvePlayRuntimeProvider(override);
|
|
2969
|
+
} catch (error) {
|
|
2970
|
+
if (_optionalChain([override, 'optionalAccess', _107 => _107.trim, 'call', _108 => _108()])) {
|
|
2971
|
+
throw new Error(
|
|
2972
|
+
`Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
|
|
2973
|
+
PLAY_EXECUTION_PROFILES
|
|
2974
|
+
).join(", ")}.`
|
|
2975
|
+
);
|
|
2976
|
+
}
|
|
2977
|
+
throw error;
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
function resolveEnabledExecutionProfile(override) {
|
|
2981
|
+
try {
|
|
2982
|
+
return resolveEnabledPlayRuntimeProvider(override);
|
|
2983
|
+
} catch (error) {
|
|
2984
|
+
if (_optionalChain([override, 'optionalAccess', _109 => _109.trim, 'call', _110 => _110()]) && error instanceof Error && /Unsupported play runtime provider/.test(error.message)) {
|
|
2985
|
+
throw new Error(
|
|
2986
|
+
`Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
|
|
2987
|
+
PLAY_EXECUTION_PROFILES
|
|
2988
|
+
).join(", ")}.`
|
|
2989
|
+
);
|
|
2990
|
+
}
|
|
2991
|
+
throw error;
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
// src/plays/local-file-discovery.ts
|
|
2996
|
+
|
|
2997
|
+
|
|
2998
|
+
|
|
2999
|
+
|
|
3000
|
+
|
|
3001
|
+
|
|
3002
|
+
|
|
3003
|
+
|
|
3004
|
+
|
|
3005
|
+
|
|
3006
|
+
|
|
3007
|
+
var SOURCE_EXTENSIONS2 = [
|
|
3008
|
+
".ts",
|
|
3009
|
+
".tsx",
|
|
3010
|
+
".mts",
|
|
3011
|
+
".cts",
|
|
3012
|
+
".js",
|
|
3013
|
+
".jsx",
|
|
3014
|
+
".mjs",
|
|
3015
|
+
".cjs",
|
|
3016
|
+
".json"
|
|
3017
|
+
];
|
|
3018
|
+
var TEXT_IMPORT_EXTENSIONS2 = /* @__PURE__ */ new Set([".md", ".txt"]);
|
|
3019
|
+
var EXPLICIT_IMPORT_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
3020
|
+
...SOURCE_EXTENSIONS2,
|
|
3021
|
+
...TEXT_IMPORT_EXTENSIONS2
|
|
3022
|
+
]);
|
|
3023
|
+
function isTextImportFile2(filePath) {
|
|
3024
|
+
return TEXT_IMPORT_EXTENSIONS2.has(_path.extname.call(void 0, filePath));
|
|
3025
|
+
}
|
|
3026
|
+
function sha2562(buffer) {
|
|
3027
|
+
return _crypto.createHash.call(void 0, "sha256").update(buffer).digest("hex");
|
|
3028
|
+
}
|
|
3029
|
+
function contentTypeForFile(filePath) {
|
|
3030
|
+
const extension = _path.extname.call(void 0, filePath).toLowerCase();
|
|
3031
|
+
if (extension === ".csv") return "text/csv";
|
|
3032
|
+
if (extension === ".json") return "application/json";
|
|
3033
|
+
if (extension === ".txt") return "text/plain";
|
|
3034
|
+
return "application/octet-stream";
|
|
3035
|
+
}
|
|
3036
|
+
function stripCommentsToSpaces2(source) {
|
|
3037
|
+
return source.replace(/\/\*[\s\S]*?\*\//g, (match) => match.replace(/[^\n]/g, " ")).replace(
|
|
3038
|
+
/(^|[^:])\/\/.*$/gm,
|
|
3039
|
+
(match, prefix) => prefix + " ".repeat(Math.max(0, match.length - prefix.length))
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
3042
|
+
function unquoteStringLiteral(literal) {
|
|
3043
|
+
const trimmed = literal.trim();
|
|
3044
|
+
const quote = trimmed[0];
|
|
3045
|
+
if (quote !== '"' && quote !== "'" || trimmed[trimmed.length - 1] !== quote) {
|
|
3046
|
+
return null;
|
|
3047
|
+
}
|
|
3048
|
+
try {
|
|
3049
|
+
return JSON.parse(
|
|
3050
|
+
quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`
|
|
3051
|
+
);
|
|
3052
|
+
} catch (e8) {
|
|
3053
|
+
return trimmed.slice(1, -1);
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
function splitTopLevelPlus(expression) {
|
|
3057
|
+
const parts = [];
|
|
3058
|
+
let start = 0;
|
|
3059
|
+
let depth = 0;
|
|
3060
|
+
let quote = null;
|
|
3061
|
+
let escaped = false;
|
|
3062
|
+
for (let index = 0; index < expression.length; index += 1) {
|
|
3063
|
+
const char = expression[index];
|
|
3064
|
+
if (quote) {
|
|
3065
|
+
if (escaped) {
|
|
3066
|
+
escaped = false;
|
|
3067
|
+
} else if (char === "\\") {
|
|
3068
|
+
escaped = true;
|
|
3069
|
+
} else if (char === quote) {
|
|
3070
|
+
quote = null;
|
|
3071
|
+
}
|
|
3072
|
+
continue;
|
|
3073
|
+
}
|
|
3074
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
3075
|
+
quote = char;
|
|
3076
|
+
continue;
|
|
3077
|
+
}
|
|
3078
|
+
if (char === "(" || char === "[" || char === "{") depth += 1;
|
|
3079
|
+
if (char === ")" || char === "]" || char === "}") depth -= 1;
|
|
3080
|
+
if (char === "+" && depth === 0) {
|
|
3081
|
+
parts.push(expression.slice(start, index));
|
|
3082
|
+
start = index + 1;
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
if (parts.length === 0) return null;
|
|
3086
|
+
parts.push(expression.slice(start));
|
|
3087
|
+
return parts;
|
|
3088
|
+
}
|
|
3089
|
+
function stripOuterParens(expression) {
|
|
3090
|
+
let value = expression.trim();
|
|
3091
|
+
while (value.startsWith("(") && value.endsWith(")")) {
|
|
3092
|
+
value = value.slice(1, -1).trim();
|
|
3093
|
+
}
|
|
3094
|
+
return value;
|
|
3095
|
+
}
|
|
3096
|
+
function isRuntimeInputExpression(expression) {
|
|
3097
|
+
return /(^|[^\w$])input([^\w$]|$)/.test(expression);
|
|
3098
|
+
}
|
|
3099
|
+
function resolveStringExpression(expression, constants) {
|
|
3100
|
+
const value = stripOuterParens(expression);
|
|
3101
|
+
if (/^(['"])(?:\\.|(?!\1)[\s\S])*\1$/.test(value)) {
|
|
3102
|
+
return unquoteStringLiteral(value);
|
|
3103
|
+
}
|
|
3104
|
+
if (/^`(?:\\.|[^`$]|\$(?!\{))*`$/.test(value)) {
|
|
3105
|
+
return value.slice(1, -1);
|
|
3106
|
+
}
|
|
3107
|
+
if (/^[A-Za-z_$][\w$]*$/.test(value)) {
|
|
3108
|
+
return _nullishCoalesce(constants.get(value), () => ( null));
|
|
3109
|
+
}
|
|
3110
|
+
const parts = splitTopLevelPlus(value);
|
|
3111
|
+
if (parts) {
|
|
3112
|
+
const resolved = parts.map(
|
|
3113
|
+
(part) => resolveStringExpression(part, constants)
|
|
3114
|
+
);
|
|
3115
|
+
return resolved.every((part) => part != null) ? resolved.join("") : null;
|
|
3116
|
+
}
|
|
3117
|
+
return null;
|
|
3118
|
+
}
|
|
3119
|
+
function collectTopLevelStringConstants(sourceCode) {
|
|
3120
|
+
const constants = /* @__PURE__ */ new Map();
|
|
3121
|
+
const source = stripCommentsToSpaces2(sourceCode);
|
|
3122
|
+
for (const match of source.matchAll(
|
|
3123
|
+
/(?:^|\n)\s*const\s+([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)/g
|
|
3124
|
+
)) {
|
|
3125
|
+
const resolved = resolveStringExpression(match[2], constants);
|
|
3126
|
+
if (resolved != null) {
|
|
3127
|
+
constants.set(match[1], resolved);
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
return constants;
|
|
3131
|
+
}
|
|
3132
|
+
function findMatchingGenericEnd(source, openIndex) {
|
|
3133
|
+
let depth = 0;
|
|
3134
|
+
let quote = null;
|
|
3135
|
+
let escaped = false;
|
|
3136
|
+
for (let index = openIndex; index < source.length; index += 1) {
|
|
3137
|
+
const char = source[index];
|
|
3138
|
+
if (quote) {
|
|
3139
|
+
if (escaped) {
|
|
3140
|
+
escaped = false;
|
|
3141
|
+
} else if (char === "\\") {
|
|
3142
|
+
escaped = true;
|
|
3143
|
+
} else if (char === quote) {
|
|
3144
|
+
quote = null;
|
|
3145
|
+
}
|
|
3146
|
+
continue;
|
|
3147
|
+
}
|
|
3148
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
3149
|
+
quote = char;
|
|
3150
|
+
continue;
|
|
3151
|
+
}
|
|
3152
|
+
if (char === "<") depth += 1;
|
|
3153
|
+
if (char === ">") {
|
|
3154
|
+
depth -= 1;
|
|
3155
|
+
if (depth === 0) return index;
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
return -1;
|
|
3159
|
+
}
|
|
3160
|
+
function findCallOpenParen(source, afterCsvIndex) {
|
|
3161
|
+
let index = afterCsvIndex;
|
|
3162
|
+
while (/\s/.test(_nullishCoalesce(source[index], () => ( "")))) index += 1;
|
|
3163
|
+
if (source[index] === "<") {
|
|
3164
|
+
const genericEnd = findMatchingGenericEnd(source, index);
|
|
3165
|
+
if (genericEnd < 0) return -1;
|
|
3166
|
+
index = genericEnd + 1;
|
|
3167
|
+
while (/\s/.test(_nullishCoalesce(source[index], () => ( "")))) index += 1;
|
|
3168
|
+
}
|
|
3169
|
+
return source[index] === "(" ? index : -1;
|
|
3170
|
+
}
|
|
3171
|
+
function firstCallArgument(source, openParen) {
|
|
3172
|
+
let depth = 0;
|
|
3173
|
+
let quote = null;
|
|
3174
|
+
let escaped = false;
|
|
3175
|
+
const start = openParen + 1;
|
|
3176
|
+
for (let index = start; index < source.length; index += 1) {
|
|
3177
|
+
const char = source[index];
|
|
3178
|
+
if (quote) {
|
|
3179
|
+
if (escaped) {
|
|
3180
|
+
escaped = false;
|
|
3181
|
+
} else if (char === "\\") {
|
|
3182
|
+
escaped = true;
|
|
3183
|
+
} else if (char === quote) {
|
|
3184
|
+
quote = null;
|
|
3185
|
+
}
|
|
3186
|
+
continue;
|
|
3187
|
+
}
|
|
3188
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
3189
|
+
quote = char;
|
|
3190
|
+
continue;
|
|
3191
|
+
}
|
|
3192
|
+
if (char === "(" || char === "[" || char === "{") depth += 1;
|
|
3193
|
+
if (char === ")" && depth === 0) {
|
|
3194
|
+
const text = source.slice(start, index).trim();
|
|
3195
|
+
return text ? { text, start, end: index } : null;
|
|
3196
|
+
}
|
|
3197
|
+
if (char === "," && depth === 0) {
|
|
3198
|
+
const text = source.slice(start, index).trim();
|
|
3199
|
+
return text ? { text, start, end: index } : null;
|
|
3200
|
+
}
|
|
3201
|
+
if (char === ")" || char === "]" || char === "}") depth -= 1;
|
|
3202
|
+
}
|
|
3203
|
+
return null;
|
|
3204
|
+
}
|
|
3205
|
+
function localImportSpecifiers(sourceCode) {
|
|
3206
|
+
const source = stripCommentsToSpaces2(sourceCode);
|
|
3207
|
+
const specifiers = [];
|
|
3208
|
+
for (const match of source.matchAll(
|
|
3209
|
+
/\b(?:import|export)\s+(?!type\b)(?:[\s\S]*?\s+from\s*)?['"]([^'"]+)['"]/g
|
|
3210
|
+
)) {
|
|
3211
|
+
if (_optionalChain([match, 'access', _111 => _111[1], 'optionalAccess', _112 => _112.startsWith, 'call', _113 => _113(".")])) specifiers.push(match[1]);
|
|
3212
|
+
}
|
|
3213
|
+
for (const match of source.matchAll(
|
|
3214
|
+
/\brequire\s*\(\s*(['"])(\.[^'"]*)\1\s*\)/g
|
|
3215
|
+
)) {
|
|
3216
|
+
specifiers.push(match[2]);
|
|
3217
|
+
}
|
|
3218
|
+
return specifiers;
|
|
3219
|
+
}
|
|
3220
|
+
async function fileExists2(filePath) {
|
|
3221
|
+
try {
|
|
3222
|
+
await _promises.stat.call(void 0, filePath);
|
|
3223
|
+
return true;
|
|
3224
|
+
} catch (e9) {
|
|
3225
|
+
return false;
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
function isPathInsideDirectory2(filePath, directory) {
|
|
3229
|
+
const relativePath = _path.relative.call(void 0, directory, filePath);
|
|
3230
|
+
return relativePath === "" || !relativePath.startsWith("..") && !_path.isAbsolute.call(void 0, relativePath);
|
|
3231
|
+
}
|
|
3232
|
+
async function resolveLocalImport2(fromFile, specifier) {
|
|
3233
|
+
const base = _path.isAbsolute.call(void 0, specifier) ? _path.resolve.call(void 0, specifier) : _path.resolve.call(void 0, _path.dirname.call(void 0, fromFile), specifier);
|
|
3234
|
+
const candidates = [base];
|
|
3235
|
+
const explicitExtension = _path.extname.call(void 0, base).toLowerCase();
|
|
3236
|
+
if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
|
|
3237
|
+
const stem = base.slice(0, -explicitExtension.length);
|
|
3238
|
+
candidates.push(
|
|
3239
|
+
...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`)
|
|
3240
|
+
);
|
|
3241
|
+
} else if (!EXPLICIT_IMPORT_EXTENSIONS2.has(explicitExtension)) {
|
|
3242
|
+
candidates.push(
|
|
3243
|
+
...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`)
|
|
3244
|
+
);
|
|
3245
|
+
candidates.push(
|
|
3246
|
+
...SOURCE_EXTENSIONS2.map((extension) => _path.join.call(void 0, base, `index${extension}`))
|
|
3247
|
+
);
|
|
3248
|
+
}
|
|
3249
|
+
for (const candidate of candidates) {
|
|
3250
|
+
if (await fileExists2(candidate)) {
|
|
3251
|
+
return candidate;
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
throw new Error(
|
|
3255
|
+
`Could not resolve local import "${specifier}" from ${fromFile}`
|
|
3256
|
+
);
|
|
3257
|
+
}
|
|
3258
|
+
async function discoverPackagedLocalFiles(entryFile) {
|
|
3259
|
+
const absoluteEntryFile = _path.resolve.call(void 0, entryFile);
|
|
3260
|
+
const packagingRoot = _path.dirname.call(void 0, absoluteEntryFile);
|
|
3261
|
+
const files = /* @__PURE__ */ new Map();
|
|
3262
|
+
const unresolved = [];
|
|
3263
|
+
const visitedFiles = /* @__PURE__ */ new Set();
|
|
3264
|
+
const visitSourceFile = async (filePath) => {
|
|
3265
|
+
const absolutePath = _path.resolve.call(void 0, filePath);
|
|
3266
|
+
if (visitedFiles.has(absolutePath)) {
|
|
3267
|
+
return;
|
|
3268
|
+
}
|
|
3269
|
+
visitedFiles.add(absolutePath);
|
|
3270
|
+
const sourceCode = await _promises.readFile.call(void 0, absolutePath, "utf-8");
|
|
3271
|
+
if (_path.extname.call(void 0, absolutePath).toLowerCase() === ".json" || isTextImportFile2(absolutePath)) {
|
|
3272
|
+
return;
|
|
3273
|
+
}
|
|
3274
|
+
const scanSource = stripCommentsToSpaces2(sourceCode);
|
|
3275
|
+
const constants = collectTopLevelStringConstants(sourceCode);
|
|
3276
|
+
const childVisits = [];
|
|
3277
|
+
for (const match of scanSource.matchAll(
|
|
3278
|
+
/\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g
|
|
3279
|
+
)) {
|
|
3280
|
+
const target = match[1];
|
|
3281
|
+
if (target !== "ctx" && !target.endsWith("Ctx")) {
|
|
3282
|
+
continue;
|
|
3283
|
+
}
|
|
3284
|
+
const openParen = findCallOpenParen(
|
|
3285
|
+
scanSource,
|
|
3286
|
+
match.index + match[0].length
|
|
3287
|
+
);
|
|
3288
|
+
if (openParen < 0) {
|
|
3289
|
+
continue;
|
|
3290
|
+
}
|
|
3291
|
+
const argument = firstCallArgument(scanSource, openParen);
|
|
3292
|
+
if (!argument) {
|
|
3293
|
+
unresolved.push({
|
|
3294
|
+
sourceFragment: "ctx.csv()",
|
|
3295
|
+
message: "ctx.csv() requires a file path string or input reference."
|
|
3296
|
+
});
|
|
3297
|
+
} else if (!isRuntimeInputExpression(argument.text)) {
|
|
3298
|
+
const resolvedPath = resolveStringExpression(argument.text, constants);
|
|
3299
|
+
if (resolvedPath == null) {
|
|
3300
|
+
unresolved.push({
|
|
3301
|
+
sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
|
|
3302
|
+
message: "Could not resolve this ctx.csv(...) path at submit time. Use a string literal, a top-level const string, or pass a runtime input like input.file."
|
|
3303
|
+
});
|
|
3304
|
+
} else {
|
|
3305
|
+
const absoluteCsvPath = _path.resolve.call(void 0, _path.dirname.call(void 0, absolutePath), resolvedPath);
|
|
3306
|
+
if (_path.isAbsolute.call(void 0, resolvedPath) || !isPathInsideDirectory2(absoluteCsvPath, packagingRoot)) {
|
|
3307
|
+
unresolved.push({
|
|
3308
|
+
sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
|
|
3309
|
+
message: "ctx.csv(...) packaged file paths must be relative paths inside the play directory. Pass external files at runtime with input.file instead."
|
|
3310
|
+
});
|
|
3311
|
+
continue;
|
|
3312
|
+
}
|
|
3313
|
+
const buffer = await _promises.readFile.call(void 0, absoluteCsvPath);
|
|
3314
|
+
const stats = await _promises.stat.call(void 0, absoluteCsvPath);
|
|
3315
|
+
files.set(absoluteCsvPath, {
|
|
3316
|
+
sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
|
|
3317
|
+
logicalPath: resolvedPath,
|
|
3318
|
+
absolutePath: absoluteCsvPath,
|
|
3319
|
+
bytes: stats.size,
|
|
3320
|
+
contentHash: sha2562(buffer),
|
|
3321
|
+
contentType: contentTypeForFile(absoluteCsvPath)
|
|
3322
|
+
});
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
for (const specifier of localImportSpecifiers(sourceCode)) {
|
|
3327
|
+
childVisits.push(
|
|
3328
|
+
resolveLocalImport2(absolutePath, specifier).then(
|
|
3329
|
+
(resolvedImport) => visitSourceFile(resolvedImport)
|
|
3330
|
+
)
|
|
3331
|
+
);
|
|
3332
|
+
}
|
|
3333
|
+
await Promise.all(childVisits);
|
|
3334
|
+
};
|
|
3335
|
+
await visitSourceFile(absoluteEntryFile);
|
|
3336
|
+
return {
|
|
3337
|
+
files: [...files.values()],
|
|
3338
|
+
unresolved
|
|
3339
|
+
};
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
// src/plays/bundle-play-file.ts
|
|
3343
|
+
var MODULE_DIR = _path.dirname.call(void 0, _url.fileURLToPath.call(void 0, import.meta.url));
|
|
3344
|
+
var SDK_PACKAGE_ROOT = _path.resolve.call(void 0, MODULE_DIR, "..", "..");
|
|
3345
|
+
var SOURCE_REPO_ROOT = _path.resolve.call(void 0, SDK_PACKAGE_ROOT, "..", "..");
|
|
3346
|
+
var HAS_SOURCE_BUNDLING_SOURCES = _fs.existsSync.call(void 0,
|
|
3347
|
+
_path.resolve.call(void 0, SOURCE_REPO_ROOT, "packages", "plays", "bundling", "index.ts")
|
|
3348
|
+
);
|
|
3349
|
+
var PACKAGED_BUNDLING_SOURCE_ROOT = _path.resolve.call(void 0,
|
|
3350
|
+
SDK_PACKAGE_ROOT,
|
|
3351
|
+
"dist",
|
|
3352
|
+
"bundling-sources"
|
|
3353
|
+
);
|
|
3354
|
+
var HAS_PACKAGED_BUNDLING_SOURCES = _fs.existsSync.call(void 0,
|
|
3355
|
+
_path.resolve.call(void 0,
|
|
3356
|
+
PACKAGED_BUNDLING_SOURCE_ROOT,
|
|
3357
|
+
"shared_libs",
|
|
3358
|
+
"plays",
|
|
3359
|
+
"bundling",
|
|
3360
|
+
"index.ts"
|
|
3361
|
+
)
|
|
3362
|
+
);
|
|
3363
|
+
var PROJECT_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? SOURCE_REPO_ROOT : HAS_PACKAGED_BUNDLING_SOURCES ? PACKAGED_BUNDLING_SOURCE_ROOT : _path.resolve.call(void 0, SDK_PACKAGE_ROOT, "..");
|
|
3364
|
+
var SDK_SOURCE_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? _path.resolve.call(void 0, SDK_PACKAGE_ROOT, "src") : HAS_PACKAGED_BUNDLING_SOURCES ? _path.resolve.call(void 0, PACKAGED_BUNDLING_SOURCE_ROOT, "sdk", "src") : _path.resolve.call(void 0, SDK_PACKAGE_ROOT, "src");
|
|
3365
|
+
var SDK_PACKAGE_JSON = _path.resolve.call(void 0, SDK_PACKAGE_ROOT, "package.json");
|
|
3366
|
+
var SDK_ENTRY_FILE = _path.resolve.call(void 0, SDK_SOURCE_ROOT, "index.ts");
|
|
3367
|
+
var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : _path.resolve.call(void 0, SDK_PACKAGE_ROOT, "dist", "index.d.ts");
|
|
3368
|
+
var hasWarnedAboutNonDevelopmentBundling = false;
|
|
3369
|
+
function warnAboutNonDevelopmentBundling(filePath) {
|
|
3370
|
+
if (hasWarnedAboutNonDevelopmentBundling) {
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
const nodeEnv = String(_nullishCoalesce(process.env.NODE_ENV, () => ( ""))).trim().toLowerCase();
|
|
3374
|
+
if (!nodeEnv || nodeEnv === "development" || nodeEnv === "test") {
|
|
3375
|
+
return;
|
|
3376
|
+
}
|
|
3377
|
+
hasWarnedAboutNonDevelopmentBundling = true;
|
|
3378
|
+
console.warn(
|
|
3379
|
+
`[deepline] Warning: live play bundling was invoked while NODE_ENV=${nodeEnv} for ${filePath}. This source-first SDK path is intended for local development. For preview/production, run a published or prebuilt play reference instead of bundling source at runtime.`
|
|
3380
|
+
);
|
|
3381
|
+
console.warn(
|
|
3382
|
+
'[deepline] Preferred production call pattern: client.play("person-to-email").run(...) or run a previously registered/published org play.'
|
|
3383
|
+
);
|
|
3384
|
+
}
|
|
3385
|
+
function defaultPlayBundleTarget() {
|
|
3386
|
+
return resolveExecutionProfile(null).artifactKind;
|
|
3387
|
+
}
|
|
3388
|
+
function createSdkPlayBundlingAdapter() {
|
|
3389
|
+
return {
|
|
3390
|
+
projectRoot: PROJECT_ROOT,
|
|
3391
|
+
nodeModulesDir: HAS_PACKAGED_BUNDLING_SOURCES ? _path.resolve.call(void 0, SDK_PACKAGE_ROOT, "node_modules") : _path.resolve.call(void 0, PROJECT_ROOT, "node_modules"),
|
|
3392
|
+
cacheDir: _path.join.call(void 0, _os.tmpdir.call(void 0, ), PLAY_BUNDLE_CACHE_NAMESPACE),
|
|
3393
|
+
sdkSourceRoot: SDK_SOURCE_ROOT,
|
|
3394
|
+
sdkPackageJson: SDK_PACKAGE_JSON,
|
|
3395
|
+
sdkEntryFile: SDK_ENTRY_FILE,
|
|
3396
|
+
sdkTypesEntryFile: HAS_SOURCE_BUNDLING_SOURCES || !_fs.existsSync.call(void 0, SDK_TYPES_ENTRY_FILE) ? SDK_ENTRY_FILE : SDK_TYPES_ENTRY_FILE,
|
|
3397
|
+
discoverPackagedLocalFiles,
|
|
3398
|
+
warnAboutNonDevelopmentBundling
|
|
3399
|
+
};
|
|
3400
|
+
}
|
|
3401
|
+
async function bundlePlayFile2(filePath, options = {}) {
|
|
3402
|
+
const localWorkspaceRoot = _path.dirname.call(void 0, _path.resolve.call(void 0, filePath));
|
|
3403
|
+
const sourceIdentityRoot = await _promises.realpath.call(void 0, localWorkspaceRoot).catch(
|
|
3404
|
+
() => localWorkspaceRoot
|
|
3405
|
+
);
|
|
3406
|
+
const result = await bundlePlayFile(filePath, {
|
|
3407
|
+
target: _nullishCoalesce(options.target, () => ( defaultPlayBundleTarget())),
|
|
3408
|
+
exportName: options.exportName,
|
|
3409
|
+
adapter: {
|
|
3410
|
+
...createSdkPlayBundlingAdapter(),
|
|
3411
|
+
sourceIdentityRoot
|
|
3412
|
+
}
|
|
3413
|
+
});
|
|
3414
|
+
if (result.success)
|
|
3415
|
+
_chunk3KC45UVFjs.validatePlaySourceFilesHaveNoInlineSecrets.call(void 0, result.sourceFiles);
|
|
3416
|
+
return result;
|
|
3417
|
+
}
|
|
3418
|
+
async function bundleDeployPlayFile(entryFile, options) {
|
|
3419
|
+
return bundlePlayFile(entryFile, {
|
|
3420
|
+
target: _chunk6A3TJUWCjs.PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
3421
|
+
adapter: {
|
|
3422
|
+
...createSdkPlayBundlingAdapter(),
|
|
3423
|
+
sourceIdentityRoot: options.sourceIdentityRoot,
|
|
3424
|
+
// CI commonly runs with NODE_ENV=production; a deploy bundles by design.
|
|
3425
|
+
warnAboutNonDevelopmentBundling: void 0
|
|
3426
|
+
}
|
|
3427
|
+
});
|
|
3428
|
+
}
|
|
3429
|
+
|
|
3430
|
+
|
|
3431
|
+
|
|
3432
|
+
|
|
3433
|
+
|
|
3434
|
+
|
|
3435
|
+
|
|
3436
|
+
|
|
3437
|
+
|
|
3438
|
+
|
|
3439
|
+
|
|
3440
|
+
exports.isAstNode = isAstNode; exports.parsePlaySourceForAnalysis = parsePlaySourceForAnalysis; exports.PLAY_DEFAULT_EXPORT = PLAY_DEFAULT_EXPORT; exports.listPlayFileExports = listPlayFileExports; exports.extractDefinedPlayName = extractDefinedPlayName; exports.resolveEnabledExecutionProfile = resolveEnabledExecutionProfile; exports.createSdkPlayBundlingAdapter = createSdkPlayBundlingAdapter; exports.bundlePlayFile = bundlePlayFile2; exports.bundleDeployPlayFile = bundleDeployPlayFile;
|