@everystack/server 0.2.23 → 0.2.26

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.
Files changed (2) hide show
  1. package/jest-preset.js +52 -19
  2. package/package.json +1 -1
package/jest-preset.js CHANGED
@@ -1,32 +1,60 @@
1
1
  /**
2
- * @everystack/server/jest-preset — drop-in jest config for a consumer's
3
- * server-boundary test project (the one that imports `@everystack/server/testing`).
2
+ * Drop-in jest config for a consumer's server-boundary test project (the one
3
+ * that imports `@everystack/server/testing`).
4
4
  *
5
5
  * // jest.config.js
6
- * module.exports = { preset: '@everystack/server/jest-preset' };
6
+ * module.exports = { preset: '@everystack/server' };
7
+ *
8
+ * Note the value is the package name, NOT '@everystack/server/jest-preset':
9
+ * jest appends `/jest-preset.js` to the preset string itself, so it resolves
10
+ * this file as `@everystack/server/jest-preset.js`.
11
+ *
12
+ * IMPORTANT — this preset OWNS `transform`. Jest gives your config precedence on
13
+ * shared keys, so if your jest config also defines `transform`, it REPLACES the
14
+ * ts-jest block below and the explicit `@everystack/server/testing` pin is lost.
15
+ * A dedicated server-boundary project should set only
16
+ * `{ preset: '@everystack/server' }` (plus non-transform keys). If you must
17
+ * customize, spread this preset and leave `transform`/`moduleNameMapper` alone:
18
+ * const p = require('@everystack/server/jest-preset');
19
+ * module.exports = { ...p, testTimeout: 30000 };
7
20
  *
8
21
  * Why a preset is needed
9
22
  * ----------------------
10
- * @everystack packages ship TypeScript source, and their subpaths (like
11
- * `@everystack/server/testing`) are reachable only through the package
12
- * `exports` map. Two things have to be true for a consumer to import them:
13
- *
14
- * 1. TypeScript must read the `exports` map. Only `node16`/`nodenext`/`bundler`
15
- * resolution does. ts-jest under `module: commonjs` silently falls back to
16
- * classic `node` resolution, which ignores `exports` TS2307. NodeNext is
17
- * the one mode that reads `exports` AND emits CommonJS for jest. Its hybrid
18
- * module kind makes ts-jest warn TS151002; we silence only that one code
19
- * (NOT via `isolatedModules: true`, which would switch ts-jest to
20
- * transpile-only and drop type-checking entirely).
23
+ * @everystack ships TypeScript source, and `@everystack/server/testing` is a
24
+ * subpath reachable only through the package `exports` map. ts-jest's resolution
25
+ * of that subpath is unreliable on a COLD cache (fresh CI, `jest --no-cache`):
26
+ * it intermittently fails to read the exports map and throws
27
+ * `TS2307: Cannot find module '@everystack/server/testing'` passing only once a
28
+ * warm cache exists, so it's green locally and red in CI. Flattening the export
29
+ * target does not fix it; an explicit pin does.
21
30
  *
22
- * 2. jest must TRANSFORM the shipped `.ts` source. Source in `node_modules` is
23
- * ignored by default, so the `transformIgnorePatterns` allowlist below opts
24
- * `@everystack/*` back in. (Inside this monorepo the pnpm symlink escapes
25
- * `node_modules` and hides this requirement real installs need it.)
31
+ * So this preset resolves its OWN testing entry from disk (below) and pins it two
32
+ * ways, both cache-independent:
33
+ * - tsconfig `paths` → the type-checker resolves it deterministically.
34
+ * - `moduleNameMapper` the jest runtime resolves it deterministically.
35
+ * It also opts `@everystack/*` back into transformation (source ships as `.ts`,
36
+ * and `node_modules` is not transformed by default).
26
37
  *
27
38
  * Requires `ts-jest` and `typescript` in the consuming project (already present
28
39
  * for any TS jest setup).
29
40
  */
41
+ const path = require('path');
42
+ const fs = require('fs');
43
+
44
+ // Resolve this package's `testing` entry from the preset's own location, so the
45
+ // pin points at a real file regardless of layout (flat src/testing.ts or nested
46
+ // src/testing/index.ts) or where the package is installed.
47
+ const TESTING_ENTRY = ['src/testing.ts', 'src/testing/index.ts']
48
+ .map((rel) => path.join(__dirname, rel))
49
+ .find((abs) => fs.existsSync(abs));
50
+
51
+ const testingPin = TESTING_ENTRY
52
+ ? { '@everystack/server/testing': [TESTING_ENTRY] }
53
+ : {};
54
+ const testingMapper = TESTING_ENTRY
55
+ ? { '^@everystack/server/testing$': TESTING_ENTRY }
56
+ : {};
57
+
30
58
  module.exports = {
31
59
  testEnvironment: 'node',
32
60
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
@@ -42,6 +70,9 @@ module.exports = {
42
70
  esModuleInterop: true,
43
71
  skipLibCheck: true,
44
72
  types: ['jest', 'node'],
73
+ baseUrl: __dirname,
74
+ // Pin the exports subpath so the type-checker resolves it cold.
75
+ paths: testingPin,
45
76
  },
46
77
  // 151002: "hybrid module kind needs isolatedModules" — expected under
47
78
  // NodeNext; suppressing it keeps full type-checking on (real type errors
@@ -52,8 +83,10 @@ module.exports = {
52
83
  },
53
84
  // @everystack packages ship source, not built dist — transform them.
54
85
  transformIgnorePatterns: ['/node_modules/(?!@everystack/)'],
55
- // NodeNext consumers may write `.js` on relative ESM specifiers; map to source.
56
86
  moduleNameMapper: {
87
+ // Pin the exports subpath so the jest runtime resolves it cold.
88
+ ...testingMapper,
89
+ // NodeNext consumers may write `.js` on relative ESM specifiers; map to source.
57
90
  '^(\\.{1,2}/.*)\\.js$': '$1',
58
91
  },
59
92
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everystack/server",
3
- "version": "0.2.23",
3
+ "version": "0.2.26",
4
4
  "description": "Server runtime primitives for Lambda — event adapters, routing, SSR, image processing",
5
5
  "license": "AGPL-3.0-only",
6
6
  "author": "Scalable Technology, Inc. <licensing@scalable.technology>",