@sister.software/oxlint-config 9.2.0 → 9.3.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/out/index.d.ts CHANGED
@@ -25,6 +25,11 @@ export interface OxlintConfigOptions {
25
25
  padding?: boolean;
26
26
  /** Require braces around single-statement work bodies (bare `return` exempt; on by default). */
27
27
  braces?: boolean;
28
+ /**
29
+ * Forbid direct `process.env` / `process.argv` access (off by default). Turn on once the project funnels those reads
30
+ * through blessed helpers, which disable `sister-software/no-process-globals`.
31
+ */
32
+ restrictProcessGlobals?: boolean;
28
33
  /** Override the default ignore patterns. */
29
34
  ignorePatterns?: string[];
30
35
  /** Extra config deep-merged last; an escape hatch for per-repo tweaks. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,cAAc,mBAAmB,CAAA;AAEjC,4FAA4F;AAC5F,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAElD,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gGAAgG;IAChG,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,YAAY,CAAA;CACxB;AAED,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,UAOjC,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,CA0ElF;AAED,eAAe,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,cAAc,mBAAmB,CAAA;AAEjC,4FAA4F;AAC5F,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAElD,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gGAAgG;IAChG,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,YAAY,CAAA;CACxB;AAED,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,UAOjC,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,CAkFlF;AAED,eAAe,kBAAkB,CAAA"}
package/out/index.js CHANGED
@@ -30,7 +30,7 @@ export const DefaultIgnorePatterns = [
30
30
  * @returns A complete oxlint config object (no `extends` required).
31
31
  */
32
32
  export function createOxlintConfig(options = {}) {
33
- const { packageNamespace = "@sister.software", copyrightHolder = "Sister Software", spdxLicenseIdentifier = "UNLICENSED", author = "Teffen Ellis, et al.", react = false, headers = true, padding = true, braces = true, ignorePatterns = DefaultIgnorePatterns, overrides = {}, } = options;
33
+ const { packageNamespace = "@sister.software", copyrightHolder = "Sister Software", spdxLicenseIdentifier = "UNLICENSED", author = "Teffen Ellis, et al.", react = false, headers = true, padding = true, braces = true, restrictProcessGlobals = false, ignorePatterns = DefaultIgnorePatterns, overrides = {}, } = options;
34
34
  const plugins = ["typescript", "unicorn", "oxc", ...(react ? ["react"] : [])];
35
35
  const rules = {
36
36
  // JavaScript
@@ -76,9 +76,15 @@ export function createOxlintConfig(options = {}) {
76
76
  // Warning severity: a stylistic nudge (auto-fixable), not a hard CI gate.
77
77
  rules["sister-software/require-braces"] = "warn";
78
78
  }
79
+ if (restrictProcessGlobals) {
80
+ // Error severity: a governance gate — direct env/argv access should fail the lint.
81
+ rules["sister-software/no-process-globals"] = "error";
82
+ }
79
83
  return {
80
84
  plugins,
81
- ...(headers || padding || braces ? { jsPlugins: ["@sister.software/oxlint-config/plugin"] } : {}),
85
+ ...(headers || padding || braces || restrictProcessGlobals
86
+ ? { jsPlugins: ["@sister.software/oxlint-config/plugin"] }
87
+ : {}),
82
88
  categories: { correctness: "error" },
83
89
  ignorePatterns,
84
90
  rules,
package/out/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE1D,cAAc,mBAAmB,CAAA;AA6BjC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,QAAQ;IACR,SAAS;IACT,mBAAmB;IACnB,iBAAiB;IACjB,aAAa;IACb,qBAAqB;CACrB,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAA+B,EAAE;IACnE,MAAM,EACL,gBAAgB,GAAG,kBAAkB,EACrC,eAAe,GAAG,iBAAiB,EACnC,qBAAqB,GAAG,YAAY,EACpC,MAAM,GAAG,sBAAsB,EAC/B,KAAK,GAAG,KAAK,EACb,OAAO,GAAG,IAAI,EACd,OAAO,GAAG,IAAI,EACd,MAAM,GAAG,IAAI,EACb,cAAc,GAAG,qBAAqB,EACtC,SAAS,GAAG,EAAE,GACd,GAAG,OAAO,CAAA;IAEX,MAAM,OAAO,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAE7E,MAAM,KAAK,GAA4B;QACtC,aAAa;QACb,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC/C,cAAc,EAAE,MAAM;QACtB,kBAAkB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QACtC,WAAW,EAAE,KAAK;QAClB,UAAU,EAAE,KAAK;QACjB,gBAAgB,EAAE;YACjB,MAAM;YACN;gBACC,IAAI,EAAE,KAAK;gBACX,iBAAiB,EAAE,IAAI;gBACvB,YAAY,EAAE,KAAK;gBACnB,yBAAyB,EAAE,IAAI;gBAC/B,8BAA8B,EAAE,IAAI;gBACpC,uFAAuF;gBACvF,gFAAgF;gBAChF,iBAAiB,EAAE,MAAM;gBACzB,kBAAkB,EAAE,IAAI;aACxB;SACD;QAED,2EAA2E;QAC3E,2BAA2B,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;QAChF,sBAAsB,EAAE,KAAK;QAC7B,+BAA+B,EAAE,KAAK;QACtC,4BAA4B,EAAE,KAAK;QACnC,2BAA2B,EAAE,KAAK;QAClC,kCAAkC,EAAE,KAAK;QACzC,4BAA4B,EAAE,KAAK;QACnC,+BAA+B,EAAE,KAAK;KACtC,CAAA;IAED,IAAI,OAAO,EAAE,CAAC;QACb,0FAA0F;QAC1F,oFAAoF;QACpF,KAAK,CAAC,qCAAqC,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,CAAA;IAC7G,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACb,0EAA0E;QAC1E,KAAK,CAAC,+BAA+B,CAAC,GAAG,MAAM,CAAA;IAChD,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACZ,0EAA0E;QAC1E,KAAK,CAAC,gCAAgC,CAAC,GAAG,MAAM,CAAA;IACjD,CAAC;IAED,OAAO;QACN,OAAO;QACP,GAAG,CAAC,OAAO,IAAI,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,uCAAuC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,UAAU,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE;QACpC,cAAc;QACd,KAAK;QACL,SAAS,EAAE,sBAAsB,CAAC,gBAAgB,CAAC;QACnD,GAAG,SAAS;KACZ,CAAA;AACF,CAAC;AAED,eAAe,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,QAAA,MAAM,oBAAoB,EAAE,MAO3B,CAAA;AAED,eAAe,oBAAoB,CAAA"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAG/C,QAAA,MAAM,oBAAoB,EAAE,MAQ3B,CAAA;AAED,eAAe,oBAAoB,CAAA"}
package/out/plugin.js CHANGED
@@ -8,12 +8,14 @@
8
8
  import { bracesRule } from "./braces-plugin.js";
9
9
  import { headerRule } from "./headers-plugin.js";
10
10
  import { paddingRule } from "./padding-plugin.js";
11
+ import { noProcessGlobalsRule } from "./process-globals-plugin.js";
11
12
  const sisterSoftwarePlugin = {
12
13
  meta: { name: "sister-software" },
13
14
  rules: {
14
15
  "require-file-header": headerRule,
15
16
  "padding-lines": paddingRule,
16
17
  "require-braces": bracesRule,
18
+ "no-process-globals": noProcessGlobalsRule,
17
19
  },
18
20
  };
19
21
  export default sisterSoftwarePlugin;
package/out/plugin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGjD,MAAM,oBAAoB,GAAW;IACpC,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;IACjC,KAAK,EAAE;QACN,qBAAqB,EAAE,UAAU;QACjC,eAAe,EAAE,WAAW;QAC5B,gBAAgB,EAAE,UAAU;KAC5B;CACD,CAAA;AAED,eAAe,oBAAoB,CAAA"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAElE,MAAM,oBAAoB,GAAW;IACpC,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;IACjC,KAAK,EAAE;QACN,qBAAqB,EAAE,UAAU;QACjC,eAAe,EAAE,WAAW;QAC5B,gBAAgB,EAAE,UAAU;QAC5B,oBAAoB,EAAE,oBAAoB;KAC1C;CACD,CAAA;AAED,eAAe,oBAAoB,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file A no-process-globals rule, authored as an oxlint JS plugin (ESLint v9-compatible API). It
6
+ * forbids direct `process.env` / `process.argv` access so those reads can be funneled through a
7
+ * few blessed helpers; the helper files disable the rule (`sister-software/no-process-globals`).
8
+ * oxlint has no `no-restricted-syntax`, so this is a small dedicated rule instead.
9
+ */
10
+ import type { Rule } from "./plugin-types.js";
11
+ export declare const noProcessGlobalsRule: Rule;
12
+ export default noProcessGlobalsRule;
13
+ //# sourceMappingURL=process-globals-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-globals-plugin.d.ts","sourceRoot":"","sources":["../src/process-globals-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,mBAAmB,CAAA;AA+BtD,eAAO,MAAM,oBAAoB,EAAE,IAwBlC,CAAA;AAED,eAAe,oBAAoB,CAAA"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file A no-process-globals rule, authored as an oxlint JS plugin (ESLint v9-compatible API). It
6
+ * forbids direct `process.env` / `process.argv` access so those reads can be funneled through a
7
+ * few blessed helpers; the helper files disable the rule (`sister-software/no-process-globals`).
8
+ * oxlint has no `no-restricted-syntax`, so this is a small dedicated rule instead.
9
+ */
10
+ /** `process` members that must be reached through a blessed helper, not accessed directly. */
11
+ const RESTRICTED_MEMBERS = new Set(["env", "argv"]);
12
+ /** The accessed member name for `process.env` (identifier) or `process["env"]` (string literal). */
13
+ function accessedMember(node) {
14
+ const property = node.property;
15
+ if (!property)
16
+ return null;
17
+ if (!node.computed && property.type === "Identifier")
18
+ return property.name ?? null;
19
+ if (node.computed && (property.type === "Literal" || property.type === "StringLiteral")) {
20
+ return typeof property.value === "string" ? property.value : null;
21
+ }
22
+ return null;
23
+ }
24
+ export const noProcessGlobalsRule = {
25
+ meta: {
26
+ name: "no-process-globals",
27
+ type: "problem",
28
+ schema: [{ type: "object", additionalProperties: true }],
29
+ },
30
+ create(context) {
31
+ return {
32
+ MemberExpression(node) {
33
+ const member = node;
34
+ if (member.object?.type !== "Identifier" || member.object.name !== "process")
35
+ return;
36
+ const name = accessedMember(member);
37
+ if (!name || !RESTRICTED_MEMBERS.has(name))
38
+ return;
39
+ context.report({
40
+ node,
41
+ message: `Direct \`process.${name}\` access is restricted — read it through the project's blessed helper (disable \`sister-software/no-process-globals\` there).`,
42
+ });
43
+ },
44
+ };
45
+ },
46
+ };
47
+ export default noProcessGlobalsRule;
48
+ //# sourceMappingURL=process-globals-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-globals-plugin.js","sourceRoot":"","sources":["../src/process-globals-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,8FAA8F;AAC9F,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;AAanD,oGAAoG;AACpG,SAAS,cAAc,CAAC,IAAgB;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAE9B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAE1B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAA;IAElF,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,eAAe,CAAC,EAAE,CAAC;QACzF,OAAO,OAAO,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;IAClE,CAAC;IAED,OAAO,IAAI,CAAA;AACZ,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAS;IACzC,IAAI,EAAE;QACL,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;KACxD;IACD,MAAM,CAAC,OAAO;QACb,OAAO;YACN,gBAAgB,CAAC,IAAI;gBACpB,MAAM,MAAM,GAAG,IAAkB,CAAA;gBAEjC,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS;oBAAE,OAAM;gBAEpF,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;gBAEnC,IAAI,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,OAAM;gBAElD,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI;oBACJ,OAAO,EAAE,oBAAoB,IAAI,gIAAgI;iBACjK,CAAC,CAAA;YACH,CAAC;SACD,CAAA;IACF,CAAC;CACD,CAAA;AAED,eAAe,oBAAoB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sister.software/oxlint-config",
3
- "version": "9.2.0",
3
+ "version": "9.3.0",
4
4
  "description": "Sister Software's oxlint config",
5
5
  "license": "AGPL-3.0",
6
6
  "author": "teffen@sister.software",
package/src/index.ts CHANGED
@@ -30,6 +30,11 @@ export interface OxlintConfigOptions {
30
30
  padding?: boolean
31
31
  /** Require braces around single-statement work bodies (bare `return` exempt; on by default). */
32
32
  braces?: boolean
33
+ /**
34
+ * Forbid direct `process.env` / `process.argv` access (off by default). Turn on once the project funnels those reads
35
+ * through blessed helpers, which disable `sister-software/no-process-globals`.
36
+ */
37
+ restrictProcessGlobals?: boolean
33
38
  /** Override the default ignore patterns. */
34
39
  ignorePatterns?: string[]
35
40
  /** Extra config deep-merged last; an escape hatch for per-repo tweaks. */
@@ -70,6 +75,7 @@ export function createOxlintConfig(options: OxlintConfigOptions = {}): OxlintCon
70
75
  headers = true,
71
76
  padding = true,
72
77
  braces = true,
78
+ restrictProcessGlobals = false,
73
79
  ignorePatterns = DefaultIgnorePatterns,
74
80
  overrides = {},
75
81
  } = options
@@ -125,9 +131,16 @@ export function createOxlintConfig(options: OxlintConfigOptions = {}): OxlintCon
125
131
  rules["sister-software/require-braces"] = "warn"
126
132
  }
127
133
 
134
+ if (restrictProcessGlobals) {
135
+ // Error severity: a governance gate — direct env/argv access should fail the lint.
136
+ rules["sister-software/no-process-globals"] = "error"
137
+ }
138
+
128
139
  return {
129
140
  plugins,
130
- ...(headers || padding || braces ? { jsPlugins: ["@sister.software/oxlint-config/plugin"] } : {}),
141
+ ...(headers || padding || braces || restrictProcessGlobals
142
+ ? { jsPlugins: ["@sister.software/oxlint-config/plugin"] }
143
+ : {}),
131
144
  categories: { correctness: "error" },
132
145
  ignorePatterns,
133
146
  rules,
package/src/plugin.ts CHANGED
@@ -10,6 +10,7 @@ import { bracesRule } from "./braces-plugin.js"
10
10
  import { headerRule } from "./headers-plugin.js"
11
11
  import { paddingRule } from "./padding-plugin.js"
12
12
  import type { Plugin } from "./plugin-types.js"
13
+ import { noProcessGlobalsRule } from "./process-globals-plugin.js"
13
14
 
14
15
  const sisterSoftwarePlugin: Plugin = {
15
16
  meta: { name: "sister-software" },
@@ -17,6 +18,7 @@ const sisterSoftwarePlugin: Plugin = {
17
18
  "require-file-header": headerRule,
18
19
  "padding-lines": paddingRule,
19
20
  "require-braces": bracesRule,
21
+ "no-process-globals": noProcessGlobalsRule,
20
22
  },
21
23
  }
22
24
 
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file A no-process-globals rule, authored as an oxlint JS plugin (ESLint v9-compatible API). It
6
+ * forbids direct `process.env` / `process.argv` access so those reads can be funneled through a
7
+ * few blessed helpers; the helper files disable the rule (`sister-software/no-process-globals`).
8
+ * oxlint has no `no-restricted-syntax`, so this is a small dedicated rule instead.
9
+ */
10
+
11
+ import type { AstNode, Rule } from "./plugin-types.js"
12
+
13
+ /** `process` members that must be reached through a blessed helper, not accessed directly. */
14
+ const RESTRICTED_MEMBERS = new Set(["env", "argv"])
15
+
16
+ interface Identifierish extends AstNode {
17
+ name?: string
18
+ value?: unknown
19
+ }
20
+
21
+ interface MemberNode extends AstNode {
22
+ object?: Identifierish
23
+ property?: Identifierish
24
+ computed?: boolean
25
+ }
26
+
27
+ /** The accessed member name for `process.env` (identifier) or `process["env"]` (string literal). */
28
+ function accessedMember(node: MemberNode): string | null {
29
+ const property = node.property
30
+
31
+ if (!property) return null
32
+
33
+ if (!node.computed && property.type === "Identifier") return property.name ?? null
34
+
35
+ if (node.computed && (property.type === "Literal" || property.type === "StringLiteral")) {
36
+ return typeof property.value === "string" ? property.value : null
37
+ }
38
+
39
+ return null
40
+ }
41
+
42
+ export const noProcessGlobalsRule: Rule = {
43
+ meta: {
44
+ name: "no-process-globals",
45
+ type: "problem",
46
+ schema: [{ type: "object", additionalProperties: true }],
47
+ },
48
+ create(context) {
49
+ return {
50
+ MemberExpression(node) {
51
+ const member = node as MemberNode
52
+
53
+ if (member.object?.type !== "Identifier" || member.object.name !== "process") return
54
+
55
+ const name = accessedMember(member)
56
+
57
+ if (!name || !RESTRICTED_MEMBERS.has(name)) return
58
+
59
+ context.report({
60
+ node,
61
+ message: `Direct \`process.${name}\` access is restricted — read it through the project's blessed helper (disable \`sister-software/no-process-globals\` there).`,
62
+ })
63
+ },
64
+ }
65
+ },
66
+ }
67
+
68
+ export default noProcessGlobalsRule