@suss/packs 0.18.0 → 0.20.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.
@@ -31,3 +31,4 @@ import '@suss/framework-react';
31
31
  import '@suss/framework-redis';
32
32
  import '@suss/framework-sqlalchemy';
33
33
  import '@suss/framework-ts-rest';
34
+ import '@suss/framework-zustand';
package/dist/mongoose.js CHANGED
@@ -112,19 +112,9 @@ function collectionOf(_selector, call) {
112
112
  return model.nameAt(2, "nothing") ?? schemaCollectionOf(model) ?? pluralized(modelName);
113
113
  }
114
114
  function modelCallIn(call) {
115
- const receiver = call.receiver();
116
- if (receiver === null) {
117
- return null;
118
- }
119
- return modelFactoryCall(receiver) ?? modelFactoryCall(receiver.callee()) ?? modelFactoryCall(receiver.receiver());
120
- }
121
- function modelFactoryCall(call) {
122
- if (call === null) {
123
- return null;
124
- }
125
- const named = call.method() ?? call.calleeText();
126
- const fromLibrary = call.isFrom(constructedFrom(CLIENT_MODULE));
127
- return named === MODEL_FACTORY && fromLibrary ? call : null;
115
+ return call.anchorCall?.(
116
+ constructedFrom({ from: [CLIENT_MODULE], named: [MODEL_FACTORY] })
117
+ ) ?? null;
128
118
  }
129
119
  function schemaCollectionOf(model) {
130
120
  return model.argument(1)?.propertyAt(1, "collection", "nothing") ?? null;
package/dist/nextjs.js CHANGED
@@ -268423,13 +268423,17 @@ function bodyStartsWithDirective(fn) {
268423
268423
  }
268424
268424
  return leadingDirectives(body.getStatements()).includes(DIRECTIVE);
268425
268425
  }
268426
- function actionUnit(func, name) {
268426
+ function actionUnit(func, name, module) {
268427
268427
  return {
268428
268428
  func,
268429
268429
  kind: "action",
268430
268430
  name,
268431
268431
  terminals: ACTION_TERMINALS,
268432
- inputMapping: { type: "allPositional" }
268432
+ inputMapping: { type: "allPositional" },
268433
+ // The identity intent and the keyed pairing pass refer to the
268434
+ // action by. The path is absolute here and the CLI makes it
268435
+ // project-relative with every other path on the summary.
268436
+ functionCallInfo: { module, exportName: name }
268433
268437
  };
268434
268438
  }
268435
268439
  function inlineName(fn) {
@@ -268450,6 +268454,7 @@ function nextjsServerActions(sourceFile, _ctx) {
268450
268454
  const out = [];
268451
268455
  const claimed = /* @__PURE__ */ new Set();
268452
268456
  const fileLevel = fileIsServerModule(sf);
268457
+ const module = sf.getFilePath();
268453
268458
  for (const fn of sf.getFunctions()) {
268454
268459
  const name = fn.getName();
268455
268460
  if (name === void 0 || fn.getBody() === void 0) {
@@ -268457,7 +268462,7 @@ function nextjsServerActions(sourceFile, _ctx) {
268457
268462
  }
268458
268463
  if (fileLevel && fn.isExported() || bodyStartsWithDirective(fn)) {
268459
268464
  claimed.add(fn);
268460
- out.push(actionUnit(fn, name));
268465
+ out.push(actionUnit(fn, name, module));
268461
268466
  }
268462
268467
  }
268463
268468
  for (const statement of sf.getVariableStatements()) {
@@ -268468,7 +268473,7 @@ function nextjsServerActions(sourceFile, _ctx) {
268468
268473
  const init = decl.getInitializer();
268469
268474
  if (init !== void 0 && (import_ts_morph.Node.isArrowFunction(init) || import_ts_morph.Node.isFunctionExpression(init))) {
268470
268475
  claimed.add(init);
268471
- out.push(actionUnit(init, decl.getName()));
268476
+ out.push(actionUnit(init, decl.getName(), module));
268472
268477
  }
268473
268478
  }
268474
268479
  }
@@ -268484,10 +268489,10 @@ function nextjsServerActions(sourceFile, _ctx) {
268484
268489
  claimed.add(fn);
268485
268490
  const name = inlineName(fn);
268486
268491
  if (name === null) {
268487
- out.push(actionUnit(fn, `serverAction#${inlineIndex}`));
268492
+ out.push(actionUnit(fn, `serverAction#${inlineIndex}`, module));
268488
268493
  inlineIndex += 1;
268489
268494
  } else {
268490
- out.push(actionUnit(fn, name));
268495
+ out.push(actionUnit(fn, name, module));
268491
268496
  }
268492
268497
  }
268493
268498
  return out;
@@ -2,6 +2,7 @@ import "./chunk-3RG5ZIWI.js";
2
2
 
3
3
  // ../framework/react-query/dist/index.js
4
4
  import { Node } from "ts-morph";
5
+ import { importedNamesOf } from "@suss/adapter-typescript";
5
6
  import { functionCallBinding } from "@suss/behavioral-ir";
6
7
  var QUERY_MODULES = ["@tanstack/react-query", "react-query"];
7
8
  var HOOK_CALLBACK_PROPERTY = {
@@ -13,15 +14,9 @@ var HOOK_CALLBACK_PROPERTY = {
13
14
  };
14
15
  function importedHooksOf(sourceFile) {
15
16
  const hooks = /* @__PURE__ */ new Map();
16
- for (const decl of sourceFile.getImportDeclarations()) {
17
- if (!QUERY_MODULES.includes(decl.getModuleSpecifierValue())) {
18
- continue;
19
- }
20
- for (const named of decl.getNamedImports()) {
21
- const name = named.getName();
22
- if (name in HOOK_CALLBACK_PROPERTY) {
23
- hooks.set(named.getAliasNode()?.getText() ?? name, name);
24
- }
17
+ for (const [local, canonical] of importedNamesOf(sourceFile, QUERY_MODULES)) {
18
+ if (canonical in HOOK_CALLBACK_PROPERTY) {
19
+ hooks.set(local, canonical);
25
20
  }
26
21
  }
27
22
  return hooks;
package/dist/react.js CHANGED
@@ -1,6 +1,12 @@
1
1
  import "./chunk-3RG5ZIWI.js";
2
2
 
3
3
  // ../framework/react/dist/index.js
4
+ import { Node } from "ts-morph";
5
+ import {
6
+ functionTargetOf,
7
+ importedNamesOf,
8
+ importedRootsOf
9
+ } from "@suss/adapter-typescript";
4
10
  var STORY_FILE_PATTERN = /\.stories\.tsx?$/;
5
11
  var TEST_FILE_PATTERN = /\.(test|spec)\.tsx?$/;
6
12
  function startsWithUppercase(name) {
@@ -36,6 +42,86 @@ var reactComponentExports = (sourceFile, ctx) => {
36
42
  }
37
43
  return out;
38
44
  };
45
+ var BOOT_CALLEES = ["createRoot", "hydrateRoot"];
46
+ var BOOT_MODULES = ["react-dom/client", "react-dom"];
47
+ function importedBootNames(sourceFile) {
48
+ const names = /* @__PURE__ */ new Set();
49
+ for (const [local, canonical] of importedNamesOf(sourceFile, BOOT_MODULES)) {
50
+ if (BOOT_CALLEES.includes(canonical)) {
51
+ names.add(local);
52
+ }
53
+ }
54
+ return names;
55
+ }
56
+ function importedDomNamespaces(sourceFile) {
57
+ return importedRootsOf(sourceFile, BOOT_MODULES);
58
+ }
59
+ function isBootRender(call, bootNames, domNamespaces) {
60
+ const callee = call.getExpression();
61
+ if (!Node.isPropertyAccessExpression(callee)) {
62
+ return false;
63
+ }
64
+ if (callee.getName() !== "render") {
65
+ return false;
66
+ }
67
+ const base = callee.getExpression();
68
+ if (Node.isCallExpression(base)) {
69
+ const inner = base.getExpression();
70
+ return Node.isIdentifier(inner) && bootNames.has(inner.getText());
71
+ }
72
+ return Node.isIdentifier(base) && domNamespaces.has(base.getText());
73
+ }
74
+ function renderedComponentOf(call) {
75
+ const argument = call.getArguments()[0];
76
+ if (argument === void 0) {
77
+ return null;
78
+ }
79
+ let tag = null;
80
+ if (Node.isJsxSelfClosingElement(argument)) {
81
+ const node = argument.getTagNameNode();
82
+ tag = Node.isIdentifier(node) ? node : null;
83
+ } else if (Node.isJsxElement(argument)) {
84
+ const node = argument.getOpeningElement().getTagNameNode();
85
+ tag = Node.isIdentifier(node) ? node : null;
86
+ }
87
+ if (tag === null || !/^[A-Z]/.test(tag.getText())) {
88
+ return null;
89
+ }
90
+ const target = functionTargetOf(tag);
91
+ return target === null ? null : { func: target.func, name: target.name };
92
+ }
93
+ var reactRootComponents = (sourceFile, _ctx) => {
94
+ const sf = sourceFile;
95
+ const text = sf.getFullText();
96
+ if (!text.includes("render")) {
97
+ return [];
98
+ }
99
+ const bootNames = importedBootNames(sf);
100
+ const domNamespaces = importedDomNamespaces(sf);
101
+ if (bootNames.size === 0 && domNamespaces.size === 0) {
102
+ return [];
103
+ }
104
+ const out = [];
105
+ const claimed = /* @__PURE__ */ new Set();
106
+ sf.forEachDescendant((node) => {
107
+ if (!Node.isCallExpression(node)) {
108
+ return;
109
+ }
110
+ if (!isBootRender(node, bootNames, domNamespaces)) {
111
+ return;
112
+ }
113
+ const component = renderedComponentOf(node);
114
+ if (component !== null && !claimed.has(component.func)) {
115
+ claimed.add(component.func);
116
+ out.push({
117
+ func: component.func,
118
+ kind: "component",
119
+ name: component.name
120
+ });
121
+ }
122
+ });
123
+ return out;
124
+ };
39
125
  var EVENT_HANDLER_INPUT = {
40
126
  type: "positionalParams",
41
127
  params: [{ position: 0, role: "event" }]
@@ -214,7 +300,10 @@ function reactFramework() {
214
300
  paramPosition: 0
215
301
  },
216
302
  subUnits: reactSubUnits,
217
- discoverUnits: reactComponentExports
303
+ discoverUnits: (sourceFile, ctx) => [
304
+ ...reactComponentExports(sourceFile, ctx),
305
+ ...reactRootComponents(sourceFile, ctx)
306
+ ]
218
307
  };
219
308
  }
220
309
  var index_default = reactFramework;
@@ -0,0 +1 @@
1
+ export { default } from '@suss/framework-zustand';
@@ -0,0 +1,38 @@
1
+ import "./chunk-3RG5ZIWI.js";
2
+
3
+ // ../framework/zustand/dist/index.js
4
+ import { constructedFrom, pack, storageCalls } from "@suss/recognize";
5
+ var WRITTEN = ({ input }) => {
6
+ const found = [];
7
+ for (const entry of input.entries("nothing")) {
8
+ if (entry.key !== null) {
9
+ found.push(entry.key);
10
+ }
11
+ }
12
+ return found;
13
+ };
14
+ var payload = (at) => ({ of: { at }, by: WRITTEN });
15
+ var METHODS = {
16
+ setState: { kind: "write", fields: payload(0) },
17
+ getState: { kind: "read" },
18
+ subscribe: { kind: "read" }
19
+ };
20
+ function storeNameOf(_names, call) {
21
+ const callee = call.calleeText();
22
+ const dot = callee.lastIndexOf(".");
23
+ return dot > 0 ? callee.slice(0, dot) : callee;
24
+ }
25
+ var STORE_CALLS = storageCalls({
26
+ system: "client-store",
27
+ client: constructedFrom("zustand", "zustand/vanilla")
28
+ }).methods(METHODS).calls({ kind: "read", fields: { selectorParam: 0 } }).container(storeNameOf).example("useAppStore((s) => s.bears)");
29
+ function zustandFramework() {
30
+ return pack("zustand", [STORE_CALLS], {
31
+ languages: ["typescript", "javascript"],
32
+ recognizedAs: "@suss/framework-zustand"
33
+ });
34
+ }
35
+ var index_default = zustandFramework;
36
+ export {
37
+ index_default as default
38
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/packs",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "description": "Every pack suss ships, as one package with a subpath per pack.",
6
6
  "keywords": [
@@ -144,6 +144,10 @@
144
144
  "types": "./dist/redis.d.ts",
145
145
  "import": "./dist/redis.js"
146
146
  },
147
+ "./zustand": {
148
+ "types": "./dist/zustand.d.ts",
149
+ "import": "./dist/zustand.js"
150
+ },
147
151
  "./sqlalchemy": {
148
152
  "types": "./dist/sqlalchemy.d.ts",
149
153
  "import": "./dist/sqlalchemy.js"
@@ -169,15 +173,15 @@
169
173
  "ts-morph": "^23.0.0"
170
174
  },
171
175
  "dependencies": {
172
- "@suss/adapter-python": "0.18.0",
173
- "@suss/adapter-ruby": "0.18.0",
174
- "@suss/adapter-typescript": "0.18.0",
175
- "@suss/behavioral-ir": "0.18.0",
176
- "@suss/contract-graphql": "0.18.0",
177
- "@suss/extractor": "0.18.0",
178
- "@suss/manifest-aws": "0.18.0",
179
- "@suss/recognize": "0.18.0",
180
- "@suss/sql": "0.18.0"
176
+ "@suss/adapter-python": "0.20.0",
177
+ "@suss/adapter-ruby": "0.20.0",
178
+ "@suss/adapter-typescript": "0.20.0",
179
+ "@suss/behavioral-ir": "0.20.0",
180
+ "@suss/contract-graphql": "0.20.0",
181
+ "@suss/extractor": "0.20.0",
182
+ "@suss/manifest-aws": "0.20.0",
183
+ "@suss/recognize": "0.20.0",
184
+ "@suss/sql": "0.20.0"
181
185
  },
182
186
  "devDependencies": {
183
187
  "@suss/client-apollo": "*",
@@ -208,6 +212,7 @@
208
212
  "@suss/framework-prisma": "*",
209
213
  "@suss/framework-react": "*",
210
214
  "@suss/framework-react-query": "*",
215
+ "@suss/framework-zustand": "*",
211
216
  "@suss/framework-react-router": "*",
212
217
  "@suss/framework-redis": "*",
213
218
  "@suss/framework-sqlalchemy": "*",