@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.
- package/LICENSE +205 -0
- package/README.md +29 -0
- package/dist/activerecord.d.ts +30 -0
- package/dist/activerecord.js +45 -0
- package/dist/apollo-client.d.ts +1 -0
- package/dist/apollo-client.js +137 -0
- package/dist/apollo.d.ts +1 -0
- package/dist/apollo.js +90 -0
- package/dist/aws-dynamodb.d.ts +1 -0
- package/dist/aws-dynamodb.js +386 -0
- package/dist/aws-eventbridge.d.ts +1 -0
- package/dist/aws-eventbridge.js +240 -0
- package/dist/aws-lambda.d.ts +1 -0
- package/dist/aws-lambda.js +382 -0
- package/dist/aws-s3.d.ts +1 -0
- package/dist/aws-s3.js +120 -0
- package/dist/aws-sqs.d.ts +1 -0
- package/dist/aws-sqs.js +296 -0
- package/dist/axios.d.ts +1 -0
- package/dist/axios.js +107 -0
- package/dist/cloudflare-workers.d.ts +1 -0
- package/dist/cloudflare-workers.js +562 -0
- package/dist/drizzle.d.ts +1 -0
- package/dist/drizzle.js +383 -0
- package/dist/express.d.ts +1 -0
- package/dist/express.js +124 -0
- package/dist/fastapi.d.ts +1 -0
- package/dist/fastapi.js +42 -0
- package/dist/fastify.d.ts +1 -0
- package/dist/fastify.js +116 -0
- package/dist/fetch.d.ts +1 -0
- package/dist/fetch.js +64 -0
- package/dist/flask-restx.d.ts +1 -0
- package/dist/flask-restx.js +59 -0
- package/dist/gcs.d.ts +1 -0
- package/dist/gcs.js +134 -0
- package/dist/graphql-ruby.d.ts +1 -0
- package/dist/graphql-ruby.js +84 -0
- package/dist/hono.d.ts +1 -0
- package/dist/hono.js +184 -0
- package/dist/mongoose.d.ts +1 -0
- package/dist/mongoose.js +379 -0
- package/dist/nestjs-graphql.d.ts +1 -0
- package/dist/nestjs-graphql.js +77 -0
- package/dist/nestjs-rest.d.ts +1 -0
- package/dist/nestjs-rest.js +89 -0
- package/dist/nextjs.d.ts +1 -0
- package/dist/nextjs.js +154 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.js +667 -0
- package/dist/prisma.d.ts +1 -0
- package/dist/prisma.js +448 -0
- package/dist/react-router.d.ts +1 -0
- package/dist/react-router.js +197 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +221 -0
- package/dist/redis.d.ts +1 -0
- package/dist/redis.js +93 -0
- package/dist/sqlalchemy.d.ts +1 -0
- package/dist/sqlalchemy.js +48 -0
- package/dist/ts-rest.d.ts +1 -0
- package/dist/ts-rest.js +89 -0
- package/package.json +208 -0
package/dist/mongoose.js
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
// ../framework/mongoose/dist/index.js
|
|
2
|
+
import {
|
|
3
|
+
Node as N
|
|
4
|
+
} from "ts-morph";
|
|
5
|
+
import { methodDeclaredIn } from "@suss/adapter-typescript";
|
|
6
|
+
import { storageBinding } from "@suss/behavioral-ir";
|
|
7
|
+
var RECOGNITION = "@suss/framework-mongoose";
|
|
8
|
+
var STORAGE_SYSTEM = "mongodb";
|
|
9
|
+
var METHODS = {
|
|
10
|
+
find: { kind: "read", filterArg: 0, projectionArg: 1 },
|
|
11
|
+
findOne: { kind: "read", filterArg: 0, projectionArg: 1 },
|
|
12
|
+
findById: { kind: "read", idArg: 0, projectionArg: 1 },
|
|
13
|
+
countDocuments: { kind: "read", filterArg: 0 },
|
|
14
|
+
exists: { kind: "read", filterArg: 0 },
|
|
15
|
+
distinct: { kind: "read", fieldArg: 0, filterArg: 1 },
|
|
16
|
+
create: { kind: "write", payloadArg: 0 },
|
|
17
|
+
insertMany: { kind: "write", payloadArg: 0 },
|
|
18
|
+
updateOne: { kind: "write", filterArg: 0, updateArg: 1 },
|
|
19
|
+
updateMany: { kind: "write", filterArg: 0, updateArg: 1 },
|
|
20
|
+
replaceOne: { kind: "write", filterArg: 0, payloadArg: 1 },
|
|
21
|
+
deleteOne: { kind: "write", filterArg: 0 },
|
|
22
|
+
deleteMany: { kind: "write", filterArg: 0 },
|
|
23
|
+
findOneAndUpdate: { kind: "write", filterArg: 0, updateArg: 1 },
|
|
24
|
+
findByIdAndUpdate: { kind: "write", idArg: 0, updateArg: 1 },
|
|
25
|
+
findOneAndDelete: { kind: "write", filterArg: 0 },
|
|
26
|
+
findByIdAndDelete: { kind: "write", idArg: 0 },
|
|
27
|
+
findOneAndReplace: { kind: "write", filterArg: 0, payloadArg: 1 }
|
|
28
|
+
};
|
|
29
|
+
function defaultCollectionName(modelName) {
|
|
30
|
+
const lower = modelName.toLowerCase();
|
|
31
|
+
if (/[^aeiou]y$/.test(lower)) {
|
|
32
|
+
return `${lower.slice(0, -1)}ies`;
|
|
33
|
+
}
|
|
34
|
+
if (/(s|x|z|ch|sh)$/.test(lower)) {
|
|
35
|
+
return `${lower}es`;
|
|
36
|
+
}
|
|
37
|
+
return `${lower}s`;
|
|
38
|
+
}
|
|
39
|
+
function resolveModelIdentity(node, resolve) {
|
|
40
|
+
if (N.isCallExpression(node)) {
|
|
41
|
+
return modelIdentityFromModelCall(node, resolve);
|
|
42
|
+
}
|
|
43
|
+
if (!N.isIdentifier(node)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const symbol = node.getSymbol();
|
|
47
|
+
if (symbol === void 0) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
for (const decl of symbol.getDeclarations()) {
|
|
51
|
+
const identity = modelIdentityFromDeclaration(decl, resolve);
|
|
52
|
+
if (identity !== null) {
|
|
53
|
+
return identity;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
function modelIdentityFromDeclaration(decl, resolve) {
|
|
59
|
+
if (N.isImportSpecifier(decl)) {
|
|
60
|
+
const symbol = decl.getNameNode().getSymbol();
|
|
61
|
+
for (const target of symbol?.getAliasedSymbol()?.getDeclarations() ?? []) {
|
|
62
|
+
const identity = modelIdentityFromDeclaration(target, resolve);
|
|
63
|
+
if (identity !== null) {
|
|
64
|
+
return identity;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (!N.isVariableDeclaration(decl)) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const init = decl.getInitializer();
|
|
73
|
+
if (init === void 0 || !N.isCallExpression(init)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return modelIdentityFromModelCall(init, resolve);
|
|
77
|
+
}
|
|
78
|
+
function modelIdentityFromModelCall(call, resolve) {
|
|
79
|
+
const callee = call.getExpression();
|
|
80
|
+
if (!isModelFactoryCall(callee, resolve)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const args = call.getArguments();
|
|
84
|
+
const modelName = literalString(args[0]);
|
|
85
|
+
if (modelName === null) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const explicitCollection = literalString(args[2]);
|
|
89
|
+
const schemaCollection = explicitCollection === null ? collectionFromSchemaArg(args[1]) : null;
|
|
90
|
+
const collection = explicitCollection ?? schemaCollection ?? defaultCollectionName(modelName);
|
|
91
|
+
return { modelName, collection };
|
|
92
|
+
}
|
|
93
|
+
function isModelFactoryCall(callee, resolve) {
|
|
94
|
+
if (N.isPropertyAccessExpression(callee)) {
|
|
95
|
+
return callee.getName() === "model" && methodDeclaredIn(callee, "mongoose", resolve);
|
|
96
|
+
}
|
|
97
|
+
return N.isIdentifier(callee) && isImportedAs(callee, "mongoose", "model");
|
|
98
|
+
}
|
|
99
|
+
function isImportedAs(identifier, module, exportName) {
|
|
100
|
+
const symbol = identifier.getSymbol();
|
|
101
|
+
if (symbol === void 0) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
for (const decl of symbol.getDeclarations()) {
|
|
105
|
+
if (N.isImportSpecifier(decl) && decl.getName() === exportName && decl.getImportDeclaration().getModuleSpecifierValue() === module) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
function collectionFromSchemaArg(schemaArg) {
|
|
112
|
+
if (schemaArg === void 0) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
const ctor = schemaConstructorOf(schemaArg);
|
|
116
|
+
const optionsArg = ctor?.getArguments()[1];
|
|
117
|
+
if (optionsArg === void 0 || !N.isObjectLiteralExpression(optionsArg)) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
for (const prop of optionsArg.getProperties()) {
|
|
121
|
+
if (N.isPropertyAssignment(prop) && prop.getName() === "collection") {
|
|
122
|
+
return literalString(prop.getInitializer());
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
function schemaConstructorOf(node) {
|
|
128
|
+
if (N.isNewExpression(node)) {
|
|
129
|
+
return node;
|
|
130
|
+
}
|
|
131
|
+
if (!N.isIdentifier(node)) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const symbol = node.getSymbol();
|
|
135
|
+
for (const decl of symbol?.getDeclarations() ?? []) {
|
|
136
|
+
if (!N.isVariableDeclaration(decl)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const init = decl.getInitializer();
|
|
140
|
+
if (init !== void 0 && N.isNewExpression(init)) {
|
|
141
|
+
return init;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
function resolveDocumentModelIdentity(node, resolve) {
|
|
147
|
+
if (N.isNewExpression(node)) {
|
|
148
|
+
return resolveModelIdentity(node.getExpression(), resolve);
|
|
149
|
+
}
|
|
150
|
+
if (N.isAwaitExpression(node) || N.isParenthesizedExpression(node)) {
|
|
151
|
+
return resolveDocumentModelIdentity(node.getExpression(), resolve);
|
|
152
|
+
}
|
|
153
|
+
if (N.isCallExpression(node)) {
|
|
154
|
+
const callee = node.getExpression();
|
|
155
|
+
if (!N.isPropertyAccessExpression(callee) || !(callee.getName() in METHODS)) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return resolveModelIdentity(callee.getExpression(), resolve);
|
|
159
|
+
}
|
|
160
|
+
if (!N.isIdentifier(node)) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const symbol = node.getSymbol();
|
|
164
|
+
for (const decl of symbol?.getDeclarations() ?? []) {
|
|
165
|
+
if (!N.isVariableDeclaration(decl)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const init = decl.getInitializer();
|
|
169
|
+
const identity = init === void 0 ? null : resolveDocumentModelIdentity(init, resolve);
|
|
170
|
+
if (identity !== null) {
|
|
171
|
+
return identity;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
function literalString(node) {
|
|
177
|
+
if (node === void 0) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return N.isStringLiteral(node) || N.isNoSubstitutionTemplateLiteral(node) ? node.getLiteralValue() : null;
|
|
181
|
+
}
|
|
182
|
+
function readObjectArg(arg) {
|
|
183
|
+
if (arg === null || arg === void 0 || typeof arg !== "object") {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
return arg.kind === "object" ? arg : null;
|
|
187
|
+
}
|
|
188
|
+
function isTruthyLiteral(value) {
|
|
189
|
+
if (value === null || typeof value !== "object") {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
if (value.kind === "number") {
|
|
193
|
+
return value.value !== 0;
|
|
194
|
+
}
|
|
195
|
+
return value.kind === "boolean" && value.value;
|
|
196
|
+
}
|
|
197
|
+
function projectionFromString(text) {
|
|
198
|
+
const included = text.trim().split(/\s+/).filter((term) => term.length > 0 && !term.startsWith("-")).map((term) => term.replace(/^\+/, ""));
|
|
199
|
+
return included.length > 0 ? included : ["*"];
|
|
200
|
+
}
|
|
201
|
+
function projectionFields(arg) {
|
|
202
|
+
if (arg !== null && typeof arg === "object" && arg.kind === "string") {
|
|
203
|
+
return projectionFromString(arg.value);
|
|
204
|
+
}
|
|
205
|
+
const object = readObjectArg(arg);
|
|
206
|
+
if (object === null) {
|
|
207
|
+
return ["*"];
|
|
208
|
+
}
|
|
209
|
+
const included = Object.entries(object.fields).filter(([, value]) => isTruthyLiteral(value)).map(([key]) => key);
|
|
210
|
+
return included.length > 0 ? included : ["*"];
|
|
211
|
+
}
|
|
212
|
+
function updateFields(arg) {
|
|
213
|
+
const object = readObjectArg(arg);
|
|
214
|
+
if (object === null) {
|
|
215
|
+
return ["*"];
|
|
216
|
+
}
|
|
217
|
+
const fields = /* @__PURE__ */ new Set();
|
|
218
|
+
for (const [key, value] of Object.entries(object.fields)) {
|
|
219
|
+
if (!key.startsWith("$")) {
|
|
220
|
+
fields.add(key);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const operand = readObjectArg(value);
|
|
224
|
+
for (const inner of Object.keys(operand?.fields ?? {})) {
|
|
225
|
+
fields.add(inner);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return fields.size > 0 ? [...fields] : ["*"];
|
|
229
|
+
}
|
|
230
|
+
function payloadFields(arg) {
|
|
231
|
+
const object = readObjectArg(arg);
|
|
232
|
+
if (object !== null) {
|
|
233
|
+
const keys = Object.keys(object.fields);
|
|
234
|
+
return keys.length > 0 ? keys : ["*"];
|
|
235
|
+
}
|
|
236
|
+
if (arg === null || arg === void 0 || typeof arg !== "object" || arg.kind !== "array") {
|
|
237
|
+
return ["*"];
|
|
238
|
+
}
|
|
239
|
+
const union = /* @__PURE__ */ new Set();
|
|
240
|
+
for (const item of arg.items) {
|
|
241
|
+
const row = readObjectArg(item);
|
|
242
|
+
if (row === null) {
|
|
243
|
+
return ["*"];
|
|
244
|
+
}
|
|
245
|
+
for (const key of Object.keys(row.fields)) {
|
|
246
|
+
union.add(key);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return union.size > 0 ? [...union] : ["*"];
|
|
250
|
+
}
|
|
251
|
+
function distinctField(arg) {
|
|
252
|
+
return arg !== null && typeof arg === "object" && arg.kind === "string" ? [arg.value] : [];
|
|
253
|
+
}
|
|
254
|
+
function fieldsOf(spec, args) {
|
|
255
|
+
if (spec.projectionArg !== void 0) {
|
|
256
|
+
return projectionFields(args[spec.projectionArg]);
|
|
257
|
+
}
|
|
258
|
+
if (spec.updateArg !== void 0) {
|
|
259
|
+
return updateFields(args[spec.updateArg]);
|
|
260
|
+
}
|
|
261
|
+
if (spec.payloadArg !== void 0) {
|
|
262
|
+
return payloadFields(args[spec.payloadArg]);
|
|
263
|
+
}
|
|
264
|
+
if (spec.fieldArg !== void 0) {
|
|
265
|
+
return distinctField(args[spec.fieldArg]);
|
|
266
|
+
}
|
|
267
|
+
return spec.kind === "write" ? ["*"] : [];
|
|
268
|
+
}
|
|
269
|
+
function selectorOf(spec, args) {
|
|
270
|
+
if (spec.idArg !== void 0) {
|
|
271
|
+
return args[spec.idArg] !== void 0 ? ["_id"] : null;
|
|
272
|
+
}
|
|
273
|
+
if (spec.filterArg === void 0) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
const object = readObjectArg(args[spec.filterArg]);
|
|
277
|
+
if (object === null) {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
const keys = Object.keys(object.fields);
|
|
281
|
+
return keys.length > 0 ? keys : null;
|
|
282
|
+
}
|
|
283
|
+
function buildAccess(opts) {
|
|
284
|
+
return {
|
|
285
|
+
type: "interaction",
|
|
286
|
+
binding: storageBinding({
|
|
287
|
+
recognition: RECOGNITION,
|
|
288
|
+
storageSystem: STORAGE_SYSTEM,
|
|
289
|
+
scope: opts.scope,
|
|
290
|
+
container: opts.collection
|
|
291
|
+
}),
|
|
292
|
+
callee: opts.calleeText,
|
|
293
|
+
interaction: {
|
|
294
|
+
class: "storage-access",
|
|
295
|
+
kind: opts.kind,
|
|
296
|
+
fields: opts.fields,
|
|
297
|
+
...opts.selector !== null ? { selector: opts.selector } : {},
|
|
298
|
+
operation: opts.operation
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function makeStaticRecognizer(scope) {
|
|
303
|
+
return (call, ctx) => {
|
|
304
|
+
const callNode = call;
|
|
305
|
+
const recognizerCtx = ctx;
|
|
306
|
+
const resolve = recognizerCtx.resolveWrittenValue ?? (() => null);
|
|
307
|
+
const callee = callNode.getExpression();
|
|
308
|
+
if (!N.isPropertyAccessExpression(callee)) {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
const method = callee.getName();
|
|
312
|
+
const spec = METHODS[method];
|
|
313
|
+
if (spec === void 0 || !methodDeclaredIn(callee, "mongoose", resolve)) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
const identity = resolveModelIdentity(callee.getExpression(), resolve);
|
|
317
|
+
const args = recognizerCtx.extractArgs?.() ?? [];
|
|
318
|
+
return [
|
|
319
|
+
buildAccess({
|
|
320
|
+
scope,
|
|
321
|
+
collection: identity?.collection ?? null,
|
|
322
|
+
calleeText: callee.getText(),
|
|
323
|
+
operation: method,
|
|
324
|
+
kind: spec.kind,
|
|
325
|
+
fields: fieldsOf(spec, args),
|
|
326
|
+
selector: selectorOf(spec, args)
|
|
327
|
+
})
|
|
328
|
+
];
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function makeSaveRecognizer(scope) {
|
|
332
|
+
return (call, ctx) => {
|
|
333
|
+
const callNode = call;
|
|
334
|
+
const recognizerCtx = ctx;
|
|
335
|
+
const resolve = recognizerCtx.resolveWrittenValue ?? (() => null);
|
|
336
|
+
const callee = callNode.getExpression();
|
|
337
|
+
if (!N.isPropertyAccessExpression(callee) || callee.getName() !== "save") {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
if (!methodDeclaredIn(callee, "mongoose", resolve)) {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
const identity = resolveDocumentModelIdentity(
|
|
344
|
+
callee.getExpression(),
|
|
345
|
+
resolve
|
|
346
|
+
);
|
|
347
|
+
return [
|
|
348
|
+
buildAccess({
|
|
349
|
+
scope,
|
|
350
|
+
collection: identity?.collection ?? null,
|
|
351
|
+
calleeText: callee.getText(),
|
|
352
|
+
operation: "save",
|
|
353
|
+
kind: "write",
|
|
354
|
+
fields: ["*"],
|
|
355
|
+
selector: null
|
|
356
|
+
})
|
|
357
|
+
];
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function mongooseFramework(options = {}) {
|
|
361
|
+
const scope = options.scope ?? "default";
|
|
362
|
+
return {
|
|
363
|
+
name: "mongoose",
|
|
364
|
+
protocol: "in-process",
|
|
365
|
+
languages: ["typescript", "javascript"],
|
|
366
|
+
discovery: [],
|
|
367
|
+
terminals: [],
|
|
368
|
+
inputMapping: { type: "positionalParams", params: [] },
|
|
369
|
+
requiresImport: ["mongoose"],
|
|
370
|
+
invocationRecognizers: [
|
|
371
|
+
makeStaticRecognizer(scope),
|
|
372
|
+
makeSaveRecognizer(scope)
|
|
373
|
+
]
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
var index_default = mongooseFramework;
|
|
377
|
+
export {
|
|
378
|
+
index_default as default
|
|
379
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-nestjs-graphql';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// ../framework/nestjs-graphql/dist/index.js
|
|
2
|
+
function nestjsGraphqlFramework(options = {}) {
|
|
3
|
+
return {
|
|
4
|
+
name: "nestjs-graphql",
|
|
5
|
+
languages: ["typescript"],
|
|
6
|
+
// Apollo Server runs underneath via `GraphQLModule.forRoot({...
|
|
7
|
+
// ApolloDriver })`; the wire transport stays HTTP regardless of
|
|
8
|
+
// whether the resolver was discovered via decorator or via an
|
|
9
|
+
// object-literal resolver map.
|
|
10
|
+
protocol: "http",
|
|
11
|
+
discovery: [
|
|
12
|
+
{
|
|
13
|
+
kind: "resolver",
|
|
14
|
+
match: {
|
|
15
|
+
type: "decoratedMethod",
|
|
16
|
+
importModule: "@nestjs/graphql",
|
|
17
|
+
// First match wins, so the framework's own decorator is
|
|
18
|
+
// tried before any wrapper a project names.
|
|
19
|
+
classDecorators: ["Resolver", ...options.classDecorators ?? []],
|
|
20
|
+
methodDecorators: [
|
|
21
|
+
"Query",
|
|
22
|
+
"Mutation",
|
|
23
|
+
"ResolveField",
|
|
24
|
+
"Subscription"
|
|
25
|
+
],
|
|
26
|
+
// The three that settle their own type, each named after the
|
|
27
|
+
// type it puts its field on. `ResolveField` is deliberately
|
|
28
|
+
// absent: it is the one that needs the class decorator.
|
|
29
|
+
methodDecoratorTypeMap: {
|
|
30
|
+
Query: "Query",
|
|
31
|
+
Mutation: "Mutation",
|
|
32
|
+
Subscription: "Subscription"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
requiresImport: ["@nestjs/graphql"]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
terminals: [
|
|
39
|
+
// Resolvers return a value; errors propagate as thrown
|
|
40
|
+
// exceptions (NestJS / Apollo map them to `errors[]` on the
|
|
41
|
+
// outgoing response). No framework-specific response-call
|
|
42
|
+
// shape: return + throw cover the observable behaviour.
|
|
43
|
+
{
|
|
44
|
+
kind: "return",
|
|
45
|
+
match: { type: "returnStatement" },
|
|
46
|
+
extraction: {}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
kind: "throw",
|
|
50
|
+
match: { type: "throwExpression" },
|
|
51
|
+
extraction: {}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
// Resolver methods can fall through and return `undefined` when the
|
|
55
|
+
// field is optional and the parent object already has the value. Keep a
|
|
56
|
+
// default transition so the unit does not come out with no transitions
|
|
57
|
+
// at all.
|
|
58
|
+
kind: "return",
|
|
59
|
+
match: { type: "functionFallthrough" },
|
|
60
|
+
extraction: {}
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
inputMapping: {
|
|
64
|
+
type: "decoratedParams",
|
|
65
|
+
decoratorRoleMap: {
|
|
66
|
+
Args: "args",
|
|
67
|
+
Parent: "parent",
|
|
68
|
+
Context: "context",
|
|
69
|
+
Info: "info"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
var index_default = nestjsGraphqlFramework;
|
|
75
|
+
export {
|
|
76
|
+
index_default as default
|
|
77
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-nestjs-rest';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// ../framework/nestjs-rest/dist/index.js
|
|
2
|
+
function nestjsRestFramework(options = {}) {
|
|
3
|
+
return {
|
|
4
|
+
name: "nestjs-rest",
|
|
5
|
+
languages: ["typescript"],
|
|
6
|
+
protocol: "http",
|
|
7
|
+
discovery: [
|
|
8
|
+
{
|
|
9
|
+
kind: "handler",
|
|
10
|
+
match: {
|
|
11
|
+
type: "decoratedRoute",
|
|
12
|
+
importModule: "@nestjs/common",
|
|
13
|
+
// First match wins, so the framework's own decorator is
|
|
14
|
+
// tried before any wrapper a project names.
|
|
15
|
+
classDecorators: ["Controller", ...options.classDecorators ?? []],
|
|
16
|
+
methodDecoratorRouteMap: {
|
|
17
|
+
Get: "GET",
|
|
18
|
+
Post: "POST",
|
|
19
|
+
Put: "PUT",
|
|
20
|
+
Delete: "DELETE",
|
|
21
|
+
Patch: "PATCH",
|
|
22
|
+
Options: "OPTIONS",
|
|
23
|
+
Head: "HEAD",
|
|
24
|
+
All: "*"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
requiresImport: ["@nestjs/common"]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
terminals: [
|
|
31
|
+
// NestJS controllers serialise the returned value as the
|
|
32
|
+
// response body and pick a 200 default unless the method
|
|
33
|
+
// declares `@HttpCode(N)` (deferred: that decorator is
|
|
34
|
+
// metadata-only). Match bare returns and treat object literals
|
|
35
|
+
// / identifiers / awaited calls as 200 responses.
|
|
36
|
+
{
|
|
37
|
+
kind: "response",
|
|
38
|
+
match: { type: "returnStatement", excludeCallReturns: false },
|
|
39
|
+
extraction: {
|
|
40
|
+
defaultStatusCode: 200
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
// `throw new HttpException(msg, status)` / `throw new
|
|
45
|
+
// BadRequestException()` etc. NestJS maps these to HTTP
|
|
46
|
+
// responses; v0 records the exception type so downstream
|
|
47
|
+
// contract-checking can pair it with the wire status that
|
|
48
|
+
// the framework would emit.
|
|
49
|
+
kind: "throw",
|
|
50
|
+
match: { type: "throwExpression" },
|
|
51
|
+
extraction: {}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
// Many controllers fall through (return undefined) when the
|
|
55
|
+
// operation is fire-and-forget (`@HttpCode(204)` for
|
|
56
|
+
// delete-style). Keep a default transition so
|
|
57
|
+
// `transitions: []` isn't the surface shape.
|
|
58
|
+
kind: "response",
|
|
59
|
+
match: { type: "functionFallthrough" },
|
|
60
|
+
extraction: {
|
|
61
|
+
defaultStatusCode: 200
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
inputMapping: {
|
|
66
|
+
type: "decoratedParams",
|
|
67
|
+
decoratorRoleMap: {
|
|
68
|
+
Body: "requestBody",
|
|
69
|
+
Param: "pathParams",
|
|
70
|
+
Query: "queryParams",
|
|
71
|
+
Headers: "headers",
|
|
72
|
+
Req: "request",
|
|
73
|
+
Request: "request",
|
|
74
|
+
Res: "response",
|
|
75
|
+
Response: "response",
|
|
76
|
+
Next: "next",
|
|
77
|
+
Session: "session",
|
|
78
|
+
Ip: "ip",
|
|
79
|
+
HostParam: "host",
|
|
80
|
+
UploadedFile: "file",
|
|
81
|
+
UploadedFiles: "files"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
var index_default = nestjsRestFramework;
|
|
87
|
+
export {
|
|
88
|
+
index_default as default
|
|
89
|
+
};
|
package/dist/nextjs.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-nextjs';
|
package/dist/nextjs.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// ../framework/nextjs/dist/index.js
|
|
2
|
+
var ROUTE_METHODS = [
|
|
3
|
+
"GET",
|
|
4
|
+
"POST",
|
|
5
|
+
"PUT",
|
|
6
|
+
"PATCH",
|
|
7
|
+
"DELETE",
|
|
8
|
+
"HEAD",
|
|
9
|
+
"OPTIONS"
|
|
10
|
+
];
|
|
11
|
+
var APP_ROUTES = {
|
|
12
|
+
type: "fromFilename",
|
|
13
|
+
root: "app",
|
|
14
|
+
dropBasenames: ["route", "page"],
|
|
15
|
+
dynamic: "brackets",
|
|
16
|
+
dropParenthesized: true
|
|
17
|
+
};
|
|
18
|
+
var PAGES_ROUTES = {
|
|
19
|
+
type: "fromFilename",
|
|
20
|
+
root: "pages",
|
|
21
|
+
dropBasenames: ["index"],
|
|
22
|
+
dynamic: "brackets"
|
|
23
|
+
};
|
|
24
|
+
var NEXT_SERVER = ["next/server"];
|
|
25
|
+
function nextjsFramework() {
|
|
26
|
+
return {
|
|
27
|
+
name: "nextjs",
|
|
28
|
+
protocol: "http",
|
|
29
|
+
languages: ["typescript", "javascript"],
|
|
30
|
+
discovery: [
|
|
31
|
+
{
|
|
32
|
+
kind: "handler",
|
|
33
|
+
match: {
|
|
34
|
+
type: "fileConvention",
|
|
35
|
+
filePattern: "**/app/**/route.{ts,tsx,js,jsx,mts,mjs}",
|
|
36
|
+
exportNames: ROUTE_METHODS
|
|
37
|
+
},
|
|
38
|
+
bindingExtraction: {
|
|
39
|
+
method: { type: "fromExportName" },
|
|
40
|
+
path: APP_ROUTES
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
kind: "handler",
|
|
45
|
+
match: {
|
|
46
|
+
type: "fileConvention",
|
|
47
|
+
filePattern: "**/pages/api/**/*.{ts,tsx,js,jsx,mts,mjs}",
|
|
48
|
+
exportNames: ["default"]
|
|
49
|
+
},
|
|
50
|
+
bindingExtraction: {
|
|
51
|
+
// One export serves every method, which is what the wildcard says.
|
|
52
|
+
// Pairing matches it against whichever method a consumer used.
|
|
53
|
+
method: { type: "literal", value: "*" },
|
|
54
|
+
path: PAGES_ROUTES
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
terminals: [
|
|
59
|
+
{
|
|
60
|
+
// NextResponse.json(body, { status })
|
|
61
|
+
kind: "response",
|
|
62
|
+
match: {
|
|
63
|
+
type: "functionCall",
|
|
64
|
+
functionName: "NextResponse.json",
|
|
65
|
+
requiresImport: NEXT_SERVER
|
|
66
|
+
},
|
|
67
|
+
extraction: {
|
|
68
|
+
body: { from: "argument", position: 0 },
|
|
69
|
+
statusCode: { from: "argumentProperty", position: 1, name: "status" },
|
|
70
|
+
defaultStatusCode: 200
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
// Response.json(body, { status }), the platform's own, which a
|
|
75
|
+
// handler can return without importing anything.
|
|
76
|
+
kind: "response",
|
|
77
|
+
match: { type: "functionCall", functionName: "Response.json" },
|
|
78
|
+
extraction: {
|
|
79
|
+
body: { from: "argument", position: 0 },
|
|
80
|
+
statusCode: { from: "argumentProperty", position: 1, name: "status" },
|
|
81
|
+
defaultStatusCode: 200
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
// new Response(body, { status }), which a handler returns for
|
|
86
|
+
// anything that is not JSON: a redirect, a stream, plain text.
|
|
87
|
+
kind: "response",
|
|
88
|
+
match: { type: "functionCall", functionName: "Response" },
|
|
89
|
+
extraction: {
|
|
90
|
+
body: { from: "argument", position: 0 },
|
|
91
|
+
statusCode: { from: "argumentProperty", position: 1, name: "status" },
|
|
92
|
+
defaultStatusCode: 200
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
// NextResponse.redirect(url) sends a 307 unless the caller says
|
|
97
|
+
// otherwise, and the alternative is written as an init object
|
|
98
|
+
// this pack does not read yet.
|
|
99
|
+
kind: "response",
|
|
100
|
+
match: {
|
|
101
|
+
type: "functionCall",
|
|
102
|
+
functionName: "NextResponse.redirect",
|
|
103
|
+
requiresImport: NEXT_SERVER
|
|
104
|
+
},
|
|
105
|
+
extraction: { defaultStatusCode: 307 }
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
// A pages handler writes to the response it was handed, the
|
|
109
|
+
// same shape Express uses.
|
|
110
|
+
kind: "response",
|
|
111
|
+
match: {
|
|
112
|
+
type: "parameterMethodCall",
|
|
113
|
+
parameterPosition: 1,
|
|
114
|
+
methodChain: ["status", "json"]
|
|
115
|
+
},
|
|
116
|
+
extraction: {
|
|
117
|
+
statusCode: { from: "argument", position: 0 },
|
|
118
|
+
body: { from: "argument", position: 0 }
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
kind: "response",
|
|
123
|
+
match: {
|
|
124
|
+
type: "parameterMethodCall",
|
|
125
|
+
parameterPosition: 1,
|
|
126
|
+
methodChain: ["json"]
|
|
127
|
+
},
|
|
128
|
+
extraction: {
|
|
129
|
+
body: { from: "argument", position: 0 },
|
|
130
|
+
defaultStatusCode: 200
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
kind: "throw",
|
|
135
|
+
match: { type: "throwExpression" },
|
|
136
|
+
extraction: {}
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
// A route handler takes the request first. The app directory hands
|
|
140
|
+
// it a context object holding the route parameters; a pages handler
|
|
141
|
+
// takes the response object there instead.
|
|
142
|
+
inputMapping: {
|
|
143
|
+
type: "positionalParams",
|
|
144
|
+
params: [
|
|
145
|
+
{ position: 0, role: "request" },
|
|
146
|
+
{ position: 1, role: "context" }
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
var index_default = nextjsFramework;
|
|
152
|
+
export {
|
|
153
|
+
index_default as default
|
|
154
|
+
};
|