@suss/packs 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +205 -0
  2. package/README.md +29 -0
  3. package/dist/activerecord.d.ts +30 -0
  4. package/dist/activerecord.js +45 -0
  5. package/dist/apollo-client.d.ts +1 -0
  6. package/dist/apollo-client.js +137 -0
  7. package/dist/apollo.d.ts +1 -0
  8. package/dist/apollo.js +90 -0
  9. package/dist/aws-dynamodb.d.ts +1 -0
  10. package/dist/aws-dynamodb.js +386 -0
  11. package/dist/aws-eventbridge.d.ts +1 -0
  12. package/dist/aws-eventbridge.js +240 -0
  13. package/dist/aws-lambda.d.ts +1 -0
  14. package/dist/aws-lambda.js +382 -0
  15. package/dist/aws-s3.d.ts +1 -0
  16. package/dist/aws-s3.js +120 -0
  17. package/dist/aws-sqs.d.ts +1 -0
  18. package/dist/aws-sqs.js +296 -0
  19. package/dist/axios.d.ts +1 -0
  20. package/dist/axios.js +107 -0
  21. package/dist/cloudflare-workers.d.ts +1 -0
  22. package/dist/cloudflare-workers.js +562 -0
  23. package/dist/drizzle.d.ts +1 -0
  24. package/dist/drizzle.js +383 -0
  25. package/dist/express.d.ts +1 -0
  26. package/dist/express.js +124 -0
  27. package/dist/fastapi.d.ts +1 -0
  28. package/dist/fastapi.js +42 -0
  29. package/dist/fastify.d.ts +1 -0
  30. package/dist/fastify.js +116 -0
  31. package/dist/fetch.d.ts +1 -0
  32. package/dist/fetch.js +64 -0
  33. package/dist/flask-restx.d.ts +1 -0
  34. package/dist/flask-restx.js +59 -0
  35. package/dist/gcs.d.ts +1 -0
  36. package/dist/gcs.js +134 -0
  37. package/dist/graphql-ruby.d.ts +1 -0
  38. package/dist/graphql-ruby.js +84 -0
  39. package/dist/hono.d.ts +1 -0
  40. package/dist/hono.js +184 -0
  41. package/dist/mongoose.d.ts +1 -0
  42. package/dist/mongoose.js +379 -0
  43. package/dist/nestjs-graphql.d.ts +1 -0
  44. package/dist/nestjs-graphql.js +77 -0
  45. package/dist/nestjs-rest.d.ts +1 -0
  46. package/dist/nestjs-rest.js +89 -0
  47. package/dist/nextjs.d.ts +1 -0
  48. package/dist/nextjs.js +154 -0
  49. package/dist/node.d.ts +1 -0
  50. package/dist/node.js +667 -0
  51. package/dist/prisma.d.ts +1 -0
  52. package/dist/prisma.js +448 -0
  53. package/dist/react-router.d.ts +1 -0
  54. package/dist/react-router.js +197 -0
  55. package/dist/react.d.ts +1 -0
  56. package/dist/react.js +221 -0
  57. package/dist/redis.d.ts +1 -0
  58. package/dist/redis.js +93 -0
  59. package/dist/sqlalchemy.d.ts +1 -0
  60. package/dist/sqlalchemy.js +48 -0
  61. package/dist/ts-rest.d.ts +1 -0
  62. package/dist/ts-rest.js +89 -0
  63. package/package.json +208 -0
@@ -0,0 +1,383 @@
1
+ // ../framework/drizzle/dist/index.js
2
+ import { Node as N } from "ts-morph";
3
+ import { resolveAliasedSymbol } from "@suss/adapter-typescript";
4
+ import { storageBinding } from "@suss/behavioral-ir";
5
+ import { readSqlAccess, sqlFromParts } from "@suss/sql";
6
+ var QUERY_API_METHODS = /* @__PURE__ */ new Set(["findMany", "findFirst"]);
7
+ var TABLE_FACTORIES = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
8
+ var CHAIN_WALK_LIMIT = 12;
9
+ var RAW_METHOD = "execute";
10
+ function makeRawRecognizer(opts) {
11
+ const storageSystem = opts.storageSystem ?? "postgresql";
12
+ const scope = opts.scope ?? "default";
13
+ return ((call) => {
14
+ const callNode = call;
15
+ const callee = callNode.getExpression();
16
+ if (!N.isPropertyAccessExpression(callee)) {
17
+ return null;
18
+ }
19
+ if (callee.getName() !== RAW_METHOD) {
20
+ return null;
21
+ }
22
+ const statement = sqlTextOf(callNode.getArguments()[0]);
23
+ if (statement === null) {
24
+ return null;
25
+ }
26
+ const accesses = readSqlAccess(statement, { dialect: storageSystem });
27
+ if (accesses.length === 0) {
28
+ return null;
29
+ }
30
+ return accesses.map((access) => ({
31
+ type: "interaction",
32
+ binding: storageBinding({
33
+ recognition: "@suss/framework-drizzle",
34
+ storageSystem,
35
+ scope,
36
+ container: access.table
37
+ }),
38
+ callee: callee.getText(),
39
+ interaction: {
40
+ class: "storage-access",
41
+ kind: access.kind,
42
+ fields: access.fields,
43
+ ...access.selector.length > 0 ? { selector: access.selector } : {},
44
+ operation: callee.getName()
45
+ }
46
+ }));
47
+ });
48
+ }
49
+ function sqlTextOf(argument) {
50
+ if (argument === void 0) {
51
+ return null;
52
+ }
53
+ if (N.isNoSubstitutionTemplateLiteral(argument)) {
54
+ return argument.getLiteralValue();
55
+ }
56
+ if (N.isTaggedTemplateExpression(argument)) {
57
+ const template = argument.getTemplate();
58
+ if (N.isNoSubstitutionTemplateLiteral(template)) {
59
+ return template.getLiteralValue();
60
+ }
61
+ const spans = template.getTemplateSpans();
62
+ return sqlFromParts(
63
+ [
64
+ template.getHead().getLiteralText(),
65
+ ...spans.map((span) => span.getLiteral().getLiteralText())
66
+ ],
67
+ // A statement that interpolates a table interpolates the schema
68
+ // object, so the name it declares is what belongs in the text.
69
+ // Everything else is a value, and a parameter is what a value
70
+ // would have been.
71
+ spans.map((span) => resolveTableName(span.getExpression()))
72
+ );
73
+ }
74
+ if (N.isStringLiteral(argument)) {
75
+ return argument.getLiteralValue();
76
+ }
77
+ return null;
78
+ }
79
+ function makeRecognizer(opts) {
80
+ const storageSystem = opts.storageSystem ?? "postgresql";
81
+ const scope = opts.scope ?? "default";
82
+ return (call) => {
83
+ const query = recognizeAnchor(call);
84
+ if (query === null) {
85
+ return null;
86
+ }
87
+ return [
88
+ {
89
+ type: "interaction",
90
+ binding: storageBinding({
91
+ recognition: "@suss/framework-drizzle",
92
+ storageSystem,
93
+ scope,
94
+ container: query.table
95
+ }),
96
+ callee: query.calleeText,
97
+ interaction: {
98
+ class: "storage-access",
99
+ kind: query.kind,
100
+ fields: query.fields,
101
+ ...query.selector !== null ? { selector: query.selector } : {},
102
+ operation: query.operation
103
+ }
104
+ }
105
+ ];
106
+ };
107
+ }
108
+ function recognizeAnchor(call) {
109
+ const callee = call.getExpression();
110
+ if (!N.isPropertyAccessExpression(callee)) {
111
+ return null;
112
+ }
113
+ const method = callee.getName();
114
+ if (method === "from") {
115
+ return recognizeSelect(call, callee.getExpression());
116
+ }
117
+ if (method === "insert" || method === "update" || method === "delete") {
118
+ return recognizeMutation(call, callee.getExpression(), method);
119
+ }
120
+ if (QUERY_API_METHODS.has(method)) {
121
+ return recognizeQueryApi(call, callee.getExpression(), method);
122
+ }
123
+ return null;
124
+ }
125
+ function recognizeSelect(fromCall, receiver) {
126
+ if (!N.isCallExpression(receiver)) {
127
+ return null;
128
+ }
129
+ const selectCallee = receiver.getExpression();
130
+ if (!N.isPropertyAccessExpression(selectCallee)) {
131
+ return null;
132
+ }
133
+ const selectName = selectCallee.getName();
134
+ if (selectName !== "select" && selectName !== "selectDistinct") {
135
+ return null;
136
+ }
137
+ if (!isDrizzleReceiver(selectCallee.getExpression())) {
138
+ return null;
139
+ }
140
+ const tableArg = fromCall.getArguments()[0];
141
+ if (tableArg === void 0) {
142
+ return null;
143
+ }
144
+ const table = resolveTableName(tableArg);
145
+ const tableExprText = tableArg.getText();
146
+ const selectArg = receiver.getArguments()[0];
147
+ const fields = selectArg !== void 0 && N.isObjectLiteralExpression(selectArg) ? objectKeys(selectArg) : ["*"];
148
+ const chain = collectChainCalls(fromCall);
149
+ const selector = selectorFromWhere(chain.get("where"), tableExprText);
150
+ return {
151
+ kind: "read",
152
+ operation: selectName,
153
+ table,
154
+ tableExprText,
155
+ fields: fields.length > 0 ? fields : ["*"],
156
+ selector,
157
+ calleeText: fromCall.getExpression().getText()
158
+ };
159
+ }
160
+ function recognizeMutation(call, receiver, operation) {
161
+ if (!isDrizzleReceiver(receiver)) {
162
+ return null;
163
+ }
164
+ const tableArg = call.getArguments()[0];
165
+ if (tableArg === void 0) {
166
+ return null;
167
+ }
168
+ const table = resolveTableName(tableArg);
169
+ const tableExprText = tableArg.getText();
170
+ const chain = collectChainCalls(call);
171
+ const fields = operation === "insert" ? valuesKeys(chain.get("values")) : operation === "update" ? setKeys(chain.get("set")) : ["*"];
172
+ const selector = selectorFromWhere(chain.get("where"), tableExprText);
173
+ return {
174
+ kind: "write",
175
+ operation,
176
+ table,
177
+ tableExprText,
178
+ fields,
179
+ selector,
180
+ calleeText: call.getExpression().getText()
181
+ };
182
+ }
183
+ function recognizeQueryApi(call, receiver, operation) {
184
+ if (!N.isPropertyAccessExpression(receiver)) {
185
+ return null;
186
+ }
187
+ const queryAccess = receiver.getExpression();
188
+ if (!N.isPropertyAccessExpression(queryAccess) || queryAccess.getName() !== "query") {
189
+ return null;
190
+ }
191
+ if (!isDrizzleReceiver(queryAccess.getExpression())) {
192
+ return null;
193
+ }
194
+ const table = resolveTableName(receiver) ?? receiver.getName();
195
+ const optionsArg = call.getArguments()[0];
196
+ const fields = [];
197
+ if (optionsArg !== void 0 && N.isObjectLiteralExpression(optionsArg)) {
198
+ const columns = objectProperty(optionsArg, "columns");
199
+ if (columns !== null && N.isObjectLiteralExpression(columns)) {
200
+ fields.push(...objectKeys(columns));
201
+ }
202
+ const withProp = objectProperty(optionsArg, "with");
203
+ if (withProp !== null && N.isObjectLiteralExpression(withProp)) {
204
+ fields.push(...objectKeys(withProp));
205
+ }
206
+ }
207
+ return {
208
+ kind: "read",
209
+ operation,
210
+ table,
211
+ tableExprText: null,
212
+ fields: fields.length > 0 ? fields : ["*"],
213
+ selector: null,
214
+ calleeText: call.getExpression().getText()
215
+ };
216
+ }
217
+ function collectChainCalls(anchor) {
218
+ const chain = /* @__PURE__ */ new Map();
219
+ let current = anchor;
220
+ for (let i = 0; i < CHAIN_WALK_LIMIT; i++) {
221
+ const parent = current.getParent();
222
+ if (parent === void 0 || !N.isPropertyAccessExpression(parent)) {
223
+ break;
224
+ }
225
+ const grandparent = parent.getParent();
226
+ if (grandparent === void 0 || !N.isCallExpression(grandparent)) {
227
+ break;
228
+ }
229
+ const name = parent.getName();
230
+ if (!chain.has(name)) {
231
+ chain.set(name, grandparent);
232
+ }
233
+ current = grandparent;
234
+ }
235
+ return chain;
236
+ }
237
+ function isDrizzleReceiver(node) {
238
+ const type = node.getType();
239
+ const symbol = type.getSymbol() ?? type.getAliasSymbol();
240
+ if (symbol === void 0) {
241
+ return false;
242
+ }
243
+ for (const decl of symbol.getDeclarations()) {
244
+ if (decl.getSourceFile().getFilePath().includes("/drizzle-orm/")) {
245
+ return true;
246
+ }
247
+ }
248
+ return false;
249
+ }
250
+ function resolveTableName(tableExpr) {
251
+ const symbol = N.isPropertyAccessExpression(tableExpr) ? tableExpr.getNameNode().getSymbol() : tableExpr.getSymbol();
252
+ if (symbol === void 0) {
253
+ return null;
254
+ }
255
+ for (const decl of symbol.getDeclarations()) {
256
+ const declared = tableNameFromDeclaration(decl);
257
+ if (declared !== null) {
258
+ return declared;
259
+ }
260
+ }
261
+ return null;
262
+ }
263
+ function tableNameFromDeclaration(decl) {
264
+ if (N.isImportSpecifier(decl)) {
265
+ const symbol = decl.getNameNode().getSymbol();
266
+ const aliased = symbol === void 0 ? void 0 : resolveAliasedSymbol(symbol);
267
+ for (const target of aliased?.getDeclarations() ?? []) {
268
+ const name = tableNameFromDeclaration(target);
269
+ if (name !== null) {
270
+ return name;
271
+ }
272
+ }
273
+ return null;
274
+ }
275
+ if (!N.isVariableDeclaration(decl)) {
276
+ return null;
277
+ }
278
+ const init = decl.getInitializer();
279
+ if (init === void 0 || !N.isCallExpression(init)) {
280
+ return null;
281
+ }
282
+ const calleeText = init.getExpression().getText();
283
+ const calleeName = calleeText.split(".").pop() ?? calleeText;
284
+ if (!TABLE_FACTORIES.has(calleeName)) {
285
+ return null;
286
+ }
287
+ const first = init.getArguments()[0];
288
+ if (first !== void 0 && N.isStringLiteral(first)) {
289
+ return first.getLiteralValue();
290
+ }
291
+ return null;
292
+ }
293
+ function objectKeys(obj) {
294
+ if (!N.isObjectLiteralExpression(obj)) {
295
+ return [];
296
+ }
297
+ const keys = [];
298
+ for (const prop of obj.getProperties()) {
299
+ if (N.isPropertyAssignment(prop) || N.isShorthandPropertyAssignment(prop)) {
300
+ keys.push(prop.getName());
301
+ }
302
+ }
303
+ return keys;
304
+ }
305
+ function objectProperty(obj, name) {
306
+ if (!N.isObjectLiteralExpression(obj)) {
307
+ return null;
308
+ }
309
+ for (const prop of obj.getProperties()) {
310
+ if (N.isPropertyAssignment(prop) && prop.getName() === name) {
311
+ return prop.getInitializer() ?? null;
312
+ }
313
+ }
314
+ return null;
315
+ }
316
+ function valuesKeys(valuesCall) {
317
+ const arg = valuesCall?.getArguments()[0];
318
+ if (arg === void 0) {
319
+ return ["*"];
320
+ }
321
+ if (N.isObjectLiteralExpression(arg)) {
322
+ const keys = objectKeys(arg);
323
+ return keys.length > 0 ? keys : ["*"];
324
+ }
325
+ if (N.isArrayLiteralExpression(arg)) {
326
+ const union = /* @__PURE__ */ new Set();
327
+ for (const element of arg.getElements()) {
328
+ for (const key of objectKeys(element)) {
329
+ union.add(key);
330
+ }
331
+ }
332
+ return union.size > 0 ? [...union] : ["*"];
333
+ }
334
+ return ["*"];
335
+ }
336
+ function setKeys(setCall) {
337
+ const arg = setCall?.getArguments()[0];
338
+ if (arg === void 0) {
339
+ return ["*"];
340
+ }
341
+ const keys = objectKeys(arg);
342
+ return keys.length > 0 ? keys : ["*"];
343
+ }
344
+ function selectorFromWhere(whereCall, tableExprText) {
345
+ if (whereCall === void 0 || tableExprText === null) {
346
+ return null;
347
+ }
348
+ const arg = whereCall.getArguments()[0];
349
+ if (arg === void 0) {
350
+ return null;
351
+ }
352
+ const columns = /* @__PURE__ */ new Set();
353
+ const visit = (node) => {
354
+ if (N.isPropertyAccessExpression(node) && node.getExpression().getText() === tableExprText) {
355
+ columns.add(node.getName());
356
+ }
357
+ node.forEachChild(visit);
358
+ };
359
+ visit(arg);
360
+ return columns.size > 0 ? [...columns] : null;
361
+ }
362
+ function drizzleFramework(options = {}) {
363
+ return {
364
+ name: "drizzle",
365
+ protocol: "in-process",
366
+ languages: ["typescript", "javascript"],
367
+ discovery: [],
368
+ terminals: [],
369
+ inputMapping: { type: "positionalParams", params: [] },
370
+ // Gate on drizzle-orm imports (matches subpaths like
371
+ // drizzle-orm/pg-core and driver entry points): files without
372
+ // them can't type-check as Drizzle receivers anyway.
373
+ requiresImport: ["drizzle-orm"],
374
+ invocationRecognizers: [
375
+ makeRecognizer(options),
376
+ makeRawRecognizer(options)
377
+ ]
378
+ };
379
+ }
380
+ var index_default = drizzleFramework;
381
+ export {
382
+ index_default as default
383
+ };
@@ -0,0 +1 @@
1
+ export { default } from '@suss/framework-express';
@@ -0,0 +1,124 @@
1
+ // ../framework/express/dist/index.js
2
+ import { httpRouteDiscovery } from "@suss/extractor";
3
+ function expressFramework() {
4
+ return {
5
+ name: "express",
6
+ protocol: "http",
7
+ languages: ["typescript", "javascript"],
8
+ // Express exposes the routable via either `Router()` (named) or
9
+ // `express()` (default). Both drive handler registration the same
10
+ // way; `httpRouteDiscovery` emits one DiscoveryPattern per name.
11
+ // Either can also be mounted onto another with `app.use(prefix,
12
+ // router)`, so a route declared on the mounted router summarizes
13
+ // with the mount's prefix composed in.
14
+ discovery: httpRouteDiscovery({
15
+ importModule: "express",
16
+ importNames: ["Router", "express"],
17
+ methods: [".get", ".post", ".put", ".delete", ".patch", ".all"],
18
+ mount: { method: "use", prefixPosition: 0, targetPosition: 1 }
19
+ }),
20
+ terminals: [
21
+ {
22
+ // res.status(N).json(body)
23
+ kind: "response",
24
+ match: {
25
+ type: "parameterMethodCall",
26
+ parameterPosition: 1,
27
+ methodChain: ["status", "json"]
28
+ },
29
+ extraction: {
30
+ statusCode: { from: "argument", position: 0 },
31
+ body: { from: "argument", position: 0 }
32
+ }
33
+ },
34
+ {
35
+ // res.json(body): implicit 200
36
+ kind: "response",
37
+ match: {
38
+ type: "parameterMethodCall",
39
+ parameterPosition: 1,
40
+ methodChain: ["json"]
41
+ },
42
+ extraction: {
43
+ body: { from: "argument", position: 0 },
44
+ defaultStatusCode: 200
45
+ }
46
+ },
47
+ {
48
+ // res.status(N).send(body)
49
+ kind: "response",
50
+ match: {
51
+ type: "parameterMethodCall",
52
+ parameterPosition: 1,
53
+ methodChain: ["status", "send"]
54
+ },
55
+ extraction: {
56
+ statusCode: { from: "argument", position: 0 },
57
+ body: { from: "argument", position: 0 }
58
+ }
59
+ },
60
+ {
61
+ // res.send(body): implicit 200
62
+ kind: "response",
63
+ match: {
64
+ type: "parameterMethodCall",
65
+ parameterPosition: 1,
66
+ methodChain: ["send"]
67
+ },
68
+ extraction: {
69
+ body: { from: "argument", position: 0 },
70
+ defaultStatusCode: 200
71
+ }
72
+ },
73
+ {
74
+ // res.sendStatus(N): sends status code with status text as body
75
+ kind: "response",
76
+ match: {
77
+ type: "parameterMethodCall",
78
+ parameterPosition: 1,
79
+ methodChain: ["sendStatus"]
80
+ },
81
+ extraction: {
82
+ statusCode: { from: "argument", position: 0 }
83
+ }
84
+ },
85
+ {
86
+ // res.redirect(url) or res.redirect(status, url)
87
+ // Arg 0 is a status code only in the 2-arg form; minArgs prevents
88
+ // extracting the URL string as a status code in the 1-arg form.
89
+ kind: "response",
90
+ match: {
91
+ type: "parameterMethodCall",
92
+ parameterPosition: 1,
93
+ methodChain: ["redirect"]
94
+ },
95
+ extraction: {
96
+ statusCode: { from: "argument", position: 0, minArgs: 2 },
97
+ defaultStatusCode: 302
98
+ }
99
+ },
100
+ {
101
+ // throw new SomeError(...); express error middleware sends the
102
+ // error's status as the wire response.
103
+ kind: "throw",
104
+ match: { type: "throwExpression" },
105
+ extraction: {
106
+ statusCode: { from: "property", name: "status" }
107
+ },
108
+ producesResponse: true
109
+ }
110
+ ],
111
+ inputMapping: {
112
+ type: "positionalParams",
113
+ params: [
114
+ { position: 0, role: "request" },
115
+ { position: 1, role: "response" },
116
+ { position: 2, role: "next" }
117
+ ]
118
+ }
119
+ };
120
+ }
121
+ var index_default = expressFramework;
122
+ export {
123
+ index_default as default
124
+ };
@@ -0,0 +1 @@
1
+ export { default } from '@suss/framework-fastapi';
@@ -0,0 +1,42 @@
1
+ // ../framework/fastapi/dist/index.js
2
+ var VERB_ATTRIBUTE_NAMES = {
3
+ get: "GET",
4
+ post: "POST",
5
+ put: "PUT",
6
+ patch: "PATCH",
7
+ delete: "DELETE",
8
+ head: "HEAD",
9
+ options: "OPTIONS"
10
+ };
11
+ function fastapiFramework(options = {}) {
12
+ return {
13
+ name: "fastapi",
14
+ protocol: "http",
15
+ ...options.wrapperModules !== void 0 ? { projectModules: options.wrapperModules } : {},
16
+ discovery: [
17
+ {
18
+ type: "decoratedFunctionRoute",
19
+ importModule: ["fastapi", ...options.wrapperModules ?? []],
20
+ verbAttributeNames: VERB_ATTRIBUTE_NAMES,
21
+ pathParamSyntax: "braces",
22
+ annotatedClassIsRequestBody: true,
23
+ // FastAPI resolves both of these itself and calls the handler with
24
+ // the result, so a parameter defaulted to one is never sent.
25
+ injectedParameterCallees: ["Depends", "Security"],
26
+ // FastAPI returns 200 for a route that declares no status.
27
+ defaultStatusCode: 200,
28
+ responseModelKeyword: "response_model",
29
+ statusCodeKeyword: "status_code",
30
+ routerComposition: {
31
+ routerConstructorName: "APIRouter",
32
+ includeMethodName: "include_router",
33
+ prefixKeyword: "prefix"
34
+ }
35
+ }
36
+ ]
37
+ };
38
+ }
39
+ var index_default = fastapiFramework;
40
+ export {
41
+ index_default as default
42
+ };
@@ -0,0 +1 @@
1
+ export { default } from '@suss/framework-fastify';
@@ -0,0 +1,116 @@
1
+ // ../framework/fastify/dist/index.js
2
+ import { httpRouteDiscovery } from "@suss/extractor";
3
+ function fastifyFramework() {
4
+ return {
5
+ name: "fastify",
6
+ protocol: "http",
7
+ languages: ["typescript", "javascript"],
8
+ // Fastify exposes the routable via either default `Fastify` or
9
+ // named `fastify()`. Both drive handler registration the same way.
10
+ // Unlike Express, Fastify's router supports `.head` and `.options`.
11
+ discovery: httpRouteDiscovery({
12
+ importModule: "fastify",
13
+ importNames: ["Fastify", "fastify"],
14
+ methods: [
15
+ ".get",
16
+ ".post",
17
+ ".put",
18
+ ".delete",
19
+ ".patch",
20
+ ".head",
21
+ ".options",
22
+ ".all"
23
+ ]
24
+ }),
25
+ terminals: [
26
+ {
27
+ // reply.code(N).send(body)
28
+ kind: "response",
29
+ match: {
30
+ type: "parameterMethodCall",
31
+ parameterPosition: 1,
32
+ methodChain: ["code", "send"]
33
+ },
34
+ extraction: {
35
+ statusCode: { from: "argument", position: 0 },
36
+ body: { from: "argument", position: 0 }
37
+ }
38
+ },
39
+ {
40
+ // reply.status(N).send(body), `.status` is the Express-style alias
41
+ kind: "response",
42
+ match: {
43
+ type: "parameterMethodCall",
44
+ parameterPosition: 1,
45
+ methodChain: ["status", "send"]
46
+ },
47
+ extraction: {
48
+ statusCode: { from: "argument", position: 0 },
49
+ body: { from: "argument", position: 0 }
50
+ }
51
+ },
52
+ {
53
+ // reply.send(body): implicit 200
54
+ kind: "response",
55
+ match: {
56
+ type: "parameterMethodCall",
57
+ parameterPosition: 1,
58
+ methodChain: ["send"]
59
+ },
60
+ extraction: {
61
+ body: { from: "argument", position: 0 },
62
+ defaultStatusCode: 200
63
+ }
64
+ },
65
+ {
66
+ // reply.redirect(url) or reply.redirect(N, url)
67
+ // Arg 0 is a status code only in the 2-arg form; minArgs prevents
68
+ // extracting the URL string as a status code in the 1-arg form.
69
+ kind: "response",
70
+ match: {
71
+ type: "parameterMethodCall",
72
+ parameterPosition: 1,
73
+ methodChain: ["redirect"]
74
+ },
75
+ extraction: {
76
+ statusCode: { from: "argument", position: 0, minArgs: 2 },
77
+ defaultStatusCode: 302
78
+ }
79
+ },
80
+ {
81
+ // throw new Error(...) / throw httpErrors.notFound() / etc.
82
+ // Status code is left for the consumer to infer from exception type;
83
+ // Fastify error libraries vary too widely to map here.
84
+ kind: "throw",
85
+ match: { type: "throwExpression" },
86
+ extraction: {}
87
+ },
88
+ {
89
+ // `return user`, `return { id, name }`, `return await db.find(id)`,
90
+ // Fastify serialises the returned value as a 200 response body.
91
+ // `excludeCallReturns: true` keeps `return reply.send(...)` out
92
+ // of this branch: that call already lands as a parameterMethodCall
93
+ // terminal above, and matching it here would double-fire.
94
+ kind: "response",
95
+ match: {
96
+ type: "returnStatement",
97
+ excludeCallReturns: true
98
+ },
99
+ extraction: {
100
+ defaultStatusCode: 200
101
+ }
102
+ }
103
+ ],
104
+ inputMapping: {
105
+ type: "positionalParams",
106
+ params: [
107
+ { position: 0, role: "request" },
108
+ { position: 1, role: "reply" }
109
+ ]
110
+ }
111
+ };
112
+ }
113
+ var index_default = fastifyFramework;
114
+ export {
115
+ index_default as default
116
+ };
@@ -0,0 +1 @@
1
+ export { default } from '@suss/client-web';