deepline 0.3.422 → 0.3.424
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/client.ts +15 -8
- package/dist/bundling-sources/sdk/src/index.ts +2 -0
- package/dist/bundling-sources/sdk/src/play.ts +227 -184
- package/dist/bundling-sources/sdk/src/plays/local-file-discovery.ts +9 -2
- package/dist/bundling-sources/sdk/src/plays/local-play-execution.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/tool-calls.ts +3 -1
- package/dist/bundling-sources/sdk/src/types.ts +5 -5
- package/dist/bundling-sources/shared_libs/monitors/fleets/verdict.ts +11 -1
- package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +38 -4
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +12 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-control-plane-capability.ts +25 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +10 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +201 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +42 -5
- package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +5 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +37 -36
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +179 -38
- package/dist/bundling-sources/shared_libs/plays/dataset.ts +2 -2
- package/dist/bundling-sources/shared_libs/plays/docflow.ts +4 -0
- package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/local-file-discovery.ts +12 -4
- package/dist/bundling-sources/shared_libs/plays/play-exports.ts +27 -5
- package/dist/bundling-sources/shared_libs/plays/script-entry.ts +992 -0
- package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +63 -0
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +8 -4
- package/dist/bundling-sources/shared_libs/plays/ts-ast.ts +2 -0
- package/dist/cli/auth-MN7MWTFR.js +40 -0
- package/dist/cli/{auth-DMLBSXLV.mjs → auth-QITAQMHF.mjs} +4 -4
- package/dist/cli/{billing-IFGFPGJV.js → billing-N5AOFDSU.js} +73 -73
- package/dist/cli/{billing-SEXKROBQ.mjs → billing-UX2GH5L2.mjs} +4 -4
- package/dist/cli/{chunk-BL3LY54Y.js → chunk-22XGRO2M.js} +8 -8
- package/dist/cli/{chunk-AARWVK4C.mjs → chunk-2BQUML3X.mjs} +792 -69
- package/dist/cli/{chunk-ERFN2QY4.mjs → chunk-3DNKFH2G.mjs} +1 -1
- package/dist/cli/{chunk-QNBHQM5R.mjs → chunk-3FQUUVN2.mjs} +1 -1
- package/dist/cli/{chunk-4CAVSRQH.mjs → chunk-3O7KATMQ.mjs} +1 -1
- package/dist/cli/{chunk-S4KGXRCV.js → chunk-3VB5DQ7Y.js} +20 -20
- package/dist/cli/{chunk-VT6WJ26Y.mjs → chunk-5MD5I4MM.mjs} +1 -1
- package/dist/cli/{chunk-W74RDGRL.mjs → chunk-5OBCPN2C.mjs} +2 -2
- package/dist/cli/{chunk-LXRDHISW.js → chunk-5YLEB4CL.js} +8 -8
- package/dist/cli/{chunk-2JKQORUX.mjs → chunk-7KNBC4RJ.mjs} +2 -2
- package/dist/cli/{chunk-MLP4CAY7.mjs → chunk-7VC7STG5.mjs} +4 -4
- package/dist/cli/{chunk-KBJP3UAU.js → chunk-7W4N6VRE.js} +35 -35
- package/dist/cli/{chunk-3CE3WGKP.mjs → chunk-7Y5M5YE3.mjs} +2 -2
- package/dist/cli/{chunk-V4RAH5D6.js → chunk-CJD5QKYK.js} +26 -26
- package/dist/cli/{chunk-AYM2KZN3.js → chunk-DD6MM6WX.js} +6 -6
- package/dist/cli/{chunk-63ILLN5H.mjs → chunk-DS7Y7X26.mjs} +2 -2
- package/dist/cli/{chunk-CTNA5QY2.mjs → chunk-EER67G2B.mjs} +43 -28
- package/dist/cli/{chunk-OZHPZCAU.js → chunk-F3MMA7JY.js} +52 -52
- package/dist/cli/{chunk-CO3VMH33.mjs → chunk-FJ5U2IZY.mjs} +28 -27
- package/dist/cli/{chunk-27GJKC5Q.js → chunk-GXOQRZXG.js} +2 -2
- package/dist/cli/{chunk-AXDEH2AM.mjs → chunk-HBW6PEVG.mjs} +2 -2
- package/dist/cli/{chunk-PKBPSMOT.js → chunk-INFLI36H.js} +43 -28
- package/dist/cli/{chunk-4PG4ARL2.mjs → chunk-KPKU53YO.mjs} +1 -1
- package/dist/cli/{chunk-2LVM22ZU.js → chunk-LSZZVHQP.js} +2 -2
- package/dist/cli/{chunk-IMZ56EOH.mjs → chunk-LXTSVUZN.mjs} +2 -2
- package/dist/cli/{chunk-WGO2DY4L.js → chunk-M2VXDQI2.js} +11 -11
- package/dist/cli/{chunk-7OJEYJ6G.mjs → chunk-M67UCQKW.mjs} +3 -3
- package/dist/cli/{chunk-KXPIFC5S.mjs → chunk-MFXQVT7P.mjs} +3 -3
- package/dist/cli/{chunk-IHG7UAHD.mjs → chunk-MLJBCS3E.mjs} +32 -13
- package/dist/cli/{chunk-4EV2FKBI.js → chunk-OSNDC3VF.js} +16 -16
- package/dist/cli/{chunk-PXO253DP.mjs → chunk-OWWFCA7A.mjs} +1 -1
- package/dist/cli/{chunk-VRI3ABTK.js → chunk-PNGJIAJ3.js} +50 -50
- package/dist/cli/{chunk-HCYNAIHZ.js → chunk-QP5ATTMC.js} +4 -4
- package/dist/cli/{chunk-GEJDBXXM.js → chunk-QWRHGGUH.js} +1 -1
- package/dist/cli/{chunk-AD47BXN2.js → chunk-R2QWSSAG.js} +8 -8
- package/dist/cli/{chunk-QADCFSGH.js → chunk-RDIN3NKA.js} +17 -17
- package/dist/cli/{chunk-JRSULUPQ.js → chunk-RISEING7.js} +2 -2
- package/dist/cli/{chunk-M6SXXFMT.mjs → chunk-UOZCQPD4.mjs} +2 -2
- package/dist/cli/{chunk-TP26TAAF.mjs → chunk-UPH6UNUI.mjs} +1 -1
- package/dist/cli/{chunk-UQQRMCOL.js → chunk-UTF57UBW.js} +6 -6
- package/dist/cli/{chunk-FEKJENBB.mjs → chunk-VC5NKF4B.mjs} +3 -3
- package/dist/cli/{chunk-BQR6UN3C.js → chunk-VUYUI35Q.js} +32 -13
- package/dist/cli/{chunk-WP7T4BPE.js → chunk-YA3LMTLU.js} +1 -1
- package/dist/cli/{chunk-OQQOXSYA.js → chunk-YHRS6XTB.js} +845 -122
- package/dist/cli/{chunk-K4X472AT.js → chunk-YMASNIC5.js} +260 -259
- package/dist/cli/{chunk-SDCIROIS.mjs → chunk-ZMU2DDID.mjs} +5 -5
- package/dist/cli/command-docs.js +2 -2
- package/dist/cli/command-docs.mjs +1 -1
- package/dist/cli/{csv-J7UVP4KB.mjs → csv-NM5IHLVM.mjs} +3 -3
- package/dist/cli/{csv-Y4YWZSLB.js → csv-RL53NPRV.js} +12 -12
- package/dist/cli/{db-CQ6NHMLG.mjs → db-FZTIS4QG.mjs} +5 -5
- package/dist/cli/{db-SVFCM6YZ.js → db-RJCFUM2J.js} +26 -26
- package/dist/cli/{describe-FSDW6LTN.js → describe-A2MGAI3Y.js} +24 -24
- package/dist/cli/{describe-Y65BU7ZY.mjs → describe-T77IEILZ.mjs} +16 -16
- package/dist/cli/describe-core.d.mts +2 -2
- package/dist/cli/describe-core.d.ts +2 -2
- package/dist/cli/describe-core.js +4 -4
- package/dist/cli/describe-core.mjs +3 -3
- package/dist/cli/{executions-IW762OIJ.mjs → executions-AMQK53QX.mjs} +4 -4
- package/dist/cli/{executions-SJIKBRHT.js → executions-R6UPRZ5N.js} +6 -6
- package/dist/cli/{feedback-VMJIWAMT.mjs → feedback-BA5ZHVCZ.mjs} +3 -3
- package/dist/cli/{feedback-RCYSUOB3.js → feedback-JFT536KI.js} +7 -7
- package/dist/cli/{git-Q2WY3K6X.mjs → git-5ONARXFO.mjs} +4 -4
- package/dist/cli/git-NHQR3NKF.js +24 -0
- package/dist/cli/index.js +135 -135
- package/dist/cli/index.mjs +37 -37
- package/dist/cli/{legacy-noops-JVEE2VHK.mjs → legacy-noops-7J4K6QUX.mjs} +4 -4
- package/dist/cli/{legacy-noops-U4YPPYXU.js → legacy-noops-WT7M7WYD.js} +7 -7
- package/dist/cli/{monitors-AY4KQRTC.mjs → monitors-N3WDXW7H.mjs} +19 -13
- package/dist/cli/{monitors-BMAOQ37R.js → monitors-YH6PKEIW.js} +99 -93
- package/dist/cli/{org-ME4X6HWH.mjs → org-2V5ELSYS.mjs} +4 -4
- package/dist/cli/{org-G5IURX74.js → org-KGYHMT5P.js} +64 -64
- package/dist/cli/{play-X5GSZOKZ.js → play-2JOQQRZI.js} +606 -567
- package/dist/cli/{play-WLYU7WQL.mjs → play-CL2LCBAF.mjs} +113 -74
- package/dist/cli/{providers-2LBMNB7B.mjs → providers-I7EEPWNW.mjs} +4 -4
- package/dist/cli/{providers-AHEUVD3R.js → providers-VIP6MCWC.js} +7 -7
- package/dist/cli/{quickstart-DP2SKLIG.js → quickstart-33WC2KWE.js} +5 -5
- package/dist/cli/{quickstart-DBLYGHJP.mjs → quickstart-VRBKQODE.mjs} +3 -3
- package/dist/cli/{search-YKJHY3ZJ.mjs → search-7TDSKXOO.mjs} +5 -5
- package/dist/cli/search-A6RZZ4LK.js +30 -0
- package/dist/cli/{secrets-ECLARBO6.mjs → secrets-DGLCIN7Y.mjs} +4 -4
- package/dist/cli/{secrets-2P3I3OEZ.js → secrets-TQH5FXAC.js} +13 -13
- package/dist/cli/{sessions-MC4ZCTSN.js → sessions-4D4UDPIS.js} +5 -5
- package/dist/cli/{sessions-3GDFID7R.mjs → sessions-D6QGKQ2G.mjs} +4 -4
- package/dist/cli/{settings-RTPJXMOA.mjs → settings-6HVXBCVR.mjs} +8 -8
- package/dist/cli/{settings-7SVR2OVL.js → settings-V3QRG4AO.js} +75 -75
- package/dist/cli/{setup-4WLIJX36.js → setup-6WP7D5I3.js} +42 -42
- package/dist/cli/{setup-OKAZZGAW.mjs → setup-CSJ3HSL7.mjs} +7 -7
- package/dist/cli/{skills-2CVL6RG5.mjs → skills-2MTWP4PS.mjs} +5 -5
- package/dist/cli/skills-QOYOARZT.js +29 -0
- package/dist/cli/{tools-KAFHP6J4.mjs → tools-GAR3BWB6.mjs} +15 -15
- package/dist/cli/tools-MGEKAIOU.js +44 -0
- package/dist/cli/update-HMZCLFLZ.js +31 -0
- package/dist/cli/{update-3ZV3W7I4.mjs → update-XV3WV3MU.mjs} +7 -7
- package/dist/cli/{workflow-DKSUNZXE.mjs → workflow-DTZAWSB2.mjs} +9 -9
- package/dist/cli/{workflow-GULDFFP3.js → workflow-WNE7ORMT.js} +19 -19
- package/dist/{client-CCWIUnk7.d.mts → client-BcfFWD4Z.d.mts} +19 -15
- package/dist/{client-vHqBm-OL.d.ts → client-DH-fmT69.d.ts} +19 -15
- package/dist/{compiler-manifest-lzWpbV3w.d.mts → compiler-manifest-DaFuA1ki.d.mts} +35 -32
- package/dist/{compiler-manifest-lzWpbV3w.d.ts → compiler-manifest-DaFuA1ki.d.ts} +35 -32
- package/dist/{index-CtNK-0nI.d.mts → index-0yS9ihly.d.mts} +10 -3
- package/dist/{index-C8Cy-YTm.d.ts → index-CRAScKPg.d.ts} +10 -3
- package/dist/index.d.mts +120 -150
- package/dist/index.d.ts +120 -150
- package/dist/index.js +77 -12
- package/dist/index.mjs +74 -9
- package/dist/install-integrity.json +99 -98
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +2 -2
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
- package/dist/cli/auth-HD5AM2WM.js +0 -40
- package/dist/cli/git-JAW3UEGA.js +0 -24
- package/dist/cli/search-4K3VSDS5.js +0 -30
- package/dist/cli/skills-ZNSQOXO2.js +0 -29
- package/dist/cli/tools-W4U4FT3R.js +0 -44
- package/dist/cli/update-IE2FPLB5.js +0 -31
|
@@ -31,7 +31,7 @@ import { existsSync, readFileSync } from "fs";
|
|
|
31
31
|
import { mkdir, readFile, realpath, stat, writeFile } from "fs/promises";
|
|
32
32
|
import { tmpdir } from "os";
|
|
33
33
|
import {
|
|
34
|
-
basename,
|
|
34
|
+
basename as basename2,
|
|
35
35
|
dirname,
|
|
36
36
|
extname,
|
|
37
37
|
isAbsolute,
|
|
@@ -194,17 +194,17 @@ var PLAY_AUTHORING_DEFINE_PLAY_OPTION_FIELDS = [
|
|
|
194
194
|
];
|
|
195
195
|
var PLAY_AUTHORING_DOCUMENTATION = {
|
|
196
196
|
fetchBatching: {
|
|
197
|
-
warning: "A static
|
|
198
|
-
guidance: "Keep the static fetch label. For a mutating batch, make the body distinct and use a replay-stable external Idempotency-Key such as `${
|
|
197
|
+
warning: "A static deepline.fetch key inside a loop is a warning because every iteration must still have distinct method, URL, body, or safe headers. One durable receipt must never stand in for every request.",
|
|
198
|
+
guidance: "Keep the static fetch label. For a mutating batch, make the body distinct and use a replay-stable external Idempotency-Key such as `${deepline.run.id}:signals:${batchIndex}`."
|
|
199
199
|
},
|
|
200
200
|
runId: {
|
|
201
|
-
semantics: "
|
|
201
|
+
semantics: "deepline.run.id is stable while Deepline retries or resumes one durable run. A separately submitted run receives a new id.",
|
|
202
202
|
use: "Use it when deriving an external idempotency key for a sequence of batches."
|
|
203
203
|
},
|
|
204
204
|
staticCallKeys: {
|
|
205
|
-
constraint: "Durable call keys \u2014 the
|
|
205
|
+
constraint: "Durable call keys \u2014 the deepline.fetch key, the deepline.dataset key, the deepline.step id \u2014 must be static string literals. The key names a durable receipt, so check, publish, and replay have to agree on it before the body runs. A key computed at runtime cannot be resolved at check time and is rejected.",
|
|
206
206
|
consequence: "This is an architectural constraint, not a style rule. A play cannot loop over a computed key, so it cannot page a large table with a helper like page(pageNumber). Unrolling one literal key per page is not a design at any real page count.",
|
|
207
|
-
workaround: "Push the aggregation server-side and call it once: a SQL function, a view, or a provider endpoint that returns the whole result. Keep unrolled literal keys only for a handful of genuinely distinct calls. To fan out over rows, use
|
|
207
|
+
workaround: "Push the aggregation server-side and call it once: a SQL function, a view, or a provider endpoint that returns the whole result. Keep unrolled literal keys only for a handful of genuinely distinct calls. To fan out over rows, use deepline.dataset with a static key \u2014 the per-row receipt identity comes from the row, not from the key."
|
|
208
208
|
}
|
|
209
209
|
};
|
|
210
210
|
var PLAY_AUTHORING_STATIC_FETCH_KEY_HINT = `${PLAY_AUTHORING_DOCUMENTATION.staticCallKeys.workaround} Do not compute the key.`;
|
|
@@ -1890,13 +1890,598 @@ function parsePlaySourceForAnalysis(sourceCode) {
|
|
|
1890
1890
|
return TypeScriptParser.parse(sourceCode, {
|
|
1891
1891
|
ecmaVersion: "latest",
|
|
1892
1892
|
sourceType: "module",
|
|
1893
|
-
allowHashBang: true
|
|
1893
|
+
allowHashBang: true,
|
|
1894
|
+
// Script plays may end early with a top-level `return`.
|
|
1895
|
+
allowReturnOutsideFunction: true
|
|
1894
1896
|
});
|
|
1895
1897
|
} catch {
|
|
1896
1898
|
return null;
|
|
1897
1899
|
}
|
|
1898
1900
|
}
|
|
1899
1901
|
|
|
1902
|
+
// ../plays/script-entry.ts
|
|
1903
|
+
import { basename } from "path";
|
|
1904
|
+
var SCRIPT_SDK = "deepline";
|
|
1905
|
+
var PLAY_FILE_PATTERN = /\.play\.[cm]?[jt]sx?$/i;
|
|
1906
|
+
var DEFINE_CALLEES = /* @__PURE__ */ new Set(["definePlay", "defineWorkflow"]);
|
|
1907
|
+
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
1908
|
+
"FunctionDeclaration",
|
|
1909
|
+
"FunctionExpression",
|
|
1910
|
+
"ArrowFunctionExpression"
|
|
1911
|
+
]);
|
|
1912
|
+
var MODULE_SCOPE = /* @__PURE__ */ new Set([
|
|
1913
|
+
"ImportDeclaration",
|
|
1914
|
+
"TSTypeAliasDeclaration",
|
|
1915
|
+
"TSInterfaceDeclaration"
|
|
1916
|
+
]);
|
|
1917
|
+
var DECLARATION_TYPES = /* @__PURE__ */ new Set([
|
|
1918
|
+
"FunctionDeclaration",
|
|
1919
|
+
"TSDeclareFunction",
|
|
1920
|
+
"ClassDeclaration",
|
|
1921
|
+
"TSTypeAliasDeclaration",
|
|
1922
|
+
"TSInterfaceDeclaration",
|
|
1923
|
+
"TSEnumDeclaration"
|
|
1924
|
+
]);
|
|
1925
|
+
var UNWRAPPED_TYPES = /* @__PURE__ */ new Set([
|
|
1926
|
+
"TSAsExpression",
|
|
1927
|
+
"TSSatisfiesExpression",
|
|
1928
|
+
"TSTypeAssertion",
|
|
1929
|
+
"ParenthesizedExpression",
|
|
1930
|
+
"AwaitExpression"
|
|
1931
|
+
]);
|
|
1932
|
+
var CONDITIONAL_TYPES = /* @__PURE__ */ new Set([
|
|
1933
|
+
...FUNCTION_TYPES,
|
|
1934
|
+
"ClassDeclaration",
|
|
1935
|
+
"ClassExpression",
|
|
1936
|
+
"IfStatement",
|
|
1937
|
+
"ConditionalExpression",
|
|
1938
|
+
"LogicalExpression",
|
|
1939
|
+
"SwitchStatement",
|
|
1940
|
+
"ForStatement",
|
|
1941
|
+
"ForInStatement",
|
|
1942
|
+
"ForOfStatement",
|
|
1943
|
+
"WhileStatement",
|
|
1944
|
+
"DoWhileStatement",
|
|
1945
|
+
"CatchClause"
|
|
1946
|
+
]);
|
|
1947
|
+
var INLINE_PLAY_FILE = ".inline.play.ts";
|
|
1948
|
+
var LEADING_IMPORT = /^\s*import\s+(?:[\w$*{}\s,]+?\s+from\s+)?['"][^'"]+['"]\s*;?/;
|
|
1949
|
+
function inlinePlaySource(code) {
|
|
1950
|
+
let header = "";
|
|
1951
|
+
let body = code;
|
|
1952
|
+
for (let match = LEADING_IMPORT.exec(body); match; ) {
|
|
1953
|
+
header += match[0];
|
|
1954
|
+
body = body.slice(match[0].length);
|
|
1955
|
+
match = LEADING_IMPORT.exec(body);
|
|
1956
|
+
}
|
|
1957
|
+
const runtimeImport = /\bimport\s+\w+\s*(,\s*\{[^}]*\}\s*)?from\s+['"]deepline['"]/.test(header) ? "" : `import ${SCRIPT_SDK} from '${SCRIPT_SDK}'; `;
|
|
1958
|
+
if (/\bexport\s+default\b/.test(code)) return runtimeImport + code;
|
|
1959
|
+
return `${runtimeImport}${header}export default async function (input: any) {${body}
|
|
1960
|
+
}
|
|
1961
|
+
`;
|
|
1962
|
+
}
|
|
1963
|
+
function playNameFromPath(filePath) {
|
|
1964
|
+
return basename(filePath).replace(/^\.+/, "").replace(/(\.play)?\.[cm]?[jt]sx?$/, "");
|
|
1965
|
+
}
|
|
1966
|
+
function parseScriptPlay(source) {
|
|
1967
|
+
const program = programOf(source);
|
|
1968
|
+
const form = program ? playForm(program) : null;
|
|
1969
|
+
if (!program || !form) return null;
|
|
1970
|
+
const { entry } = form;
|
|
1971
|
+
const header = headerOf(program);
|
|
1972
|
+
const contextName = defaultImportName(header.find(isSdkImport)) ?? SCRIPT_SDK;
|
|
1973
|
+
const parts = scriptPlayParts(program, contextName, entry?.node ?? null);
|
|
1974
|
+
const configExport = configExportOf(program);
|
|
1975
|
+
const headerEnd = header.at(-1)?.end ?? 0;
|
|
1976
|
+
const [entryCall = null] = entry ? entryCallsOf(program, entry) : [];
|
|
1977
|
+
const callStatement = entryCall ? program.body.find(
|
|
1978
|
+
(node) => node.start <= entryCall.start && node.end >= entryCall.end
|
|
1979
|
+
) : void 0;
|
|
1980
|
+
const excluded = new Set(
|
|
1981
|
+
[
|
|
1982
|
+
entry?.exportStatement,
|
|
1983
|
+
entry?.declaration,
|
|
1984
|
+
callStatement,
|
|
1985
|
+
configExport
|
|
1986
|
+
].filter(Boolean)
|
|
1987
|
+
);
|
|
1988
|
+
const moduleCode = program.body.slice(header.length).filter(
|
|
1989
|
+
(node) => !excluded.has(node) && !MODULE_SCOPE.has(node.type) && !(node.type === "ExpressionStatement" && scriptCallName(unwrapped(node.expression), contextName) === "config") && // Beside a play function, module code that neither awaits nor uses
|
|
1990
|
+
// the runtime only names values and helpers, as a definePlay file's
|
|
1991
|
+
// module scope does.
|
|
1992
|
+
(!entry || usesRuntime(node, contextName))
|
|
1993
|
+
);
|
|
1994
|
+
const body = entry?.node.body;
|
|
1995
|
+
const code = [
|
|
1996
|
+
...moduleCode,
|
|
1997
|
+
...body?.type === "BlockStatement" ? body.body : []
|
|
1998
|
+
];
|
|
1999
|
+
const [parameter] = entry?.node.params ?? [];
|
|
2000
|
+
return {
|
|
2001
|
+
entry,
|
|
2002
|
+
entryCall,
|
|
2003
|
+
code,
|
|
2004
|
+
contextName,
|
|
2005
|
+
headerEnd,
|
|
2006
|
+
delegate: delegateOf(code, contextName),
|
|
2007
|
+
config: (configExport && configObjectOf(configExport)) ?? parts.config,
|
|
2008
|
+
// The entry's parameter is its input; `(input) => ({ ... })` returns its
|
|
2009
|
+
// expression.
|
|
2010
|
+
inputType: parameterType(parameter) ?? parts.inputType,
|
|
2011
|
+
outputs: body && body.type !== "BlockStatement" ? [body] : parts.outputs
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
2014
|
+
function playRuntimeNames(source) {
|
|
2015
|
+
const program = programOf(source);
|
|
2016
|
+
const imported = program ? program.body.filter(isSdkImport).map(defaultImportName) : [];
|
|
2017
|
+
return /* @__PURE__ */ new Set([
|
|
2018
|
+
"ctx",
|
|
2019
|
+
SCRIPT_SDK,
|
|
2020
|
+
...imported.filter((name) => name !== null)
|
|
2021
|
+
]);
|
|
2022
|
+
}
|
|
2023
|
+
function isRuntimeReceiver(name, runtimeNames) {
|
|
2024
|
+
return runtimeNames.has(name) || name.endsWith("Ctx");
|
|
2025
|
+
}
|
|
2026
|
+
function delegateOf(code, contextName) {
|
|
2027
|
+
const [statement, extra] = code.filter(
|
|
2028
|
+
(node) => !isSignatureStatement(node, contextName) && !isDeclarationOnly(node)
|
|
2029
|
+
);
|
|
2030
|
+
if (extra || statement?.type !== "ReturnStatement") return null;
|
|
2031
|
+
const returned = statement.argument;
|
|
2032
|
+
const call = isAstNode(returned) && returned.type === "AwaitExpression" ? returned.argument : returned;
|
|
2033
|
+
if (!isAstNode(call) || call.type !== "CallExpression") return null;
|
|
2034
|
+
const [runtime] = call.arguments;
|
|
2035
|
+
return isAstNode(call.callee) && call.callee.type === "Identifier" && runtime?.type === "Identifier" && (runtime.name === "ctx" || runtime.name === contextName) ? { handlerName: call.callee.name } : null;
|
|
2036
|
+
}
|
|
2037
|
+
function isSignatureStatement(node, contextName) {
|
|
2038
|
+
if (node.type === "ExpressionStatement") {
|
|
2039
|
+
return scriptCallName(unwrapped(node.expression), contextName) === "config";
|
|
2040
|
+
}
|
|
2041
|
+
if (node.type !== "VariableDeclaration") return false;
|
|
2042
|
+
const declarations = node.declarations;
|
|
2043
|
+
return declarations.length === 1 && scriptCallName(unwrapped(declarations[0].init), contextName) === "input";
|
|
2044
|
+
}
|
|
2045
|
+
function isDeclarationOnly(node) {
|
|
2046
|
+
if (DECLARATION_TYPES.has(node.type)) return true;
|
|
2047
|
+
return node.type === "VariableDeclaration" && node.kind === "const" && node.declarations.every(
|
|
2048
|
+
(declarator) => isAstNode(declarator.init) && isLiteralValue(declarator.init)
|
|
2049
|
+
);
|
|
2050
|
+
}
|
|
2051
|
+
function isLiteralValue(node) {
|
|
2052
|
+
return node.type === "TemplateLiteral" ? node.expressions.length === 0 : node.type === "Literal" && (node.regex !== void 0 || ["string", "number", "bigint"].includes(typeof node.value));
|
|
2053
|
+
}
|
|
2054
|
+
function unwrapped(node) {
|
|
2055
|
+
let current = isAstNode(node) ? node : null;
|
|
2056
|
+
while (current && UNWRAPPED_TYPES.has(current.type)) {
|
|
2057
|
+
const inner = current.expression ?? current.argument;
|
|
2058
|
+
current = isAstNode(inner) ? inner : null;
|
|
2059
|
+
}
|
|
2060
|
+
return current;
|
|
2061
|
+
}
|
|
2062
|
+
function parameterType(parameter) {
|
|
2063
|
+
const target = parameter?.type === "AssignmentPattern" ? parameter.left : parameter;
|
|
2064
|
+
const annotation = isAstNode(target) ? target.typeAnnotation : null;
|
|
2065
|
+
return isAstNode(annotation) && isAstNode(annotation.typeAnnotation) ? annotation.typeAnnotation : null;
|
|
2066
|
+
}
|
|
2067
|
+
function scriptPlayParts(program, contextName, playFunction) {
|
|
2068
|
+
const parts = { config: null, inputType: null, outputs: [] };
|
|
2069
|
+
const visit = (node, insideFunction) => {
|
|
2070
|
+
if (node.type === "ReturnStatement" && !insideFunction && isAstNode(node.argument)) {
|
|
2071
|
+
parts.outputs.push(node.argument);
|
|
2072
|
+
}
|
|
2073
|
+
const call = scriptCallName(node, contextName);
|
|
2074
|
+
const [argument] = Array.isArray(node.arguments) ? node.arguments.filter(isAstNode) : [];
|
|
2075
|
+
if (call === "config" && argument?.type === "ObjectExpression") {
|
|
2076
|
+
parts.config ??= argument;
|
|
2077
|
+
} else if (call === "input") {
|
|
2078
|
+
parts.inputType ??= typeArgument(node);
|
|
2079
|
+
} else if (call === "output" && argument) {
|
|
2080
|
+
parts.outputs.push(argument);
|
|
2081
|
+
}
|
|
2082
|
+
const nested = node === playFunction ? false : insideFunction || FUNCTION_TYPES.has(node.type);
|
|
2083
|
+
childNodes(node).forEach((child) => visit(child, nested));
|
|
2084
|
+
};
|
|
2085
|
+
visit(program, playFunction !== null);
|
|
2086
|
+
return parts;
|
|
2087
|
+
}
|
|
2088
|
+
function usesRuntime(node, contextName) {
|
|
2089
|
+
if (node.type === "AwaitExpression" || node.type === "Identifier" && node.name === contextName) {
|
|
2090
|
+
return true;
|
|
2091
|
+
}
|
|
2092
|
+
if (FUNCTION_TYPES.has(node.type)) return false;
|
|
2093
|
+
return childNodes(node).some((child) => usesRuntime(child, contextName));
|
|
2094
|
+
}
|
|
2095
|
+
function scriptCallName(node, contextName) {
|
|
2096
|
+
if (node?.type !== "CallExpression" || !isAstNode(node.callee)) return null;
|
|
2097
|
+
const callee = node.callee;
|
|
2098
|
+
if (callee.type !== "MemberExpression" || callee.computed || !isAstNode(callee.object) || callee.object.type !== "Identifier" || callee.object.name !== contextName || !isAstNode(callee.property)) {
|
|
2099
|
+
return null;
|
|
2100
|
+
}
|
|
2101
|
+
const name = callee.property.name;
|
|
2102
|
+
return name === "config" || name === "input" || name === "output" ? name : null;
|
|
2103
|
+
}
|
|
2104
|
+
function typeArgument(call) {
|
|
2105
|
+
const instantiation = call.typeArguments ?? call.typeParameters;
|
|
2106
|
+
return isAstNode(instantiation) && Array.isArray(instantiation.params) ? instantiation.params.find(isAstNode) ?? null : null;
|
|
2107
|
+
}
|
|
2108
|
+
function wrapScriptPlay(source, script, { typed }) {
|
|
2109
|
+
const { entry, entryCall } = script;
|
|
2110
|
+
const unknownType = typed ? ": unknown" : "";
|
|
2111
|
+
const anyType = typed ? ": any" : "";
|
|
2112
|
+
const runtimeImport = defaultImportName(
|
|
2113
|
+
headerOf(programOf(source)).find(isSdkImport)
|
|
2114
|
+
) ? `import { runScriptPlay as __deeplineRunScriptPlay } from '${SCRIPT_SDK}';` : `import ${SCRIPT_SDK}, { runScriptPlay as __deeplineRunScriptPlay } from '${SCRIPT_SDK}';`;
|
|
2115
|
+
const entryBindings = entry ? ` let __deeplineEntry${anyType}; let __deeplineEntryResult${anyType};` : "";
|
|
2116
|
+
const prefix = `${runtimeImport} export default async function (__deeplineContext${unknownType}, __deeplineInput${anyType}) { return __deeplineRunScriptPlay(__deeplineContext, __deeplineInput, async () => {${entryBindings}`;
|
|
2117
|
+
const edits = [
|
|
2118
|
+
{
|
|
2119
|
+
at: script.headerEnd,
|
|
2120
|
+
text: script.headerEnd === 0 ? `${prefix} ` : ` ${prefix}`
|
|
2121
|
+
}
|
|
2122
|
+
];
|
|
2123
|
+
const configExport = configExportOf(programOf(source));
|
|
2124
|
+
if (configExport) {
|
|
2125
|
+
const declared = configExport.declaration;
|
|
2126
|
+
edits.push({
|
|
2127
|
+
at: configExport.start,
|
|
2128
|
+
end: declared.start,
|
|
2129
|
+
text: blank(
|
|
2130
|
+
source.slice(configExport.start, declared.start)
|
|
2131
|
+
)
|
|
2132
|
+
});
|
|
2133
|
+
}
|
|
2134
|
+
let entryName = "__deeplineEntry";
|
|
2135
|
+
if (entry) {
|
|
2136
|
+
const statement = entry.exportStatement;
|
|
2137
|
+
const declared = statement.declaration;
|
|
2138
|
+
if (entry.exportedAs === "specifier") {
|
|
2139
|
+
entryName = entry.name;
|
|
2140
|
+
edits.push({
|
|
2141
|
+
at: statement.start,
|
|
2142
|
+
end: statement.end,
|
|
2143
|
+
text: blank(
|
|
2144
|
+
source.slice(statement.start, statement.end)
|
|
2145
|
+
)
|
|
2146
|
+
});
|
|
2147
|
+
} else if (entry.exportedAs === "declaration" && entry.name) {
|
|
2148
|
+
entryName = entry.name;
|
|
2149
|
+
edits.push({
|
|
2150
|
+
at: statement.start,
|
|
2151
|
+
end: declared.start,
|
|
2152
|
+
text: blank(
|
|
2153
|
+
source.slice(statement.start, declared.start)
|
|
2154
|
+
)
|
|
2155
|
+
});
|
|
2156
|
+
} else {
|
|
2157
|
+
edits.push({
|
|
2158
|
+
at: statement.start,
|
|
2159
|
+
end: declared.start,
|
|
2160
|
+
text: "__deeplineEntry = "
|
|
2161
|
+
});
|
|
2162
|
+
if (entry.exportedAs === "declaration") {
|
|
2163
|
+
edits.push({ at: statement.end, text: ";" });
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
if (entryCall) {
|
|
2167
|
+
edits.push(
|
|
2168
|
+
{ at: entryCall.start, text: "(__deeplineEntryResult = " },
|
|
2169
|
+
{ at: entryCall.end, text: ")" }
|
|
2170
|
+
);
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
const dispatch = !entry ? "" : entryCall ? " return await __deeplineEntryResult;" : (
|
|
2174
|
+
// A play function that takes no input is called without one.
|
|
2175
|
+
` return await ${entryName}(${entry.node.params.length ? "__deeplineInput" : ""});`
|
|
2176
|
+
);
|
|
2177
|
+
return edits.sort(
|
|
2178
|
+
(left, right) => right.at - left.at || (right.end ?? right.at) - (left.end ?? left.at)
|
|
2179
|
+
).reduce(
|
|
2180
|
+
(text, edit) => text.slice(0, edit.at) + edit.text + text.slice(edit.end ?? edit.at),
|
|
2181
|
+
source
|
|
2182
|
+
) + `
|
|
2183
|
+
;${dispatch} }); }
|
|
2184
|
+
`;
|
|
2185
|
+
}
|
|
2186
|
+
function blank(text) {
|
|
2187
|
+
return text.replace(/[^\n]/g, " ");
|
|
2188
|
+
}
|
|
2189
|
+
function validateScriptPlay(source, script) {
|
|
2190
|
+
const { contextName, entry } = script;
|
|
2191
|
+
const program = programOf(source);
|
|
2192
|
+
const statements = program.body;
|
|
2193
|
+
const defaultExport = statements.find(isDefaultExport);
|
|
2194
|
+
if (defaultExport && !entry) {
|
|
2195
|
+
fail(
|
|
2196
|
+
source,
|
|
2197
|
+
defaultExport,
|
|
2198
|
+
"The default export must be the play function: export default async function (input) { ... return { ... }; }."
|
|
2199
|
+
);
|
|
2200
|
+
}
|
|
2201
|
+
if (entry) {
|
|
2202
|
+
const calls = entryCallsOf(program, entry);
|
|
2203
|
+
if (calls.length > 1) {
|
|
2204
|
+
fail(
|
|
2205
|
+
source,
|
|
2206
|
+
calls[1],
|
|
2207
|
+
`The play function is called ${calls.length} times at the top of the file; the runtime runs it once per run. Call it once, or not at all.`
|
|
2208
|
+
);
|
|
2209
|
+
}
|
|
2210
|
+
const moduleResult = (node, insideFunction) => {
|
|
2211
|
+
const call = scriptCallName(node, contextName);
|
|
2212
|
+
if (!insideFunction && (node.type === "ReturnStatement" || call === "output")) {
|
|
2213
|
+
fail(
|
|
2214
|
+
source,
|
|
2215
|
+
node,
|
|
2216
|
+
"The play function's return is the play's result; this top-level result would compete with it. Return the result from the play function."
|
|
2217
|
+
);
|
|
2218
|
+
}
|
|
2219
|
+
const nested = insideFunction || FUNCTION_TYPES.has(node.type);
|
|
2220
|
+
childNodes(node).forEach((child) => moduleResult(child, nested));
|
|
2221
|
+
};
|
|
2222
|
+
moduleResult(program, false);
|
|
2223
|
+
}
|
|
2224
|
+
const lateImport = statements.slice(headerOf(program).length).find((node) => node.type === "ImportDeclaration");
|
|
2225
|
+
if (lateImport) {
|
|
2226
|
+
fail(
|
|
2227
|
+
source,
|
|
2228
|
+
lateImport,
|
|
2229
|
+
"Move this import above the play code; imports come first in a script play."
|
|
2230
|
+
);
|
|
2231
|
+
}
|
|
2232
|
+
const topLevelConfig = new Set(
|
|
2233
|
+
statements.map(
|
|
2234
|
+
(node) => node.type === "ExpressionStatement" ? node.expression : null
|
|
2235
|
+
).filter((node) => isAstNode(node))
|
|
2236
|
+
);
|
|
2237
|
+
const configExport = configExportOf(program);
|
|
2238
|
+
if (configExport) {
|
|
2239
|
+
const config = configObjectOf(configExport);
|
|
2240
|
+
if (!config) {
|
|
2241
|
+
fail(
|
|
2242
|
+
source,
|
|
2243
|
+
configExport,
|
|
2244
|
+
"export const config must be one object literal, e.g. export const config = { description: '...' };"
|
|
2245
|
+
);
|
|
2246
|
+
}
|
|
2247
|
+
validateConfigName(source, config);
|
|
2248
|
+
}
|
|
2249
|
+
const configCalls = [];
|
|
2250
|
+
const inputTypes = /* @__PURE__ */ new Set();
|
|
2251
|
+
const visit = (node) => {
|
|
2252
|
+
const call = scriptCallName(node, contextName);
|
|
2253
|
+
const args = Array.isArray(node.arguments) ? node.arguments : [];
|
|
2254
|
+
if (call === "config") {
|
|
2255
|
+
configCalls.push(node);
|
|
2256
|
+
if (!topLevelConfig.has(node)) {
|
|
2257
|
+
fail(
|
|
2258
|
+
source,
|
|
2259
|
+
node,
|
|
2260
|
+
`${contextName}.config(...) must be its own top-level statement.`
|
|
2261
|
+
);
|
|
2262
|
+
}
|
|
2263
|
+
if (args.length !== 1 || !isAstNode(args[0]) || args[0].type !== "ObjectExpression") {
|
|
2264
|
+
fail(
|
|
2265
|
+
source,
|
|
2266
|
+
node,
|
|
2267
|
+
`${contextName}.config(...) takes one object literal, e.g. ${contextName}.config({ description: '...' }).`
|
|
2268
|
+
);
|
|
2269
|
+
}
|
|
2270
|
+
validateConfigName(source, args[0]);
|
|
2271
|
+
if (configCalls.length > 1) {
|
|
2272
|
+
fail(source, node, `${contextName}.config(...) may appear only once.`);
|
|
2273
|
+
}
|
|
2274
|
+
if (configExport) {
|
|
2275
|
+
fail(
|
|
2276
|
+
source,
|
|
2277
|
+
node,
|
|
2278
|
+
`The play config is declared twice: export const config (line ${lineOf(source, configExport)}) and ${contextName}.config(...) (line ${lineOf(source, node)}). Keep only export const config.`
|
|
2279
|
+
);
|
|
2280
|
+
}
|
|
2281
|
+
} else if (call === "input") {
|
|
2282
|
+
if (args.length > 0) {
|
|
2283
|
+
fail(
|
|
2284
|
+
source,
|
|
2285
|
+
node,
|
|
2286
|
+
`${contextName}.input() takes no arguments; declare the shape as a type: ${contextName}.input<{ domain: string }>().`
|
|
2287
|
+
);
|
|
2288
|
+
}
|
|
2289
|
+
const type = typeArgument(node);
|
|
2290
|
+
if (type)
|
|
2291
|
+
inputTypes.add(source.slice(type.start, type.end));
|
|
2292
|
+
if (inputTypes.size > 1) {
|
|
2293
|
+
fail(
|
|
2294
|
+
source,
|
|
2295
|
+
node,
|
|
2296
|
+
`${contextName}.input<T>() is called with different types (${[...inputTypes].join(", ")}). Use one input type.`
|
|
2297
|
+
);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
childNodes(node).forEach(visit);
|
|
2301
|
+
};
|
|
2302
|
+
visit(program);
|
|
2303
|
+
}
|
|
2304
|
+
var SCRIPT_PLAY_MODULE_DECLARATION = `import type { DefinedPlay } from '${SCRIPT_SDK}';
|
|
2305
|
+
declare const play: DefinedPlay<Record<string, unknown>, Record<string, unknown>>;
|
|
2306
|
+
export default play;
|
|
2307
|
+
`;
|
|
2308
|
+
function validateConfigName(source, config) {
|
|
2309
|
+
const name = (config.properties ?? []).find(
|
|
2310
|
+
(property) => property.type === "Property" && !property.computed && isAstNode(property.key) && (property.key.name === "name" || property.key.value === "name")
|
|
2311
|
+
);
|
|
2312
|
+
if (name && !(isAstNode(name.value) && name.value.type === "Literal" && typeof name.value.value === "string" && name.value.value.trim())) {
|
|
2313
|
+
fail(source, name, "config name must be a non-empty string literal.");
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
function lineOf(source, node) {
|
|
2317
|
+
return source.slice(0, node.start).split("\n").length;
|
|
2318
|
+
}
|
|
2319
|
+
function fail(source, node, message) {
|
|
2320
|
+
throw new Error(`line ${lineOf(source, node)}: ${message}`);
|
|
2321
|
+
}
|
|
2322
|
+
function childNodes(node) {
|
|
2323
|
+
return Object.entries(node).flatMap(
|
|
2324
|
+
([key, value]) => key === "loc" ? [] : Array.isArray(value) ? value.filter(isAstNode) : isAstNode(value) ? [value] : []
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
var programs = /* @__PURE__ */ new Map();
|
|
2328
|
+
var MAX_PROGRAMS = 16;
|
|
2329
|
+
function programOf(source) {
|
|
2330
|
+
const program = programs.has(source) ? programs.get(source) : parse(source);
|
|
2331
|
+
programs.delete(source);
|
|
2332
|
+
programs.set(source, program);
|
|
2333
|
+
if (programs.size > MAX_PROGRAMS) {
|
|
2334
|
+
programs.delete(programs.keys().next().value);
|
|
2335
|
+
}
|
|
2336
|
+
return program;
|
|
2337
|
+
}
|
|
2338
|
+
function headerOf(program) {
|
|
2339
|
+
const statements = program.body;
|
|
2340
|
+
const firstCode = statements.findIndex(
|
|
2341
|
+
(node) => !MODULE_SCOPE.has(node.type)
|
|
2342
|
+
);
|
|
2343
|
+
return firstCode === -1 ? statements : statements.slice(0, firstCode);
|
|
2344
|
+
}
|
|
2345
|
+
function isSdkImport(node) {
|
|
2346
|
+
return node.type === "ImportDeclaration" && isAstNode(node.source) && node.source.value === SCRIPT_SDK;
|
|
2347
|
+
}
|
|
2348
|
+
function parse(source) {
|
|
2349
|
+
try {
|
|
2350
|
+
return TypeScriptParser.parse(source, {
|
|
2351
|
+
ecmaVersion: "latest",
|
|
2352
|
+
sourceType: "module",
|
|
2353
|
+
allowHashBang: true,
|
|
2354
|
+
// Script plays may end early with a top-level `return`.
|
|
2355
|
+
allowReturnOutsideFunction: true
|
|
2356
|
+
});
|
|
2357
|
+
} catch (error) {
|
|
2358
|
+
const looksLikeScript = /\bdeepline\s*\./.test(source) && !/\bexport\b|\bdefinePlay\b/.test(source);
|
|
2359
|
+
if (!looksLikeScript) return null;
|
|
2360
|
+
const line = error.loc?.line;
|
|
2361
|
+
throw new Error(
|
|
2362
|
+
`line ${line ?? "?"}: ${error.message.replace(/ \(\d+:\d+\)$/, "")}`
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
function playForm(program) {
|
|
2367
|
+
if (containsDefinePlayCall(program)) return null;
|
|
2368
|
+
const configExport = configExportOf(program);
|
|
2369
|
+
const exports = program.body.filter(
|
|
2370
|
+
(node) => node !== configExport && /^Export|^TSExportAssignment$/.test(node.type)
|
|
2371
|
+
);
|
|
2372
|
+
if (exports.length === 0) return { entry: null };
|
|
2373
|
+
const [statement] = exports;
|
|
2374
|
+
if (exports.length !== 1 || !isDefaultExport(statement)) return null;
|
|
2375
|
+
const entry = entryOf(program, statement);
|
|
2376
|
+
if (entry && entry.node.params.length > 1) return null;
|
|
2377
|
+
if (!importsRuntime(program) && (!entry || importsRuntimeName(program))) {
|
|
2378
|
+
return null;
|
|
2379
|
+
}
|
|
2380
|
+
return { entry };
|
|
2381
|
+
}
|
|
2382
|
+
function configExportOf(program) {
|
|
2383
|
+
return program.body.find(
|
|
2384
|
+
(node) => node.type === "ExportNamedDeclaration" && !node.source && isAstNode(node.declaration) && node.declaration.type === "VariableDeclaration" && node.declaration.declarations.some(
|
|
2385
|
+
(declarator) => declarator.id.name === "config"
|
|
2386
|
+
)
|
|
2387
|
+
) ?? null;
|
|
2388
|
+
}
|
|
2389
|
+
function configObjectOf(configExport) {
|
|
2390
|
+
const declaration = configExport.declaration;
|
|
2391
|
+
const declarators = declaration.declarations;
|
|
2392
|
+
if (declaration.kind !== "const" || declarators.length !== 1) return null;
|
|
2393
|
+
const init = unwrapped(declarators[0].init);
|
|
2394
|
+
return init?.type === "ObjectExpression" ? init : null;
|
|
2395
|
+
}
|
|
2396
|
+
function isDefaultExport(node) {
|
|
2397
|
+
if (node.type === "ExportDefaultDeclaration") return true;
|
|
2398
|
+
const specifiers = node.specifiers ?? [];
|
|
2399
|
+
return node.type === "ExportNamedDeclaration" && !node.declaration && !node.source && specifiers.length === 1 && exportedName(specifiers[0]) === "default";
|
|
2400
|
+
}
|
|
2401
|
+
function exportedName(specifier) {
|
|
2402
|
+
const exported = specifier.exported;
|
|
2403
|
+
return exported?.name ?? exported?.value;
|
|
2404
|
+
}
|
|
2405
|
+
function entryOf(program, statement) {
|
|
2406
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
2407
|
+
const declared = unwrapped(statement.declaration);
|
|
2408
|
+
if (declared && FUNCTION_TYPES.has(declared.type)) {
|
|
2409
|
+
const id = declared.id;
|
|
2410
|
+
return {
|
|
2411
|
+
node: declared,
|
|
2412
|
+
name: declared.type === "FunctionDeclaration" && id ? id.name : null,
|
|
2413
|
+
exportedAs: declared.type === "FunctionDeclaration" ? "declaration" : "expression",
|
|
2414
|
+
exportStatement: statement,
|
|
2415
|
+
declaration: null
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
return declared?.type === "Identifier" ? boundEntry(program, statement, declared.name, "binding") : null;
|
|
2419
|
+
}
|
|
2420
|
+
const [specifier] = statement.specifiers;
|
|
2421
|
+
const local = specifier.local;
|
|
2422
|
+
return boundEntry(program, statement, local.name, "specifier");
|
|
2423
|
+
}
|
|
2424
|
+
function boundEntry(program, exportStatement, name, exportedAs) {
|
|
2425
|
+
for (const node of program.body) {
|
|
2426
|
+
if (node.type === "FunctionDeclaration" && node.id?.name === name) {
|
|
2427
|
+
return { node, name, exportedAs, exportStatement, declaration: node };
|
|
2428
|
+
}
|
|
2429
|
+
if (node.type !== "VariableDeclaration") continue;
|
|
2430
|
+
for (const declarator of node.declarations) {
|
|
2431
|
+
const init = unwrapped(declarator.init);
|
|
2432
|
+
if (declarator.id.name === name && init && FUNCTION_TYPES.has(init.type)) {
|
|
2433
|
+
return {
|
|
2434
|
+
node: init,
|
|
2435
|
+
name,
|
|
2436
|
+
exportedAs,
|
|
2437
|
+
exportStatement,
|
|
2438
|
+
declaration: node
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
return null;
|
|
2444
|
+
}
|
|
2445
|
+
function entryCallsOf(program, entry) {
|
|
2446
|
+
if (!entry.name) return [];
|
|
2447
|
+
const calls = [];
|
|
2448
|
+
const visit = (node) => {
|
|
2449
|
+
if (CONDITIONAL_TYPES.has(node.type)) return;
|
|
2450
|
+
if (node.type === "CallExpression" && isAstNode(node.callee) && node.callee.type === "Identifier" && node.callee.name === entry.name) {
|
|
2451
|
+
calls.push(node);
|
|
2452
|
+
}
|
|
2453
|
+
childNodes(node).forEach(visit);
|
|
2454
|
+
};
|
|
2455
|
+
program.body.filter(
|
|
2456
|
+
(node) => node !== entry.declaration && node !== entry.exportStatement
|
|
2457
|
+
).forEach(visit);
|
|
2458
|
+
return calls;
|
|
2459
|
+
}
|
|
2460
|
+
function importsRuntime(program) {
|
|
2461
|
+
return program.body.some(
|
|
2462
|
+
(node) => isSdkImport(node) && defaultImportName(node) !== null
|
|
2463
|
+
);
|
|
2464
|
+
}
|
|
2465
|
+
function importsRuntimeName(program) {
|
|
2466
|
+
return program.body.some(
|
|
2467
|
+
(node) => node.type === "ImportDeclaration" && node.specifiers.some(
|
|
2468
|
+
(specifier) => specifier.local.name === SCRIPT_SDK
|
|
2469
|
+
)
|
|
2470
|
+
);
|
|
2471
|
+
}
|
|
2472
|
+
function containsDefinePlayCall(node) {
|
|
2473
|
+
if (node.type === "CallExpression" && isAstNode(node.callee)) {
|
|
2474
|
+
const callee = node.callee;
|
|
2475
|
+
const name = callee.type === "Identifier" ? callee.name : callee.type === "MemberExpression" && isAstNode(callee.property) ? callee.property.name : null;
|
|
2476
|
+
if (DEFINE_CALLEES.has(name)) return true;
|
|
2477
|
+
}
|
|
2478
|
+
return childNodes(node).some(containsDefinePlayCall);
|
|
2479
|
+
}
|
|
2480
|
+
function defaultImportName(importDeclaration) {
|
|
2481
|
+
const specifier = importDeclaration?.specifiers?.find((node) => node.type === "ImportDefaultSpecifier");
|
|
2482
|
+
return specifier && isAstNode(specifier.local) ? specifier.local.name : null;
|
|
2483
|
+
}
|
|
2484
|
+
|
|
1900
2485
|
// ../plays/play-exports.ts
|
|
1901
2486
|
var PLAY_DEFAULT_EXPORT = "default";
|
|
1902
2487
|
function getIdentifierName(node) {
|
|
@@ -1933,19 +2518,34 @@ function definePlayName(node) {
|
|
|
1933
2518
|
astArray(expression.arguments)[0] ?? null
|
|
1934
2519
|
);
|
|
1935
2520
|
if (first?.type !== "ObjectExpression") return stringLiteralValue(first);
|
|
1936
|
-
|
|
1937
|
-
|
|
2521
|
+
return objectStringProperty(first, "id");
|
|
2522
|
+
}
|
|
2523
|
+
function objectStringProperty(object, propertyName) {
|
|
2524
|
+
let value = null;
|
|
2525
|
+
for (const property of astArray(object?.properties)) {
|
|
1938
2526
|
if (property.type !== "Property" || property.computed) continue;
|
|
1939
2527
|
const key = isAstNode(property.key) ? property.key : null;
|
|
1940
2528
|
const keyName = getIdentifierName(key) ?? (key?.type === "Literal" && typeof key.value === "string" ? key.value : null);
|
|
1941
|
-
if (keyName !==
|
|
1942
|
-
|
|
2529
|
+
if (keyName !== propertyName) continue;
|
|
2530
|
+
value = stringLiteralValue(
|
|
2531
|
+
isAstNode(property.value) ? property.value : null
|
|
2532
|
+
);
|
|
1943
2533
|
}
|
|
1944
|
-
return
|
|
2534
|
+
return value;
|
|
1945
2535
|
}
|
|
1946
2536
|
function listPlayFileExports(sourceCode) {
|
|
1947
2537
|
const ast = parsePlaySourceForAnalysis(sourceCode);
|
|
1948
2538
|
if (!ast) return null;
|
|
2539
|
+
const script = parseScriptPlay(sourceCode);
|
|
2540
|
+
if (script) {
|
|
2541
|
+
return [
|
|
2542
|
+
{
|
|
2543
|
+
name: PLAY_DEFAULT_EXPORT,
|
|
2544
|
+
aliases: [],
|
|
2545
|
+
playName: objectStringProperty(script.config, "name")
|
|
2546
|
+
}
|
|
2547
|
+
];
|
|
2548
|
+
}
|
|
1949
2549
|
const declarations = /* @__PURE__ */ new Map();
|
|
1950
2550
|
const namedExports = /* @__PURE__ */ new Map();
|
|
1951
2551
|
let defaultExpression = null;
|
|
@@ -1979,8 +2579,8 @@ function listPlayFileExports(sourceCode) {
|
|
|
1979
2579
|
}
|
|
1980
2580
|
for (const specifier of astArray(statement.specifiers)) {
|
|
1981
2581
|
const localName = getIdentifierName(specifier.local);
|
|
1982
|
-
const
|
|
1983
|
-
if (localName &&
|
|
2582
|
+
const exportedName2 = getIdentifierName(specifier.exported);
|
|
2583
|
+
if (localName && exportedName2) namedExports.set(exportedName2, localName);
|
|
1984
2584
|
}
|
|
1985
2585
|
}
|
|
1986
2586
|
const defaultLocalName = getIdentifierName(
|
|
@@ -2000,13 +2600,13 @@ function listPlayFileExports(sourceCode) {
|
|
|
2000
2600
|
)
|
|
2001
2601
|
});
|
|
2002
2602
|
}
|
|
2003
|
-
for (const [
|
|
2004
|
-
if (
|
|
2603
|
+
for (const [exportedName2, localName] of namedExports) {
|
|
2604
|
+
if (exportedName2 === PLAY_DEFAULT_EXPORT) continue;
|
|
2005
2605
|
if (aliasedLocals.has(localName)) continue;
|
|
2006
2606
|
const declaration = declarations.get(localName) ?? null;
|
|
2007
2607
|
if (!isDefinePlayCall(declaration)) continue;
|
|
2008
2608
|
exports.push({
|
|
2009
|
-
name:
|
|
2609
|
+
name: exportedName2,
|
|
2010
2610
|
aliases: [],
|
|
2011
2611
|
playName: definePlayName(declaration)
|
|
2012
2612
|
});
|
|
@@ -2598,14 +3198,14 @@ function playExportSourceRanges(sourceCode) {
|
|
|
2598
3198
|
}
|
|
2599
3199
|
}
|
|
2600
3200
|
const resolveCall = (expression, seen = /* @__PURE__ */ new Set()) => {
|
|
2601
|
-
const
|
|
2602
|
-
if (!
|
|
2603
|
-
if (isDefinePlayCall(
|
|
2604
|
-
if (
|
|
3201
|
+
const unwrapped2 = unwrapExportExpression(expression);
|
|
3202
|
+
if (!unwrapped2) return null;
|
|
3203
|
+
if (isDefinePlayCall(unwrapped2)) return unwrapped2;
|
|
3204
|
+
if (unwrapped2.type !== "Identifier" || typeof unwrapped2.name !== "string" || seen.has(unwrapped2.name)) {
|
|
2605
3205
|
return null;
|
|
2606
3206
|
}
|
|
2607
|
-
seen.add(
|
|
2608
|
-
return resolveCall(declarations.get(
|
|
3207
|
+
seen.add(unwrapped2.name);
|
|
3208
|
+
return resolveCall(declarations.get(unwrapped2.name) ?? null, seen);
|
|
2609
3209
|
};
|
|
2610
3210
|
const defaultCall = resolveCall(defaultExpression);
|
|
2611
3211
|
const ranges = [];
|
|
@@ -2660,6 +3260,7 @@ function attachBindingsToBlocks(sourceCode, blocks, bindings, errors, rejectedNo
|
|
|
2660
3260
|
const exportRanges = playExportSourceRanges(sourceCode);
|
|
2661
3261
|
for (const binding of bindings) {
|
|
2662
3262
|
let owners = blocks.filter((block) => block.nodes.has(binding.nodeId));
|
|
3263
|
+
if (owners.length === 0 && binding.sourcePath) continue;
|
|
2663
3264
|
if (owners.length === 0) {
|
|
2664
3265
|
errors.push(
|
|
2665
3266
|
`Docflow annotation "${binding.nodeId}" does not name a graph node.`
|
|
@@ -2914,12 +3515,12 @@ function isDocflowStepCallForName(node, stepName) {
|
|
|
2914
3515
|
);
|
|
2915
3516
|
}
|
|
2916
3517
|
function docflowExpressionWrapsStepBuilder(expression, stepName) {
|
|
2917
|
-
const
|
|
2918
|
-
if (isDocflowStepCallForName(
|
|
2919
|
-
const pending = [
|
|
3518
|
+
const unwrapped2 = expression.type === "AwaitExpression" && isAstNode(expression.argument) ? expression.argument : expression;
|
|
3519
|
+
if (isDocflowStepCallForName(unwrapped2, stepName)) return false;
|
|
3520
|
+
const pending = [unwrapped2];
|
|
2920
3521
|
while (pending.length > 0) {
|
|
2921
3522
|
const node = pending.pop();
|
|
2922
|
-
if (node !==
|
|
3523
|
+
if (node !== unwrapped2 && isDocflowStepCallForName(node, stepName)) {
|
|
2923
3524
|
return true;
|
|
2924
3525
|
}
|
|
2925
3526
|
for (const child of Object.values(node)) {
|
|
@@ -3240,6 +3841,29 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
|
|
|
3240
3841
|
const expression = resolve4(
|
|
3241
3842
|
local ?? legacyExports.get(requested) ?? (exportName === null ? definitions[0] ?? null : null)
|
|
3242
3843
|
);
|
|
3844
|
+
const functionTypes = [
|
|
3845
|
+
"FunctionDeclaration",
|
|
3846
|
+
"FunctionExpression",
|
|
3847
|
+
"ArrowFunctionExpression"
|
|
3848
|
+
];
|
|
3849
|
+
const localName = identifier(local);
|
|
3850
|
+
const defaultIsFunction = !local && !legacyExports.has("default") && definitions.length === 0 || expression !== null && functionTypes.includes(expression.type) || localName !== null && astArray(ast.body).some(
|
|
3851
|
+
(statement) => statement.type === "FunctionDeclaration" && identifier(statement.id) === localName
|
|
3852
|
+
);
|
|
3853
|
+
if (requested === "default" && defaultIsFunction) {
|
|
3854
|
+
const config = exports.has("config") ? declarations.get("config") ?? null : scriptConfigCall(ast);
|
|
3855
|
+
if (config) {
|
|
3856
|
+
const compatibility = property(config, "compatibility");
|
|
3857
|
+
const marker2 = compatibility.kind === "found" ? property(compatibility.value, "authoringContract") : compatibility;
|
|
3858
|
+
if (marker2.kind !== "found") return { marker: marker2, localExport: true };
|
|
3859
|
+
const value2 = resolve4(marker2.value);
|
|
3860
|
+
return {
|
|
3861
|
+
marker: value2?.type === "Literal" ? { kind: "value", value: value2.value } : { kind: "unknown" },
|
|
3862
|
+
localExport: true
|
|
3863
|
+
};
|
|
3864
|
+
}
|
|
3865
|
+
return { marker: { kind: "absent" }, localExport: Boolean(local) };
|
|
3866
|
+
}
|
|
3243
3867
|
if (!expression || expression.type !== "CallExpression") {
|
|
3244
3868
|
return {
|
|
3245
3869
|
marker: {
|
|
@@ -3262,6 +3886,17 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
|
|
|
3262
3886
|
definition: expression
|
|
3263
3887
|
};
|
|
3264
3888
|
}
|
|
3889
|
+
function scriptConfigCall(ast) {
|
|
3890
|
+
for (const statement of astArray(ast.body)) {
|
|
3891
|
+
const call = statement.type === "ExpressionStatement" && isAstNode(statement.expression) ? statement.expression : null;
|
|
3892
|
+
const callee = call?.type === "CallExpression" && isAstNode(call.callee) ? call.callee : null;
|
|
3893
|
+
if (callee?.type === "MemberExpression" && !callee.computed && identifier(callee.property) === "config") {
|
|
3894
|
+
const [argument] = astArray(call.arguments);
|
|
3895
|
+
if (argument?.type === "ObjectExpression") return argument;
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
return null;
|
|
3899
|
+
}
|
|
3265
3900
|
function resolvePlaySourceAuthoringContractEdition(marker, pinnedEdition) {
|
|
3266
3901
|
if (marker.kind === "unknown") {
|
|
3267
3902
|
throw new PlayAuthoringFieldValidationError(
|
|
@@ -3298,7 +3933,6 @@ var SOURCE_EXTENSIONS = [
|
|
|
3298
3933
|
".cjs",
|
|
3299
3934
|
".json"
|
|
3300
3935
|
];
|
|
3301
|
-
var PLAY_SOURCE_FILE_PATTERN = /\.play\.(?:[cm]?[jt]sx?)$/i;
|
|
3302
3936
|
var TEXT_IMPORT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt"]);
|
|
3303
3937
|
var EXPLICIT_IMPORT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
3304
3938
|
...SOURCE_EXTENSIONS,
|
|
@@ -3331,7 +3965,7 @@ function sourceIdentityPath(filePath, sourceIdentityRoot) {
|
|
|
3331
3965
|
const resolvedFilePath = resolve(filePath);
|
|
3332
3966
|
const logicalPath = relative(identityRoot, resolvedFilePath);
|
|
3333
3967
|
if (!logicalPath) {
|
|
3334
|
-
return
|
|
3968
|
+
return basename2(resolvedFilePath);
|
|
3335
3969
|
}
|
|
3336
3970
|
if (logicalPath === ".." || logicalPath.startsWith(`..${sep}`) || isAbsolute(logicalPath)) {
|
|
3337
3971
|
return filePath;
|
|
@@ -3378,7 +4012,7 @@ function getPackageName(specifier) {
|
|
|
3378
4012
|
return specifier.split("/")[0] ?? specifier;
|
|
3379
4013
|
}
|
|
3380
4014
|
function isPlaySourceFile(filePath) {
|
|
3381
|
-
return
|
|
4015
|
+
return PLAY_FILE_PATTERN.test(filePath);
|
|
3382
4016
|
}
|
|
3383
4017
|
function stripCommentsToSpaces(source) {
|
|
3384
4018
|
return source.replace(/\/\*[\s\S]*?\*\//g, (match) => match.replace(/[^\n]/g, " ")).replace(
|
|
@@ -3452,15 +4086,17 @@ function findSourceImportReferences(sourceCode) {
|
|
|
3452
4086
|
(left, right) => left.line === right.line ? left.column - right.column : left.line - right.line
|
|
3453
4087
|
);
|
|
3454
4088
|
}
|
|
3455
|
-
function extractDefinedPlayName(sourceCode) {
|
|
3456
|
-
return extractDefinedPlayMetadata(sourceCode, null)?.name ?? null;
|
|
4089
|
+
function extractDefinedPlayName(sourceCode, filePath) {
|
|
4090
|
+
return extractDefinedPlayMetadata(sourceCode, null, filePath)?.name ?? null;
|
|
3457
4091
|
}
|
|
3458
4092
|
function parsePlaySourceAst(sourceCode) {
|
|
3459
4093
|
try {
|
|
3460
4094
|
return TypeScriptParser.parse(sourceCode, {
|
|
3461
4095
|
ecmaVersion: "latest",
|
|
3462
4096
|
sourceType: "module",
|
|
3463
|
-
allowHashBang: true
|
|
4097
|
+
allowHashBang: true,
|
|
4098
|
+
// Script plays may end early with a top-level `return`.
|
|
4099
|
+
allowReturnOutsideFunction: true
|
|
3464
4100
|
});
|
|
3465
4101
|
} catch {
|
|
3466
4102
|
try {
|
|
@@ -3474,7 +4110,9 @@ function parsePlaySourceAst(sourceCode) {
|
|
|
3474
4110
|
return Parser2.parse(transformed, {
|
|
3475
4111
|
ecmaVersion: "latest",
|
|
3476
4112
|
sourceType: "module",
|
|
3477
|
-
allowHashBang: true
|
|
4113
|
+
allowHashBang: true,
|
|
4114
|
+
// Script plays may end early with a top-level `return`.
|
|
4115
|
+
allowReturnOutsideFunction: true
|
|
3478
4116
|
});
|
|
3479
4117
|
} catch {
|
|
3480
4118
|
return null;
|
|
@@ -3581,9 +4219,9 @@ function buildPlayMetadataContext(ast) {
|
|
|
3581
4219
|
}
|
|
3582
4220
|
for (const specifier of astArray(statement.specifiers)) {
|
|
3583
4221
|
const localName = getIdentifierName3(specifier.local);
|
|
3584
|
-
const
|
|
3585
|
-
if (localName &&
|
|
3586
|
-
namedExports.set(
|
|
4222
|
+
const exportedName2 = getIdentifierName3(specifier.exported) ?? (isAstNode(specifier.exported) && specifier.exported.type === "Literal" && typeof specifier.exported.value === "string" ? specifier.exported.value : null);
|
|
4223
|
+
if (localName && exportedName2) {
|
|
4224
|
+
namedExports.set(exportedName2, localName);
|
|
3587
4225
|
}
|
|
3588
4226
|
}
|
|
3589
4227
|
}
|
|
@@ -3915,6 +4553,32 @@ function playMetadataFromDefinePlayCall(node, context) {
|
|
|
3915
4553
|
toolResponseReceiptRevisionUnknown
|
|
3916
4554
|
};
|
|
3917
4555
|
}
|
|
4556
|
+
function playMetadataFromScriptConfig(config, context, filePath) {
|
|
4557
|
+
const toolErrorSchemaVersion = toolErrorSchemaVersionFromOptions(
|
|
4558
|
+
config,
|
|
4559
|
+
context
|
|
4560
|
+
);
|
|
4561
|
+
const toolResponseReceiptRevision = toolResponseReceiptRevisionFromOptions(
|
|
4562
|
+
config,
|
|
4563
|
+
context
|
|
4564
|
+
);
|
|
4565
|
+
return {
|
|
4566
|
+
name: stringPropertyFromObjectExpression(config, "name", context) ?? (filePath ? playNameFromPath(filePath) : null),
|
|
4567
|
+
description: stringPropertyFromObjectExpression(
|
|
4568
|
+
config,
|
|
4569
|
+
"description",
|
|
4570
|
+
context
|
|
4571
|
+
),
|
|
4572
|
+
sandboxRuntimeDeclaration: sandboxRuntimeDeclarationFromOptions(
|
|
4573
|
+
config,
|
|
4574
|
+
context
|
|
4575
|
+
),
|
|
4576
|
+
toolErrorSchemaVersion: toolErrorSchemaVersion ?? null,
|
|
4577
|
+
toolErrorSchemaVersionUnknown: toolErrorSchemaVersion === null,
|
|
4578
|
+
toolResponseReceiptRevision: toolResponseReceiptRevision ?? null,
|
|
4579
|
+
toolResponseReceiptRevisionUnknown: toolResponseReceiptRevision === null
|
|
4580
|
+
};
|
|
4581
|
+
}
|
|
3918
4582
|
function resolveExportExpression(exportName, context) {
|
|
3919
4583
|
if (exportName === "default") {
|
|
3920
4584
|
const commonJsDefault = context.commonJsExports.get("default");
|
|
@@ -3945,10 +4609,13 @@ function resolveExportExpression(exportName, context) {
|
|
|
3945
4609
|
}
|
|
3946
4610
|
return null;
|
|
3947
4611
|
}
|
|
3948
|
-
function extractDefinedPlayMetadata(sourceCode, exportName) {
|
|
4612
|
+
function extractDefinedPlayMetadata(sourceCode, exportName, filePath) {
|
|
3949
4613
|
const ast = parsePlaySourceAst(sourceCode);
|
|
3950
4614
|
if (!ast) return null;
|
|
3951
4615
|
const context = buildPlayMetadataContext(ast);
|
|
4616
|
+
const script = exportName === null || exportName === "default" ? parseScriptPlay(sourceCode) : null;
|
|
4617
|
+
if (script)
|
|
4618
|
+
return playMetadataFromScriptConfig(script.config, context, filePath);
|
|
3952
4619
|
const exportedExpression = resolveExportExpression(exportName, context);
|
|
3953
4620
|
const exportedMetadata = playMetadataFromDefinePlayCall(
|
|
3954
4621
|
exportedExpression,
|
|
@@ -4221,6 +4888,7 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
|
|
|
4221
4888
|
const targets = [];
|
|
4222
4889
|
const injectedContextAt = /* @__PURE__ */ new Set();
|
|
4223
4890
|
const parents = buildDocflowParentIndex(ast);
|
|
4891
|
+
const scriptContext = parseScriptPlay(sourceCode)?.contextName ?? null;
|
|
4224
4892
|
for (const binding of parsed.bindings) {
|
|
4225
4893
|
const resolution = resolveDocflowBinding(ast, binding, lineStarts, parents);
|
|
4226
4894
|
const context = findDocflowContext({
|
|
@@ -4230,7 +4898,7 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
|
|
|
4230
4898
|
bindingLine: binding.line,
|
|
4231
4899
|
lineStarts,
|
|
4232
4900
|
parents
|
|
4233
|
-
});
|
|
4901
|
+
}) ?? (scriptContext ? { kind: "named", name: scriptContext } : null);
|
|
4234
4902
|
if (!context) continue;
|
|
4235
4903
|
if (context.kind === "unsupported") {
|
|
4236
4904
|
throw new Error(
|
|
@@ -4310,26 +4978,32 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
|
|
|
4310
4978
|
sourceCode
|
|
4311
4979
|
);
|
|
4312
4980
|
}
|
|
4313
|
-
function docflowRuntimeInstrumentationPlugin(
|
|
4314
|
-
const customerSourceFiles = new
|
|
4315
|
-
|
|
4981
|
+
function docflowRuntimeInstrumentationPlugin(analyzedSources, scriptEntry) {
|
|
4982
|
+
const customerSourceFiles = new Map(
|
|
4983
|
+
Object.entries(analyzedSources).filter(([path]) => extname(path).toLowerCase() !== ".json").map(([path, contents]) => [resolve(path), contents])
|
|
4316
4984
|
);
|
|
4317
4985
|
return {
|
|
4318
4986
|
name: "deepline-docflow-runtime-instrumentation",
|
|
4319
4987
|
setup(buildContext) {
|
|
4320
4988
|
buildContext.onLoad({ filter: /./ }, (args) => {
|
|
4321
|
-
if (
|
|
4989
|
+
if (scriptEntry && resolve(args.path) === resolve(scriptEntry.path)) {
|
|
4990
|
+
return {
|
|
4991
|
+
contents: scriptEntryModule(scriptEntry.source, args.path),
|
|
4992
|
+
loader: sourceLoaderForPath(args.path),
|
|
4993
|
+
resolveDir: dirname(args.path)
|
|
4994
|
+
};
|
|
4995
|
+
}
|
|
4996
|
+
const contents = customerSourceFiles.get(resolve(args.path));
|
|
4997
|
+
if (contents === void 0) return void 0;
|
|
4322
4998
|
if (isTextImportFile(args.path)) {
|
|
4323
4999
|
return {
|
|
4324
|
-
contents
|
|
5000
|
+
contents,
|
|
4325
5001
|
loader: "text",
|
|
4326
5002
|
resolveDir: dirname(args.path)
|
|
4327
5003
|
};
|
|
4328
5004
|
}
|
|
4329
5005
|
return {
|
|
4330
|
-
contents: instrumentPlayDocflowRuntimeHits(
|
|
4331
|
-
readFileSync(args.path, "utf8")
|
|
4332
|
-
),
|
|
5006
|
+
contents: instrumentPlayDocflowRuntimeHits(contents),
|
|
4333
5007
|
loader: sourceLoaderForPath(args.path),
|
|
4334
5008
|
resolveDir: dirname(args.path)
|
|
4335
5009
|
};
|
|
@@ -4337,6 +5011,18 @@ function docflowRuntimeInstrumentationPlugin(customerSourceFilePaths) {
|
|
|
4337
5011
|
}
|
|
4338
5012
|
};
|
|
4339
5013
|
}
|
|
5014
|
+
function scriptEntryModule(source, path) {
|
|
5015
|
+
const instrumented = instrumentPlayDocflowRuntimeHits(source);
|
|
5016
|
+
const script = parseScriptPlay(instrumented);
|
|
5017
|
+
if (!script) {
|
|
5018
|
+
throw new Error(
|
|
5019
|
+
"Docflow instrumentation turned a script play into a non-script."
|
|
5020
|
+
);
|
|
5021
|
+
}
|
|
5022
|
+
return wrapScriptPlay(instrumented, script, {
|
|
5023
|
+
typed: /^tsx?$/.test(sourceLoaderForPath(path))
|
|
5024
|
+
});
|
|
5025
|
+
}
|
|
4340
5026
|
function buildImportedPlayProxyModule(playName) {
|
|
4341
5027
|
const serializedName = JSON.stringify(playName);
|
|
4342
5028
|
return `
|
|
@@ -4473,6 +5159,8 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
|
|
|
4473
5159
|
const nodeBuiltins = /* @__PURE__ */ new Set();
|
|
4474
5160
|
const packages = /* @__PURE__ */ new Map();
|
|
4475
5161
|
const importedPlayDependencies = /* @__PURE__ */ new Map();
|
|
5162
|
+
const importedPlaySources = /* @__PURE__ */ new Map();
|
|
5163
|
+
let entryScript = null;
|
|
4476
5164
|
const visited = /* @__PURE__ */ new Set();
|
|
4477
5165
|
const importViolations = [];
|
|
4478
5166
|
const visitFile = async (filePath) => {
|
|
@@ -4486,6 +5174,13 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
|
|
|
4486
5174
|
absolutePath,
|
|
4487
5175
|
"utf-8"
|
|
4488
5176
|
);
|
|
5177
|
+
if (absolutePath === absoluteEntryFile) {
|
|
5178
|
+
const script = parseScriptPlay(sourceCode2);
|
|
5179
|
+
if (script) {
|
|
5180
|
+
validateScriptPlay(sourceCode2, script);
|
|
5181
|
+
entryScript = sourceCode2;
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
4489
5184
|
localFiles.set(absolutePath, sourceCode2);
|
|
4490
5185
|
if (extname(absolutePath).toLowerCase() === ".json" || isTextImportFile(absolutePath)) {
|
|
4491
5186
|
return;
|
|
@@ -4518,10 +5213,18 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
|
|
|
4518
5213
|
resolved,
|
|
4519
5214
|
"utf-8"
|
|
4520
5215
|
);
|
|
4521
|
-
const
|
|
5216
|
+
const importedScript = parseScriptPlay(importedSource);
|
|
5217
|
+
if (importedScript)
|
|
5218
|
+
validateScriptPlay(importedSource, importedScript);
|
|
5219
|
+
if (importedScript)
|
|
5220
|
+
importedPlaySources.set(resolved, SCRIPT_PLAY_MODULE_DECLARATION);
|
|
5221
|
+
const importedPlayName = extractDefinedPlayName(
|
|
5222
|
+
importedSource,
|
|
5223
|
+
resolved
|
|
5224
|
+
);
|
|
4522
5225
|
if (!importedPlayName) {
|
|
4523
5226
|
throw new Error(
|
|
4524
|
-
`${absolutePath}:${line}:${column} Imported play file "${specifier}"
|
|
5227
|
+
`${absolutePath}:${line}:${column} Imported play file "${specifier}" is not a play: write it as a script play (import deepline from 'deepline') or default-export a play function, so it can be runtime-composed.`
|
|
4525
5228
|
);
|
|
4526
5229
|
}
|
|
4527
5230
|
importedPlayDependencies.set(resolved, {
|
|
@@ -4582,6 +5285,7 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
|
|
|
4582
5285
|
})).sort((left, right) => left.filePath.localeCompare(right.filePath))
|
|
4583
5286
|
})
|
|
4584
5287
|
);
|
|
5288
|
+
const authoredSource = sourceCode;
|
|
4585
5289
|
const sourceAst = parsePlaySourceAst(sourceCode);
|
|
4586
5290
|
if (!sourceAst)
|
|
4587
5291
|
throw new Error(
|
|
@@ -4594,7 +5298,11 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
|
|
|
4594
5298
|
const metadata = (selection.marker.kind === "value" && selection.definition ? playMetadataFromDefinePlayCall(
|
|
4595
5299
|
selection.definition,
|
|
4596
5300
|
buildPlayMetadataContext(sourceAst)
|
|
4597
|
-
) : extractDefinedPlayMetadata(
|
|
5301
|
+
) : extractDefinedPlayMetadata(
|
|
5302
|
+
authoredSource,
|
|
5303
|
+
exportName,
|
|
5304
|
+
absoluteEntryFile
|
|
5305
|
+
)) ?? (exportName === "default" ? extractDefinedPlayMetadata(authoredSource, null, absoluteEntryFile) : null);
|
|
4598
5306
|
const compatibilityDiagnostic = metadata?.toolErrorSchemaVersionUnknown ? "definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1." : metadata?.toolResponseReceiptRevisionUnknown ? "definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string." : null;
|
|
4599
5307
|
try {
|
|
4600
5308
|
resolvePlaySourceAuthoringContractEdition(selection.marker);
|
|
@@ -4634,7 +5342,9 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
4634
5342
|
sourceHasLocalPlayExport: selection.localExport,
|
|
4635
5343
|
importedPlayDependencies: [...importedPlayDependencies.values()].sort(
|
|
4636
5344
|
(left, right) => left.filePath.localeCompare(right.filePath)
|
|
4637
|
-
)
|
|
5345
|
+
),
|
|
5346
|
+
importedPlaySources: Object.fromEntries(importedPlaySources),
|
|
5347
|
+
entryScript
|
|
4638
5348
|
};
|
|
4639
5349
|
}
|
|
4640
5350
|
function artifactCachePath(graphHash, artifactKind, adapter) {
|
|
@@ -4704,21 +5414,21 @@ function getBundleSizeError(filePath, bundledCode, artifactKind) {
|
|
|
4704
5414
|
artifactKind
|
|
4705
5415
|
);
|
|
4706
5416
|
}
|
|
4707
|
-
async function runEsbuildForCjsNode(entryFile,
|
|
5417
|
+
async function runEsbuildForCjsNode(entryFile, analyzedSources, entryScript, importedPlayDependencies, adapter, exportName, bundleRoot) {
|
|
4708
5418
|
const sdkAliasPlugin = localSdkAliasPlugin(adapter);
|
|
4709
5419
|
const playProxyPlugin = importedPlayProxyPlugin(importedPlayDependencies);
|
|
4710
|
-
const docflowPlugin = docflowRuntimeInstrumentationPlugin(
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
const namedExportShim = exportName
|
|
4715
|
-
|
|
5420
|
+
const docflowPlugin = docflowRuntimeInstrumentationPlugin(
|
|
5421
|
+
analyzedSources,
|
|
5422
|
+
entryScript === null ? null : { path: entryFile, source: entryScript }
|
|
5423
|
+
);
|
|
5424
|
+
const namedExportShim = exportName !== "default" ? `export { ${exportName} as default } from ${JSON.stringify(entryFile)};
|
|
5425
|
+
` : null;
|
|
4716
5426
|
const result = await build({
|
|
4717
5427
|
...namedExportShim ? {
|
|
4718
5428
|
stdin: {
|
|
4719
5429
|
contents: namedExportShim,
|
|
4720
5430
|
resolveDir: dirname(entryFile),
|
|
4721
|
-
sourcefile: `${
|
|
5431
|
+
sourcefile: `${basename2(entryFile)}.${exportName}.entry.ts`,
|
|
4722
5432
|
loader: "ts"
|
|
4723
5433
|
}
|
|
4724
5434
|
} : { entryPoints: [entryFile] },
|
|
@@ -4790,7 +5500,9 @@ async function bundlePlayFile(filePath, options) {
|
|
|
4790
5500
|
`${analysis.graphHash}
|
|
4791
5501
|
entry-export:${exportName}
|
|
4792
5502
|
authoring-contract-edition:${edition}${edition >= 10 ? "\nimported-proxy-options:description" : ""}${preservedCompatibility === void 0 ? "\ndataset-row-input:current_run" : `
|
|
4793
|
-
preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
|
|
5503
|
+
preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}` + // A script entry is bundled wrapped; keep its artifacts apart.
|
|
5504
|
+
// definePlay plays keep their existing hash.
|
|
5505
|
+
(analysis.entryScript === null ? "" : "\nentry-form:script-v2")
|
|
4794
5506
|
);
|
|
4795
5507
|
const sourceFiles = Object.fromEntries(
|
|
4796
5508
|
Object.entries(analysis.sourceFiles).map(([sourcePath, sourceCode]) => [
|
|
@@ -4823,7 +5535,11 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
|
|
|
4823
5535
|
...analysis.importedPlayDependencies.map(
|
|
4824
5536
|
(dependency) => dependency.filePath
|
|
4825
5537
|
)
|
|
4826
|
-
]
|
|
5538
|
+
],
|
|
5539
|
+
sourceFiles: {
|
|
5540
|
+
...analysis.sourceFiles,
|
|
5541
|
+
...analysis.importedPlaySources
|
|
5542
|
+
}
|
|
4827
5543
|
}) ?? []
|
|
4828
5544
|
];
|
|
4829
5545
|
if (typecheckErrors.length > 0) {
|
|
@@ -4838,7 +5554,10 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
|
|
|
4838
5554
|
target,
|
|
4839
5555
|
adapter
|
|
4840
5556
|
);
|
|
4841
|
-
const discoveredFiles = await adapter.discoverPackagedLocalFiles(
|
|
5557
|
+
const discoveredFiles = await adapter.discoverPackagedLocalFiles(
|
|
5558
|
+
absolutePath,
|
|
5559
|
+
analysis.sourceFiles
|
|
5560
|
+
);
|
|
4842
5561
|
if (cachedArtifact) {
|
|
4843
5562
|
const cachedArtifactSizeError = getBundleSizeError(
|
|
4844
5563
|
absolutePath,
|
|
@@ -4882,7 +5601,8 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
|
|
|
4882
5601
|
const bundleRoot = resolve(sourceIdentityRoot ?? adapter.projectRoot);
|
|
4883
5602
|
const buildOutcome = await runEsbuildForCjsNode(
|
|
4884
5603
|
absolutePath,
|
|
4885
|
-
analysis.
|
|
5604
|
+
analysis.sourceFiles,
|
|
5605
|
+
analysis.entryScript,
|
|
4886
5606
|
analysis.importedPlayDependencies,
|
|
4887
5607
|
adapter,
|
|
4888
5608
|
exportName,
|
|
@@ -4900,10 +5620,10 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
|
|
|
4900
5620
|
sourceMapText,
|
|
4901
5621
|
bundleRoot
|
|
4902
5622
|
);
|
|
4903
|
-
const virtualBaseName = exportName === "default" ?
|
|
5623
|
+
const virtualBaseName = exportName === "default" ? basename2(absolutePath).replace(/\.[^.]+$/, "") : `${basename2(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
|
|
4904
5624
|
const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
|
|
4905
5625
|
const executableCode = `${bundledCode}
|
|
4906
|
-
//# sourceMappingURL=${
|
|
5626
|
+
//# sourceMappingURL=${basename2(virtualFilename)}.map
|
|
4907
5627
|
`;
|
|
4908
5628
|
const bundleSizeError = getBundleSizeError(
|
|
4909
5629
|
absolutePath,
|
|
@@ -5070,7 +5790,7 @@ function resolveEnabledExecutionProfile(override) {
|
|
|
5070
5790
|
import { createHash as createHash2 } from "crypto";
|
|
5071
5791
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
5072
5792
|
import {
|
|
5073
|
-
basename as
|
|
5793
|
+
basename as basename3,
|
|
5074
5794
|
dirname as dirname2,
|
|
5075
5795
|
extname as extname2,
|
|
5076
5796
|
isAbsolute as isAbsolute2,
|
|
@@ -5329,7 +6049,7 @@ async function resolveLocalImport2(fromFile, specifier) {
|
|
|
5329
6049
|
`Could not resolve local import "${specifier}" from ${fromFile}`
|
|
5330
6050
|
);
|
|
5331
6051
|
}
|
|
5332
|
-
async function discoverPackagedLocalFiles(entryFile) {
|
|
6052
|
+
async function discoverPackagedLocalFiles(entryFile, analyzedSources = {}) {
|
|
5333
6053
|
const absoluteEntryFile = resolve2(entryFile);
|
|
5334
6054
|
const packagingRoot = dirname2(absoluteEntryFile);
|
|
5335
6055
|
const files = /* @__PURE__ */ new Map();
|
|
@@ -5341,18 +6061,19 @@ async function discoverPackagedLocalFiles(entryFile) {
|
|
|
5341
6061
|
return;
|
|
5342
6062
|
}
|
|
5343
6063
|
visitedFiles.add(absolutePath);
|
|
5344
|
-
const sourceCode = await readFile2(absolutePath, "utf-8");
|
|
6064
|
+
const sourceCode = analyzedSources[absolutePath] ?? await readFile2(absolutePath, "utf-8");
|
|
5345
6065
|
if (extname2(absolutePath).toLowerCase() === ".json" || isTextImportFile2(absolutePath)) {
|
|
5346
6066
|
return;
|
|
5347
6067
|
}
|
|
5348
6068
|
const scanSource = stripCommentsToSpaces2(sourceCode);
|
|
5349
6069
|
const constants = collectTopLevelStringConstants(sourceCode);
|
|
6070
|
+
const runtimeNames = playRuntimeNames(sourceCode);
|
|
5350
6071
|
const childVisits = [];
|
|
5351
6072
|
for (const match of scanSource.matchAll(
|
|
5352
6073
|
/\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g
|
|
5353
6074
|
)) {
|
|
5354
6075
|
const target = match[1];
|
|
5355
|
-
if (target
|
|
6076
|
+
if (!isRuntimeReceiver(target, runtimeNames)) {
|
|
5356
6077
|
continue;
|
|
5357
6078
|
}
|
|
5358
6079
|
const openParen = findCallOpenParen(
|
|
@@ -5509,6 +6230,8 @@ async function bundleDeployPlayFile(entryFile, options) {
|
|
|
5509
6230
|
export {
|
|
5510
6231
|
isAstNode,
|
|
5511
6232
|
parsePlaySourceForAnalysis,
|
|
6233
|
+
INLINE_PLAY_FILE,
|
|
6234
|
+
inlinePlaySource,
|
|
5512
6235
|
PLAY_DEFAULT_EXPORT,
|
|
5513
6236
|
listPlayFileExports,
|
|
5514
6237
|
extractDefinedPlayName,
|