@sister.software/oxlint-config 9.0.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 ADDED
@@ -0,0 +1,64 @@
1
+ # @sister.software/oxlint-config
2
+
3
+ Sister Software's shared [oxlint](https://oxc.rs) configuration.
4
+
5
+ Replaces `@sister.software/eslint-config`. It preserves the two features that mattered most —
6
+ **platform-layering import boundaries** and **license-header enforcement** — while shedding the
7
+ ESLint plugin ecosystem that made major upgrades painful.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ yarn add -D @sister.software/oxlint-config oxlint
13
+ ```
14
+
15
+ `oxlint` is a peer dependency. Node `>=24` is required (oxlint runs the `.ts` config and the JS
16
+ header plugin via Node).
17
+
18
+ ## Usage
19
+
20
+ Create an `oxlint.config.ts` (oxlint auto-discovers it):
21
+
22
+ ```ts
23
+ import { createOxlintConfig } from "@sister.software/oxlint-config"
24
+
25
+ export default createOxlintConfig({
26
+ spdxLicenseIdentifier: "AGPL-3.0",
27
+ })
28
+ ```
29
+
30
+ `createOxlintConfig()` returns a complete oxlint config object — there is no `extends` step.
31
+
32
+ ### Options
33
+
34
+ | Option | Default | Purpose |
35
+ | ----------------------- | ------------------------ | -------------------------------------------------- |
36
+ | `packageNamespace` | `@sister.software` | Namespace the runtime-boundary rules apply to. |
37
+ | `copyrightHolder` | `Sister Software` | `@copyright` value stamped into file headers. |
38
+ | `spdxLicenseIdentifier` | `UNLICENSED` | `@license` value stamped into file headers. |
39
+ | `author` | `Teffen Ellis, et al.` | `@author` value stamped into file headers. |
40
+ | `react` | `false` | Enable oxlint's React plugin. |
41
+ | `headers` | `true` | Enforce file headers (error severity, auto-fixed). |
42
+ | `ignorePatterns` | build/output dirs | Replace the default ignore list. |
43
+ | `overrides` | `{}` | Extra config merged last (escape hatch). |
44
+
45
+ ## Features
46
+
47
+ ### Platform layering
48
+
49
+ Files are matched by their final name segment, and cross-runtime imports are flagged via core
50
+ `no-restricted-imports`:
51
+
52
+ - `browser` → `client`, `browser`
53
+ - `node` → `server`, `node`, `sdk`
54
+ - `agnostic` → `shared`, `common`
55
+ - `worker` → `worker`
56
+
57
+ A `*-client` file importing a `*-server` package (or vice versa) is an error; `*-shared`/`*-common`
58
+ files may not import Node built-ins at all.
59
+
60
+ ### License headers
61
+
62
+ A bundled oxlint JS plugin (`sister-software/require-file-header`) reports and auto-fixes the
63
+ `@copyright`/`@license`/`@author` header, preserving any other JSDoc tags already in the leading
64
+ comment block. Run `oxlint --fix` to stamp headers.
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file A JSDoc-aware license-header rule, authored as an oxlint JS plugin (ESLint v9-compatible
6
+ * API). It reports files missing the `@copyright`/`@license`/`@author` header and autofixes them
7
+ * while preserving any other JSDoc tags already present in the leading comment block.
8
+ */
9
+ interface Comment {
10
+ type: string;
11
+ value: string;
12
+ range: [number, number];
13
+ }
14
+ interface SourceCode {
15
+ getText(): string;
16
+ getAllComments(): Comment[];
17
+ }
18
+ interface Fixer {
19
+ insertTextBeforeRange(range: [number, number], text: string): unknown;
20
+ replaceTextRange(range: [number, number], text: string): unknown;
21
+ }
22
+ interface RuleContext {
23
+ options: unknown[];
24
+ sourceCode?: SourceCode;
25
+ getSourceCode?(): SourceCode;
26
+ report(descriptor: {
27
+ node: unknown;
28
+ message: string;
29
+ fix?(fixer: Fixer): unknown;
30
+ }): void;
31
+ }
32
+ interface Rule {
33
+ meta: {
34
+ name: string;
35
+ type: string;
36
+ fixable: "code";
37
+ schema: unknown[];
38
+ };
39
+ create(context: RuleContext): Record<string, (node: unknown) => void>;
40
+ }
41
+ interface Plugin {
42
+ meta: {
43
+ name: string;
44
+ };
45
+ rules: Record<string, Rule>;
46
+ }
47
+ /** Options accepted by the header rule. */
48
+ export interface HeaderRuleOptions {
49
+ copyrightHolder?: string;
50
+ spdxLicenseIdentifier?: string;
51
+ author?: string;
52
+ }
53
+ /** The Sister Software oxlint header plugin. Registers the `sister-software/require-file-header` rule. */
54
+ declare const headerPlugin: Plugin;
55
+ export default headerPlugin;
56
+ //# sourceMappingURL=headers-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers-plugin.d.ts","sourceRoot":"","sources":["../src/headers-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,UAAU,OAAO;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvB;AAED,UAAU,UAAU;IACnB,OAAO,IAAI,MAAM,CAAA;IACjB,cAAc,IAAI,OAAO,EAAE,CAAA;CAC3B;AAED,UAAU,KAAK;IACd,qBAAqB,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IACrE,gBAAgB,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CAChE;AAED,UAAU,WAAW;IACpB,OAAO,EAAE,OAAO,EAAE,CAAA;IAClB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,aAAa,CAAC,IAAI,UAAU,CAAA;IAC5B,MAAM,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAA;KAAE,GAAG,IAAI,CAAA;CACzF;AAED,UAAU,IAAI;IACb,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAA;IACxE,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,CAAA;CACrE;AAED,UAAU,MAAM;IACf,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;CAC3B;AAID,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IACjC,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAiFD,0GAA0G;AAC1G,QAAA,MAAM,YAAY,EAAE,MAGnB,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file A JSDoc-aware license-header rule, authored as an oxlint JS plugin (ESLint v9-compatible
6
+ * API). It reports files missing the `@copyright`/`@license`/`@author` header and autofixes them
7
+ * while preserving any other JSDoc tags already present in the leading comment block.
8
+ */
9
+ const HEADER_TAG_PATTERN = /^@(copyright|license|author)\b/;
10
+ /**
11
+ * Splits a block comment's inner text into trimmed, non-empty content lines (one per JSDoc line), stripping the leading
12
+ * ` * ` decoration.
13
+ */
14
+ function parseInnerLines(comment) {
15
+ return comment.value
16
+ .split("\n")
17
+ .map((line) => line.replace(/^\s*\*?\s?/, "").replace(/\s+$/, ""))
18
+ .filter((line) => line.length > 0);
19
+ }
20
+ const rule = {
21
+ meta: {
22
+ name: "require-file-header",
23
+ type: "layout",
24
+ fixable: "code",
25
+ // Permissive schema: oxlint's alpha JS-plugin layer mangles complex option schemas, so we
26
+ // accept any object and read options defensively below.
27
+ schema: [{ type: "object", additionalProperties: true }],
28
+ },
29
+ create(context) {
30
+ const options = (context.options[0] ?? {});
31
+ const copyrightHolder = options.copyrightHolder ?? "Sister Software";
32
+ const spdxLicenseIdentifier = options.spdxLicenseIdentifier ?? "UNLICENSED";
33
+ const author = options.author ?? "Teffen Ellis, et al.";
34
+ const headerLines = [`@copyright ${copyrightHolder}`, `@license ${spdxLicenseIdentifier}`, `@author ${author}`];
35
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
36
+ function buildBlock(preservedLines) {
37
+ return "/**\n" + [...headerLines, ...preservedLines].map((line) => ` * ${line}`).join("\n") + "\n */";
38
+ }
39
+ return {
40
+ Program(node) {
41
+ const text = sourceCode.getText();
42
+ // A leading shebang (`#!...`) must stay on line 1, so the header goes *after* it.
43
+ const shebang = /^#![^\n]*\n?/.exec(text)?.[0] ?? "";
44
+ const comments = sourceCode.getAllComments();
45
+ // The first *block* comment, skipping any shebang (which some ASTs surface as a leading
46
+ // comment). It counts as the header block only if nothing but the shebang precedes it.
47
+ const firstBlock = comments.find((comment) => comment.type === "Block");
48
+ const leading = firstBlock && text.slice(shebang.length, firstBlock.range[0]).trim() === "" ? firstBlock : null;
49
+ if (leading) {
50
+ const existing = parseInnerLines(leading);
51
+ const missing = headerLines.filter((line) => !existing.includes(line));
52
+ if (missing.length === 0)
53
+ return;
54
+ const preserved = existing.filter((line) => !HEADER_TAG_PATTERN.test(line));
55
+ const block = buildBlock(preserved);
56
+ context.report({
57
+ node,
58
+ message: `File header missing or incorrect: ${missing.join(", ")}`,
59
+ fix(fixer) {
60
+ return fixer.replaceTextRange(leading.range, block);
61
+ },
62
+ });
63
+ }
64
+ else {
65
+ const block = buildBlock([]);
66
+ const insertAt = shebang.length;
67
+ context.report({
68
+ node,
69
+ message: "File header missing (@copyright/@license/@author).",
70
+ fix(fixer) {
71
+ return fixer.insertTextBeforeRange([insertAt, insertAt], block + "\n\n");
72
+ },
73
+ });
74
+ }
75
+ },
76
+ };
77
+ },
78
+ };
79
+ /** The Sister Software oxlint header plugin. Registers the `sister-software/require-file-header` rule. */
80
+ const headerPlugin = {
81
+ meta: { name: "sister-software" },
82
+ rules: { "require-file-header": rule },
83
+ };
84
+ export default headerPlugin;
85
+ //# sourceMappingURL=headers-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers-plugin.js","sourceRoot":"","sources":["../src/headers-plugin.ts"],"names":[],"mappings":"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"}
package/out/index.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file oxlint configuration factory for Sister Software projects.
6
+ */
7
+ export * from "./restrictions.js";
8
+ /** An oxlint configuration object, as consumed by `oxlint.config.ts` / `.oxlintrc.json`. */
9
+ export type OxlintConfig = Record<string, unknown>;
10
+ /** Options for {@link createOxlintConfig}. */
11
+ export interface OxlintConfigOptions {
12
+ /** The package namespace whose runtime boundaries are enforced, e.g. `@sister.software`. */
13
+ packageNamespace?: string;
14
+ /** The copyright holder stamped into file headers. */
15
+ copyrightHolder?: string;
16
+ /** The SPDX license identifier stamped into file headers. */
17
+ spdxLicenseIdentifier?: string;
18
+ /** The author stamped into file headers. */
19
+ author?: string;
20
+ /** Enable oxlint's React plugin (off by default). */
21
+ react?: boolean;
22
+ /** Enforce file headers via the bundled JS plugin (on by default). */
23
+ headers?: boolean;
24
+ /** Override the default ignore patterns. */
25
+ ignorePatterns?: string[];
26
+ /** Extra config deep-merged last; an escape hatch for per-repo tweaks. */
27
+ overrides?: OxlintConfig;
28
+ }
29
+ /** Default ignore patterns for generated/build output. */
30
+ export declare const DefaultIgnorePatterns: string[];
31
+ /**
32
+ * Builds the complete oxlint configuration for a Sister Software package.
33
+ *
34
+ * Consumers use it directly from an `oxlint.config.ts`:
35
+ *
36
+ * ```ts
37
+ * import { createOxlintConfig } from "@sister.software/oxlint-config"
38
+ * export default createOxlintConfig({ spdxLicenseIdentifier: "AGPL-3.0" })
39
+ * ```
40
+ *
41
+ * @param options Configuration options.
42
+ * @returns A complete oxlint config object (no `extends` required).
43
+ */
44
+ export declare function createOxlintConfig(options?: OxlintConfigOptions): OxlintConfig;
45
+ export default createOxlintConfig;
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,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;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,CA8DlF;AAED,eAAe,kBAAkB,CAAA"}
package/out/index.js ADDED
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file oxlint configuration factory for Sister Software projects.
6
+ */
7
+ import { createRuntimeOverrides } from "./restrictions.js";
8
+ export * from "./restrictions.js";
9
+ /** Default ignore patterns for generated/build output. */
10
+ export const DefaultIgnorePatterns = [
11
+ "**/out",
12
+ "**/dist",
13
+ "**/.docusaurus/**",
14
+ "**/node_modules",
15
+ "**/coverage",
16
+ "**/storybook-static",
17
+ ];
18
+ /**
19
+ * Builds the complete oxlint configuration for a Sister Software package.
20
+ *
21
+ * Consumers use it directly from an `oxlint.config.ts`:
22
+ *
23
+ * ```ts
24
+ * import { createOxlintConfig } from "@sister.software/oxlint-config"
25
+ * export default createOxlintConfig({ spdxLicenseIdentifier: "AGPL-3.0" })
26
+ * ```
27
+ *
28
+ * @param options Configuration options.
29
+ * @returns A complete oxlint config object (no `extends` required).
30
+ */
31
+ export function createOxlintConfig(options = {}) {
32
+ const { packageNamespace = "@sister.software", copyrightHolder = "Sister Software", spdxLicenseIdentifier = "UNLICENSED", author = "Teffen Ellis, et al.", react = false, headers = true, ignorePatterns = DefaultIgnorePatterns, overrides = {}, } = options;
33
+ const plugins = ["typescript", "unicorn", "oxc", ...(react ? ["react"] : [])];
34
+ const rules = {
35
+ // JavaScript
36
+ eqeqeq: ["error", "always", { null: "ignore" }],
37
+ "prefer-const": "warn",
38
+ "object-shorthand": ["warn", "always"],
39
+ "no-shadow": "off",
40
+ "no-undef": "off",
41
+ "no-unused-vars": [
42
+ "warn",
43
+ {
44
+ args: "all",
45
+ argsIgnorePattern: "^_",
46
+ caughtErrors: "all",
47
+ caughtErrorsIgnorePattern: "^_",
48
+ destructuredArrayIgnorePattern: "^_",
49
+ // Matches the prior ESLint config: unused vars are not reported (Prettier/oxfmt and TS
50
+ // already cover most cases); only unused args without a `_` prefix are flagged.
51
+ varsIgnorePattern: "^\\w",
52
+ ignoreRestSiblings: true,
53
+ },
54
+ ],
55
+ // TypeScript — intentionally permissive (matches the prior ESLint config).
56
+ "typescript/ban-ts-comment": ["warn", { "ts-ignore": "allow-with-description" }],
57
+ "typescript/ban-types": "off",
58
+ "typescript/no-empty-interface": "off",
59
+ "typescript/no-explicit-any": "off",
60
+ "typescript/no-misused-new": "off",
61
+ "typescript/no-non-null-assertion": "off",
62
+ "typescript/no-var-requires": "off",
63
+ "typescript/no-require-imports": "off",
64
+ };
65
+ if (headers) {
66
+ // Error severity: missing headers should fail `oxlint` (a real CI gate) and surface as an
67
+ // editor error. The rule is auto-fixable, so `oxlint --fix` keeps the friction low.
68
+ rules["sister-software/require-file-header"] = ["error", { copyrightHolder, spdxLicenseIdentifier, author }];
69
+ }
70
+ return {
71
+ plugins,
72
+ ...(headers ? { jsPlugins: ["@sister.software/oxlint-config/headers-plugin"] } : {}),
73
+ categories: { correctness: "error" },
74
+ ignorePatterns,
75
+ rules,
76
+ overrides: createRuntimeOverrides(packageNamespace),
77
+ ...overrides,
78
+ };
79
+ }
80
+ export default createOxlintConfig;
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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;AAyBjC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,QAAQ;IACR,SAAS;IACT,mBAAmB;IACnB,iBAAiB;IACjB,aAAa;IACb,qBAAqB;CACrB,CAAA;AAED;;;;;;;;;;;;GAYG;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,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,OAAO;QACN,OAAO;QACP,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,+CAA+C,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file Platform-layering import restrictions, ported to oxlint's `no-restricted-imports`.
6
+ */
7
+ /**
8
+ * Reserved package-name suffixes mapped to their target runtime.
9
+ *
10
+ * A package whose final name segment matches one of these signals that runtime, and imports across incompatible runtime
11
+ * boundaries become lint errors.
12
+ */
13
+ export declare const RuntimePackageNamesRecord: {
14
+ readonly browser: readonly ["client", "browser"];
15
+ readonly node: readonly ["server", "node", "sdk"];
16
+ readonly agnostic: readonly ["shared", "common"];
17
+ readonly worker: readonly ["worker"];
18
+ };
19
+ export type RuntimePackageNamesRecord = typeof RuntimePackageNamesRecord;
20
+ /** Valid runtime names. */
21
+ export type RuntimeName = keyof RuntimePackageNamesRecord;
22
+ /**
23
+ * Given a package name, produces the glob matcher for files belonging to that package.
24
+ *
25
+ * @param packageName The final package-name segment, e.g. `client`.
26
+ * @returns A single-element glob array, e.g. `["**\/client.{js,...}"]`.
27
+ */
28
+ export declare function createPackageFileMatcher(packageName: string): string[];
29
+ /** A restricted-import entry: an exact module name plus the message shown when it is imported. */
30
+ export interface RestrictedPath {
31
+ name: string;
32
+ message: string;
33
+ }
34
+ /**
35
+ * Unprefixed Node built-ins (e.g. `fs`), each nudging toward the `node:` prefix. Used by browser- and node-runtime
36
+ * files where the bare form is ambiguous.
37
+ */
38
+ export declare function ambiguousNodeBuiltinPaths(): RestrictedPath[];
39
+ /**
40
+ * Every Node built-in (prefixed and unprefixed), each carrying the given message. Used by agnostic-runtime files, which
41
+ * must not assume a Node runtime at all.
42
+ */
43
+ export declare function allNodeBuiltinPaths(message: string): RestrictedPath[];
44
+ /** A per-file-glob oxlint override: applies `rules` only to files matching `files`. */
45
+ export interface OxlintOverride {
46
+ files: string[];
47
+ rules: Record<string, unknown>;
48
+ }
49
+ /**
50
+ * Generates the per-runtime overrides enforcing platform layering. One override is emitted for each browser-, node-,
51
+ * and agnostic-runtime package name (matching the original ESLint config — worker files are a restricted _target_ but
52
+ * have no override of their own).
53
+ *
54
+ * @param packageNamespace The namespace whose packages are subject to the rules, e.g. `@sister.software`.
55
+ * @returns An array of oxlint `overrides` entries.
56
+ */
57
+ export declare function createRuntimeOverrides(packageNamespace: string): OxlintOverride[];
58
+ //# sourceMappingURL=restrictions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restrictions.d.ts","sourceRoot":"","sources":["../src/restrictions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;CAK5B,CAAA;AAEV,MAAM,MAAM,yBAAyB,GAAG,OAAO,yBAAyB,CAAA;AAExE,2BAA2B;AAC3B,MAAM,MAAM,WAAW,GAAG,MAAM,yBAAyB,CAAA;AAEzD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtE;AAiBD,kGAAkG;AAClG,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,cAAc,EAAE,CAK5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAErE;AA+ED,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AA6BD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,GAAG,cAAc,EAAE,CAqDjF"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file Platform-layering import restrictions, ported to oxlint's `no-restricted-imports`.
6
+ */
7
+ import { builtinModules } from "node:module";
8
+ //#region Runtime data
9
+ /**
10
+ * Reserved package-name suffixes mapped to their target runtime.
11
+ *
12
+ * A package whose final name segment matches one of these signals that runtime, and imports across incompatible runtime
13
+ * boundaries become lint errors.
14
+ */
15
+ export const RuntimePackageNamesRecord = {
16
+ browser: ["client", "browser"],
17
+ node: ["server", "node", "sdk"],
18
+ agnostic: ["shared", "common"],
19
+ worker: ["worker"],
20
+ };
21
+ /**
22
+ * Given a package name, produces the glob matcher for files belonging to that package.
23
+ *
24
+ * @param packageName The final package-name segment, e.g. `client`.
25
+ * @returns A single-element glob array, e.g. `["**\/client.{js,...}"]`.
26
+ */
27
+ export function createPackageFileMatcher(packageName) {
28
+ return [`**/${packageName}.{js,mjs,cjs,ts,d.ts,mts,tsx}`];
29
+ }
30
+ /** Joins a namespace and package name into a specifier, e.g. `@sister.software/client`. */
31
+ function namespaced(packageNamespace, packageName) {
32
+ return [packageNamespace, packageName].filter(Boolean).join("/");
33
+ }
34
+ //#endregion
35
+ //#region Node built-in helpers
36
+ const NODE_BUILTINS_NO_PREFIX = builtinModules.filter((moduleName) => !moduleName.startsWith("_") && !moduleName.startsWith("node:"));
37
+ const NODE_BUILTINS_PREFIXED = NODE_BUILTINS_NO_PREFIX.map((moduleName) => `node:${moduleName}`);
38
+ /**
39
+ * Unprefixed Node built-ins (e.g. `fs`), each nudging toward the `node:` prefix. Used by browser- and node-runtime
40
+ * files where the bare form is ambiguous.
41
+ */
42
+ export function ambiguousNodeBuiltinPaths() {
43
+ return NODE_BUILTINS_NO_PREFIX.map((name) => ({
44
+ name,
45
+ message: `Ambiguous module: did you mean \`node:${name}\`?`,
46
+ }));
47
+ }
48
+ /**
49
+ * Every Node built-in (prefixed and unprefixed), each carrying the given message. Used by agnostic-runtime files, which
50
+ * must not assume a Node runtime at all.
51
+ */
52
+ export function allNodeBuiltinPaths(message) {
53
+ return [...NODE_BUILTINS_NO_PREFIX, ...NODE_BUILTINS_PREFIXED].map((name) => ({ name, message }));
54
+ }
55
+ //#endregion
56
+ //#region Browser globals
57
+ /**
58
+ * Browser globals whose bare use is ambiguous (they collide with common identifiers). Browser- and node-runtime files
59
+ * warn on these, nudging toward an explicit `window.` access.
60
+ */
61
+ const BROWSER_GLOBALS = [
62
+ "addEventListener",
63
+ "blur",
64
+ "close",
65
+ "closed",
66
+ "confirm",
67
+ "defaultStatus",
68
+ "defaultstatus",
69
+ "event",
70
+ "external",
71
+ "find",
72
+ "focus",
73
+ "frameElement",
74
+ "frames",
75
+ "history",
76
+ "innerHeight",
77
+ "innerWidth",
78
+ "length",
79
+ "location",
80
+ "locationbar",
81
+ "menubar",
82
+ "moveBy",
83
+ "moveTo",
84
+ "name",
85
+ "onblur",
86
+ "onerror",
87
+ "onfocus",
88
+ "onload",
89
+ "onresize",
90
+ "onunload",
91
+ "open",
92
+ "opener",
93
+ "opera",
94
+ "outerHeight",
95
+ "outerWidth",
96
+ "pageXOffset",
97
+ "pageYOffset",
98
+ "parent",
99
+ "print",
100
+ "removeEventListener",
101
+ "resizeBy",
102
+ "resizeTo",
103
+ "screen",
104
+ "screenLeft",
105
+ "screenTop",
106
+ "screenX",
107
+ "screenY",
108
+ "scroll",
109
+ "scrollbars",
110
+ "scrollBy",
111
+ "scrollTo",
112
+ "scrollX",
113
+ "scrollY",
114
+ "self",
115
+ "status",
116
+ "statusbar",
117
+ "stop",
118
+ "toolbar",
119
+ "top",
120
+ ];
121
+ function restrictedBrowserGlobalsRule() {
122
+ return ["warn", ...BROWSER_GLOBALS.map((name) => ({ name, message: `Ambiguous: did you mean \`window.${name}\`?` }))];
123
+ }
124
+ /**
125
+ * Builds the `patterns` entries forbidding a runtime from importing packages of incompatible runtimes, each with a
126
+ * tailored message.
127
+ */
128
+ function crossRuntimePatterns(packageNamespace, self, incompatible) {
129
+ return incompatible.flatMap((targetRuntime) => RuntimePackageNamesRecord[targetRuntime].map((packageName) => {
130
+ const specifier = namespaced(packageNamespace, packageName);
131
+ return {
132
+ group: [specifier, `${specifier}/**`],
133
+ message: `A "${self}"-runtime module must not import "${specifier}", which targets the "${targetRuntime}" runtime. Move shared code into a "shared"/"common" package and import that from both.`,
134
+ };
135
+ }));
136
+ }
137
+ /**
138
+ * Generates the per-runtime overrides enforcing platform layering. One override is emitted for each browser-, node-,
139
+ * and agnostic-runtime package name (matching the original ESLint config — worker files are a restricted _target_ but
140
+ * have no override of their own).
141
+ *
142
+ * @param packageNamespace The namespace whose packages are subject to the rules, e.g. `@sister.software`.
143
+ * @returns An array of oxlint `overrides` entries.
144
+ */
145
+ export function createRuntimeOverrides(packageNamespace) {
146
+ const overrides = [];
147
+ for (const packageName of RuntimePackageNamesRecord.browser) {
148
+ overrides.push({
149
+ files: createPackageFileMatcher(packageName),
150
+ rules: {
151
+ "no-restricted-imports": [
152
+ "warn",
153
+ {
154
+ paths: ambiguousNodeBuiltinPaths(),
155
+ patterns: crossRuntimePatterns(packageNamespace, "browser", ["node", "worker"]),
156
+ },
157
+ ],
158
+ "no-restricted-globals": restrictedBrowserGlobalsRule(),
159
+ },
160
+ });
161
+ }
162
+ for (const packageName of RuntimePackageNamesRecord.node) {
163
+ overrides.push({
164
+ files: createPackageFileMatcher(packageName),
165
+ rules: {
166
+ "no-restricted-imports": [
167
+ "warn",
168
+ {
169
+ paths: ambiguousNodeBuiltinPaths(),
170
+ patterns: crossRuntimePatterns(packageNamespace, "node", ["browser", "worker"]),
171
+ },
172
+ ],
173
+ "no-restricted-globals": restrictedBrowserGlobalsRule(),
174
+ },
175
+ });
176
+ }
177
+ for (const packageName of RuntimePackageNamesRecord.agnostic) {
178
+ overrides.push({
179
+ files: createPackageFileMatcher(packageName),
180
+ rules: {
181
+ "no-restricted-imports": [
182
+ "warn",
183
+ {
184
+ paths: allNodeBuiltinPaths(`A "shared"/"common" module assumes no runtime and must not import Node built-ins.`),
185
+ patterns: crossRuntimePatterns(packageNamespace, "agnostic", ["browser", "node", "worker"]),
186
+ },
187
+ ],
188
+ },
189
+ });
190
+ }
191
+ return overrides;
192
+ }
193
+ //#endregion
194
+ //# sourceMappingURL=restrictions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restrictions.js","sourceRoot":"","sources":["../src/restrictions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C,sBAAsB;AAEtB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACxC,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC;IAC/B,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC9B,MAAM,EAAE,CAAC,QAAQ,CAAC;CACT,CAAA;AAOV;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAmB;IAC3D,OAAO,CAAC,MAAM,WAAW,+BAA+B,CAAC,CAAA;AAC1D,CAAC;AAED,2FAA2F;AAC3F,SAAS,UAAU,CAAC,gBAAwB,EAAE,WAAmB;IAChE,OAAO,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjE,CAAC;AAED,YAAY;AAEZ,+BAA+B;AAE/B,MAAM,uBAAuB,GAAG,cAAc,CAAC,MAAM,CACpD,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAC9E,CAAA;AAED,MAAM,sBAAsB,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,QAAQ,UAAU,EAAE,CAAC,CAAA;AAQhG;;;GAGG;AACH,MAAM,UAAU,yBAAyB;IACxC,OAAO,uBAAuB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI;QACJ,OAAO,EAAE,yCAAyC,IAAI,KAAK;KAC3D,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IAClD,OAAO,CAAC,GAAG,uBAAuB,EAAE,GAAG,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;AAClG,CAAC;AAED,YAAY;AAEZ,yBAAyB;AAEzB;;;GAGG;AACH,MAAM,eAAe,GAAG;IACvB,kBAAkB;IAClB,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,eAAe;IACf,eAAe;IACf,OAAO;IACP,UAAU;IACV,MAAM;IACN,OAAO;IACP,cAAc;IACd,QAAQ;IACR,SAAS;IACT,aAAa;IACb,YAAY;IACZ,QAAQ;IACR,UAAU;IACV,aAAa;IACb,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,SAAS;IACT,SAAS;IACT,QAAQ;IACR,UAAU;IACV,UAAU;IACV,MAAM;IACN,QAAQ;IACR,OAAO;IACP,aAAa;IACb,YAAY;IACZ,aAAa;IACb,aAAa;IACb,QAAQ;IACR,OAAO;IACP,qBAAqB;IACrB,UAAU;IACV,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,WAAW;IACX,SAAS;IACT,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,UAAU;IACV,UAAU;IACV,SAAS;IACT,SAAS;IACT,MAAM;IACN,QAAQ;IACR,WAAW;IACX,MAAM;IACN,SAAS;IACT,KAAK;CACI,CAAA;AAEV,SAAS,4BAA4B;IACpC,OAAO,CAAC,MAAM,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,oCAAoC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;AACtH,CAAC;AAkBD;;;GAGG;AACH,SAAS,oBAAoB,CAC5B,gBAAwB,EACxB,IAAiB,EACjB,YAAoC;IAEpC,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE,CAC7C,yBAAyB,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;QAC5D,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAA;QAE3D,OAAO;YACN,KAAK,EAAE,CAAC,SAAS,EAAE,GAAG,SAAS,KAAK,CAAC;YACrC,OAAO,EAAE,MAAM,IAAI,qCAAqC,SAAS,yBAAyB,aAAa,yFAAyF;SAChM,CAAA;IACF,CAAC,CAAC,CACF,CAAA;AACF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,gBAAwB;IAC9D,MAAM,SAAS,GAAqB,EAAE,CAAA;IAEtC,KAAK,MAAM,WAAW,IAAI,yBAAyB,CAAC,OAAO,EAAE,CAAC;QAC7D,SAAS,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,wBAAwB,CAAC,WAAW,CAAC;YAC5C,KAAK,EAAE;gBACN,uBAAuB,EAAE;oBACxB,MAAM;oBACN;wBACC,KAAK,EAAE,yBAAyB,EAAE;wBAClC,QAAQ,EAAE,oBAAoB,CAAC,gBAAgB,EAAE,SAAS,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;qBAC/E;iBACD;gBACD,uBAAuB,EAAE,4BAA4B,EAAE;aACvD;SACD,CAAC,CAAA;IACH,CAAC;IAED,KAAK,MAAM,WAAW,IAAI,yBAAyB,CAAC,IAAI,EAAE,CAAC;QAC1D,SAAS,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,wBAAwB,CAAC,WAAW,CAAC;YAC5C,KAAK,EAAE;gBACN,uBAAuB,EAAE;oBACxB,MAAM;oBACN;wBACC,KAAK,EAAE,yBAAyB,EAAE;wBAClC,QAAQ,EAAE,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;qBAC/E;iBACD;gBACD,uBAAuB,EAAE,4BAA4B,EAAE;aACvD;SACD,CAAC,CAAA;IACH,CAAC;IAED,KAAK,MAAM,WAAW,IAAI,yBAAyB,CAAC,QAAQ,EAAE,CAAC;QAC9D,SAAS,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,wBAAwB,CAAC,WAAW,CAAC;YAC5C,KAAK,EAAE;gBACN,uBAAuB,EAAE;oBACxB,MAAM;oBACN;wBACC,KAAK,EAAE,mBAAmB,CACzB,mFAAmF,CACnF;wBACD,QAAQ,EAAE,oBAAoB,CAAC,gBAAgB,EAAE,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;qBAC3F;iBACD;aACD;SACD,CAAC,CAAA;IACH,CAAC;IAED,OAAO,SAAS,CAAA;AACjB,CAAC;AAED,YAAY"}