prostgles-server 4.2.419 → 4.2.421
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/DBSchemaBuilder/getServerFunctionReturnTypes.d.ts.map +1 -1
- package/dist/DBSchemaBuilder/getServerFunctionReturnTypes.js +64 -248
- package/dist/DBSchemaBuilder/getServerFunctionReturnTypes.js.map +1 -1
- package/dist/PublishParser/defineServerFunction.d.ts +35 -5
- package/dist/PublishParser/defineServerFunction.d.ts.map +1 -1
- package/dist/PublishParser/defineServerFunction.js +15 -1
- package/dist/PublishParser/defineServerFunction.js.map +1 -1
- package/lib/DBSchemaBuilder/getServerFunctionReturnTypes.ts +85 -281
- package/lib/PublishParser/defineServerFunction.ts +65 -7
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getServerFunctionReturnTypes.d.ts","sourceRoot":"","sources":["../../lib/DBSchemaBuilder/getServerFunctionReturnTypes.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,4BAA4B,GAAI,cAAc,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"getServerFunctionReturnTypes.d.ts","sourceRoot":"","sources":["../../lib/DBSchemaBuilder/getServerFunctionReturnTypes.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,4BAA4B,GAAI,cAAc,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAwHrF,CAAC"}
|
|
@@ -13,264 +13,80 @@ const getServerFunctionReturnTypes = (instancePath) => {
|
|
|
13
13
|
const { fileNames, options } = ts.parseJsonConfigFileContent(config, ts.sys, (0, path_1.dirname)(configPath));
|
|
14
14
|
const program = ts.createProgram(fileNames, options);
|
|
15
15
|
const checker = program.getTypeChecker();
|
|
16
|
-
const
|
|
16
|
+
const sourceFile = program.getSourceFile(instancePath);
|
|
17
17
|
const result = new Map();
|
|
18
|
-
if (!
|
|
18
|
+
if (!sourceFile) {
|
|
19
19
|
throw new Error(`Source file not found: ${instancePath}`);
|
|
20
20
|
}
|
|
21
21
|
const globalBuiltins = (0, getGlobalBuiltinTypes_1.getGlobalBuiltinTypes)(instancePath, checker, program);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
current = current.expression;
|
|
50
|
-
}
|
|
51
|
-
else if (ts.isSatisfiesExpression(current)) {
|
|
52
|
-
current = current.expression;
|
|
53
|
-
}
|
|
54
|
-
else if (ts.isTypeAssertionExpression(current)) {
|
|
55
|
-
current = current.expression;
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return current;
|
|
62
|
-
};
|
|
63
|
-
/**
|
|
64
|
-
* Extract return type from a defineFunction call
|
|
65
|
-
*/
|
|
66
|
-
const extractFromDefineCall = (callExpr, propertyName) => {
|
|
67
|
-
const arg = callExpr.arguments[0];
|
|
68
|
-
if (!arg) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (!ts.isObjectLiteralExpression(arg)) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const runProp = arg.properties.find((x) => (ts.isPropertyAssignment(x) || ts.isMethodDeclaration(x)) && x.name.getText() === "run");
|
|
75
|
-
if (!runProp) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const runExpr = ts.isPropertyAssignment(runProp) ? runProp.initializer : runProp; // method declarations are already function-like
|
|
79
|
-
if (!ts.isFunctionLike(runExpr)) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const sig = checker.getSignatureFromDeclaration(runExpr);
|
|
83
|
-
if (!sig) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const returnType = checker.getReturnTypeOfSignature(sig);
|
|
87
|
-
const resolvedReturnType = (0, resolveTypeToStructure_1.resolveTypeToStructure)(globalBuiltins, propertyName, checker, returnType);
|
|
88
|
-
result.set(propertyName, resolvedReturnType);
|
|
89
|
-
};
|
|
90
|
-
/**
|
|
91
|
-
* Check if a call expression is a define function call
|
|
92
|
-
*/
|
|
93
|
-
const isDefineFunctionCall = (node) => {
|
|
94
|
-
if (!ts.isCallExpression(node))
|
|
95
|
-
return false;
|
|
96
|
-
const callee = node.expression;
|
|
97
|
-
if (ts.isIdentifier(callee)) {
|
|
98
|
-
const name = callee.getText();
|
|
99
|
-
const isDefine = name.toLowerCase().includes("define") && name.toLowerCase().includes("function");
|
|
100
|
-
return isDefine;
|
|
101
|
-
}
|
|
102
|
-
return false;
|
|
103
|
-
};
|
|
104
|
-
const extractFromAwaitExpression = (spreadExpr, depth) => {
|
|
105
|
-
const awaitedExpr = spreadExpr.expression;
|
|
106
|
-
if (ts.isCallExpression(awaitedExpr)) {
|
|
107
|
-
// Resolve the function being called and extract from its return
|
|
108
|
-
const calleeExpr = awaitedExpr.expression;
|
|
109
|
-
if (ts.isIdentifier(calleeExpr)) {
|
|
110
|
-
const symbol = checker.getSymbolAtLocation(calleeExpr);
|
|
111
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
112
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
113
|
-
const body = resolveFunctionBody(decl.initializer);
|
|
114
|
-
if (body) {
|
|
115
|
-
extractFromFunctionBody(body, depth + 2);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (decl && ts.isFunctionDeclaration(decl) && decl.body) {
|
|
119
|
-
extractFromFunctionBody(decl.body, depth + 2);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
/**
|
|
125
|
-
* Extract methods from an object literal that contains method definitions
|
|
126
|
-
*/
|
|
127
|
-
const extractMethodsFromObjectLiteral = (obj, depth = 0) => {
|
|
128
|
-
for (const prop of obj.properties) {
|
|
129
|
-
if (ts.isPropertyAssignment(prop)) {
|
|
130
|
-
const propName = prop.name.getText();
|
|
131
|
-
if (isDefineFunctionCall(prop.initializer) || ts.isCallExpression(prop.initializer)) {
|
|
132
|
-
extractFromDefineCall(prop.initializer, propName);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (ts.isSpreadAssignment(prop)) {
|
|
136
|
-
const spreadExpr = prop.expression;
|
|
137
|
-
if (ts.isIdentifier(spreadExpr)) {
|
|
138
|
-
const symbol = checker.getSymbolAtLocation(spreadExpr);
|
|
139
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
140
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
141
|
-
if (ts.isObjectLiteralExpression(decl.initializer)) {
|
|
142
|
-
extractMethodsFromObjectLiteral(decl.initializer, depth + 2);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
const init = unwrapExpression(decl.initializer);
|
|
146
|
-
if (ts.isAwaitExpression(init)) {
|
|
147
|
-
extractFromAwaitExpression(init, depth);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (ts.isObjectLiteralExpression(spreadExpr)) {
|
|
153
|
-
extractMethodsFromObjectLiteral(spreadExpr, depth + 2);
|
|
154
|
-
}
|
|
155
|
-
// Handle await expressions: ...await someAsyncFunction()
|
|
156
|
-
if (ts.isAwaitExpression(spreadExpr)) {
|
|
157
|
-
extractFromAwaitExpression(spreadExpr, depth);
|
|
22
|
+
if (sourceFile.isDeclarationFile) {
|
|
23
|
+
throw new Error(`Source file is a declaration file: ${instancePath}`);
|
|
24
|
+
}
|
|
25
|
+
ts.forEachChild(sourceFile, function visit(node) {
|
|
26
|
+
if (ts.isCallExpression(node) &&
|
|
27
|
+
ts.isIdentifier(node.expression) &&
|
|
28
|
+
node.expression.text === "prostgles") {
|
|
29
|
+
const arg = node.arguments[0];
|
|
30
|
+
if (!arg || !ts.isObjectLiteralExpression(arg))
|
|
31
|
+
return;
|
|
32
|
+
const fnProp = arg.properties.find((p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "functions");
|
|
33
|
+
if (!fnProp)
|
|
34
|
+
return;
|
|
35
|
+
const functionsExpr = fnProp.initializer;
|
|
36
|
+
const recordType = resolveToRecordType(functionsExpr);
|
|
37
|
+
if (!recordType)
|
|
38
|
+
return;
|
|
39
|
+
for (const prop of checker.getPropertiesOfType(recordType)) {
|
|
40
|
+
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration ?? prop.declarations[0]);
|
|
41
|
+
const runReturnType = getRunReturnType(propType);
|
|
42
|
+
/** Peel away any wrapping helper functions */
|
|
43
|
+
let finalRunReturnType = runReturnType;
|
|
44
|
+
while (finalRunReturnType &&
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
46
|
+
finalRunReturnType.symbol?.valueDeclaration &&
|
|
47
|
+
ts.isFunctionLike(finalRunReturnType.symbol.valueDeclaration)) {
|
|
48
|
+
finalRunReturnType = unwrapMaybePromise(checker.getReturnTypeOfSignature(finalRunReturnType.getCallSignatures()[0]));
|
|
158
49
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const symbol = checker.getShorthandAssignmentValueSymbol(prop);
|
|
163
|
-
const decl = symbol?.valueDeclaration;
|
|
164
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
165
|
-
if (isDefineFunctionCall(decl.initializer)) {
|
|
166
|
-
extractFromDefineCall(decl.initializer, propName);
|
|
167
|
-
}
|
|
50
|
+
if (finalRunReturnType) {
|
|
51
|
+
const resolvedReturnType = (0, resolveTypeToStructure_1.resolveTypeToStructure)(globalBuiltins, prop.getName(), checker, finalRunReturnType);
|
|
52
|
+
result.set(prop.getName(), resolvedReturnType);
|
|
168
53
|
}
|
|
169
54
|
}
|
|
170
55
|
}
|
|
171
|
-
};
|
|
172
|
-
/**
|
|
173
|
-
* Find return statements in a function body
|
|
174
|
-
*/
|
|
175
|
-
const findReturnStatements = (node) => {
|
|
176
|
-
const returns = [];
|
|
177
|
-
const visit = (n) => {
|
|
178
|
-
if (ts.isReturnStatement(n)) {
|
|
179
|
-
returns.push(n);
|
|
180
|
-
}
|
|
181
|
-
if (!ts.isFunctionLike(n) || n === node) {
|
|
182
|
-
ts.forEachChild(n, visit);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
56
|
ts.forEachChild(node, visit);
|
|
186
|
-
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* Extract from function body
|
|
190
|
-
*/
|
|
191
|
-
const extractFromFunctionBody = (body, depth = 0) => {
|
|
192
|
-
// Handle concise body: () => ({ ... })
|
|
193
|
-
if (!ts.isBlock(body)) {
|
|
194
|
-
const unwrapped = unwrapExpression(body);
|
|
195
|
-
if (ts.isObjectLiteralExpression(unwrapped)) {
|
|
196
|
-
extractMethodsFromObjectLiteral(unwrapped, depth + 1);
|
|
197
|
-
}
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
const returnStatements = findReturnStatements(body);
|
|
201
|
-
for (let i = 0; i < returnStatements.length; i++) {
|
|
202
|
-
const ret = returnStatements[i];
|
|
203
|
-
if (!ret?.expression) {
|
|
204
|
-
continue;
|
|
205
|
-
}
|
|
206
|
-
// Unwrap any type assertions
|
|
207
|
-
const unwrapped = unwrapExpression(ret.expression);
|
|
208
|
-
// Direct object literal return
|
|
209
|
-
if (ts.isObjectLiteralExpression(unwrapped)) {
|
|
210
|
-
extractMethodsFromObjectLiteral(unwrapped, depth + 2);
|
|
211
|
-
}
|
|
212
|
-
// Return of a variable: return result
|
|
213
|
-
if (ts.isIdentifier(unwrapped)) {
|
|
214
|
-
const symbol = checker.getSymbolAtLocation(unwrapped);
|
|
215
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
216
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
217
|
-
if (ts.isObjectLiteralExpression(decl.initializer)) {
|
|
218
|
-
extractMethodsFromObjectLiteral(decl.initializer, depth + 2);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
const resolveFunctionBody = (expr) => {
|
|
225
|
-
// Arrow function (including async)
|
|
226
|
-
if (ts.isArrowFunction(expr)) {
|
|
227
|
-
return expr.body;
|
|
228
|
-
}
|
|
229
|
-
// Function expression
|
|
230
|
-
if (ts.isFunctionExpression(expr)) {
|
|
231
|
-
return expr.body;
|
|
232
|
-
}
|
|
233
|
-
// Identifier referencing a function
|
|
234
|
-
if (ts.isIdentifier(expr)) {
|
|
235
|
-
const symbol = checker.getSymbolAtLocation(expr);
|
|
236
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
237
|
-
if (decl) {
|
|
238
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
239
|
-
return resolveFunctionBody(decl.initializer);
|
|
240
|
-
}
|
|
241
|
-
if (ts.isFunctionDeclaration(decl) && decl.body) {
|
|
242
|
-
return decl.body;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return undefined;
|
|
247
|
-
};
|
|
248
|
-
const visit = (n) => {
|
|
249
|
-
// Look for: functions: someExpression
|
|
250
|
-
if (ts.isPropertyAssignment(n) && n.name.getText() === "functions") {
|
|
251
|
-
const body = resolveFunctionBody(n.initializer);
|
|
252
|
-
if (body) {
|
|
253
|
-
extractFromFunctionBody(body);
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
console.warn("Could not resolve functions property initializer:", n.initializer.getText());
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
// Look for: { functions } (shorthand)
|
|
260
|
-
if (ts.isShorthandPropertyAssignment(n) && n.name.getText() === "functions") {
|
|
261
|
-
const symbol = checker.getShorthandAssignmentValueSymbol(n);
|
|
262
|
-
const decl = symbol?.valueDeclaration;
|
|
263
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
264
|
-
const body = resolveFunctionBody(decl.initializer);
|
|
265
|
-
if (body) {
|
|
266
|
-
extractFromFunctionBody(body);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
ts.forEachChild(n, visit);
|
|
271
|
-
};
|
|
272
|
-
visit(sf);
|
|
57
|
+
});
|
|
273
58
|
return result;
|
|
59
|
+
/** Resolve any expression to the final `Record<string, ServerFunctionDefinition>` */
|
|
60
|
+
function resolveToRecordType(expr) {
|
|
61
|
+
let t = checker.getTypeAtLocation(expr);
|
|
62
|
+
// If it's a function type (ServerFunctionDefinitions)
|
|
63
|
+
const [sig] = t.getCallSignatures();
|
|
64
|
+
if (sig) {
|
|
65
|
+
t = unwrapMaybePromise(checker.getReturnTypeOfSignature(sig));
|
|
66
|
+
}
|
|
67
|
+
// Strip undefined/null
|
|
68
|
+
t = checker.getNonNullableType(t);
|
|
69
|
+
return checker.getApparentType(t);
|
|
70
|
+
}
|
|
71
|
+
/** Extract `run` return type from ServerFunctionDefinition */
|
|
72
|
+
function getRunReturnType(fnDefType) {
|
|
73
|
+
const runSymbol = checker.getPropertyOfType(fnDefType, "run");
|
|
74
|
+
if (!runSymbol)
|
|
75
|
+
return;
|
|
76
|
+
let runType = checker.getTypeOfSymbolAtLocation(runSymbol, runSymbol.valueDeclaration ?? runSymbol.declarations[0]);
|
|
77
|
+
// run is usually `undefined | ((...) => MaybePromise<T>)`
|
|
78
|
+
runType = checker.getNonNullableType(runType);
|
|
79
|
+
/** Follow any wrapping function calls */
|
|
80
|
+
const [sig] = runType.getCallSignatures();
|
|
81
|
+
if (!sig)
|
|
82
|
+
return;
|
|
83
|
+
return unwrapMaybePromise(checker.getReturnTypeOfSignature(sig));
|
|
84
|
+
}
|
|
85
|
+
/** Unwrap `MaybePromise<T>` and `Promise<T>` */
|
|
86
|
+
function unwrapMaybePromise(type) {
|
|
87
|
+
const awaited = checker.getAwaitedType(type);
|
|
88
|
+
return awaited ?? type;
|
|
89
|
+
}
|
|
274
90
|
};
|
|
275
91
|
exports.getServerFunctionReturnTypes = getServerFunctionReturnTypes;
|
|
276
92
|
//# sourceMappingURL=getServerFunctionReturnTypes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getServerFunctionReturnTypes.js","sourceRoot":"","sources":["../../lib/DBSchemaBuilder/getServerFunctionReturnTypes.ts"],"names":[],"mappings":";;;AAAA,iCAAiC;AACjC,+BAA+B;AAC/B,qEAAkE;AAClE,mEAAgE;AAEzD,MAAM,4BAA4B,GAAG,CAAC,YAAoB,EAAuB,EAAE;IACxF,MAAM,UAAU,GAAG,EAAE,CAAC,cAAc,CAAC,IAAA,cAAO,EAAC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAE5D,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,0BAA0B,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,IAAA,cAAO,EAAC,UAAU,CAAC,CAAC,CAAC;IAElG,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IACzC,MAAM,
|
|
1
|
+
{"version":3,"file":"getServerFunctionReturnTypes.js","sourceRoot":"","sources":["../../lib/DBSchemaBuilder/getServerFunctionReturnTypes.ts"],"names":[],"mappings":";;;AAAA,iCAAiC;AACjC,+BAA+B;AAC/B,qEAAkE;AAClE,mEAAgE;AAEzD,MAAM,4BAA4B,GAAG,CAAC,YAAoB,EAAuB,EAAE;IACxF,MAAM,UAAU,GAAG,EAAE,CAAC,cAAc,CAAC,IAAA,cAAO,EAAC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAE5D,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,0BAA0B,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,IAAA,cAAO,EAAC,UAAU,CAAC,CAAC,CAAC;IAElG,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,cAAc,GAAG,IAAA,6CAAqB,EAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAE7E,IAAI,UAAU,CAAC,iBAAiB,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,sCAAsC,YAAY,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,SAAS,KAAK,CAAC,IAAI;QAC7C,IACE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACzB,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,WAAW,EACpC,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,yBAAyB,CAAC,GAAG,CAAC;gBAAE,OAAO;YAEvD,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAChC,CAAC,CAAC,EAA8B,EAAE,CAChC,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,CACvF,CAAC;YACF,IAAI,CAAC,MAAM;gBAAE,OAAO;YAEpB,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC;YACzC,MAAM,UAAU,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;YAEtD,IAAI,CAAC,UAAU;gBAAE,OAAO;YAExB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,yBAAyB,CAChD,IAAI,EACJ,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,YAAa,CAAC,CAAC,CAAE,CAChD,CAAC;gBACF,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAEjD,8CAA8C;gBAC9C,IAAI,kBAAkB,GAAG,aAAa,CAAC;gBACvC,OACE,kBAAkB;oBAClB,uEAAuE;oBACvE,kBAAkB,CAAC,MAAM,EAAE,gBAAgB;oBAC3C,EAAE,CAAC,cAAc,CAAC,kBAAkB,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAC7D,CAAC;oBACD,kBAAkB,GAAG,kBAAkB,CACrC,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAE,CAAC,CAC7E,CAAC;gBACJ,CAAC;gBAED,IAAI,kBAAkB,EAAE,CAAC;oBACvB,MAAM,kBAAkB,GAAG,IAAA,+CAAsB,EAC/C,cAAc,EACd,IAAI,CAAC,OAAO,EAAE,EACd,OAAO,EACP,kBAAkB,CACnB,CAAC;oBACF,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;IAEd,qFAAqF;IACrF,SAAS,mBAAmB,CAAC,IAAmB;QAC9C,IAAI,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAExC,sDAAsD;QACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,CAAC;QACpC,IAAI,GAAG,EAAE,CAAC;YACR,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,uBAAuB;QACvB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,8DAA8D;IAC9D,SAAS,gBAAgB,CAAC,SAAkB;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,IAAI,OAAO,GAAG,OAAO,CAAC,yBAAyB,CAC7C,SAAS,EACT,SAAS,CAAC,gBAAgB,IAAI,SAAS,CAAC,YAAa,CAAC,CAAC,CAAE,CAC1D,CAAC;QAEF,0DAA0D;QAC1D,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAE9C,yCAAyC;QAEzC,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC1C,IAAI,CAAC,GAAG;YAAE,OAAO;QAEjB,OAAO,kBAAkB,CAAC,OAAO,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,gDAAgD;IAChD,SAAS,kBAAkB,CAAC,IAAa;QACvC,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC7C,OAAO,OAAO,IAAI,IAAI,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAxHW,QAAA,4BAA4B,gCAwHvC"}
|
|
@@ -22,13 +22,43 @@ export type ServerFunctionDefinitions<S = void, SUser extends SessionUser = Sess
|
|
|
22
22
|
* params will be undefined on first run to generate the definitions
|
|
23
23
|
*/
|
|
24
24
|
params: undefined | PublishParams<S, SUser>) => MaybePromise<Record<string, ServerFunctionDefinition>>;
|
|
25
|
-
export declare const createServerFunctionWithContext: <
|
|
25
|
+
export declare const createServerFunctionWithContext: <Context>(
|
|
26
26
|
/**
|
|
27
27
|
* undefined if not allowed
|
|
28
28
|
*/
|
|
29
|
-
context:
|
|
30
|
-
input?:
|
|
29
|
+
context: Context | undefined) => <Input extends Record<string, JSONB.FieldType> | undefined, Run extends (args: JSONBObjectTypeIfDefined<Input>, context: Context) => MaybePromise<any>>(args: {
|
|
30
|
+
input?: Input;
|
|
31
31
|
description?: string;
|
|
32
|
-
run:
|
|
33
|
-
}) =>
|
|
32
|
+
run: Run;
|
|
33
|
+
}) => {
|
|
34
|
+
run: ((validatedArgs: any) => Run) | undefined;
|
|
35
|
+
input?: Input;
|
|
36
|
+
description?: string;
|
|
37
|
+
};
|
|
38
|
+
type InputOf<T> = T extends {
|
|
39
|
+
input?: infer I;
|
|
40
|
+
} ? I : undefined;
|
|
41
|
+
type SafeInput<I> = I extends Record<string, JSONB.FieldType> ? I : undefined;
|
|
42
|
+
type ServerFunctionArgsFrom<Context, Def> = {
|
|
43
|
+
input?: InputOf<Def>;
|
|
44
|
+
description?: string;
|
|
45
|
+
run: (args: JSONBObjectTypeIfDefined<SafeInput<InputOf<Def>>>, context: Context) => MaybePromise<any>;
|
|
46
|
+
};
|
|
47
|
+
type ServerFunctionBlock<Context, Defs> = {
|
|
48
|
+
[K in keyof Defs]: ServerFunctionArgsFrom<Context, Defs[K]>;
|
|
49
|
+
};
|
|
50
|
+
type WrappedDef<Context, Def> = Def extends ({
|
|
51
|
+
input?: infer I;
|
|
52
|
+
description?: infer D;
|
|
53
|
+
run: (a: any, c: Context) => infer R;
|
|
54
|
+
}) ? {
|
|
55
|
+
input?: SafeInput<I>;
|
|
56
|
+
description?: D extends string ? D : string | undefined;
|
|
57
|
+
run: undefined | ((a: any) => R);
|
|
58
|
+
} : never;
|
|
59
|
+
type WrappedBlock<Context, Defs> = {
|
|
60
|
+
[K in keyof Defs]: WrappedDef<Context, Defs[K]>;
|
|
61
|
+
};
|
|
62
|
+
export declare const createServerFunctionBlockWithContext: <Context>(context: Context | undefined) => <const Defs extends Record<string, any>>(defs: Defs & ServerFunctionBlock<Context, Defs>) => WrappedBlock<Context, Defs>;
|
|
63
|
+
export {};
|
|
34
64
|
//# sourceMappingURL=defineServerFunction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defineServerFunction.d.ts","sourceRoot":"","sources":["../../lib/PublishParser/defineServerFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,KAAK,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;CACzF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,SAAS,GAAG,SAAS,EACtE,MAAM;IACN,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;CACtF,KAAwB,wBAAwB,CAAC;AAElD,MAAM,MAAM,yBAAyB,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,SAAS,WAAW,GAAG,WAAW,IAAI;AACzF;;GAEG;AACH,MAAM,EAAE,SAAS,GAAG,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,KACxC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC;AAE5D,eAAO,MAAM,+BAA+B,GAAI,
|
|
1
|
+
{"version":3,"file":"defineServerFunction.d.ts","sourceRoot":"","sources":["../../lib/PublishParser/defineServerFunction.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createServerFunctionWithContext = exports.defineServerFunction = void 0;
|
|
3
|
+
exports.createServerFunctionBlockWithContext = exports.createServerFunctionWithContext = exports.defineServerFunction = void 0;
|
|
4
4
|
const defineServerFunction = (args) => args;
|
|
5
5
|
exports.defineServerFunction = defineServerFunction;
|
|
6
6
|
const createServerFunctionWithContext = (
|
|
@@ -17,4 +17,18 @@ context) => {
|
|
|
17
17
|
});
|
|
18
18
|
};
|
|
19
19
|
exports.createServerFunctionWithContext = createServerFunctionWithContext;
|
|
20
|
+
const createServerFunctionBlockWithContext = (context) => {
|
|
21
|
+
return (defs) => {
|
|
22
|
+
const wrapped = {};
|
|
23
|
+
for (const key in defs) {
|
|
24
|
+
const def = defs[key];
|
|
25
|
+
wrapped[key] = {
|
|
26
|
+
...def,
|
|
27
|
+
run: context === undefined ? undefined : (args) => def.run(args, context),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return wrapped;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
exports.createServerFunctionBlockWithContext = createServerFunctionBlockWithContext;
|
|
20
34
|
//# sourceMappingURL=defineServerFunction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defineServerFunction.js","sourceRoot":"","sources":["../../lib/PublishParser/defineServerFunction.ts"],"names":[],"mappings":";;;AAaO,MAAM,oBAAoB,GAAG,CAElC,IAOD,EAAE,EAAE,CAAC,IAA2C,CAAC;AATrC,QAAA,oBAAoB,wBASiB;AAS3C,MAAM,+BAA+B,GAAG;AAC7C;;GAEG;AACH,
|
|
1
|
+
{"version":3,"file":"defineServerFunction.js","sourceRoot":"","sources":["../../lib/PublishParser/defineServerFunction.ts"],"names":[],"mappings":";;;AAaO,MAAM,oBAAoB,GAAG,CAElC,IAOD,EAAE,EAAE,CAAC,IAA2C,CAAC;AATrC,QAAA,oBAAoB,wBASiB;AAS3C,MAAM,+BAA+B,GAAG;AAC7C;;GAEG;AACH,OAA4B,EAC5B,EAAE;IACF,OAAO,CAGL,IAID,EAAE,EAAE,CACH,CAAC;QACC,GAAG,IAAI;QACP,GAAG,EACD,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAClC,CAAC,aAAkB,EAAE,EAAE;YACrB,iEAAiE;YACjE,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAQ,CAAC;QACjD,CAAC,CACF;KACJ,CAAoC,CAAC;AAC1C,CAAC,CAAC;AAxBW,QAAA,+BAA+B,mCAwB1C;AAuCK,MAAM,oCAAoC,GAAG,CAAU,OAA4B,EAAE,EAAE;IAC5F,OAAO,CACL,IAA+C,EAClB,EAAE;QAC/B,MAAM,OAAO,GAAG,EAAiC,CAAC;QAElD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,GAAG;gBACb,GAAG,GAAG;gBACN,GAAG,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;aAC/E,CAAC;QACJ,CAAC;QAED,OAAO,OAA0D,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC,CAAC;AAhBW,QAAA,oCAAoC,wCAgB/C"}
|
|
@@ -12,311 +12,115 @@ export const getServerFunctionReturnTypes = (instancePath: string): Map<string,
|
|
|
12
12
|
|
|
13
13
|
const program = ts.createProgram(fileNames, options);
|
|
14
14
|
const checker = program.getTypeChecker();
|
|
15
|
-
const
|
|
16
|
-
const result = new Map();
|
|
15
|
+
const sourceFile = program.getSourceFile(instancePath);
|
|
16
|
+
const result = new Map<string, string>();
|
|
17
17
|
|
|
18
|
-
if (!
|
|
18
|
+
if (!sourceFile) {
|
|
19
19
|
throw new Error(`Source file not found: ${instancePath}`);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const globalBuiltins = getGlobalBuiltinTypes(instancePath, checker, program);
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const aliased = checker.getAliasedSymbol(symbol);
|
|
28
|
-
return aliased;
|
|
29
|
-
}
|
|
30
|
-
return symbol;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const getDeclarationFromSymbol = (symbol: ts.Symbol | undefined) => {
|
|
34
|
-
const actualSymbol = getActualSymbol(symbol);
|
|
35
|
-
if (!actualSymbol) return undefined;
|
|
36
|
-
return actualSymbol.valueDeclaration ?? actualSymbol.declarations?.[0];
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Unwrap AsExpression, ParenthesizedExpression, etc. to get the actual expression
|
|
41
|
-
*/
|
|
42
|
-
const unwrapExpression = (expr: ts.Expression) => {
|
|
43
|
-
let current = expr;
|
|
44
|
-
let iterations = 0;
|
|
45
|
-
while (iterations < 10) {
|
|
46
|
-
iterations++;
|
|
47
|
-
if (ts.isAsExpression(current)) {
|
|
48
|
-
current = current.expression;
|
|
49
|
-
} else if (ts.isParenthesizedExpression(current)) {
|
|
50
|
-
current = current.expression;
|
|
51
|
-
} else if (ts.isSatisfiesExpression(current)) {
|
|
52
|
-
current = current.expression;
|
|
53
|
-
} else if (ts.isTypeAssertionExpression(current)) {
|
|
54
|
-
current = current.expression;
|
|
55
|
-
} else {
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return current;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Extract return type from a defineFunction call
|
|
64
|
-
*/
|
|
65
|
-
const extractFromDefineCall = (callExpr: ts.CallExpression, propertyName: string) => {
|
|
66
|
-
const arg = callExpr.arguments[0];
|
|
67
|
-
if (!arg) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!ts.isObjectLiteralExpression(arg)) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const runProp = arg.properties.find(
|
|
76
|
-
(x): x is ts.PropertyAssignment | ts.MethodDeclaration =>
|
|
77
|
-
(ts.isPropertyAssignment(x) || ts.isMethodDeclaration(x)) && x.name.getText() === "run",
|
|
78
|
-
);
|
|
79
|
-
if (!runProp) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const runExpr = ts.isPropertyAssignment(runProp) ? runProp.initializer : runProp; // method declarations are already function-like
|
|
84
|
-
|
|
85
|
-
if (!ts.isFunctionLike(runExpr)) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const sig = checker.getSignatureFromDeclaration(runExpr);
|
|
90
|
-
if (!sig) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const returnType = checker.getReturnTypeOfSignature(sig);
|
|
95
|
-
const resolvedReturnType = resolveTypeToStructure(
|
|
96
|
-
globalBuiltins,
|
|
97
|
-
propertyName,
|
|
98
|
-
checker,
|
|
99
|
-
returnType,
|
|
100
|
-
);
|
|
101
|
-
result.set(propertyName, resolvedReturnType);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Check if a call expression is a define function call
|
|
106
|
-
*/
|
|
107
|
-
const isDefineFunctionCall = (node: ts.Node): node is ts.CallExpression => {
|
|
108
|
-
if (!ts.isCallExpression(node)) return false;
|
|
109
|
-
const callee = node.expression;
|
|
110
|
-
if (ts.isIdentifier(callee)) {
|
|
111
|
-
const name = callee.getText();
|
|
112
|
-
const isDefine =
|
|
113
|
-
name.toLowerCase().includes("define") && name.toLowerCase().includes("function");
|
|
114
|
-
|
|
115
|
-
return isDefine;
|
|
116
|
-
}
|
|
117
|
-
return false;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const extractFromAwaitExpression = (spreadExpr: ts.AwaitExpression, depth: number) => {
|
|
121
|
-
const awaitedExpr = spreadExpr.expression;
|
|
122
|
-
|
|
123
|
-
if (ts.isCallExpression(awaitedExpr)) {
|
|
124
|
-
// Resolve the function being called and extract from its return
|
|
125
|
-
const calleeExpr = awaitedExpr.expression;
|
|
126
|
-
if (ts.isIdentifier(calleeExpr)) {
|
|
127
|
-
const symbol = checker.getSymbolAtLocation(calleeExpr);
|
|
128
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
129
|
-
|
|
130
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
131
|
-
const body = resolveFunctionBody(decl.initializer);
|
|
132
|
-
if (body) {
|
|
133
|
-
extractFromFunctionBody(body, depth + 2);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (decl && ts.isFunctionDeclaration(decl) && decl.body) {
|
|
137
|
-
extractFromFunctionBody(decl.body, depth + 2);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Extract methods from an object literal that contains method definitions
|
|
145
|
-
*/
|
|
146
|
-
const extractMethodsFromObjectLiteral = (obj: ts.ObjectLiteralExpression, depth = 0) => {
|
|
147
|
-
for (const prop of obj.properties) {
|
|
148
|
-
if (ts.isPropertyAssignment(prop)) {
|
|
149
|
-
const propName = prop.name.getText();
|
|
150
|
-
|
|
151
|
-
if (isDefineFunctionCall(prop.initializer) || ts.isCallExpression(prop.initializer)) {
|
|
152
|
-
extractFromDefineCall(prop.initializer, propName);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (ts.isSpreadAssignment(prop)) {
|
|
157
|
-
const spreadExpr = prop.expression;
|
|
158
|
-
|
|
159
|
-
if (ts.isIdentifier(spreadExpr)) {
|
|
160
|
-
const symbol = checker.getSymbolAtLocation(spreadExpr);
|
|
161
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
162
|
-
|
|
163
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
164
|
-
if (ts.isObjectLiteralExpression(decl.initializer)) {
|
|
165
|
-
extractMethodsFromObjectLiteral(decl.initializer, depth + 2);
|
|
166
|
-
} else {
|
|
167
|
-
const init = unwrapExpression(decl.initializer);
|
|
168
|
-
if (ts.isAwaitExpression(init)) {
|
|
169
|
-
extractFromAwaitExpression(init, depth);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (ts.isObjectLiteralExpression(spreadExpr)) {
|
|
176
|
-
extractMethodsFromObjectLiteral(spreadExpr, depth + 2);
|
|
177
|
-
}
|
|
24
|
+
if (sourceFile.isDeclarationFile) {
|
|
25
|
+
throw new Error(`Source file is a declaration file: ${instancePath}`);
|
|
26
|
+
}
|
|
178
27
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
28
|
+
ts.forEachChild(sourceFile, function visit(node) {
|
|
29
|
+
if (
|
|
30
|
+
ts.isCallExpression(node) &&
|
|
31
|
+
ts.isIdentifier(node.expression) &&
|
|
32
|
+
node.expression.text === "prostgles"
|
|
33
|
+
) {
|
|
34
|
+
const arg = node.arguments[0];
|
|
35
|
+
if (!arg || !ts.isObjectLiteralExpression(arg)) return;
|
|
36
|
+
|
|
37
|
+
const fnProp = arg.properties.find(
|
|
38
|
+
(p): p is ts.PropertyAssignment =>
|
|
39
|
+
ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "functions",
|
|
40
|
+
);
|
|
41
|
+
if (!fnProp) return;
|
|
42
|
+
|
|
43
|
+
const functionsExpr = fnProp.initializer;
|
|
44
|
+
const recordType = resolveToRecordType(functionsExpr);
|
|
45
|
+
|
|
46
|
+
if (!recordType) return;
|
|
47
|
+
|
|
48
|
+
for (const prop of checker.getPropertiesOfType(recordType)) {
|
|
49
|
+
const propType = checker.getTypeOfSymbolAtLocation(
|
|
50
|
+
prop,
|
|
51
|
+
prop.valueDeclaration ?? prop.declarations![0]!,
|
|
52
|
+
);
|
|
53
|
+
const runReturnType = getRunReturnType(propType);
|
|
54
|
+
|
|
55
|
+
/** Peel away any wrapping helper functions */
|
|
56
|
+
let finalRunReturnType = runReturnType;
|
|
57
|
+
while (
|
|
58
|
+
finalRunReturnType &&
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
60
|
+
finalRunReturnType.symbol?.valueDeclaration &&
|
|
61
|
+
ts.isFunctionLike(finalRunReturnType.symbol.valueDeclaration)
|
|
62
|
+
) {
|
|
63
|
+
finalRunReturnType = unwrapMaybePromise(
|
|
64
|
+
checker.getReturnTypeOfSignature(finalRunReturnType.getCallSignatures()[0]!),
|
|
65
|
+
);
|
|
182
66
|
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (ts.isShorthandPropertyAssignment(prop)) {
|
|
186
|
-
const propName = prop.name.getText();
|
|
187
67
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
68
|
+
if (finalRunReturnType) {
|
|
69
|
+
const resolvedReturnType = resolveTypeToStructure(
|
|
70
|
+
globalBuiltins,
|
|
71
|
+
prop.getName(),
|
|
72
|
+
checker,
|
|
73
|
+
finalRunReturnType,
|
|
74
|
+
);
|
|
75
|
+
result.set(prop.getName(), resolvedReturnType);
|
|
194
76
|
}
|
|
195
77
|
}
|
|
196
78
|
}
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Find return statements in a function body
|
|
201
|
-
*/
|
|
202
|
-
const findReturnStatements = (node: ts.Node) => {
|
|
203
|
-
const returns: ts.ReturnStatement[] = [];
|
|
204
|
-
|
|
205
|
-
const visit = (n: ts.Node) => {
|
|
206
|
-
if (ts.isReturnStatement(n)) {
|
|
207
|
-
returns.push(n);
|
|
208
|
-
}
|
|
209
|
-
if (!ts.isFunctionLike(n) || n === node) {
|
|
210
|
-
ts.forEachChild(n, visit);
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
79
|
|
|
214
80
|
ts.forEachChild(node, visit);
|
|
215
|
-
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Extract from function body
|
|
220
|
-
*/
|
|
221
|
-
const extractFromFunctionBody = (body: ts.FunctionBody | ts.ConciseBody, depth = 0) => {
|
|
222
|
-
// Handle concise body: () => ({ ... })
|
|
223
|
-
if (!ts.isBlock(body)) {
|
|
224
|
-
const unwrapped = unwrapExpression(body);
|
|
225
|
-
if (ts.isObjectLiteralExpression(unwrapped)) {
|
|
226
|
-
extractMethodsFromObjectLiteral(unwrapped, depth + 1);
|
|
227
|
-
}
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
81
|
+
});
|
|
230
82
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
for (let i = 0; i < returnStatements.length; i++) {
|
|
234
|
-
const ret = returnStatements[i];
|
|
235
|
-
|
|
236
|
-
if (!ret?.expression) {
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Unwrap any type assertions
|
|
241
|
-
const unwrapped = unwrapExpression(ret.expression);
|
|
242
|
-
|
|
243
|
-
// Direct object literal return
|
|
244
|
-
if (ts.isObjectLiteralExpression(unwrapped)) {
|
|
245
|
-
extractMethodsFromObjectLiteral(unwrapped, depth + 2);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Return of a variable: return result
|
|
249
|
-
if (ts.isIdentifier(unwrapped)) {
|
|
250
|
-
const symbol = checker.getSymbolAtLocation(unwrapped);
|
|
251
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
252
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
253
|
-
if (ts.isObjectLiteralExpression(decl.initializer)) {
|
|
254
|
-
extractMethodsFromObjectLiteral(decl.initializer, depth + 2);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
};
|
|
83
|
+
return result;
|
|
260
84
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return expr.body;
|
|
265
|
-
}
|
|
85
|
+
/** Resolve any expression to the final `Record<string, ServerFunctionDefinition>` */
|
|
86
|
+
function resolveToRecordType(expr: ts.Expression): ts.Type | undefined {
|
|
87
|
+
let t = checker.getTypeAtLocation(expr);
|
|
266
88
|
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
89
|
+
// If it's a function type (ServerFunctionDefinitions)
|
|
90
|
+
const [sig] = t.getCallSignatures();
|
|
91
|
+
if (sig) {
|
|
92
|
+
t = unwrapMaybePromise(checker.getReturnTypeOfSignature(sig));
|
|
270
93
|
}
|
|
271
94
|
|
|
272
|
-
//
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const decl = getDeclarationFromSymbol(symbol);
|
|
277
|
-
|
|
278
|
-
if (decl) {
|
|
279
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
280
|
-
return resolveFunctionBody(decl.initializer);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (ts.isFunctionDeclaration(decl) && decl.body) {
|
|
284
|
-
return decl.body;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
95
|
+
// Strip undefined/null
|
|
96
|
+
t = checker.getNonNullableType(t);
|
|
97
|
+
return checker.getApparentType(t);
|
|
98
|
+
}
|
|
288
99
|
|
|
289
|
-
|
|
290
|
-
|
|
100
|
+
/** Extract `run` return type from ServerFunctionDefinition */
|
|
101
|
+
function getRunReturnType(fnDefType: ts.Type) {
|
|
102
|
+
const runSymbol = checker.getPropertyOfType(fnDefType, "run");
|
|
103
|
+
if (!runSymbol) return;
|
|
291
104
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (body) {
|
|
297
|
-
extractFromFunctionBody(body);
|
|
298
|
-
} else {
|
|
299
|
-
console.warn("Could not resolve functions property initializer:", n.initializer.getText());
|
|
300
|
-
}
|
|
301
|
-
}
|
|
105
|
+
let runType = checker.getTypeOfSymbolAtLocation(
|
|
106
|
+
runSymbol,
|
|
107
|
+
runSymbol.valueDeclaration ?? runSymbol.declarations![0]!,
|
|
108
|
+
);
|
|
302
109
|
|
|
303
|
-
//
|
|
304
|
-
|
|
305
|
-
const symbol = checker.getShorthandAssignmentValueSymbol(n);
|
|
306
|
-
const decl = symbol?.valueDeclaration;
|
|
110
|
+
// run is usually `undefined | ((...) => MaybePromise<T>)`
|
|
111
|
+
runType = checker.getNonNullableType(runType);
|
|
307
112
|
|
|
308
|
-
|
|
309
|
-
const body = resolveFunctionBody(decl.initializer);
|
|
310
|
-
if (body) {
|
|
311
|
-
extractFromFunctionBody(body);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
113
|
+
/** Follow any wrapping function calls */
|
|
315
114
|
|
|
316
|
-
|
|
317
|
-
|
|
115
|
+
const [sig] = runType.getCallSignatures();
|
|
116
|
+
if (!sig) return;
|
|
318
117
|
|
|
319
|
-
|
|
118
|
+
return unwrapMaybePromise(checker.getReturnTypeOfSignature(sig));
|
|
119
|
+
}
|
|
320
120
|
|
|
321
|
-
|
|
121
|
+
/** Unwrap `MaybePromise<T>` and `Promise<T>` */
|
|
122
|
+
function unwrapMaybePromise(type: ts.Type) {
|
|
123
|
+
const awaited = checker.getAwaitedType(type);
|
|
124
|
+
return awaited ?? type;
|
|
125
|
+
}
|
|
322
126
|
};
|
|
@@ -29,16 +29,19 @@ export type ServerFunctionDefinitions<S = void, SUser extends SessionUser = Sess
|
|
|
29
29
|
params: undefined | PublishParams<S, SUser>,
|
|
30
30
|
) => MaybePromise<Record<string, ServerFunctionDefinition>>;
|
|
31
31
|
|
|
32
|
-
export const createServerFunctionWithContext = <
|
|
32
|
+
export const createServerFunctionWithContext = <Context>(
|
|
33
33
|
/**
|
|
34
34
|
* undefined if not allowed
|
|
35
35
|
*/
|
|
36
|
-
context:
|
|
36
|
+
context: Context | undefined,
|
|
37
37
|
) => {
|
|
38
|
-
return <
|
|
39
|
-
|
|
38
|
+
return <
|
|
39
|
+
Input extends Record<string, JSONB.FieldType> | undefined,
|
|
40
|
+
Run extends (args: JSONBObjectTypeIfDefined<Input>, context: Context) => MaybePromise<any>,
|
|
41
|
+
>(args: {
|
|
42
|
+
input?: Input;
|
|
40
43
|
description?: string;
|
|
41
|
-
run:
|
|
44
|
+
run: Run;
|
|
42
45
|
}) =>
|
|
43
46
|
({
|
|
44
47
|
...args,
|
|
@@ -46,8 +49,63 @@ export const createServerFunctionWithContext = <C>(
|
|
|
46
49
|
context === undefined ? undefined : (
|
|
47
50
|
(validatedArgs: any) => {
|
|
48
51
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
49
|
-
return args.run(validatedArgs, context);
|
|
52
|
+
return args.run(validatedArgs, context) as Run;
|
|
50
53
|
}
|
|
51
54
|
),
|
|
52
|
-
})
|
|
55
|
+
}) satisfies ServerFunctionDefinition;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
type InputOf<T> = T extends { input?: infer I } ? I : undefined;
|
|
59
|
+
|
|
60
|
+
// if inference fails or is invalid → fall back to undefined
|
|
61
|
+
type SafeInput<I> = I extends Record<string, JSONB.FieldType> ? I : undefined;
|
|
62
|
+
|
|
63
|
+
type ServerFunctionArgsFrom<Context, Def> = {
|
|
64
|
+
input?: InputOf<Def>;
|
|
65
|
+
description?: string;
|
|
66
|
+
run: (
|
|
67
|
+
args: JSONBObjectTypeIfDefined<SafeInput<InputOf<Def>>>,
|
|
68
|
+
context: Context,
|
|
69
|
+
) => MaybePromise<any>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type ServerFunctionBlock<Context, Defs> = {
|
|
73
|
+
[K in keyof Defs]: ServerFunctionArgsFrom<Context, Defs[K]>;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
type WrappedDef<Context, Def> =
|
|
77
|
+
Def extends (
|
|
78
|
+
{
|
|
79
|
+
input?: infer I;
|
|
80
|
+
description?: infer D;
|
|
81
|
+
run: (a: any, c: Context) => infer R;
|
|
82
|
+
}
|
|
83
|
+
) ?
|
|
84
|
+
{
|
|
85
|
+
input?: SafeInput<I>;
|
|
86
|
+
description?: D extends string ? D : string | undefined;
|
|
87
|
+
run: undefined | ((a: any) => R); // keep return type, widen args
|
|
88
|
+
}
|
|
89
|
+
: never;
|
|
90
|
+
|
|
91
|
+
type WrappedBlock<Context, Defs> = {
|
|
92
|
+
[K in keyof Defs]: WrappedDef<Context, Defs[K]>;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const createServerFunctionBlockWithContext = <Context>(context: Context | undefined) => {
|
|
96
|
+
return <const Defs extends Record<string, any>>(
|
|
97
|
+
defs: Defs & ServerFunctionBlock<Context, Defs>,
|
|
98
|
+
): WrappedBlock<Context, Defs> => {
|
|
99
|
+
const wrapped = {} as WrappedBlock<Context, Defs>;
|
|
100
|
+
|
|
101
|
+
for (const key in defs) {
|
|
102
|
+
const def = defs[key];
|
|
103
|
+
wrapped[key] = {
|
|
104
|
+
...def,
|
|
105
|
+
run: context === undefined ? undefined : (args: any) => def.run(args, context),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return wrapped satisfies Record<string, ServerFunctionDefinition>;
|
|
110
|
+
};
|
|
53
111
|
};
|