@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/README.md
CHANGED
|
@@ -8,24 +8,23 @@ Every pack suss ships, as one package with a subpath per pack.
|
|
|
8
8
|
npm install --save-dev @suss/packs
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
takes:
|
|
11
|
+
Each pack has its own subpath, and the subpath is the name that
|
|
12
|
+
`suss extract -f` takes:
|
|
13
13
|
|
|
14
14
|
```ts
|
|
15
15
|
import mongoose from "@suss/packs/mongoose";
|
|
16
16
|
import express from "@suss/packs/express";
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
The CLI resolves `-f mongoose` to `@suss/packs/mongoose`
|
|
20
|
-
|
|
19
|
+
The CLI resolves `-f mongoose` to `@suss/packs/mongoose` itself, so you
|
|
20
|
+
do not need an import to run `suss`.
|
|
21
21
|
|
|
22
22
|
## Why one package
|
|
23
23
|
|
|
24
|
-
npm
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
directory and a line in the exports map.
|
|
24
|
+
npm issues a publishing credential through a trusted publisher, and each
|
|
25
|
+
package has to configure its trusted publisher by hand on npmjs.com.
|
|
26
|
+
With one package that setup happens once for every pack. Adding a pack
|
|
27
|
+
takes a directory and a line in the exports map.
|
|
28
28
|
|
|
29
|
-
The packs have no dependencies outside `@suss/*`, and
|
|
30
|
-
|
|
31
|
-
them up.
|
|
29
|
+
The packs have no dependencies outside `@suss/*`, and together they come
|
|
30
|
+
to about 1.2 MB, so splitting them up would save nothing.
|
package/dist/activerecord.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ import '@suss/framework-bigquery';
|
|
|
17
17
|
import '@suss/framework-cloudflare-workers';
|
|
18
18
|
import '@suss/framework-drizzle';
|
|
19
19
|
import '@suss/framework-express';
|
|
20
|
+
import '@suss/framework-fabrication';
|
|
21
|
+
import '@suss/framework-factory-bot';
|
|
20
22
|
import '@suss/client-faraday';
|
|
21
23
|
import '@suss/framework-fastapi';
|
|
22
24
|
import '@suss/framework-fastify';
|
|
@@ -26,6 +28,7 @@ import '@suss/framework-gcs';
|
|
|
26
28
|
import '@suss/framework-graphql-ruby';
|
|
27
29
|
import '@suss/framework-hono';
|
|
28
30
|
import '@suss/client-httpx';
|
|
31
|
+
import '@suss/framework-minitest';
|
|
29
32
|
import '@suss/framework-mongoose';
|
|
30
33
|
import '@suss/framework-nestjs-graphql';
|
|
31
34
|
import '@suss/framework-nestjs-microservices';
|
|
@@ -37,13 +40,17 @@ import '@suss/framework-package-exports';
|
|
|
37
40
|
import '@suss/framework-pg-ruby';
|
|
38
41
|
import '@suss/framework-pg';
|
|
39
42
|
import '@suss/framework-prisma';
|
|
43
|
+
import '@suss/framework-pytest';
|
|
40
44
|
import '@suss/framework-rails';
|
|
41
45
|
import '@suss/framework-react-query';
|
|
42
46
|
import '@suss/framework-react-router';
|
|
43
47
|
import '@suss/framework-react';
|
|
44
48
|
import '@suss/framework-redis';
|
|
45
49
|
import '@suss/client-requests';
|
|
50
|
+
import '@suss/framework-rspec';
|
|
46
51
|
import '@suss/framework-sqlalchemy';
|
|
47
52
|
import '@suss/framework-sqlmodel';
|
|
48
53
|
import '@suss/framework-ts-rest';
|
|
54
|
+
import '@suss/framework-typeorm';
|
|
55
|
+
import '@suss/framework-vitest';
|
|
49
56
|
import '@suss/framework-zustand';
|
package/dist/activerecord.js
CHANGED
|
@@ -1,10 +1,38 @@
|
|
|
1
1
|
// ../framework/activerecord/dist/index.js
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { storageSystemOption } from "@suss/extractor";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
var STORAGE_SYSTEM_OF_ADAPTER = {
|
|
7
|
+
postgresql: "postgresql",
|
|
8
|
+
mysql2: "mysql",
|
|
9
|
+
trilogy: "mysql",
|
|
10
|
+
sqlite3: "sqlite"
|
|
11
|
+
};
|
|
12
|
+
function storageSystemFromDatabaseYml(projectRoot) {
|
|
13
|
+
const file = path.join(projectRoot, "config", "database.yml");
|
|
14
|
+
if (!fs.existsSync(file)) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const systems = /* @__PURE__ */ new Set();
|
|
18
|
+
for (const match of fs.readFileSync(file, "utf8").matchAll(/^\s*adapter:\s*(.*)$/gm)) {
|
|
19
|
+
const system = STORAGE_SYSTEM_OF_ADAPTER[adapterName(match[1] ?? "")];
|
|
20
|
+
if (system === void 0) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
systems.add(system);
|
|
24
|
+
}
|
|
25
|
+
const [only] = systems;
|
|
26
|
+
return systems.size === 1 && only !== void 0 ? { storageSystem: only } : null;
|
|
27
|
+
}
|
|
28
|
+
function adapterName(written) {
|
|
29
|
+
const value = written.replace(/\s+#.*$/, "").trim();
|
|
30
|
+
return /^(["'])(.*)\1$/.exec(value)?.[2] ?? value;
|
|
31
|
+
}
|
|
4
32
|
var optionsSchema = z.object({
|
|
5
33
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
34
|
+
* The database behind the connection. ActiveRecord works with several,
|
|
35
|
+
* and database.yml picks one, so the project has to supply it.
|
|
8
36
|
*/
|
|
9
37
|
storageSystem: storageSystemOption
|
|
10
38
|
}).strict();
|
|
@@ -196,7 +224,26 @@ function activeRecordStorage(options) {
|
|
|
196
224
|
plural: ["has_many", "has_and_belongs_to_many"],
|
|
197
225
|
classNameKeyword: "class_name"
|
|
198
226
|
},
|
|
199
|
-
|
|
227
|
+
scopes: ["scope"],
|
|
228
|
+
storageSystem: options.storageSystem,
|
|
229
|
+
raises: [
|
|
230
|
+
{
|
|
231
|
+
exception: "ActiveRecord::RecordNotFound",
|
|
232
|
+
methods: [
|
|
233
|
+
"find",
|
|
234
|
+
"find_by!",
|
|
235
|
+
"find_sole_by",
|
|
236
|
+
"sole",
|
|
237
|
+
"first!",
|
|
238
|
+
"last!",
|
|
239
|
+
"take!"
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
exception: "ActiveRecord::RecordInvalid",
|
|
244
|
+
methods: ["save!", "create!", "update!", "find_or_create_by!"]
|
|
245
|
+
}
|
|
246
|
+
]
|
|
200
247
|
}
|
|
201
248
|
];
|
|
202
249
|
}
|
|
@@ -233,12 +280,13 @@ var declares = {
|
|
|
233
280
|
{ ecosystem: "rubygems", name: "activerecord" },
|
|
234
281
|
{ ecosystem: "rubygems", name: "rails" }
|
|
235
282
|
],
|
|
236
|
-
reads: "ActiveRecord calls (Ruby): a call matches when its method is one ActiveRecord defines as a read or a write and the class behind its receiver reaches `ActiveRecord::Base`, following what each class extends through the project. Statements the project wrote itself are read for the tables they touch, whether they went through `find_by_sql` and `count_by_sql` or through the connection. A write also runs the model's callbacks, and what they reach
|
|
283
|
+
reads: "ActiveRecord calls (Ruby): a call matches when its method is one ActiveRecord defines as a read or a write and the class behind its receiver reaches `ActiveRecord::Base`, following what each class extends through the project. Statements the project wrote itself are read for the tables they touch, whether they went through `find_by_sql` and `count_by_sql` or through the connection. A write also runs the model's callbacks, and what they reach is recorded on the body that did the write.",
|
|
237
284
|
configuration: {
|
|
238
285
|
file: "suss.activerecord.json",
|
|
239
286
|
example: { storageSystem: "postgresql" },
|
|
240
287
|
required: true,
|
|
241
|
-
why: "which database is behind the connection: postgresql, mysql, or sqlite. ActiveRecord talks to all of them and database.yml settles which, so the pack cannot."
|
|
288
|
+
why: "which database is behind the connection: postgresql, mysql, or sqlite. ActiveRecord talks to all of them and database.yml settles which, so the pack cannot.",
|
|
289
|
+
readFromProject: storageSystemFromDatabaseYml
|
|
242
290
|
}
|
|
243
291
|
};
|
|
244
292
|
var index_default = activeRecordFramework;
|
package/dist/aiohttp.js
CHANGED
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
// ../client/aiohttp/dist/index.js
|
|
2
|
-
var
|
|
2
|
+
var VERB_METHODS_THAT_FOLLOW = {
|
|
3
3
|
get: "GET",
|
|
4
4
|
post: "POST",
|
|
5
5
|
put: "PUT",
|
|
6
6
|
patch: "PATCH",
|
|
7
7
|
delete: "DELETE",
|
|
8
|
-
head: "HEAD",
|
|
9
8
|
options: "OPTIONS"
|
|
10
9
|
};
|
|
10
|
+
function verbCalls(verbs, redirectDelivery) {
|
|
11
|
+
return {
|
|
12
|
+
type: "clientCall",
|
|
13
|
+
importModule: ["aiohttp"],
|
|
14
|
+
verbAttributeNames: verbs,
|
|
15
|
+
url: { position: 0, keyword: "url" },
|
|
16
|
+
receiverConstructors: ["ClientSession"],
|
|
17
|
+
response: {
|
|
18
|
+
redirectDelivery,
|
|
19
|
+
redirectOption: { name: "allow_redirects", handsBack: [false] }
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
11
23
|
function aiohttpClient() {
|
|
12
24
|
return {
|
|
13
25
|
name: "aiohttp",
|
|
14
26
|
protocol: "http",
|
|
15
27
|
discovery: [],
|
|
28
|
+
// `head` defaults `allow_redirects` to False, and every other call,
|
|
29
|
+
// `request("HEAD", url)` included, defaults it to True.
|
|
16
30
|
clients: [
|
|
17
31
|
{
|
|
18
|
-
|
|
19
|
-
importModule: ["aiohttp"],
|
|
20
|
-
verbAttributeNames: VERB_METHODS,
|
|
21
|
-
url: { position: 0, keyword: "url" },
|
|
32
|
+
...verbCalls(VERB_METHODS_THAT_FOLLOW, "followed"),
|
|
22
33
|
methodCall: {
|
|
23
34
|
attribute: "request",
|
|
24
35
|
methodPosition: 0,
|
|
25
36
|
methodKeyword: "method",
|
|
26
37
|
urlPosition: 1
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
verbCalls({ head: "HEAD" }, "response")
|
|
30
41
|
],
|
|
31
42
|
// `ClientSession.__aenter__` returns the session, so `async with
|
|
32
43
|
// aiohttp.ClientSession() as s` puts the constructed session in s.
|
package/dist/apollo-client.js
CHANGED
|
@@ -11,20 +11,18 @@ var DOCUMENT_HOOKS = [
|
|
|
11
11
|
];
|
|
12
12
|
var optionsSchema = z.object({
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
* client is constructed with
|
|
16
|
-
* expression when the value is computed
|
|
17
|
-
* `import.meta.env.VITE_GRAPHQL_URL
|
|
18
|
-
*
|
|
19
|
-
* that share root field names.
|
|
14
|
+
* The provider workspace each client talks to, keyed by the endpoint
|
|
15
|
+
* the client is constructed with. The key is the uri string, or the
|
|
16
|
+
* expression as written when the value is computed, such as
|
|
17
|
+
* `import.meta.env.VITE_GRAPHQL_URL`. One entry per client keeps
|
|
18
|
+
* apart two GraphQL services that share root field names.
|
|
20
19
|
*/
|
|
21
20
|
clients: z.record(z.string(), z.string()).optional(),
|
|
22
21
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* matching entry wins.
|
|
22
|
+
* The workspace for operations in a set of files, for a frontend
|
|
23
|
+
* that uses two clients. A hook call does not show which client it
|
|
24
|
+
* goes through, so the pack decides by file. The first entry whose
|
|
25
|
+
* globs match the operation's file wins.
|
|
28
26
|
*/
|
|
29
27
|
operationScopes: z.array(
|
|
30
28
|
z.object({ files: z.array(z.string()), workspace: z.string() }).strict()
|
|
@@ -34,10 +32,8 @@ function apolloClientPack(options = {}) {
|
|
|
34
32
|
return {
|
|
35
33
|
name: "apollo-client",
|
|
36
34
|
languages: ["typescript", "javascript"],
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// transport tag stays "http" for v0, the Apollo HttpLink is the
|
|
40
|
-
// default path).
|
|
35
|
+
// Subscriptions can run over WebSocket, but operationType already
|
|
36
|
+
// records them, and HttpLink is Apollo's default transport.
|
|
41
37
|
protocol: "http",
|
|
42
38
|
discovery: [
|
|
43
39
|
{
|
|
@@ -47,15 +43,11 @@ function apolloClientPack(options = {}) {
|
|
|
47
43
|
importModule: "@apollo/client",
|
|
48
44
|
hooks: [...DOCUMENT_HOOKS]
|
|
49
45
|
},
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
// on the match itself stays exact-match for discovery's own
|
|
53
|
-
// gating.
|
|
46
|
+
// requiresImport matches by prefix, so it also admits
|
|
47
|
+
// `@apollo/client/react`. importModule above matches exactly.
|
|
54
48
|
requiresImport: ["@apollo/client"]
|
|
55
49
|
},
|
|
56
|
-
//
|
|
57
|
-
// Apollo's current stable major is one path; the react-only
|
|
58
|
-
// export is here to handle projects that pin per-runtime.
|
|
50
|
+
// For projects that import the hooks from the React entry point.
|
|
59
51
|
{
|
|
60
52
|
kind: "client",
|
|
61
53
|
match: {
|
|
@@ -65,13 +57,9 @@ function apolloClientPack(options = {}) {
|
|
|
65
57
|
},
|
|
66
58
|
requiresImport: ["@apollo/client"]
|
|
67
59
|
},
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
// `
|
|
71
|
-
// than via a hook. The client identifier can be any name,
|
|
72
|
-
// we gate on the `ApolloClient` constructor being imported
|
|
73
|
-
// so random `.query()` method calls in unrelated code don't
|
|
74
|
-
// light up.
|
|
60
|
+
// `client.query(...)` outside a hook, as in server-side fetching.
|
|
61
|
+
// The client variable can have any name, so the match requires an
|
|
62
|
+
// `ApolloClient` import to skip unrelated `.query()` calls.
|
|
75
63
|
{
|
|
76
64
|
kind: "client",
|
|
77
65
|
match: {
|
|
@@ -99,16 +87,16 @@ function apolloClientPack(options = {}) {
|
|
|
99
87
|
requiresImport: ["@apollo/client"]
|
|
100
88
|
}
|
|
101
89
|
],
|
|
102
|
-
// The
|
|
103
|
-
//
|
|
90
|
+
// The endpoint an operation goes to comes from the `uri` option on
|
|
91
|
+
// whichever of these built its client.
|
|
104
92
|
graphqlClients: [
|
|
105
93
|
{
|
|
106
94
|
importModule: "@apollo/client",
|
|
107
95
|
importName: "ApolloClient",
|
|
108
96
|
uriProperty: "uri",
|
|
109
|
-
// `createFragmentRegistry`
|
|
110
|
-
//
|
|
111
|
-
//
|
|
97
|
+
// With a registry from `createFragmentRegistry` on the cache, a
|
|
98
|
+
// document can spread a fragment it does not define, and the
|
|
99
|
+
// client fills it in at run time.
|
|
112
100
|
fragmentRegistry: {
|
|
113
101
|
cacheProperty: "cache",
|
|
114
102
|
cacheConstructor: {
|
|
@@ -144,10 +132,9 @@ function apolloClientPack(options = {}) {
|
|
|
144
132
|
}
|
|
145
133
|
],
|
|
146
134
|
inputMapping: {
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
// directly (role "variable"), independent of this mapping.
|
|
135
|
+
// The inputs are the `$variables` in the operation header. The
|
|
136
|
+
// adapter reads them from the resolved document, so no positional
|
|
137
|
+
// parameter is mapped here.
|
|
151
138
|
type: "positionalParams",
|
|
152
139
|
params: []
|
|
153
140
|
}
|
|
@@ -157,7 +144,7 @@ var declares = {
|
|
|
157
144
|
kind: "client",
|
|
158
145
|
package: "@suss/client-apollo",
|
|
159
146
|
dependencies: [{ ecosystem: "npm", name: "@apollo/client" }],
|
|
160
|
-
reads: "`@apollo/client` hooks
|
|
147
|
+
reads: "`@apollo/client` hooks and imperative `client.query` calls."
|
|
161
148
|
};
|
|
162
149
|
var index_default = apolloClientPack;
|
|
163
150
|
export {
|
package/dist/apollo.js
CHANGED
|
@@ -3,9 +3,8 @@ function apolloFramework() {
|
|
|
3
3
|
return {
|
|
4
4
|
name: "apollo",
|
|
5
5
|
languages: ["typescript", "javascript"],
|
|
6
|
-
// Apollo Server runs over HTTP
|
|
7
|
-
//
|
|
8
|
-
// and surfaced via `graphql-resolver` semantics in the binding.
|
|
6
|
+
// Apollo Server runs over HTTP. The GraphQL type and field are set
|
|
7
|
+
// per resolver, on the `graphql-resolver` binding.
|
|
9
8
|
protocol: "http",
|
|
10
9
|
discovery: [
|
|
11
10
|
{
|
|
@@ -14,14 +13,12 @@ function apolloFramework() {
|
|
|
14
13
|
type: "resolverMap",
|
|
15
14
|
importModule: "@apollo/server",
|
|
16
15
|
importName: "ApolloServer",
|
|
17
|
-
// Apollo v4 convention: the config key is `resolvers`.
|
|
18
16
|
mapProperty: "resolvers"
|
|
19
17
|
},
|
|
20
18
|
requiresImport: ["@apollo/server"]
|
|
21
19
|
},
|
|
22
|
-
//
|
|
23
|
-
// `
|
|
24
|
-
// module. Covers the bulk of real-world Apollo code before v4.
|
|
20
|
+
// Apollo before v4 exported the same `ApolloServer` from
|
|
21
|
+
// `apollo-server` and `apollo-server-express`.
|
|
25
22
|
{
|
|
26
23
|
kind: "resolver",
|
|
27
24
|
match: {
|
|
@@ -44,10 +41,8 @@ function apolloFramework() {
|
|
|
44
41
|
}
|
|
45
42
|
],
|
|
46
43
|
terminals: [
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// response). No framework-specific response-call shape to
|
|
50
|
-
// match; return + throw cover the observable behavior.
|
|
44
|
+
// A resolver has no response call. It returns a value or throws,
|
|
45
|
+
// and Apollo turns a thrown error into `errors[]`.
|
|
51
46
|
{
|
|
52
47
|
kind: "return",
|
|
53
48
|
match: { type: "returnStatement" },
|
|
@@ -58,21 +53,18 @@ function apolloFramework() {
|
|
|
58
53
|
match: { type: "throwExpression" },
|
|
59
54
|
extraction: {}
|
|
60
55
|
},
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
// `transitions: []` isn't the shape we ship.
|
|
56
|
+
// A resolver that returns nothing hands off to Apollo's default
|
|
57
|
+
// resolver. Without this terminal it would come out with no
|
|
58
|
+
// transitions.
|
|
65
59
|
{
|
|
66
60
|
kind: "return",
|
|
67
61
|
match: { type: "functionFallthrough" },
|
|
68
62
|
extraction: {}
|
|
69
63
|
}
|
|
70
64
|
],
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
// role so downstream checks can distinguish "uses args" from
|
|
75
|
-
// "delegates to context" etc.
|
|
65
|
+
// All four positions get a role, even though most resolvers ignore
|
|
66
|
+
// `parent` and `info`, so a check can tell a resolver that reads
|
|
67
|
+
// `args` from one that hands off to `context`.
|
|
76
68
|
inputMapping: {
|
|
77
69
|
type: "positionalParams",
|
|
78
70
|
params: [
|
package/dist/aws-dynamodb.js
CHANGED
|
@@ -214,9 +214,9 @@ function updateExpressionAttributes(expression, names) {
|
|
|
214
214
|
}
|
|
215
215
|
var optionsSchema = z.object({
|
|
216
216
|
/**
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* signing library
|
|
217
|
+
* More modules that get a file read when it imports them. A relative
|
|
218
|
+
* import of a helper matches no module, so the usual entry is the
|
|
219
|
+
* signing library the helper imports.
|
|
220
220
|
*/
|
|
221
221
|
requiresImport: z.array(z.string()).optional()
|
|
222
222
|
}).strict();
|
|
@@ -335,7 +335,7 @@ var declares = {
|
|
|
335
335
|
{ ecosystem: "npm", name: "@aws-sdk/lib-dynamodb" },
|
|
336
336
|
{ ecosystem: "npm", name: "@aws-sdk/client-dynamodb" }
|
|
337
337
|
],
|
|
338
|
-
reads: "AWS SDK v3 DynamoDB calls
|
|
338
|
+
reads: "AWS SDK v3 DynamoDB calls. Each one becomes a storage-access interaction."
|
|
339
339
|
};
|
|
340
340
|
var index_default = dynamoFramework;
|
|
341
341
|
export {
|
package/dist/aws-eventbridge.js
CHANGED
|
@@ -7,8 +7,8 @@ import { constructedFrom, messageSends, pack } from "@suss/recognize";
|
|
|
7
7
|
var EVENTBRIDGE = "@aws-sdk/client-eventbridge";
|
|
8
8
|
var optionsSchema = z.object({
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Each publisher adds a recognizer, and the pack also reads files that
|
|
11
|
+
* import the publisher's module.
|
|
12
12
|
*/
|
|
13
13
|
producers: z.array(configuredCallOption).optional()
|
|
14
14
|
}).strict();
|
|
@@ -92,7 +92,7 @@ var declares = {
|
|
|
92
92
|
kind: "effects",
|
|
93
93
|
package: "@suss/framework-aws-eventbridge",
|
|
94
94
|
dependencies: [{ ecosystem: "npm", name: "@aws-sdk/client-eventbridge" }],
|
|
95
|
-
reads: "AWS EventBridge `PutEvents` producer calls
|
|
95
|
+
reads: "AWS EventBridge `PutEvents` producer calls. Each one becomes a message-bus interaction."
|
|
96
96
|
};
|
|
97
97
|
var index_default = eventBridgeFramework;
|
|
98
98
|
export {
|
package/dist/aws-lambda.js
CHANGED
|
@@ -146,9 +146,9 @@ function templatesForFiles(files) {
|
|
|
146
146
|
}
|
|
147
147
|
var HTTP_TERMINALS = [
|
|
148
148
|
{
|
|
149
|
-
// `return { statusCode, body, headers? }`,
|
|
150
|
-
//
|
|
151
|
-
//
|
|
149
|
+
// `return { statusCode, body, headers? }`, at the return or in a helper
|
|
150
|
+
// the adapter follows. `body` contains the serialized payload, so
|
|
151
|
+
// `JSON.stringify(x)` is unwrapped to the shape of `x`.
|
|
152
152
|
kind: "response",
|
|
153
153
|
match: { type: "returnShape", requiredProperties: ["statusCode"] },
|
|
154
154
|
extraction: {
|
|
@@ -157,9 +157,9 @@ var HTTP_TERMINALS = [
|
|
|
157
157
|
}
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
|
-
// `return { batchItemFailures }
|
|
161
|
-
//
|
|
162
|
-
//
|
|
160
|
+
// `return { batchItemFailures }` makes Lambda retry the records it
|
|
161
|
+
// lists. Lambda defines this shape, so the pack can match on it the
|
|
162
|
+
// same way it matches the envelope above.
|
|
163
163
|
kind: "return",
|
|
164
164
|
match: {
|
|
165
165
|
type: "returnShape",
|
|
@@ -168,9 +168,8 @@ var HTTP_TERMINALS = [
|
|
|
168
168
|
extraction: {}
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
// specific status is the platform's, not the handler's.
|
|
171
|
+
// An uncaught throw becomes a throw-output transition. API Gateway
|
|
172
|
+
// turns it into a 5xx, and the platform picks which one.
|
|
174
173
|
kind: "throw",
|
|
175
174
|
match: { type: "throwExpression" },
|
|
176
175
|
extraction: {}
|
|
@@ -184,10 +183,9 @@ var NON_HTTP_TERMINALS = [
|
|
|
184
183
|
extraction: {}
|
|
185
184
|
},
|
|
186
185
|
{
|
|
187
|
-
// A queue consumer acknowledges a batch by
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
// transition, and everything it does goes with it.
|
|
186
|
+
// A queue consumer acknowledges a batch by returning without an error.
|
|
187
|
+
// Without this pattern the handler has no terminal, so it gets no
|
|
188
|
+
// transition and everything it does is lost with it.
|
|
191
189
|
kind: "return",
|
|
192
190
|
match: { type: "functionFallthrough" },
|
|
193
191
|
extraction: {}
|
|
@@ -367,45 +365,25 @@ function awsLambdaFramework(_options = {}) {
|
|
|
367
365
|
return {
|
|
368
366
|
name: "aws-lambda",
|
|
369
367
|
protocol: "http",
|
|
370
|
-
// Sentry's wrapper
|
|
371
|
-
//
|
|
372
|
-
//
|
|
373
|
-
// those by reading the factory body.
|
|
368
|
+
// The adapter cannot read Sentry's wrapper inside the library, so the
|
|
369
|
+
// pack declares that the handler is argument 0. A wrapper written in
|
|
370
|
+
// the project needs no entry, because the adapter reads its body.
|
|
374
371
|
transparentWrappers: [
|
|
375
|
-
{
|
|
376
|
-
callee: "Sentry.wrapHandler",
|
|
377
|
-
argument: 0,
|
|
378
|
-
module: "@sentry/aws-serverless"
|
|
379
|
-
}
|
|
372
|
+
{ module: "@sentry/aws-serverless", name: "wrapHandler", argument: 0 }
|
|
380
373
|
],
|
|
381
374
|
languages: ["typescript", "javascript"],
|
|
382
|
-
//
|
|
383
|
-
//
|
|
375
|
+
// The routing is in the template, so the callback finds handlers
|
|
376
|
+
// there and the pattern list stays empty.
|
|
384
377
|
discovery: [],
|
|
385
378
|
discoverUnits: awsLambdaDiscovery(),
|
|
386
|
-
//
|
|
387
|
-
//
|
|
379
|
+
// Discovery reads the templates, so they go into the cache key and an
|
|
380
|
+
// edited template makes the next run read the project again.
|
|
388
381
|
discoveryInputs: templatesForFiles,
|
|
389
|
-
// No import gate
|
|
390
|
-
//
|
|
391
|
-
// A
|
|
392
|
-
//
|
|
393
|
-
// `@types/aws-lambda`, to annotate its export. A JavaScript handler
|
|
394
|
-
// has nothing to annotate and writes no such import. Gating
|
|
395
|
-
// discovery on it therefore meant "TypeScript handlers that bothered
|
|
396
|
-
// to annotate", and every JavaScript Lambda service extracted
|
|
397
|
-
// nothing.
|
|
398
|
-
//
|
|
399
|
-
// The SAM template is the gate instead, and a better one, because it
|
|
400
|
-
// says which handlers outright. `discoverUnits` looks each file up in
|
|
401
|
-
// the template reachable from it, and a directory with no template
|
|
402
|
-
// resolves to null once and stays memoized.
|
|
403
|
-
// Route units extract against these. Non-HTTP accounting units get their
|
|
404
|
-
// own wider list, attached per unit by the discovery callback.
|
|
382
|
+
// No import gate: a JavaScript handler imports nothing from
|
|
383
|
+
// `aws-lambda`, so the template acts as the gate. See the README.
|
|
384
|
+
// A unit that is not HTTP gets a longer list from the discovery
|
|
385
|
+
// callback in place of this one.
|
|
405
386
|
terminals: HTTP_TERMINALS,
|
|
406
|
-
// Lambda's handler signature is `(event, context, callback?)`. The
|
|
407
|
-
// HTTP request data (path params, query, body) lives on `event`;
|
|
408
|
-
// decomposing it into typed inputs is a follow-up.
|
|
409
387
|
inputMapping: {
|
|
410
388
|
type: "positionalParams",
|
|
411
389
|
params: [
|
|
@@ -413,9 +391,9 @@ function awsLambdaFramework(_options = {}) {
|
|
|
413
391
|
{ position: 1, role: "context" }
|
|
414
392
|
]
|
|
415
393
|
},
|
|
416
|
-
// A proxy integration
|
|
417
|
-
// body
|
|
418
|
-
//
|
|
394
|
+
// A proxy integration passes the handler API Gateway's event, with the
|
|
395
|
+
// body as a string the handler parses. A read of the body records that
|
|
396
|
+
// the handler took all of it, with no field name.
|
|
419
397
|
requestSpelling: {
|
|
420
398
|
headers: { path: ["event", "headers"], saysWhichField: true },
|
|
421
399
|
query: {
|
|
@@ -425,17 +403,16 @@ function awsLambdaFramework(_options = {}) {
|
|
|
425
403
|
params: { path: ["event", "pathParameters"], saysWhichField: true },
|
|
426
404
|
body: { path: ["event", "body"], saysWhichField: false }
|
|
427
405
|
},
|
|
428
|
-
//
|
|
429
|
-
//
|
|
406
|
+
// Powertools reads these variables from inside node_modules, where no
|
|
407
|
+
// walk over the project goes, so without this entry they look unread.
|
|
430
408
|
libraryEnvVars: [
|
|
431
409
|
{
|
|
432
410
|
module: "@aws-lambda-powertools/",
|
|
433
411
|
prefixes: ["POWERTOOLS_"]
|
|
434
412
|
}
|
|
435
413
|
],
|
|
436
|
-
//
|
|
437
|
-
//
|
|
438
|
-
// command came from anyway.
|
|
414
|
+
// A pack-level `requiresImport` would gate `discoverUnits` too. Each
|
|
415
|
+
// declaration already checks which SDK its command class came from.
|
|
439
416
|
invocationRecognizers: invokes.map(
|
|
440
417
|
(match) => compile(match.declared, "@suss/framework-aws-lambda")
|
|
441
418
|
),
|
|
@@ -446,7 +423,7 @@ var declares = {
|
|
|
446
423
|
kind: "framework",
|
|
447
424
|
package: "@suss/framework-aws-lambda",
|
|
448
425
|
dependencies: [{ ecosystem: "npm", name: "@types/aws-lambda" }],
|
|
449
|
-
reads: "AWS Lambda HTTP handlers, paired
|
|
426
|
+
reads: "AWS Lambda HTTP handlers, paired with the routes a SAM or CloudFormation template declares."
|
|
450
427
|
};
|
|
451
428
|
var index_default = awsLambdaFramework;
|
|
452
429
|
export {
|
package/dist/aws-s3.js
CHANGED
|
@@ -38,7 +38,7 @@ var declares = {
|
|
|
38
38
|
kind: "effects",
|
|
39
39
|
package: "@suss/framework-aws-s3",
|
|
40
40
|
dependencies: [{ ecosystem: "npm", name: "@aws-sdk/client-s3" }],
|
|
41
|
-
reads: "AWS SDK v3 S3 object calls
|
|
41
|
+
reads: "AWS SDK v3 S3 object calls. Each one becomes a storage-access interaction."
|
|
42
42
|
};
|
|
43
43
|
var index_default = s3Framework;
|
|
44
44
|
export {
|
|
@@ -32,7 +32,7 @@ var declares = {
|
|
|
32
32
|
kind: "effects",
|
|
33
33
|
package: "@suss/framework-aws-secrets-manager",
|
|
34
34
|
dependencies: [{ ecosystem: "npm", name: "@aws-sdk/client-secrets-manager" }],
|
|
35
|
-
reads: "AWS Secrets Manager calls
|
|
35
|
+
reads: "AWS Secrets Manager calls. Each one becomes a storage-access interaction on the secret."
|
|
36
36
|
};
|
|
37
37
|
var index_default = secretsManagerFramework;
|
|
38
38
|
export {
|
package/dist/aws-sns.js
CHANGED
|
@@ -30,7 +30,7 @@ var PUBLISH_BATCH = messageSends({
|
|
|
30
30
|
wire: "aws.sns",
|
|
31
31
|
client: constructedFrom(SNS),
|
|
32
32
|
messages: { each: "in", property: "PublishBatchRequestEntries" },
|
|
33
|
-
//
|
|
33
|
+
// The topic is on the command input, once, beside the list of messages.
|
|
34
34
|
channel: [{ property: TOPIC, on: "theInput" }],
|
|
35
35
|
routingKey: "Subject",
|
|
36
36
|
body: "Message"
|
|
@@ -48,7 +48,7 @@ var declares = {
|
|
|
48
48
|
kind: "effects",
|
|
49
49
|
package: "@suss/framework-aws-sns",
|
|
50
50
|
dependencies: [{ ecosystem: "npm", name: "@aws-sdk/client-sns" }],
|
|
51
|
-
reads: "AWS SDK v3 SNS `Publish` and `PublishBatch` calls
|
|
51
|
+
reads: "AWS SDK v3 SNS `Publish` and `PublishBatch` calls. Each one becomes a message-send interaction on the topic."
|
|
52
52
|
};
|
|
53
53
|
var index_default = snsFramework;
|
|
54
54
|
export {
|