-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdevcheck.mjs
More file actions
106 lines (100 loc) · 5.16 KB
/
Copy pathdevcheck.mjs
File metadata and controls
106 lines (100 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* @Project: @cldmv/holdmytask
* @Filename: /devcheck.mjs
* @Date: 2025-11-08 22:18:57 -08:00 (1762669137)
* @Author: Nate Hyson <CLDMV>
* @Email: <Shinrai@users.noreply.github.com>
* -----
* @Last modified by: Nate Hyson <CLDMV> (Shinrai@users.noreply.github.com)
* @Last modified time: 2025-11-21 14:51:16 -08:00 (1763765476)
* -----
* @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved.
*/
import { existsSync } from "node:fs";
import { fileURLToPath } from "node:url";
import path from "node:path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const srcPath = path.join(__dirname, "src");
// Detect if we're running in a CI environment
const isCI = !!(
process.env.CI || // Generic CI flag
process.env.GITHUB_ACTIONS || // GitHub Actions
process.env.TRAVIS || // Travis CI
process.env.CIRCLECI || // CircleCI
process.env.GITLAB_CI || // GitLab CI
process.env.BUILDKITE || // Buildkite
process.env.JENKINS_URL || // Jenkins
process.env.TF_BUILD // Azure DevOps
);
// Skip when installed as a dependency (a `node_modules` segment anywhere above this
// file - covers scoped `node_modules/@cldmv/holdmytask` and unscoped installs). The
// npm-published package ships neither `src/` nor this file, so this branch is already
// moot there; but a git/tarball install DOES include them, and without this guard
// devcheck would `process.exit(1)` inside a consumer's app. A "parent dir ===
// node_modules" check would miss scoped packages (parent is the scope dir).
const isInstalledPackage = __dirname.split(path.sep).includes("node_modules");
// Only meaningful in a source checkout. When `src/` is present the developer should be
// loading from it via the `holdmytask-dev` condition; if that condition isn't set they
// are silently running the built `dist/` copy instead, so warn - even after a build,
// since a built checkout has BOTH src/ and dist/ and the condition is the only thing
// that selects src/.
if (existsSync(srcPath) && !isCI && !isInstalledPackage) {
// The condition selects src/ (see the `./main` export in package.json). It can be
// supplied via NODE_OPTIONS (`NODE_OPTIONS=--conditions=holdmytask-dev`) OR directly
// on the node CLI (`node --conditions=holdmytask-dev` / `-C holdmytask-dev`), which
// lands in execArgv - this is how vitest passes it to workers - so scan both. Each
// `--conditions` occurrence is ONE literal condition value: Node does not split it on
// `,` or `|` (verified - `--conditions=holdmytask-dev,x` and
// `--conditions=holdmytask-dev|x` do NOT enable `holdmytask-dev`), and multiple
// conditions are passed as repeated flags. So collect each value whole and match
// EXACTLY - no substring, no splitting - so `not-holdmytask-dev`, `holdmytask-dev,x`,
// and `holdmytask-dev|production` all correctly fail to count. Namespaced (not the
// generic `development`) so a consuming app's own `--conditions=development` can't
// flip this package to a source tree it doesn't ship. NODE_ENV is deliberately NOT
// consulted: it does not affect which tree resolves.
const conditions = [];
const scan = (tokens) => {
for (let i = 0; i < tokens.length; i++) {
if (tokens[i] === "--conditions" || tokens[i] === "-C") {
// Space form (`--conditions x` / `-C x`): consume the following token as this
// flag's value and SKIP it, so a value that itself looks like a flag (e.g. the
// literal `--conditions=x`) isn't re-interpreted on the next iteration.
if (tokens[i + 1] !== undefined) {
conditions.push(tokens[i + 1]);
i++;
}
} else if (tokens[i].startsWith("--conditions=")) {
conditions.push(tokens[i].slice("--conditions=".length));
}
// Note: `-C=x` is intentionally not handled - Node rejects it ("bad option"),
// so it can never appear in execArgv/NODE_OPTIONS. Valid forms are
// `--conditions=x`, `--conditions x`, and `-C x`.
}
};
scan(process.execArgv);
scan((process.env.NODE_OPTIONS || "").split(/\s+/).filter(Boolean));
const hasHoldMyTaskDev = conditions.includes("holdmytask-dev");
if (!hasHoldMyTaskDev) {
console.error("❌ Development environment not properly configured!");
console.error("📁 Source folder detected but the 'holdmytask-dev' condition is not set,");
console.error(" so imports resolve to dist/ by default (or fail if it isn't built) instead of src/.");
console.error("");
console.error("🔧 To load from src/ for development, set the condition:");
console.error(" Windows (cmd):");
console.error(" set NODE_OPTIONS=--conditions=holdmytask-dev");
console.error("");
console.error(" Windows (PowerShell):");
console.error(" $env:NODE_OPTIONS='--conditions=holdmytask-dev'");
console.error("");
console.error(" Unix/Linux/macOS:");
console.error(" export NODE_OPTIONS=--conditions=holdmytask-dev");
console.error("");
console.error(" ...or pass it directly: node --conditions=holdmytask-dev <file>");
console.error("");
console.error("💡 'holdmytask-dev' is namespaced so it can't conflict with a consumer's");
console.error(" own development conditions.");
console.error("🚀 CI environments automatically skip this check.");
process.exit(1);
}
}