@suss/packs 0.22.2 → 0.22.3
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/fastapi.js +14 -0
- package/dist/flask-restx.js +9 -2
- package/dist/graphql-ruby.js +4 -2
- package/dist/nestjs-rest.js +3 -4
- package/dist/rails.js +133 -16
- package/dist/sqlalchemy.js +27 -1
- package/package.json +10 -10
package/dist/fastapi.js
CHANGED
|
@@ -37,6 +37,20 @@ function fastapiFramework(options = {}) {
|
|
|
37
37
|
defaultStatusCode: 200,
|
|
38
38
|
responseModelKeyword: "response_model",
|
|
39
39
|
statusCodeKeyword: "status_code",
|
|
40
|
+
// FastAPI re-exports Starlette's class, and a project may import
|
|
41
|
+
// it from either module.
|
|
42
|
+
responseStatusCalls: [
|
|
43
|
+
{
|
|
44
|
+
callee: "fastapi.HTTPException",
|
|
45
|
+
statusKeyword: "status_code",
|
|
46
|
+
statusArgument: 0
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
callee: "starlette.exceptions.HTTPException",
|
|
50
|
+
statusKeyword: "status_code",
|
|
51
|
+
statusArgument: 0
|
|
52
|
+
}
|
|
53
|
+
],
|
|
40
54
|
routerComposition: {
|
|
41
55
|
routerConstructorName: "APIRouter",
|
|
42
56
|
includeMethodName: "include_router",
|
package/dist/flask-restx.js
CHANGED
|
@@ -57,8 +57,15 @@ function flaskRestxFramework(options = {}) {
|
|
|
57
57
|
// and sets no status of its own.
|
|
58
58
|
defaultStatusCode: 200,
|
|
59
59
|
// Flask reads a status out of `return body, 201`, so the 200
|
|
60
|
-
// above only
|
|
61
|
-
statusFromReturnedTuple: true
|
|
60
|
+
// above only applies where the body writes no status of its own.
|
|
61
|
+
statusFromReturnedTuple: true,
|
|
62
|
+
// flask-restx re-exports Flask's function, which re-exports
|
|
63
|
+
// Werkzeug's, and a project may import it from any of the three.
|
|
64
|
+
responseStatusCalls: [
|
|
65
|
+
{ callee: "flask_restx.abort", statusArgument: 0 },
|
|
66
|
+
{ callee: "flask.abort", statusArgument: 0 },
|
|
67
|
+
{ callee: "werkzeug.exceptions.abort", statusArgument: 0 }
|
|
68
|
+
]
|
|
62
69
|
}
|
|
63
70
|
]
|
|
64
71
|
};
|
package/dist/graphql-ruby.js
CHANGED
|
@@ -11,8 +11,10 @@ var optionsSchema = z.object({
|
|
|
11
11
|
*/
|
|
12
12
|
root: z.string(),
|
|
13
13
|
/**
|
|
14
|
-
* The directory
|
|
15
|
-
*
|
|
14
|
+
* The directory a relative `root` is read against: the config file's
|
|
15
|
+
* own directory, or the directory the run reads when the options came
|
|
16
|
+
* without one. The CLI supplies this; it is not written in the file
|
|
17
|
+
* itself.
|
|
16
18
|
*/
|
|
17
19
|
configDirectory: z.string().optional(),
|
|
18
20
|
/** Base classes beyond `Types::BaseObject` that also mark a class as declaring GraphQL fields. */
|
package/dist/nestjs-rest.js
CHANGED
|
@@ -65,10 +65,9 @@ function nestjsRestFramework(options = {}) {
|
|
|
65
65
|
extraction: {}
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
// `transitions: []` isn't the surface shape.
|
|
68
|
+
// A method that runs off the end returns undefined, and Nest
|
|
69
|
+
// sends the same 200 with an empty body it sends for a bare
|
|
70
|
+
// `return;`. Only `@HttpCode(N)` changes that.
|
|
72
71
|
kind: "response",
|
|
73
72
|
match: { type: "functionFallthrough" },
|
|
74
73
|
extraction: {
|
package/dist/rails.js
CHANGED
|
@@ -136,7 +136,9 @@ function joinKey(prefix, segment) {
|
|
|
136
136
|
return prefix === "" ? segment : `${prefix}/${segment}`;
|
|
137
137
|
}
|
|
138
138
|
function joinPath(prefix, segment) {
|
|
139
|
-
|
|
139
|
+
const trimmed = segment.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
140
|
+
const base = prefix.replace(/\/+$/, "");
|
|
141
|
+
return trimmed === "" ? base || "/" : `${base}/${trimmed}`;
|
|
140
142
|
}
|
|
141
143
|
function handleResourceCall(call, ctx, out, plural) {
|
|
142
144
|
const args = readSimpleArgs(call);
|
|
@@ -144,10 +146,10 @@ function handleResourceCall(call, ctx, out, plural) {
|
|
|
144
146
|
if (symbol === null) {
|
|
145
147
|
return;
|
|
146
148
|
}
|
|
147
|
-
const controllerSegment = plural ? symbol : pluralize(symbol);
|
|
149
|
+
const controllerSegment = wordValue(args.keyword.controller) ?? (plural ? symbol : pluralize(symbol));
|
|
148
150
|
const controllerKey = joinKey(ctx.modulePrefix, controllerSegment);
|
|
149
151
|
const prefixBase = ctx.resource !== void 0 ? ctx.resource.nestedBase : ctx.pathPrefix;
|
|
150
|
-
const base = joinPath(prefixBase, symbol);
|
|
152
|
+
const base = joinPath(prefixBase, wordValue(args.keyword.path) ?? symbol);
|
|
151
153
|
const only = readSymbolList(args.keyword.only);
|
|
152
154
|
const except = readSymbolList(args.keyword.except);
|
|
153
155
|
const table = plural ? RESTFUL_ROUTES_PLURAL : RESTFUL_ROUTES_SINGULAR;
|
|
@@ -165,12 +167,13 @@ function handleResourceCall(call, ctx, out, plural) {
|
|
|
165
167
|
if (body === null) {
|
|
166
168
|
return;
|
|
167
169
|
}
|
|
170
|
+
const nestedBase = plural ? `${base}/:${singularize(symbol)}_id` : base;
|
|
168
171
|
const nested = {
|
|
169
172
|
controllerKey,
|
|
170
173
|
collectionBase: base,
|
|
171
174
|
memberBase: plural ? `${base}/:id` : base,
|
|
172
|
-
nestedBase
|
|
173
|
-
ambientBase:
|
|
175
|
+
nestedBase,
|
|
176
|
+
ambientBase: nestedBase
|
|
174
177
|
};
|
|
175
178
|
walkBody(body, { ...ctx, resource: nested }, out);
|
|
176
179
|
}
|
|
@@ -186,6 +189,15 @@ function handleOnBlock(call, ctx, out, isMember) {
|
|
|
186
189
|
const ambientBase = isMember ? ctx.resource.memberBase : ctx.resource.collectionBase;
|
|
187
190
|
walkBody(body, { ...ctx, resource: { ...ctx.resource, ambientBase } }, out);
|
|
188
191
|
}
|
|
192
|
+
function baseForOn(resource, on) {
|
|
193
|
+
if (on === "collection") {
|
|
194
|
+
return resource.collectionBase;
|
|
195
|
+
}
|
|
196
|
+
if (on === "member") {
|
|
197
|
+
return resource.memberBase;
|
|
198
|
+
}
|
|
199
|
+
return resource.ambientBase;
|
|
200
|
+
}
|
|
189
201
|
function handleVerb(call, ctx, out, method) {
|
|
190
202
|
const args = readSimpleArgs(call);
|
|
191
203
|
const target = readRouteTarget(args);
|
|
@@ -193,9 +205,9 @@ function handleVerb(call, ctx, out, method) {
|
|
|
193
205
|
const literalPath = args.positional[0] ? stringValueOf(args.positional[0]) : null;
|
|
194
206
|
const path2 = target.path ?? literalPath;
|
|
195
207
|
if (path2 !== null) {
|
|
196
|
-
out.add(target.controllerKey, target.action, {
|
|
208
|
+
out.add(joinKey(ctx.modulePrefix, target.controllerKey), target.action, {
|
|
197
209
|
method,
|
|
198
|
-
path:
|
|
210
|
+
path: joinPath(ctx.pathPrefix, path2)
|
|
199
211
|
});
|
|
200
212
|
}
|
|
201
213
|
return;
|
|
@@ -207,11 +219,7 @@ function handleVerb(call, ctx, out, method) {
|
|
|
207
219
|
if (symbol === null) {
|
|
208
220
|
return;
|
|
209
221
|
}
|
|
210
|
-
const
|
|
211
|
-
const base = on === "collection" ? ctx.resource.collectionBase : on === "member" ? ctx.resource.memberBase : ctx.resource.ambientBase;
|
|
212
|
-
if (base === null) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
222
|
+
const base = baseForOn(ctx.resource, wordValue(args.keyword.on));
|
|
215
223
|
out.add(ctx.resource.controllerKey, symbol, {
|
|
216
224
|
method,
|
|
217
225
|
path: `${base}/${symbol}`
|
|
@@ -221,7 +229,7 @@ function handleRoot(call, ctx, out) {
|
|
|
221
229
|
const args = readSimpleArgs(call);
|
|
222
230
|
const target = readRouteTarget(args) ?? (args.positional[0] ? splitControllerAction(stringValueOf(args.positional[0]) ?? "") : null);
|
|
223
231
|
if (target !== null) {
|
|
224
|
-
out.add(target.controllerKey, target.action, {
|
|
232
|
+
out.add(joinKey(ctx.modulePrefix, target.controllerKey), target.action, {
|
|
225
233
|
method: "GET",
|
|
226
234
|
path: ctx.pathPrefix === "" ? "/" : ctx.pathPrefix
|
|
227
235
|
});
|
|
@@ -247,7 +255,7 @@ function handleNamespace(call, ctx, out) {
|
|
|
247
255
|
function handleScope(call, ctx, out) {
|
|
248
256
|
const args = readSimpleArgs(call);
|
|
249
257
|
const moduleName = wordValue(args.keyword.module);
|
|
250
|
-
const pathSegment = wordValue(args.keyword.path);
|
|
258
|
+
const pathSegment = wordValue(args.keyword.path) ?? (args.positional[0] ? wordValue(args.positional[0]) : null);
|
|
251
259
|
const block = field(call, "block");
|
|
252
260
|
const body = block !== null ? field(block, "body") : null;
|
|
253
261
|
if (body === null) {
|
|
@@ -329,16 +337,92 @@ function readRoutesFile(absRoutesPath, displayPath) {
|
|
|
329
337
|
gaps: out.gapsAgainst(displayPath)
|
|
330
338
|
};
|
|
331
339
|
}
|
|
340
|
+
var RACK_STATUS_CODE_NAMES = {
|
|
341
|
+
continue: 100,
|
|
342
|
+
switching_protocols: 101,
|
|
343
|
+
processing: 102,
|
|
344
|
+
early_hints: 103,
|
|
345
|
+
ok: 200,
|
|
346
|
+
created: 201,
|
|
347
|
+
accepted: 202,
|
|
348
|
+
non_authoritative_information: 203,
|
|
349
|
+
no_content: 204,
|
|
350
|
+
reset_content: 205,
|
|
351
|
+
partial_content: 206,
|
|
352
|
+
multi_status: 207,
|
|
353
|
+
already_reported: 208,
|
|
354
|
+
im_used: 226,
|
|
355
|
+
multiple_choices: 300,
|
|
356
|
+
moved_permanently: 301,
|
|
357
|
+
found: 302,
|
|
358
|
+
see_other: 303,
|
|
359
|
+
not_modified: 304,
|
|
360
|
+
use_proxy: 305,
|
|
361
|
+
temporary_redirect: 307,
|
|
362
|
+
permanent_redirect: 308,
|
|
363
|
+
bad_request: 400,
|
|
364
|
+
unauthorized: 401,
|
|
365
|
+
payment_required: 402,
|
|
366
|
+
forbidden: 403,
|
|
367
|
+
not_found: 404,
|
|
368
|
+
method_not_allowed: 405,
|
|
369
|
+
not_acceptable: 406,
|
|
370
|
+
proxy_authentication_required: 407,
|
|
371
|
+
request_timeout: 408,
|
|
372
|
+
conflict: 409,
|
|
373
|
+
gone: 410,
|
|
374
|
+
length_required: 411,
|
|
375
|
+
precondition_failed: 412,
|
|
376
|
+
request_entity_too_large: 413,
|
|
377
|
+
payload_too_large: 413,
|
|
378
|
+
content_too_large: 413,
|
|
379
|
+
request_uri_too_long: 414,
|
|
380
|
+
uri_too_long: 414,
|
|
381
|
+
unsupported_media_type: 415,
|
|
382
|
+
requested_range_not_satisfiable: 416,
|
|
383
|
+
range_not_satisfiable: 416,
|
|
384
|
+
expectation_failed: 417,
|
|
385
|
+
misdirected_request: 421,
|
|
386
|
+
unprocessable_entity: 422,
|
|
387
|
+
unprocessable_content: 422,
|
|
388
|
+
locked: 423,
|
|
389
|
+
failed_dependency: 424,
|
|
390
|
+
too_early: 425,
|
|
391
|
+
upgrade_required: 426,
|
|
392
|
+
precondition_required: 428,
|
|
393
|
+
too_many_requests: 429,
|
|
394
|
+
request_header_fields_too_large: 431,
|
|
395
|
+
unavailable_for_legal_reasons: 451,
|
|
396
|
+
internal_server_error: 500,
|
|
397
|
+
not_implemented: 501,
|
|
398
|
+
bad_gateway: 502,
|
|
399
|
+
service_unavailable: 503,
|
|
400
|
+
gateway_timeout: 504,
|
|
401
|
+
http_version_not_supported: 505,
|
|
402
|
+
variant_also_negotiates: 506,
|
|
403
|
+
insufficient_storage: 507,
|
|
404
|
+
loop_detected: 508,
|
|
405
|
+
not_extended: 510,
|
|
406
|
+
network_authentication_required: 511
|
|
407
|
+
};
|
|
332
408
|
var optionsSchema = z.object({
|
|
333
409
|
/** The app directory a bare controller name is looked up under. Every Rails app scaffolds this at `app`. */
|
|
334
410
|
root: z.string().optional(),
|
|
335
411
|
/**
|
|
336
|
-
* The directory
|
|
337
|
-
*
|
|
412
|
+
* The directory a relative `root` or `routesFile` is read against: the
|
|
413
|
+
* config file's own directory, or the directory the run reads when the
|
|
414
|
+
* options came without one. The CLI supplies this; it is not written in
|
|
415
|
+
* the file itself.
|
|
338
416
|
*/
|
|
339
417
|
configDirectory: z.string().optional(),
|
|
340
418
|
/** Base classes beyond `ApplicationController` that also mark a class as a controller. */
|
|
341
419
|
baseClassNames: z.array(z.string()).optional(),
|
|
420
|
+
/**
|
|
421
|
+
* Methods beyond Rails' own that every controller in this project
|
|
422
|
+
* gets without defining them, from a gem such as Devise. They are
|
|
423
|
+
* left off an action's effects the same way Rails' own are.
|
|
424
|
+
*/
|
|
425
|
+
inheritedMethodNames: z.array(z.string()).optional(),
|
|
342
426
|
/** Where this project's routes live, relative to `configDirectory` when there is one. Every Rails app scaffolds this at `config/routes.rb`. */
|
|
343
427
|
routesFile: z.string().optional()
|
|
344
428
|
}).strict();
|
|
@@ -355,6 +439,33 @@ var RESTFUL_ACTIONS = {
|
|
|
355
439
|
update: { method: "PATCH", pathTemplate: "/:resource/:id" },
|
|
356
440
|
destroy: { method: "DELETE", pathTemplate: "/:resource/:id" }
|
|
357
441
|
};
|
|
442
|
+
var RESPONSE_STATUS_CALLS = [
|
|
443
|
+
{ name: "render", statusKeyword: "status" },
|
|
444
|
+
{ name: "head", statusArgument: 0, statusKeyword: "status" },
|
|
445
|
+
{ name: "redirect_to", statusKeyword: "status", defaultStatusCode: 302 },
|
|
446
|
+
{ name: "redirect_back", statusKeyword: "status", defaultStatusCode: 302 }
|
|
447
|
+
];
|
|
448
|
+
var RAILS_CONTROLLER_METHODS = [
|
|
449
|
+
"params",
|
|
450
|
+
"request",
|
|
451
|
+
"response",
|
|
452
|
+
"session",
|
|
453
|
+
"cookies",
|
|
454
|
+
"flash",
|
|
455
|
+
"headers",
|
|
456
|
+
"render",
|
|
457
|
+
"head",
|
|
458
|
+
"redirect_to",
|
|
459
|
+
"redirect_back",
|
|
460
|
+
"respond_to",
|
|
461
|
+
"render_to_string",
|
|
462
|
+
"url_for",
|
|
463
|
+
"helpers",
|
|
464
|
+
"logger",
|
|
465
|
+
"action_name",
|
|
466
|
+
"controller_name",
|
|
467
|
+
"controller_path"
|
|
468
|
+
];
|
|
358
469
|
function controllerKeyFromQualified(qualifiedName) {
|
|
359
470
|
const withoutSuffix = qualifiedName.endsWith("Controller") ? qualifiedName.slice(0, -"Controller".length) : qualifiedName;
|
|
360
471
|
return underscoreConstantPath(withoutSuffix);
|
|
@@ -400,6 +511,12 @@ function railsFramework(options = {}) {
|
|
|
400
511
|
pathConvention: "railsUnderscore",
|
|
401
512
|
ancestryRootClassNames: [...RAILS_ROOT_CLASS_NAMES],
|
|
402
513
|
defaultStatusCode: 200,
|
|
514
|
+
responseStatusCalls: RESPONSE_STATUS_CALLS,
|
|
515
|
+
statusCodeNames: RACK_STATUS_CODE_NAMES,
|
|
516
|
+
inheritedMethodNames: [
|
|
517
|
+
...RAILS_CONTROLLER_METHODS,
|
|
518
|
+
...options.inheritedMethodNames ?? []
|
|
519
|
+
],
|
|
403
520
|
routesFile,
|
|
404
521
|
routeFor: (controllerQualifiedName, actionName) => {
|
|
405
522
|
const key = controllerKeyFromQualified(controllerQualifiedName);
|
package/dist/sqlalchemy.js
CHANGED
|
@@ -14,7 +14,32 @@ function sqlalchemyStorage(options) {
|
|
|
14
14
|
{
|
|
15
15
|
module: "sqlalchemy.orm",
|
|
16
16
|
queryTypes: ["Query", "Session"],
|
|
17
|
-
writes: [
|
|
17
|
+
writes: [
|
|
18
|
+
"update",
|
|
19
|
+
"delete",
|
|
20
|
+
"add",
|
|
21
|
+
"add_all",
|
|
22
|
+
"merge",
|
|
23
|
+
"flush",
|
|
24
|
+
"commit",
|
|
25
|
+
"bulk_save_objects",
|
|
26
|
+
"bulk_insert_mappings",
|
|
27
|
+
"bulk_update_mappings"
|
|
28
|
+
],
|
|
29
|
+
// A Session runs a statement built by `select`/`update`/... whose
|
|
30
|
+
// own chain is read, and the rest of these manage the session.
|
|
31
|
+
recordsNothing: [
|
|
32
|
+
"execute",
|
|
33
|
+
"scalars",
|
|
34
|
+
"scalar",
|
|
35
|
+
"begin",
|
|
36
|
+
"rollback",
|
|
37
|
+
"close",
|
|
38
|
+
"expire",
|
|
39
|
+
"expire_all",
|
|
40
|
+
"expunge",
|
|
41
|
+
"expunge_all"
|
|
42
|
+
],
|
|
18
43
|
storageSystem: options.storageSystem
|
|
19
44
|
},
|
|
20
45
|
{
|
|
@@ -25,6 +50,7 @@ function sqlalchemyStorage(options) {
|
|
|
25
50
|
// constructor rather than reaching it through a mapped class, so there
|
|
26
51
|
// is no project method in between whose return says what it is.
|
|
27
52
|
queryFunctions: ["select", "insert", "update", "delete"],
|
|
53
|
+
valueMethods: ["values"],
|
|
28
54
|
storageSystem: options.storageSystem
|
|
29
55
|
}
|
|
30
56
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/packs",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Every pack suss ships, as one package with a subpath per pack.",
|
|
6
6
|
"keywords": [
|
|
@@ -189,15 +189,15 @@
|
|
|
189
189
|
"ts-morph": "^23.0.0"
|
|
190
190
|
},
|
|
191
191
|
"dependencies": {
|
|
192
|
-
"@suss/adapter-python": "0.22.
|
|
193
|
-
"@suss/adapter-ruby": "0.22.
|
|
194
|
-
"@suss/adapter-typescript": "0.22.
|
|
195
|
-
"@suss/behavioral-ir": "0.22.
|
|
196
|
-
"@suss/contract-graphql": "0.22.
|
|
197
|
-
"@suss/extractor": "0.22.
|
|
198
|
-
"@suss/manifest-aws": "0.22.
|
|
199
|
-
"@suss/recognize": "0.22.
|
|
200
|
-
"@suss/sql": "0.22.
|
|
192
|
+
"@suss/adapter-python": "0.22.3",
|
|
193
|
+
"@suss/adapter-ruby": "0.22.3",
|
|
194
|
+
"@suss/adapter-typescript": "0.22.3",
|
|
195
|
+
"@suss/behavioral-ir": "0.22.3",
|
|
196
|
+
"@suss/contract-graphql": "0.22.3",
|
|
197
|
+
"@suss/extractor": "0.22.3",
|
|
198
|
+
"@suss/manifest-aws": "0.22.3",
|
|
199
|
+
"@suss/recognize": "0.22.3",
|
|
200
|
+
"@suss/sql": "0.22.3",
|
|
201
201
|
"zod": "^4.0.0"
|
|
202
202
|
},
|
|
203
203
|
"devDependencies": {
|