@suss/packs 0.33.1 → 0.34.1
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/README.md +10 -11
- package/dist/activerecord.d.ts +7 -0
- package/dist/activerecord.js +53 -5
- package/dist/aiohttp.js +20 -9
- package/dist/apollo-client.js +26 -39
- package/dist/apollo.js +12 -20
- package/dist/aws-dynamodb.js +4 -4
- package/dist/aws-eventbridge.js +3 -3
- package/dist/aws-lambda.js +31 -54
- package/dist/aws-s3.js +1 -1
- package/dist/aws-secrets-manager.js +1 -1
- package/dist/aws-sns.js +2 -2
- package/dist/aws-sqs.js +20 -11
- package/dist/aws-ssm.js +1 -1
- package/dist/axios.js +36 -37
- package/dist/bigquery-python.js +3 -3
- package/dist/bigquery.js +1 -1
- package/dist/{chunk-NYWZHQBJ.js → chunk-GK4BILHB.js} +8 -9
- package/dist/cloudflare-workers.js +26 -35
- package/dist/drizzle.js +15 -20
- package/dist/express.js +3 -6
- package/dist/fabrication.d.ts +1 -0
- package/dist/fabrication.js +36 -0
- package/dist/factory-bot.d.ts +1 -0
- package/dist/factory-bot.js +36 -0
- package/dist/faraday.js +8 -6
- package/dist/fastapi.js +123 -5
- package/dist/fastify.js +10 -14
- package/dist/fetch.js +12 -6
- package/dist/flask-restx.js +19 -12
- package/dist/gcs.js +1 -1
- package/dist/graphql-ruby.js +20 -16
- package/dist/hono.js +17 -27
- package/dist/httpx.js +8 -6
- package/dist/minitest.d.ts +1 -0
- package/dist/minitest.js +59 -0
- package/dist/mongoose.js +7 -7
- package/dist/nestjs-graphql.js +14 -25
- package/dist/nestjs-microservices.js +9 -10
- package/dist/nestjs-rest.js +193 -23
- package/dist/net-http.js +9 -7
- package/dist/nextjs.js +16 -17
- package/dist/node.js +139 -23
- package/dist/package-exports.js +1 -1
- package/dist/pg.js +3 -2
- package/dist/prisma.js +375 -56
- package/dist/pytest.d.ts +1 -0
- package/dist/pytest.js +81 -0
- package/dist/rails.js +1792 -132
- package/dist/react-query.js +1 -1
- package/dist/react-router.js +21 -48
- package/dist/react.js +14 -5
- package/dist/redis.js +1 -1
- package/dist/requests.js +27 -19
- package/dist/rspec.d.ts +1 -0
- package/dist/rspec.js +135 -0
- package/dist/sqlalchemy.js +1 -1
- package/dist/sqlmodel.js +7 -8
- package/dist/ts-rest.js +6 -8
- package/dist/typeorm.d.ts +1 -0
- package/dist/typeorm.js +291 -0
- package/dist/vitest.d.ts +1 -0
- package/dist/vitest.js +64 -0
- package/package.json +47 -11
package/dist/fastapi.js
CHANGED
|
@@ -1,11 +1,88 @@
|
|
|
1
1
|
// ../framework/fastapi/dist/index.js
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
var STARLETTE_STATUS = {
|
|
4
|
+
HTTP_100_CONTINUE: 100,
|
|
5
|
+
HTTP_101_SWITCHING_PROTOCOLS: 101,
|
|
6
|
+
HTTP_102_PROCESSING: 102,
|
|
7
|
+
HTTP_103_EARLY_HINTS: 103,
|
|
8
|
+
HTTP_200_OK: 200,
|
|
9
|
+
HTTP_201_CREATED: 201,
|
|
10
|
+
HTTP_202_ACCEPTED: 202,
|
|
11
|
+
HTTP_203_NON_AUTHORITATIVE_INFORMATION: 203,
|
|
12
|
+
HTTP_204_NO_CONTENT: 204,
|
|
13
|
+
HTTP_205_RESET_CONTENT: 205,
|
|
14
|
+
HTTP_206_PARTIAL_CONTENT: 206,
|
|
15
|
+
HTTP_207_MULTI_STATUS: 207,
|
|
16
|
+
HTTP_208_ALREADY_REPORTED: 208,
|
|
17
|
+
HTTP_226_IM_USED: 226,
|
|
18
|
+
HTTP_300_MULTIPLE_CHOICES: 300,
|
|
19
|
+
HTTP_301_MOVED_PERMANENTLY: 301,
|
|
20
|
+
HTTP_302_FOUND: 302,
|
|
21
|
+
HTTP_303_SEE_OTHER: 303,
|
|
22
|
+
HTTP_304_NOT_MODIFIED: 304,
|
|
23
|
+
HTTP_305_USE_PROXY: 305,
|
|
24
|
+
HTTP_306_RESERVED: 306,
|
|
25
|
+
HTTP_307_TEMPORARY_REDIRECT: 307,
|
|
26
|
+
HTTP_308_PERMANENT_REDIRECT: 308,
|
|
27
|
+
HTTP_400_BAD_REQUEST: 400,
|
|
28
|
+
HTTP_401_UNAUTHORIZED: 401,
|
|
29
|
+
HTTP_402_PAYMENT_REQUIRED: 402,
|
|
30
|
+
HTTP_403_FORBIDDEN: 403,
|
|
31
|
+
HTTP_404_NOT_FOUND: 404,
|
|
32
|
+
HTTP_405_METHOD_NOT_ALLOWED: 405,
|
|
33
|
+
HTTP_406_NOT_ACCEPTABLE: 406,
|
|
34
|
+
HTTP_407_PROXY_AUTHENTICATION_REQUIRED: 407,
|
|
35
|
+
HTTP_408_REQUEST_TIMEOUT: 408,
|
|
36
|
+
HTTP_409_CONFLICT: 409,
|
|
37
|
+
HTTP_410_GONE: 410,
|
|
38
|
+
HTTP_411_LENGTH_REQUIRED: 411,
|
|
39
|
+
HTTP_412_PRECONDITION_FAILED: 412,
|
|
40
|
+
HTTP_413_REQUEST_ENTITY_TOO_LARGE: 413,
|
|
41
|
+
HTTP_413_CONTENT_TOO_LARGE: 413,
|
|
42
|
+
HTTP_414_REQUEST_URI_TOO_LONG: 414,
|
|
43
|
+
HTTP_414_URI_TOO_LONG: 414,
|
|
44
|
+
HTTP_415_UNSUPPORTED_MEDIA_TYPE: 415,
|
|
45
|
+
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE: 416,
|
|
46
|
+
HTTP_416_RANGE_NOT_SATISFIABLE: 416,
|
|
47
|
+
HTTP_417_EXPECTATION_FAILED: 417,
|
|
48
|
+
HTTP_418_IM_A_TEAPOT: 418,
|
|
49
|
+
HTTP_421_MISDIRECTED_REQUEST: 421,
|
|
50
|
+
HTTP_422_UNPROCESSABLE_ENTITY: 422,
|
|
51
|
+
HTTP_422_UNPROCESSABLE_CONTENT: 422,
|
|
52
|
+
HTTP_423_LOCKED: 423,
|
|
53
|
+
HTTP_424_FAILED_DEPENDENCY: 424,
|
|
54
|
+
HTTP_425_TOO_EARLY: 425,
|
|
55
|
+
HTTP_426_UPGRADE_REQUIRED: 426,
|
|
56
|
+
HTTP_428_PRECONDITION_REQUIRED: 428,
|
|
57
|
+
HTTP_429_TOO_MANY_REQUESTS: 429,
|
|
58
|
+
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
|
|
59
|
+
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS: 451,
|
|
60
|
+
HTTP_500_INTERNAL_SERVER_ERROR: 500,
|
|
61
|
+
HTTP_501_NOT_IMPLEMENTED: 501,
|
|
62
|
+
HTTP_502_BAD_GATEWAY: 502,
|
|
63
|
+
HTTP_503_SERVICE_UNAVAILABLE: 503,
|
|
64
|
+
HTTP_504_GATEWAY_TIMEOUT: 504,
|
|
65
|
+
HTTP_505_HTTP_VERSION_NOT_SUPPORTED: 505,
|
|
66
|
+
HTTP_506_VARIANT_ALSO_NEGOTIATES: 506,
|
|
67
|
+
HTTP_507_INSUFFICIENT_STORAGE: 507,
|
|
68
|
+
HTTP_508_LOOP_DETECTED: 508,
|
|
69
|
+
HTTP_510_NOT_EXTENDED: 510,
|
|
70
|
+
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED: 511
|
|
71
|
+
};
|
|
72
|
+
var STATUS_MODULES = ["fastapi.status", "starlette.status"];
|
|
73
|
+
var STATUS_CONSTANTS = Object.fromEntries(
|
|
74
|
+
STATUS_MODULES.flatMap(
|
|
75
|
+
(module) => Object.entries(STARLETTE_STATUS).map(([name, status]) => [
|
|
76
|
+
`${module}.${name}`,
|
|
77
|
+
status
|
|
78
|
+
])
|
|
79
|
+
)
|
|
80
|
+
);
|
|
3
81
|
var optionsSchema = z.object({
|
|
4
82
|
/**
|
|
5
|
-
* Modules
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* configures the pack rather than hardcoded here.
|
|
83
|
+
* Modules that re-export FastAPI's constructors, on top of `fastapi`
|
|
84
|
+
* itself. A dependency stub fills this in; a project's config file
|
|
85
|
+
* may not set it.
|
|
9
86
|
*/
|
|
10
87
|
wrapperModules: z.array(z.string()).optional()
|
|
11
88
|
}).strict();
|
|
@@ -18,10 +95,42 @@ var VERB_ATTRIBUTE_NAMES = {
|
|
|
18
95
|
head: "HEAD",
|
|
19
96
|
options: "OPTIONS"
|
|
20
97
|
};
|
|
98
|
+
var PARAMETER_SOURCES = {
|
|
99
|
+
Header: { role: "headers", underscoresAs: "-" },
|
|
100
|
+
Query: { role: "queryParams" },
|
|
101
|
+
Path: { role: "pathParams" },
|
|
102
|
+
Body: { role: "requestBody" },
|
|
103
|
+
Form: { role: "requestBody" },
|
|
104
|
+
Cookie: { role: "cookies" }
|
|
105
|
+
};
|
|
106
|
+
var REQUEST_SPELLING = {
|
|
107
|
+
headers: { path: ["headers"], saysWhichField: true },
|
|
108
|
+
query: { path: ["queryParams"], saysWhichField: true },
|
|
109
|
+
params: { path: ["pathParams"], saysWhichField: true },
|
|
110
|
+
body: { path: ["requestBody"], saysWhichField: true }
|
|
111
|
+
};
|
|
112
|
+
var INJECTED_PARAMETER_TYPES = [
|
|
113
|
+
"fastapi.Request",
|
|
114
|
+
"fastapi.Response",
|
|
115
|
+
"fastapi.BackgroundTasks",
|
|
116
|
+
"fastapi.WebSocket",
|
|
117
|
+
"fastapi.requests.Request",
|
|
118
|
+
"fastapi.requests.HTTPConnection",
|
|
119
|
+
"fastapi.responses.Response",
|
|
120
|
+
"fastapi.background.BackgroundTasks",
|
|
121
|
+
"fastapi.websockets.WebSocket",
|
|
122
|
+
"fastapi.security.SecurityScopes",
|
|
123
|
+
"starlette.requests.Request",
|
|
124
|
+
"starlette.requests.HTTPConnection",
|
|
125
|
+
"starlette.responses.Response",
|
|
126
|
+
"starlette.background.BackgroundTasks",
|
|
127
|
+
"starlette.websockets.WebSocket"
|
|
128
|
+
];
|
|
21
129
|
function fastapiFramework(options = {}) {
|
|
22
130
|
return {
|
|
23
131
|
name: "fastapi",
|
|
24
132
|
protocol: "http",
|
|
133
|
+
requestSpelling: REQUEST_SPELLING,
|
|
25
134
|
...options.wrapperModules !== void 0 ? { projectModules: options.wrapperModules } : {},
|
|
26
135
|
discovery: [
|
|
27
136
|
{
|
|
@@ -33,10 +142,19 @@ function fastapiFramework(options = {}) {
|
|
|
33
142
|
// FastAPI resolves both of these itself and calls the handler with
|
|
34
143
|
// the result, so a parameter defaulted to one is never sent.
|
|
35
144
|
injectedParameterCallees: ["Depends", "Security"],
|
|
145
|
+
// FastAPI also hands a route these objects by the annotation alone.
|
|
146
|
+
injectedParameterTypes: INJECTED_PARAMETER_TYPES,
|
|
147
|
+
parameterSources: PARAMETER_SOURCES,
|
|
148
|
+
parameterAliasKeyword: "alias",
|
|
36
149
|
// FastAPI returns 200 for a route that declares no status.
|
|
37
150
|
defaultStatusCode: 200,
|
|
151
|
+
// FastAPI checks every declared request input before the handler
|
|
152
|
+
// runs, and responds to a bad one itself.
|
|
153
|
+
validationFailureStatus: 422,
|
|
154
|
+
statusCodeConstants: STATUS_CONSTANTS,
|
|
38
155
|
responseModelKeyword: "response_model",
|
|
39
156
|
statusCodeKeyword: "status_code",
|
|
157
|
+
responsesKeyword: "responses",
|
|
40
158
|
// FastAPI re-exports Starlette's class, and a project may import
|
|
41
159
|
// it from either module.
|
|
42
160
|
responseStatusCalls: [
|
|
@@ -106,7 +224,7 @@ var declares = {
|
|
|
106
224
|
kind: "framework",
|
|
107
225
|
package: "@suss/framework-fastapi",
|
|
108
226
|
dependencies: [{ ecosystem: "pypi", name: "fastapi" }],
|
|
109
|
-
reads: `FastAPI routes (Python)
|
|
227
|
+
reads: `FastAPI routes (Python). The verb comes from the decorator's attribute name, \`APIRouter\` prefixes are composed one \`include_router\` hop deep, and \`response_model\` and \`status_code\` are taken as the declared contract.`
|
|
110
228
|
};
|
|
111
229
|
var index_default = fastapiFramework;
|
|
112
230
|
export {
|
package/dist/fastify.js
CHANGED
|
@@ -17,8 +17,8 @@ function fastifyFramework(_options = {}) {
|
|
|
17
17
|
name: "fastify",
|
|
18
18
|
protocol: "http",
|
|
19
19
|
languages: ["typescript", "javascript"],
|
|
20
|
-
//
|
|
21
|
-
// named `fastify
|
|
20
|
+
// Projects import the app factory as the default `Fastify` or the
|
|
21
|
+
// named `fastify`, and both register routes the same way.
|
|
22
22
|
discovery: [
|
|
23
23
|
...httpRouteDiscovery({
|
|
24
24
|
importModule: "fastify",
|
|
@@ -48,7 +48,7 @@ function fastifyFramework(_options = {}) {
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
|
-
// reply.status(N).send(body),
|
|
51
|
+
// reply.status(N).send(body), the alias for `code`
|
|
52
52
|
kind: "response",
|
|
53
53
|
match: {
|
|
54
54
|
type: "parameterMethodCall",
|
|
@@ -74,9 +74,8 @@ function fastifyFramework(_options = {}) {
|
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
|
-
// reply.redirect(url) or reply.redirect(N, url)
|
|
78
|
-
//
|
|
79
|
-
// extracting the URL string as a status code in the 1-arg form.
|
|
77
|
+
// reply.redirect(url) or reply.redirect(N, url). `minArgs` keeps
|
|
78
|
+
// the URL in the one-argument form from being read as a status.
|
|
80
79
|
kind: "response",
|
|
81
80
|
match: {
|
|
82
81
|
type: "parameterMethodCall",
|
|
@@ -89,19 +88,16 @@ function fastifyFramework(_options = {}) {
|
|
|
89
88
|
}
|
|
90
89
|
},
|
|
91
90
|
{
|
|
92
|
-
// throw
|
|
93
|
-
//
|
|
94
|
-
// Fastify error libraries vary too widely to map here.
|
|
91
|
+
// throw httpErrors.notFound(). Fastify error libraries differ too
|
|
92
|
+
// much to map a status here, so the throw does not record one.
|
|
95
93
|
kind: "throw",
|
|
96
94
|
match: { type: "throwExpression" },
|
|
97
95
|
extraction: {}
|
|
98
96
|
},
|
|
99
97
|
{
|
|
100
|
-
// `return user
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
// of this branch: that call already lands as a parameterMethodCall
|
|
104
|
-
// terminal above, and matching it here would double-fire.
|
|
98
|
+
// `return user`: Fastify sends the value as a 200 body. Without
|
|
99
|
+
// `excludeCallReturns`, `return reply.send(...)` would match here
|
|
100
|
+
// and again as the `send` terminal above.
|
|
105
101
|
kind: "response",
|
|
106
102
|
match: {
|
|
107
103
|
type: "returnStatement",
|
package/dist/fetch.js
CHANGED
|
@@ -19,12 +19,12 @@ function webFetchPack() {
|
|
|
19
19
|
property: "method",
|
|
20
20
|
default: "GET"
|
|
21
21
|
},
|
|
22
|
-
path: { type: "fromArgument", position: 0 }
|
|
22
|
+
path: { type: "fromArgument", position: 0 },
|
|
23
|
+
options: { position: 1 }
|
|
23
24
|
},
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// filter doesn't blow up perf.
|
|
25
|
+
// `fetch` is a global, so there is no import to gate on. Walking
|
|
26
|
+
// every file stays cheap because discovery only looks for calls
|
|
27
|
+
// named `fetch`.
|
|
28
28
|
requiresImport: []
|
|
29
29
|
}
|
|
30
30
|
],
|
|
@@ -55,7 +55,12 @@ function webFetchPack() {
|
|
|
55
55
|
{ name: "text", access: "method", semantics: { type: "body" } },
|
|
56
56
|
{ name: "body", access: "property", semantics: { type: "body" } },
|
|
57
57
|
{ name: "headers", access: "property", semantics: { type: "headers" } }
|
|
58
|
-
]
|
|
58
|
+
],
|
|
59
|
+
// fetch follows 301, 302, 303, 307 and 308, so the caller sees the
|
|
60
|
+
// final response, unless the call passes `redirect: "manual"` or
|
|
61
|
+
// `redirect: "error"`.
|
|
62
|
+
redirectDelivery: "followed",
|
|
63
|
+
redirectOption: { name: "redirect", handsBack: ["manual", "error"] }
|
|
59
64
|
};
|
|
60
65
|
}
|
|
61
66
|
var declares = {
|
|
@@ -63,6 +68,7 @@ var declares = {
|
|
|
63
68
|
package: "@suss/client-web",
|
|
64
69
|
dependencies: [],
|
|
65
70
|
shippedWith: "typescript",
|
|
71
|
+
sourcePattern: /(?:^|[^.\w$]|\b(?:window|globalThis|self)\.)fetch\s*\(/m,
|
|
66
72
|
reads: "Global `fetch` call sites."
|
|
67
73
|
};
|
|
68
74
|
var index_default = webFetchPack;
|
package/dist/flask-restx.js
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
var optionsSchema = z.object({
|
|
4
4
|
/**
|
|
5
|
-
* Modules
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* whoever configures the pack rather than hardcoded here.
|
|
5
|
+
* Modules that re-export flask-restx's route decorator, on top of
|
|
6
|
+
* `flask_restx` itself. A dependency stub fills this in; a project's
|
|
7
|
+
* config file may not set it.
|
|
9
8
|
*/
|
|
10
9
|
wrapperModules: z.array(z.string()).optional()
|
|
11
10
|
}).strict();
|
|
@@ -30,8 +29,8 @@ function flaskRestxFramework(options = {}) {
|
|
|
30
29
|
decoratorName: "route",
|
|
31
30
|
verbMethodNames: VERB_METHOD_NAMES,
|
|
32
31
|
pathParamSyntax: "flaskConverters",
|
|
33
|
-
//
|
|
34
|
-
//
|
|
32
|
+
// The Python adapter's README has a table of what each of these
|
|
33
|
+
// settings does to a written prefix.
|
|
35
34
|
pathRepeatedSlashes: "merged",
|
|
36
35
|
routerComposition: {
|
|
37
36
|
routerConstructorName: "Namespace",
|
|
@@ -53,11 +52,9 @@ function flaskRestxFramework(options = {}) {
|
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
},
|
|
56
|
-
// Flask returns 200 from a resource method that returns a value
|
|
57
|
-
// and sets no status of its own.
|
|
58
55
|
defaultStatusCode: 200,
|
|
59
56
|
// Flask reads a status out of `return body, 201`, so the 200
|
|
60
|
-
// above only
|
|
57
|
+
// above applies only when the return writes no status.
|
|
61
58
|
statusFromReturnedTuple: true,
|
|
62
59
|
// flask-restx re-exports Flask's function, which re-exports
|
|
63
60
|
// Werkzeug's, and a project may import it from any of the three.
|
|
@@ -70,8 +67,8 @@ function flaskRestxFramework(options = {}) {
|
|
|
70
67
|
{
|
|
71
68
|
type: "decoratedWrapper",
|
|
72
69
|
attribute: "before_request",
|
|
73
|
-
// A blueprint's own hook is
|
|
74
|
-
// a namespace
|
|
70
|
+
// A blueprint's own hook is skipped, because a route is decorated
|
|
71
|
+
// on a namespace and the blueprint only mounts it.
|
|
75
72
|
registrars: [
|
|
76
73
|
{
|
|
77
74
|
constructorName: "Flask",
|
|
@@ -100,7 +97,17 @@ function flaskRestxFramework(options = {}) {
|
|
|
100
97
|
}
|
|
101
98
|
]
|
|
102
99
|
}
|
|
103
|
-
]
|
|
100
|
+
],
|
|
101
|
+
// A resource method reads the request off Flask's module-level object.
|
|
102
|
+
requestObjects: [{ module: "flask", name: "request" }],
|
|
103
|
+
// A path parameter is handed to the method, and the rest is read off
|
|
104
|
+
// Flask's `request`: `request.args` for the query string.
|
|
105
|
+
requestSpelling: {
|
|
106
|
+
headers: { path: ["request", "headers"], saysWhichField: true },
|
|
107
|
+
query: { path: ["request", "args"], saysWhichField: true },
|
|
108
|
+
params: { path: ["pathParams"], saysWhichField: true },
|
|
109
|
+
body: { path: ["request", "json"], saysWhichField: true }
|
|
110
|
+
}
|
|
104
111
|
};
|
|
105
112
|
}
|
|
106
113
|
var declares = {
|
package/dist/gcs.js
CHANGED
|
@@ -53,7 +53,7 @@ var declares = {
|
|
|
53
53
|
kind: "effects",
|
|
54
54
|
package: "@suss/framework-gcs",
|
|
55
55
|
dependencies: [{ ecosystem: "npm", name: "@google-cloud/storage" }],
|
|
56
|
-
reads: "Google Cloud Storage calls
|
|
56
|
+
reads: "Google Cloud Storage calls. Each one becomes a storage-access interaction."
|
|
57
57
|
};
|
|
58
58
|
var index_default = gcsFramework;
|
|
59
59
|
export {
|
package/dist/graphql-ruby.js
CHANGED
|
@@ -4,20 +4,24 @@ import { z } from "zod";
|
|
|
4
4
|
import { SCALAR_SHAPES } from "@suss/contract-graphql";
|
|
5
5
|
var optionsSchema = z.object({
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* The directory the pack looks under for the class a `mutation:` or
|
|
8
|
+
* `resolver:` field references, for example
|
|
9
|
+
* `path.join(repoRoot, "app/graphql")`. A relative path resolves
|
|
10
|
+
* against `configDirectory`, or the working directory when that is
|
|
11
|
+
* unset.
|
|
11
12
|
*/
|
|
12
13
|
root: z.string(),
|
|
13
14
|
/**
|
|
14
|
-
* The
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* itself.
|
|
15
|
+
* The CLI fills this in with the config file's directory, or with the
|
|
16
|
+
* directory the run reads when there is no file. A config file does
|
|
17
|
+
* not set it.
|
|
18
18
|
*/
|
|
19
19
|
configDirectory: z.string().optional(),
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Base classes beyond the generated `Types::Base*` ones whose
|
|
22
|
+
* subclasses declare GraphQL fields. A config file may not set this; a
|
|
23
|
+
* dependency stub fills it.
|
|
24
|
+
*/
|
|
21
25
|
baseClassNames: z.array(z.string()).optional(),
|
|
22
26
|
/** The schema-wide camelCase default. A `field` or `argument` call's own `camelize:` keyword overrides it for that one name. */
|
|
23
27
|
camelize: z.boolean().optional()
|
|
@@ -72,10 +76,9 @@ function graphqlRubyFramework(options) {
|
|
|
72
76
|
requiredDefault: true,
|
|
73
77
|
camelizeKeyword: "camelize",
|
|
74
78
|
camelizeDefault: options.camelize ?? true,
|
|
75
|
-
// The standard scalars come from the shared SDL table, so a
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
// `Integer` class as a synonym for its `Int` scalar.
|
|
79
|
+
// The standard scalars come from the shared SDL table, so a contract
|
|
80
|
+
// read from Ruby uses the same shapes as one read from SDL.
|
|
81
|
+
// graphql-ruby also accepts Ruby's `Integer` class for `Int`.
|
|
79
82
|
scalars: {
|
|
80
83
|
...SCALAR_SHAPES,
|
|
81
84
|
Integer: { type: "number" }
|
|
@@ -98,7 +101,7 @@ function graphqlRubyFramework(options) {
|
|
|
98
101
|
discovery: [pattern],
|
|
99
102
|
// A resolver that reads a model through the dataloader passes the model
|
|
100
103
|
// as an argument, so the read is recorded against that model when a
|
|
101
|
-
// storage pack in the same run
|
|
104
|
+
// storage pack in the same run recognizes it as one.
|
|
102
105
|
loaders: [
|
|
103
106
|
{
|
|
104
107
|
loader: "dataloader",
|
|
@@ -121,12 +124,13 @@ var declares = {
|
|
|
121
124
|
kind: "framework",
|
|
122
125
|
package: "@suss/framework-graphql-ruby",
|
|
123
126
|
dependencies: [{ ecosystem: "rubygems", name: "graphql" }],
|
|
124
|
-
reads: "graphql-ruby class-based field DSL (Ruby)
|
|
127
|
+
reads: "graphql-ruby class-based field DSL (Ruby). The pack follows `mutation:` and `resolver:` wiring one hop out to what the referenced class declares. It also records the model a resolver reads through `dataloader`, when a storage pack in the run recognizes that model.",
|
|
125
128
|
configuration: {
|
|
126
129
|
file: "suss.graphql-ruby.json",
|
|
127
130
|
example: { root: "app/graphql" },
|
|
128
131
|
required: true,
|
|
129
|
-
why: "the directory a field's wired class is looked up under, read relative to this file. A Rails app generated by the library keeps its types and mutations under app/graphql."
|
|
132
|
+
why: "the directory a field's wired class is looked up under, read relative to this file. A Rails app generated by the library keeps its types and mutations under app/graphql.",
|
|
133
|
+
defaults: { root: "app/graphql" }
|
|
130
134
|
}
|
|
131
135
|
};
|
|
132
136
|
var index_default = graphqlRubyFramework;
|
package/dist/hono.js
CHANGED
|
@@ -37,21 +37,15 @@ function honoFramework(_options = {}) {
|
|
|
37
37
|
name: "hono",
|
|
38
38
|
protocol: "http",
|
|
39
39
|
languages: ["typescript", "javascript"],
|
|
40
|
-
// createRoute
|
|
41
|
-
//
|
|
42
|
-
// the library, where
|
|
40
|
+
// `createRoute` returns its config unchanged, so the call is the route
|
|
41
|
+
// object. The pack has to declare this because the function's body is
|
|
42
|
+
// in the library, where suss cannot read it.
|
|
43
43
|
transparentWrappers: [
|
|
44
|
-
{
|
|
44
|
+
{ module: "@hono/zod-openapi", name: "createRoute", argument: 0 }
|
|
45
45
|
],
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// through an import when it's declared in another file. A mount
|
|
50
|
-
// nested more than one level deep composes too, since the same
|
|
51
|
-
// index a mount resolves to is asked again for its own mount; a
|
|
52
|
-
// mount the resolution store can't follow to a concrete sub-app,
|
|
53
|
-
// or whose prefix isn't a string literal, leaves the route's path
|
|
54
|
-
// as written.
|
|
46
|
+
// A route on a sub-app mounted with `app.route(prefix, sub)` gets the
|
|
47
|
+
// prefix in front of its path, at any depth of nesting. The README
|
|
48
|
+
// covers the mounts that leave a path as written.
|
|
55
49
|
discovery: [
|
|
56
50
|
...httpRouteDiscovery({
|
|
57
51
|
importModule: "hono",
|
|
@@ -66,11 +60,9 @@ function honoFramework(_options = {}) {
|
|
|
66
60
|
mount: { method: "route", prefixPosition: 0, targetPosition: 1 }
|
|
67
61
|
}),
|
|
68
62
|
{
|
|
69
|
-
// app.openapi(route, handler)
|
|
70
|
-
// createRoute({ method, path
|
|
71
|
-
//
|
|
72
|
-
// the reference, and the route object has its own method and path on
|
|
73
|
-
// it.
|
|
63
|
+
// `app.openapi(route, handler)`, where the route is often a
|
|
64
|
+
// `createRoute({ method, path })` object in another file. The
|
|
65
|
+
// method and path come off that object.
|
|
74
66
|
kind: "handler",
|
|
75
67
|
match: {
|
|
76
68
|
type: "registrationCall",
|
|
@@ -109,9 +101,9 @@ function honoFramework(_options = {}) {
|
|
|
109
101
|
importNames: ["Hono", "OpenAPIHono"],
|
|
110
102
|
methods: METHODS
|
|
111
103
|
}),
|
|
112
|
-
// The createRoute object
|
|
113
|
-
//
|
|
114
|
-
//
|
|
104
|
+
// The `createRoute` object lists the endpoint's responses, so a
|
|
105
|
+
// handler that returns a status missing from that list gets a
|
|
106
|
+
// contract finding.
|
|
115
107
|
contractReading: {
|
|
116
108
|
discovery: {
|
|
117
109
|
importModule: "@hono/zod-openapi",
|
|
@@ -190,8 +182,8 @@ function honoFramework(_options = {}) {
|
|
|
190
182
|
extraction: { defaultStatusCode: 404 }
|
|
191
183
|
},
|
|
192
184
|
{
|
|
193
|
-
// throw new HTTPException(status, { message })
|
|
194
|
-
// exception's status as the
|
|
185
|
+
// throw new HTTPException(status, { message }): Hono sends the
|
|
186
|
+
// exception's status as the response.
|
|
195
187
|
kind: "throw",
|
|
196
188
|
match: { type: "throwExpression" },
|
|
197
189
|
extraction: {
|
|
@@ -203,14 +195,12 @@ function honoFramework(_options = {}) {
|
|
|
203
195
|
producesResponse: true
|
|
204
196
|
}
|
|
205
197
|
],
|
|
206
|
-
// One parameter, the context, carrying the request and the response
|
|
207
|
-
// methods together.
|
|
208
198
|
inputMapping: {
|
|
209
199
|
type: "positionalParams",
|
|
210
200
|
params: [{ position: 0, role: "context" }]
|
|
211
201
|
},
|
|
212
|
-
// `c.req.header("x-tenant-id")`
|
|
213
|
-
//
|
|
202
|
+
// In `c.req.header("x-tenant-id")` the field is an argument, and the
|
|
203
|
+
// recorded read keeps only the method, so it loses which field it was.
|
|
214
204
|
requestSpelling: {
|
|
215
205
|
headers: { path: ["context", "req", "header"], saysWhichField: false },
|
|
216
206
|
query: { path: ["context", "req", "query"], saysWhichField: false },
|
package/dist/httpx.js
CHANGED
|
@@ -25,20 +25,22 @@ function httpxClient() {
|
|
|
25
25
|
methodKeyword: "method",
|
|
26
26
|
urlPosition: 1
|
|
27
27
|
},
|
|
28
|
-
// Both are written as a context manager as often as they are
|
|
29
|
-
// assigned, and the adapter reads a `with ... as` the same way.
|
|
30
28
|
receiverConstructors: ["Client", "AsyncClient"],
|
|
31
|
-
// httpx
|
|
32
|
-
//
|
|
29
|
+
// httpx copies the requests response API, with `is_success` in
|
|
30
|
+
// place of `ok`.
|
|
33
31
|
response: {
|
|
34
32
|
statusCode: ["status_code"],
|
|
35
33
|
success: ["is_success"],
|
|
36
34
|
body: ["json", "text", "content"],
|
|
37
|
-
failureDelivery: "response"
|
|
35
|
+
failureDelivery: "response",
|
|
36
|
+
// httpx hands a 3xx back unless the call passes
|
|
37
|
+
// `follow_redirects=True`.
|
|
38
|
+
redirectDelivery: "response",
|
|
39
|
+
redirectOption: { name: "follow_redirects", handsBack: [false] }
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
],
|
|
41
|
-
// Both classes document `__enter__` as
|
|
43
|
+
// Both classes document `__enter__` as returning the client, so
|
|
42
44
|
// `with httpx.Client() as c` puts the constructed client in c.
|
|
43
45
|
contextManagers: [
|
|
44
46
|
{ module: "httpx", returnsSelf: ["Client", "AsyncClient"] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { declares, default, optionsSchema } from '@suss/framework-minitest';
|
package/dist/minitest.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// ../framework/minitest/dist/index.js
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var optionsSchema = z.object({
|
|
4
|
+
/**
|
|
5
|
+
* The test files to read, matched on whole path segments from the
|
|
6
|
+
* end. `suss extract --intent` fills it in from the tests the PRDs
|
|
7
|
+
* list, so a run reads those files and no others. Left out, every
|
|
8
|
+
* `*_test.rb` file is read.
|
|
9
|
+
*/
|
|
10
|
+
files: z.array(z.string().min(1)).optional()
|
|
11
|
+
}).strict();
|
|
12
|
+
var TEST_CASE_CLASSES = [
|
|
13
|
+
"Minitest::Test",
|
|
14
|
+
"ActiveSupport::TestCase",
|
|
15
|
+
"ActionDispatch::IntegrationTest",
|
|
16
|
+
"ActionDispatch::SystemTestCase",
|
|
17
|
+
"ActionController::TestCase",
|
|
18
|
+
"ActionMailer::TestCase",
|
|
19
|
+
"ActionView::TestCase",
|
|
20
|
+
"ActiveJob::TestCase",
|
|
21
|
+
"ActionCable::TestCase",
|
|
22
|
+
"ActionCable::Channel::TestCase",
|
|
23
|
+
"ActionCable::Connection::TestCase",
|
|
24
|
+
"Rails::Generators::TestCase"
|
|
25
|
+
];
|
|
26
|
+
function minitestFramework(options = {}) {
|
|
27
|
+
return {
|
|
28
|
+
name: "minitest",
|
|
29
|
+
protocol: "in-process",
|
|
30
|
+
discovery: [],
|
|
31
|
+
testClasses: [
|
|
32
|
+
{
|
|
33
|
+
filePatterns: ["*_test.rb"],
|
|
34
|
+
baseClassNames: TEST_CASE_CLASSES,
|
|
35
|
+
testMethodPrefix: "test_",
|
|
36
|
+
testBlockMethods: ["test"],
|
|
37
|
+
blockTestName: { prefix: "test_", spacesAs: "_" },
|
|
38
|
+
setupBlockMethods: ["setup"],
|
|
39
|
+
setupMethodNames: ["setup", "before_setup"],
|
|
40
|
+
skipStatements: ["skip"],
|
|
41
|
+
assertionPrefixes: ["assert", "refute", "must_", "wont_", "flunk"],
|
|
42
|
+
stubMethods: ["stub", "stubs", "expects"],
|
|
43
|
+
...options.files !== void 0 ? { files: options.files } : {}
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
var declares = {
|
|
49
|
+
kind: "framework",
|
|
50
|
+
package: "@suss/framework-minitest",
|
|
51
|
+
dependencies: [],
|
|
52
|
+
reads: "Minitest and Rails test cases (Ruby), named by class and test method, so a PRD scenario can say which test covers it."
|
|
53
|
+
};
|
|
54
|
+
var index_default = minitestFramework;
|
|
55
|
+
export {
|
|
56
|
+
declares,
|
|
57
|
+
index_default as default,
|
|
58
|
+
optionsSchema
|
|
59
|
+
};
|
package/dist/mongoose.js
CHANGED
|
@@ -97,9 +97,9 @@ var METHODS = {
|
|
|
97
97
|
},
|
|
98
98
|
findByIdAndDelete: { kind: "write", selector: BY_ID, fields: WHOLE_DOCUMENT },
|
|
99
99
|
findOneAndReplace: { kind: "write", selector: filter(0), fields: payload(1) },
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
//
|
|
100
|
+
// The pack does not track changes to a document after it is built, so
|
|
101
|
+
// the constructor's fields may be stale by the save. A save touches
|
|
102
|
+
// every field.
|
|
103
103
|
save: { kind: "write", fields: WHOLE_DOCUMENT }
|
|
104
104
|
};
|
|
105
105
|
var MODEL_FACTORY = "model";
|
|
@@ -131,9 +131,9 @@ function pluralized(modelName) {
|
|
|
131
131
|
}
|
|
132
132
|
var optionsSchema = z.object({
|
|
133
133
|
/**
|
|
134
|
-
* Scope
|
|
135
|
-
*
|
|
136
|
-
*
|
|
134
|
+
* Scope for the storage binding, `"default"` when unset. Set it when a
|
|
135
|
+
* project has more than one MongoDB connection and their accesses
|
|
136
|
+
* should pair separately.
|
|
137
137
|
*/
|
|
138
138
|
scope: scopeOption.optional()
|
|
139
139
|
}).strict();
|
|
@@ -156,7 +156,7 @@ var declares = {
|
|
|
156
156
|
kind: "effects",
|
|
157
157
|
package: "@suss/framework-mongoose",
|
|
158
158
|
dependencies: [{ ecosystem: "npm", name: "mongoose" }],
|
|
159
|
-
reads: `Mongoose model calls
|
|
159
|
+
reads: `Mongoose model calls. Each one becomes a storage-access interaction on the collection that the model's \`.model(...)\` call declares.`
|
|
160
160
|
};
|
|
161
161
|
var index_default = mongooseFramework;
|
|
162
162
|
export {
|