@multiplatform.one/config 7.4.0 → 7.5.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/README.md CHANGED
@@ -55,3 +55,30 @@ Extend from the tsconfig presets:
55
55
  ```
56
56
 
57
57
  Available presets: `base.json`, `build.json`, `app.json`.
58
+
59
+ ### Oxlint
60
+
61
+ Convention rules travel with the package. Consuming apps add one line:
62
+
63
+ ```json
64
+ {
65
+ "jsPlugins": ["@multiplatform.one/config/oxlint"]
66
+ }
67
+ ```
68
+
69
+ Then enable `mpo-conventions/no-hex-literals` on the globs you want (mpo's
70
+ own `oxlintrc.json` turns it on for `features/**`). Palette modules
71
+ (`themes/base.ts`, `themes/accent.ts`, `*palette*`) are exempt.
72
+
73
+ ### Lint (node-script checks)
74
+
75
+ CSS-in-apps, features-twin, silent token no-ops, and the LC-65 size-recipe
76
+ pilot run through `runConventionChecks({ roots })`:
77
+
78
+ ```ts
79
+ import { runConventionChecks } from "@multiplatform.one/config/lint";
80
+
81
+ runConventionChecks({
82
+ roots: { root: process.cwd() },
83
+ });
84
+ ```
package/lib/vitest.js CHANGED
@@ -1,8 +1,33 @@
1
+ import Module from "node:module";
2
+ import fs from "node:fs";
1
3
  import path from "node:path";
2
4
  import { tamaguiPlugin } from "@tamagui/vite-plugin";
5
+ import { fileURLToPath } from "node:url";
3
6
  import react from "@vitejs/plugin-react";
4
7
 
5
8
  //#region src/vitest.ts
9
+ const pinReactRequireSetup = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../pin-react-require.cjs");
10
+ /**
11
+ * CJS `require('react')` does not go through Vite aliases. `use-sync-external-store`
12
+ * is a valid Node import, so Vitest leaves it external even when we ask to inline
13
+ * it, and Node then loads the hoisted root copy — a different inode than the
14
+ * `.pnpm` copy Vite binds. Patching Module._resolveFilename in the vitest
15
+ * process (config eval + workers that re-load this factory) makes that
16
+ * require land on the same physical copy as the aliases.
17
+ */
18
+ function pinNodeReactRequire(reactDir, reactDomDir, schedulerDir) {
19
+ const ctor = Module;
20
+ if (ctor._mpoOneReact) return;
21
+ ctor._mpoOneReact = true;
22
+ const orig = ctor._resolveFilename;
23
+ ctor._resolveFilename = function pinned(request, parent, isMain, options) {
24
+ const next = request === "react" ? reactDir : request.startsWith("react/") ? path.join(reactDir, request.slice(6)) : request === "react-dom" ? reactDomDir : request.startsWith("react-dom/") ? path.join(reactDomDir, request.slice(10)) : request === "scheduler" ? schedulerDir : null;
25
+ if (next) try {
26
+ return orig.call(this, next, parent, isMain, options);
27
+ } catch {}
28
+ return orig.call(this, request, parent, isMain, options);
29
+ };
30
+ }
6
31
  /**
7
32
  * Creates a shared Vitest configuration for multiplatform.one packages.
8
33
  *
@@ -49,18 +74,31 @@ function createVitestConfig(options = {}) {
49
74
  resolveAliases["react-native-svg"] = "@tamagui/react-native-svg";
50
75
  }
51
76
  if (dedupeReact) {
52
- resolveAliases.react = path.resolve(rootNodeModules, "react");
53
- resolveAliases["react-dom"] = path.resolve(rootNodeModules, "react-dom");
54
- resolveAliases["react-dom/client"] = path.resolve(rootNodeModules, "react-dom/client");
55
- resolveAliases["react-dom/server"] = path.resolve(rootNodeModules, "react-dom/server");
56
- resolveAliases["react/jsx-runtime"] = path.resolve(rootNodeModules, "react/jsx-runtime");
57
- resolveAliases["react/jsx-dev-runtime"] = path.resolve(rootNodeModules, "react/jsx-dev-runtime");
58
- resolveAliases.scheduler = path.resolve(rootNodeModules, "scheduler");
77
+ const onePhysicalCopy = (pkg) => {
78
+ for (const base of [path.resolve(process.cwd(), "node_modules"), rootNodeModules]) try {
79
+ return fs.realpathSync(path.resolve(base, pkg));
80
+ } catch {}
81
+ return path.resolve(rootNodeModules, pkg);
82
+ };
83
+ const reactDir = onePhysicalCopy("react");
84
+ const reactDomDir = onePhysicalCopy("react-dom");
85
+ resolveAliases.react = reactDir;
86
+ resolveAliases["react-dom"] = reactDomDir;
87
+ resolveAliases["react-dom/client"] = path.join(reactDomDir, "client");
88
+ resolveAliases["react-dom/server"] = path.join(reactDomDir, "server");
89
+ resolveAliases["react/jsx-runtime"] = path.join(reactDir, "jsx-runtime");
90
+ resolveAliases["react/jsx-dev-runtime"] = path.join(reactDir, "jsx-dev-runtime");
91
+ const schedulerDir = onePhysicalCopy("scheduler");
92
+ resolveAliases.scheduler = schedulerDir;
93
+ process.env.MPO_VITEST_REACT = reactDir;
94
+ process.env.MPO_VITEST_REACT_DOM = reactDomDir;
95
+ process.env.MPO_VITEST_SCHEDULER = schedulerDir;
96
+ pinNodeReactRequire(reactDir, reactDomDir, schedulerDir);
59
97
  }
60
98
  const testConfig = {
61
99
  environment,
62
100
  globals: true,
63
- setupFiles,
101
+ setupFiles: dedupeReact ? [pinReactRequireSetup, ...setupFiles] : setupFiles,
64
102
  testTimeout,
65
103
  coverage: {
66
104
  provider: "v8",
@@ -88,9 +126,11 @@ function createVitestConfig(options = {}) {
88
126
  "one",
89
127
  /@tamagui\//,
90
128
  "tamagui",
129
+ /@tanstack\//,
130
+ "use-sync-external-store",
91
131
  ...inlineDeps
92
132
  ],
93
- ...externalDeps.length > 0 ? { external: externalDeps } : {},
133
+ ...externalDeps.length > 0 ? { external: [pinReactRequireSetup, ...externalDeps] } : { external: [pinReactRequireSetup] },
94
134
  interopDefault: true
95
135
  } }
96
136
  };
@@ -102,8 +142,6 @@ function createVitestConfig(options = {}) {
102
142
  test: testConfig,
103
143
  resolve: {
104
144
  extensions: [
105
- ".test.ts",
106
- ".test.tsx",
107
145
  ".web.ts",
108
146
  ".web.tsx",
109
147
  ".web.js",
@@ -123,11 +161,7 @@ function createVitestConfig(options = {}) {
123
161
  ...aliases
124
162
  },
125
163
  conditions,
126
- dedupe: dedupeReact ? [
127
- "react",
128
- "react-dom",
129
- "scheduler"
130
- ] : []
164
+ dedupe: []
131
165
  },
132
166
  define: {
133
167
  __DEV__: true,
@@ -135,7 +169,12 @@ function createVitestConfig(options = {}) {
135
169
  process: JSON.stringify({
136
170
  env: {
137
171
  NODE_ENV: "test",
138
- NODE_DEBUG: false
172
+ NODE_DEBUG: false,
173
+ ...dedupeReact ? {
174
+ MPO_VITEST_REACT: process.env.MPO_VITEST_REACT,
175
+ MPO_VITEST_REACT_DOM: process.env.MPO_VITEST_REACT_DOM,
176
+ MPO_VITEST_SCHEDULER: process.env.MPO_VITEST_SCHEDULER
177
+ } : {}
139
178
  },
140
179
  platform: process.platform,
141
180
  version: process.version,
package/lint.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export type ConventionRoots = {
2
+ root?: string;
3
+ apps?: string;
4
+ features?: string;
5
+ public?: string;
6
+ };
7
+
8
+ export type RunConventionChecksOptions = {
9
+ roots?: ConventionRoots;
10
+ };
11
+
12
+ export function resolveRoots(roots?: ConventionRoots): {
13
+ root: string;
14
+ apps: string;
15
+ features: string;
16
+ public: string;
17
+ };
18
+
19
+ export function runConventionChecks(options?: RunConventionChecksOptions): number;