@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/fetch.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// ../client/web/dist/index.js
|
|
2
|
+
function webFetchPack() {
|
|
3
|
+
return {
|
|
4
|
+
name: "fetch",
|
|
5
|
+
protocol: "http",
|
|
6
|
+
languages: ["typescript"],
|
|
7
|
+
discovery: [
|
|
8
|
+
{
|
|
9
|
+
kind: "client",
|
|
10
|
+
match: {
|
|
11
|
+
type: "clientCall",
|
|
12
|
+
importModule: "global",
|
|
13
|
+
importName: "fetch"
|
|
14
|
+
},
|
|
15
|
+
bindingExtraction: {
|
|
16
|
+
method: {
|
|
17
|
+
type: "fromArgumentProperty",
|
|
18
|
+
position: 1,
|
|
19
|
+
property: "method",
|
|
20
|
+
default: "GET"
|
|
21
|
+
},
|
|
22
|
+
path: { type: "fromArgumentLiteral", position: 0 }
|
|
23
|
+
},
|
|
24
|
+
// No import gate: `fetch` is a global. Walk every file,
|
|
25
|
+
// the discovery dispatch is itself cheap (just looks for
|
|
26
|
+
// call expressions named `fetch`), so the lack of pre-
|
|
27
|
+
// filter doesn't blow up perf.
|
|
28
|
+
requiresImport: []
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
terminals: [
|
|
32
|
+
{
|
|
33
|
+
kind: "return",
|
|
34
|
+
match: { type: "returnStatement" },
|
|
35
|
+
extraction: {}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
kind: "throw",
|
|
39
|
+
match: { type: "throwExpression" },
|
|
40
|
+
extraction: {}
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
inputMapping: {
|
|
44
|
+
type: "positionalParams",
|
|
45
|
+
params: []
|
|
46
|
+
},
|
|
47
|
+
responseSemantics: [
|
|
48
|
+
{
|
|
49
|
+
name: "ok",
|
|
50
|
+
access: "property",
|
|
51
|
+
semantics: { type: "statusRange", min: 200, max: 299 }
|
|
52
|
+
},
|
|
53
|
+
{ name: "status", access: "property", semantics: { type: "statusCode" } },
|
|
54
|
+
{ name: "json", access: "method", semantics: { type: "body" } },
|
|
55
|
+
{ name: "text", access: "method", semantics: { type: "body" } },
|
|
56
|
+
{ name: "body", access: "property", semantics: { type: "body" } },
|
|
57
|
+
{ name: "headers", access: "property", semantics: { type: "headers" } }
|
|
58
|
+
]
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
var index_default = webFetchPack;
|
|
62
|
+
export {
|
|
63
|
+
index_default as default
|
|
64
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-flask-restx';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// ../framework/flask-restx/dist/index.js
|
|
2
|
+
var VERB_METHOD_NAMES = {
|
|
3
|
+
get: "GET",
|
|
4
|
+
post: "POST",
|
|
5
|
+
put: "PUT",
|
|
6
|
+
delete: "DELETE",
|
|
7
|
+
patch: "PATCH",
|
|
8
|
+
head: "HEAD",
|
|
9
|
+
options: "OPTIONS"
|
|
10
|
+
};
|
|
11
|
+
function flaskRestxFramework(options = {}) {
|
|
12
|
+
return {
|
|
13
|
+
name: "flask-restx",
|
|
14
|
+
protocol: "http",
|
|
15
|
+
...options.wrapperModules !== void 0 ? { projectModules: options.wrapperModules } : {},
|
|
16
|
+
discovery: [
|
|
17
|
+
{
|
|
18
|
+
type: "decoratedClassRoute",
|
|
19
|
+
importModule: ["flask_restx", ...options.wrapperModules ?? []],
|
|
20
|
+
decoratorName: "route",
|
|
21
|
+
verbMethodNames: VERB_METHOD_NAMES,
|
|
22
|
+
pathParamSyntax: "flaskConverters",
|
|
23
|
+
// What each of these settings means for a written prefix is the
|
|
24
|
+
// grid in the Python adapter's README.
|
|
25
|
+
pathRepeatedSlashes: "merged",
|
|
26
|
+
routerComposition: {
|
|
27
|
+
routerConstructorName: "Namespace",
|
|
28
|
+
includeMethodName: "add_namespace",
|
|
29
|
+
prefixKeyword: "path",
|
|
30
|
+
mountPrefixEffect: "replaces",
|
|
31
|
+
constructorPrefixRequired: true,
|
|
32
|
+
constructorPrefixTrailingSlash: "trimmed",
|
|
33
|
+
noValuePrefix: "unstated",
|
|
34
|
+
mountObjectPrefix: {
|
|
35
|
+
prefixKeyword: "prefix",
|
|
36
|
+
carrier: {
|
|
37
|
+
importModule: ["flask"],
|
|
38
|
+
constructorName: "Blueprint",
|
|
39
|
+
argumentIndex: 0,
|
|
40
|
+
prefixKeyword: "url_prefix",
|
|
41
|
+
handoffMethodName: "init_app",
|
|
42
|
+
registerMethodName: "register_blueprint"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
// Flask returns 200 from a resource method that returns a value
|
|
47
|
+
// and sets no status of its own.
|
|
48
|
+
defaultStatusCode: 200,
|
|
49
|
+
// Flask reads a status out of `return body, 201`, so the 200
|
|
50
|
+
// above only stands when the body writes no status of its own.
|
|
51
|
+
statusFromReturnedTuple: true
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
var index_default = flaskRestxFramework;
|
|
57
|
+
export {
|
|
58
|
+
index_default as default
|
|
59
|
+
};
|
package/dist/gcs.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-gcs';
|
package/dist/gcs.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// ../framework/gcs/dist/index.js
|
|
2
|
+
import { Node as N } from "ts-morph";
|
|
3
|
+
import { methodDeclaredIn, readName } from "@suss/adapter-typescript";
|
|
4
|
+
import { storageBinding } from "@suss/behavioral-ir";
|
|
5
|
+
var RECOGNITION = "@suss/framework-gcs";
|
|
6
|
+
var CLIENT_MODULE = "@google-cloud/storage";
|
|
7
|
+
var OPERATIONS = {
|
|
8
|
+
download: "read",
|
|
9
|
+
createReadStream: "read",
|
|
10
|
+
getMetadata: "read",
|
|
11
|
+
exists: "read",
|
|
12
|
+
isPublic: "read",
|
|
13
|
+
getFiles: "read",
|
|
14
|
+
save: "write",
|
|
15
|
+
upload: "write",
|
|
16
|
+
createWriteStream: "write",
|
|
17
|
+
delete: "write",
|
|
18
|
+
copy: "write",
|
|
19
|
+
move: "write",
|
|
20
|
+
rename: "write",
|
|
21
|
+
setMetadata: "write",
|
|
22
|
+
makePublic: "write",
|
|
23
|
+
makePrivate: "write"
|
|
24
|
+
};
|
|
25
|
+
var SIGNED_URL = "getSignedUrl";
|
|
26
|
+
var SIGNED_ACTIONS = {
|
|
27
|
+
read: "read",
|
|
28
|
+
write: "write",
|
|
29
|
+
delete: "write",
|
|
30
|
+
resumable: "write"
|
|
31
|
+
};
|
|
32
|
+
var BUCKET_STEP = "bucket";
|
|
33
|
+
var FILE_STEP = "file";
|
|
34
|
+
function gcsRecognizer(call, ctx) {
|
|
35
|
+
const callNode = call;
|
|
36
|
+
const resolve = ctx.resolveWrittenValue ?? (() => null);
|
|
37
|
+
const callee = callNode.getExpression();
|
|
38
|
+
if (!N.isPropertyAccessExpression(callee)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const operation = callee.getName();
|
|
42
|
+
const kind = kindOf(operation, callNode, resolve);
|
|
43
|
+
if (kind === null || !methodDeclaredIn(callee, CLIENT_MODULE)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const chain = walkChain(callee.getExpression(), resolve);
|
|
47
|
+
return [
|
|
48
|
+
{
|
|
49
|
+
type: "interaction",
|
|
50
|
+
binding: storageBinding({
|
|
51
|
+
recognition: RECOGNITION,
|
|
52
|
+
storageSystem: "gcs",
|
|
53
|
+
scope: "default",
|
|
54
|
+
container: chain.bucket,
|
|
55
|
+
accessPath: null
|
|
56
|
+
}),
|
|
57
|
+
callee: callee.getText(),
|
|
58
|
+
interaction: {
|
|
59
|
+
class: "storage-access",
|
|
60
|
+
kind,
|
|
61
|
+
// An object has no fields, so a call says nothing about any.
|
|
62
|
+
fields: [],
|
|
63
|
+
operation,
|
|
64
|
+
...chain.object !== null ? { selector: [chain.object] } : {}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
function kindOf(operation, call, resolve) {
|
|
70
|
+
if (operation !== SIGNED_URL) {
|
|
71
|
+
return OPERATIONS[operation] ?? null;
|
|
72
|
+
}
|
|
73
|
+
const config = call.getArguments()[0];
|
|
74
|
+
const asked = config === void 0 ? null : property(config, "action");
|
|
75
|
+
const action = asked === null ? null : readName(asked, { resolve });
|
|
76
|
+
return action === null ? "read" : SIGNED_ACTIONS[action] ?? "read";
|
|
77
|
+
}
|
|
78
|
+
function walkChain(subject, resolve) {
|
|
79
|
+
let step = subject;
|
|
80
|
+
const found = { bucket: null, object: null };
|
|
81
|
+
for (let hops = 0; step !== null && hops < MAX_CHAIN_STEPS; hops++) {
|
|
82
|
+
if (N.isIdentifier(step) || N.isPropertyAccessExpression(step)) {
|
|
83
|
+
const written = resolve(step);
|
|
84
|
+
step = written === step ? null : written;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (!N.isCallExpression(step)) {
|
|
88
|
+
return found;
|
|
89
|
+
}
|
|
90
|
+
const callee = step.getExpression();
|
|
91
|
+
if (!N.isPropertyAccessExpression(callee)) {
|
|
92
|
+
return found;
|
|
93
|
+
}
|
|
94
|
+
const named = callee.getName();
|
|
95
|
+
const argument = step.getArguments()[0];
|
|
96
|
+
if (named === FILE_STEP && found.object === null) {
|
|
97
|
+
found.object = argument === void 0 ? null : readName(argument, { resolve, unsettled: "reference" });
|
|
98
|
+
}
|
|
99
|
+
if (named === BUCKET_STEP && found.bucket === null) {
|
|
100
|
+
found.bucket = argument === void 0 ? null : readName(argument, { resolve, unsettled: "reference" });
|
|
101
|
+
return found;
|
|
102
|
+
}
|
|
103
|
+
step = callee.getExpression();
|
|
104
|
+
}
|
|
105
|
+
return found;
|
|
106
|
+
}
|
|
107
|
+
var MAX_CHAIN_STEPS = 8;
|
|
108
|
+
function property(input, name) {
|
|
109
|
+
if (!N.isObjectLiteralExpression(input)) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
for (const prop of input.getProperties()) {
|
|
113
|
+
if (N.isPropertyAssignment(prop) && prop.getName() === name) {
|
|
114
|
+
return prop.getInitializer() ?? null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
function gcsFramework() {
|
|
120
|
+
return {
|
|
121
|
+
name: "gcs",
|
|
122
|
+
protocol: "gcs",
|
|
123
|
+
languages: ["typescript", "javascript"],
|
|
124
|
+
discovery: [],
|
|
125
|
+
terminals: [],
|
|
126
|
+
inputMapping: { type: "positionalParams", params: [] },
|
|
127
|
+
requiresImport: [CLIENT_MODULE],
|
|
128
|
+
invocationRecognizers: [gcsRecognizer]
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
var index_default = gcsFramework;
|
|
132
|
+
export {
|
|
133
|
+
index_default as default
|
|
134
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-graphql-ruby';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// ../framework/graphql-ruby/dist/index.js
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { SCALAR_SHAPES } from "@suss/contract-graphql";
|
|
4
|
+
var DEFAULT_BASE_CLASS_NAMES = [
|
|
5
|
+
"Types::BaseObject",
|
|
6
|
+
"Types::BaseInterface",
|
|
7
|
+
"Types::BaseInputObject",
|
|
8
|
+
"Types::BaseEnum",
|
|
9
|
+
"Types::BaseUnion",
|
|
10
|
+
"Types::BaseScalar"
|
|
11
|
+
];
|
|
12
|
+
function rootDirectory(options) {
|
|
13
|
+
if (options.configDirectory === void 0 || path.isAbsolute(options.root)) {
|
|
14
|
+
return options.root;
|
|
15
|
+
}
|
|
16
|
+
return path.resolve(options.configDirectory, options.root);
|
|
17
|
+
}
|
|
18
|
+
function graphqlRubyFramework(options) {
|
|
19
|
+
if (typeof options?.root !== "string" || options.root === "") {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"it needs `root`, the directory a wired field's class is looked up under, and no default can be right: that is this project's own directory layout. A Rails app generated by the library keeps it at app/graphql."
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
const pattern = {
|
|
25
|
+
type: "graphqlObjectFields",
|
|
26
|
+
baseClassNames: [
|
|
27
|
+
...DEFAULT_BASE_CLASS_NAMES,
|
|
28
|
+
...options.baseClassNames ?? []
|
|
29
|
+
],
|
|
30
|
+
root: rootDirectory(options),
|
|
31
|
+
pathConvention: "railsUnderscore",
|
|
32
|
+
fieldCallName: "field",
|
|
33
|
+
typeCallName: "type",
|
|
34
|
+
argumentCallName: "argument",
|
|
35
|
+
wiringKeywords: ["mutation", "resolver"],
|
|
36
|
+
resolverMethodName: "resolve",
|
|
37
|
+
// The classes graphql-ruby's own generated base classes extend or
|
|
38
|
+
// mix in. A project's chain ends at one of them.
|
|
39
|
+
ancestryRootClassNames: [
|
|
40
|
+
"GraphQL::Schema::Object",
|
|
41
|
+
"GraphQL::Schema::Mutation",
|
|
42
|
+
"GraphQL::Schema::Resolver",
|
|
43
|
+
"GraphQL::Schema::Interface",
|
|
44
|
+
"GraphQL::Schema::InputObject",
|
|
45
|
+
"GraphQL::Schema::Enum",
|
|
46
|
+
"GraphQL::Schema::Union",
|
|
47
|
+
"GraphQL::Schema::Scalar"
|
|
48
|
+
],
|
|
49
|
+
requiredKeyword: "required",
|
|
50
|
+
// graphql-ruby registers an argument as required unless the call
|
|
51
|
+
// opts out with `required: false`.
|
|
52
|
+
requiredDefault: true,
|
|
53
|
+
camelizeKeyword: "camelize",
|
|
54
|
+
camelizeDefault: options.camelize ?? true,
|
|
55
|
+
// The standard scalars come from the shared SDL table, so a
|
|
56
|
+
// contract read from Ruby compares against one read from SDL
|
|
57
|
+
// without a vocabulary mismatch. graphql-ruby accepts Ruby's own
|
|
58
|
+
// `Integer` class as a synonym for its `Int` scalar.
|
|
59
|
+
scalars: {
|
|
60
|
+
...SCALAR_SHAPES,
|
|
61
|
+
Integer: { type: "number" }
|
|
62
|
+
},
|
|
63
|
+
scalarNamePrefixes: ["GraphQL::Types::"],
|
|
64
|
+
typeNameConvention: "stripTypeSuffix",
|
|
65
|
+
// RelayClassicMutation wraps every declared argument into one
|
|
66
|
+
// `input` argument on the wire and adds clientMutationId to it.
|
|
67
|
+
argumentWrapping: {
|
|
68
|
+
ancestorClassName: "GraphQL::Schema::RelayClassicMutation",
|
|
69
|
+
argumentName: "input",
|
|
70
|
+
extraFields: {
|
|
71
|
+
clientMutationId: { type: { type: "text" }, required: false }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
name: "graphql-ruby",
|
|
77
|
+
protocol: "http-graphql",
|
|
78
|
+
discovery: [pattern]
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
var index_default = graphqlRubyFramework;
|
|
82
|
+
export {
|
|
83
|
+
index_default as default
|
|
84
|
+
};
|
package/dist/hono.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-hono';
|
package/dist/hono.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// ../framework/hono/dist/index.js
|
|
2
|
+
import { httpRouteDiscovery } from "@suss/extractor";
|
|
3
|
+
var HTTP_EXCEPTION_CODES = {
|
|
4
|
+
HTTPException: 500
|
|
5
|
+
};
|
|
6
|
+
function honoFramework() {
|
|
7
|
+
return {
|
|
8
|
+
name: "hono",
|
|
9
|
+
protocol: "http",
|
|
10
|
+
languages: ["typescript", "javascript"],
|
|
11
|
+
// createRoute wraps its config without changing it; the call IS the
|
|
12
|
+
// route object. Declared here because the wrapper's body lives in
|
|
13
|
+
// the library, where nobody can read it.
|
|
14
|
+
transparentWrappers: [
|
|
15
|
+
{ callee: "createRoute", argument: 0, module: "@hono/zod-openapi" }
|
|
16
|
+
],
|
|
17
|
+
// `new Hono()` and `new OpenAPIHono()` both register the same way.
|
|
18
|
+
// Sub-apps mounted with `app.route(prefix, sub)` compose the
|
|
19
|
+
// prefix into a route declared on the sub-app, following the sub-app
|
|
20
|
+
// through an import when it's declared in another file. A mount
|
|
21
|
+
// nested more than one level deep composes too, since the same
|
|
22
|
+
// index a mount resolves to is asked again for its own mount; a
|
|
23
|
+
// mount the resolution store can't follow to a concrete sub-app,
|
|
24
|
+
// or whose prefix isn't a string literal, leaves the route's path
|
|
25
|
+
// as written.
|
|
26
|
+
discovery: [
|
|
27
|
+
...httpRouteDiscovery({
|
|
28
|
+
importModule: "hono",
|
|
29
|
+
importNames: ["Hono", "OpenAPIHono"],
|
|
30
|
+
methods: [
|
|
31
|
+
".get",
|
|
32
|
+
".post",
|
|
33
|
+
".put",
|
|
34
|
+
".delete",
|
|
35
|
+
".patch",
|
|
36
|
+
".options",
|
|
37
|
+
".all"
|
|
38
|
+
],
|
|
39
|
+
mount: { method: "route", prefixPosition: 0, targetPosition: 1 }
|
|
40
|
+
}),
|
|
41
|
+
...httpRouteDiscovery({
|
|
42
|
+
importModule: "@hono/zod-openapi",
|
|
43
|
+
importNames: ["OpenAPIHono"],
|
|
44
|
+
methods: [
|
|
45
|
+
".get",
|
|
46
|
+
".post",
|
|
47
|
+
".put",
|
|
48
|
+
".delete",
|
|
49
|
+
".patch",
|
|
50
|
+
".options",
|
|
51
|
+
".all"
|
|
52
|
+
],
|
|
53
|
+
mount: { method: "route", prefixPosition: 0, targetPosition: 1 }
|
|
54
|
+
}),
|
|
55
|
+
{
|
|
56
|
+
// app.openapi(route, handler), where the route is a
|
|
57
|
+
// createRoute({ method, path, ... }) object that usually lives
|
|
58
|
+
// on a shared contract in another file. The fact layer follows
|
|
59
|
+
// the reference, and the route object has its own method and path on
|
|
60
|
+
// it.
|
|
61
|
+
kind: "handler",
|
|
62
|
+
match: {
|
|
63
|
+
type: "registrationCall",
|
|
64
|
+
importModule: "@hono/zod-openapi",
|
|
65
|
+
importName: "OpenAPIHono",
|
|
66
|
+
registrationChain: [".openapi"]
|
|
67
|
+
},
|
|
68
|
+
bindingExtraction: {
|
|
69
|
+
method: {
|
|
70
|
+
type: "fromArgumentProperty",
|
|
71
|
+
position: 0,
|
|
72
|
+
property: "method"
|
|
73
|
+
},
|
|
74
|
+
path: { type: "fromArgumentProperty", position: 0, property: "path" }
|
|
75
|
+
},
|
|
76
|
+
requiresImport: ["@hono/zod-openapi"]
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
// The createRoute object registered alongside the handler declares
|
|
80
|
+
// the endpoint's responses, so a handler returning a status the
|
|
81
|
+
// route never declares is a contract finding, not a style choice.
|
|
82
|
+
contractReading: {
|
|
83
|
+
discovery: {
|
|
84
|
+
importModule: "@hono/zod-openapi",
|
|
85
|
+
importName: "OpenAPIHono",
|
|
86
|
+
registrationChain: [".openapi"]
|
|
87
|
+
},
|
|
88
|
+
responseExtraction: { property: "responses" },
|
|
89
|
+
methodProperty: "method",
|
|
90
|
+
pathProperty: "path",
|
|
91
|
+
endpoint: { from: "registrationArgument", position: 0 }
|
|
92
|
+
},
|
|
93
|
+
terminals: [
|
|
94
|
+
{
|
|
95
|
+
// c.json(body, status?)
|
|
96
|
+
kind: "response",
|
|
97
|
+
match: {
|
|
98
|
+
type: "parameterMethodCall",
|
|
99
|
+
parameterPosition: 0,
|
|
100
|
+
methodChain: ["json"]
|
|
101
|
+
},
|
|
102
|
+
extraction: {
|
|
103
|
+
statusCode: { from: "argument", position: 1 },
|
|
104
|
+
body: { from: "argument", position: 0 },
|
|
105
|
+
defaultStatusCode: 200
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
// c.text(body, status?)
|
|
110
|
+
kind: "response",
|
|
111
|
+
match: {
|
|
112
|
+
type: "parameterMethodCall",
|
|
113
|
+
parameterPosition: 0,
|
|
114
|
+
methodChain: ["text"]
|
|
115
|
+
},
|
|
116
|
+
extraction: {
|
|
117
|
+
statusCode: { from: "argument", position: 1 },
|
|
118
|
+
body: { from: "argument", position: 0 },
|
|
119
|
+
defaultStatusCode: 200
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
// c.body(data, status?)
|
|
124
|
+
kind: "response",
|
|
125
|
+
match: {
|
|
126
|
+
type: "parameterMethodCall",
|
|
127
|
+
parameterPosition: 0,
|
|
128
|
+
methodChain: ["body"]
|
|
129
|
+
},
|
|
130
|
+
extraction: {
|
|
131
|
+
statusCode: { from: "argument", position: 1 },
|
|
132
|
+
body: { from: "argument", position: 0 },
|
|
133
|
+
defaultStatusCode: 200
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
// c.redirect(location, status?). Hono defaults to 302.
|
|
138
|
+
kind: "response",
|
|
139
|
+
match: {
|
|
140
|
+
type: "parameterMethodCall",
|
|
141
|
+
parameterPosition: 0,
|
|
142
|
+
methodChain: ["redirect"]
|
|
143
|
+
},
|
|
144
|
+
extraction: {
|
|
145
|
+
statusCode: { from: "argument", position: 1 },
|
|
146
|
+
defaultStatusCode: 302
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
// c.notFound()
|
|
151
|
+
kind: "response",
|
|
152
|
+
match: {
|
|
153
|
+
type: "parameterMethodCall",
|
|
154
|
+
parameterPosition: 0,
|
|
155
|
+
methodChain: ["notFound"]
|
|
156
|
+
},
|
|
157
|
+
extraction: { defaultStatusCode: 404 }
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
// throw new HTTPException(status, { message }); hono sends the
|
|
161
|
+
// exception's status as the wire response.
|
|
162
|
+
kind: "throw",
|
|
163
|
+
match: { type: "throwExpression" },
|
|
164
|
+
extraction: {
|
|
165
|
+
statusCode: {
|
|
166
|
+
from: "constructor",
|
|
167
|
+
codes: HTTP_EXCEPTION_CODES
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
producesResponse: true
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
// One parameter, the context, carrying the request and the response
|
|
174
|
+
// methods together.
|
|
175
|
+
inputMapping: {
|
|
176
|
+
type: "positionalParams",
|
|
177
|
+
params: [{ position: 0, role: "context" }]
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
var index_default = honoFramework;
|
|
182
|
+
export {
|
|
183
|
+
index_default as default
|
|
184
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-mongoose';
|