@zukhruf/eslint 0.1.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/LICENSE +21 -0
- package/README.md +138 -0
- package/dist/authoring/ast.d.ts +10 -0
- package/dist/authoring/ast.d.ts.map +1 -0
- package/dist/authoring/ast.js +22 -0
- package/dist/authoring/ast.js.map +1 -0
- package/dist/authoring/import-ban.d.ts +14 -0
- package/dist/authoring/import-ban.d.ts.map +1 -0
- package/dist/authoring/import-ban.js +32 -0
- package/dist/authoring/import-ban.js.map +1 -0
- package/dist/authoring/path-scope.d.ts +12 -0
- package/dist/authoring/path-scope.d.ts.map +1 -0
- package/dist/authoring/path-scope.js +28 -0
- package/dist/authoring/path-scope.js.map +1 -0
- package/dist/authoring/rule-module.d.ts +14 -0
- package/dist/authoring/rule-module.d.ts.map +1 -0
- package/dist/authoring/rule-module.js +23 -0
- package/dist/authoring/rule-module.js.map +1 -0
- package/dist/authoring/scoped-rule.d.ts +8 -0
- package/dist/authoring/scoped-rule.d.ts.map +1 -0
- package/dist/authoring/scoped-rule.js +12 -0
- package/dist/authoring/scoped-rule.js.map +1 -0
- package/dist/authoring/selector-rule.d.ts +17 -0
- package/dist/authoring/selector-rule.d.ts.map +1 -0
- package/dist/authoring/selector-rule.js +23 -0
- package/dist/authoring/selector-rule.js.map +1 -0
- package/dist/base/config.d.ts +8 -0
- package/dist/base/config.d.ts.map +1 -0
- package/dist/base/config.js +122 -0
- package/dist/base/config.js.map +1 -0
- package/dist/base/options.d.ts +23 -0
- package/dist/base/options.d.ts.map +1 -0
- package/dist/base/options.js +22 -0
- package/dist/base/options.js.map +1 -0
- package/dist/concept.d.ts +16 -0
- package/dist/concept.d.ts.map +1 -0
- package/dist/concept.js +5 -0
- package/dist/concept.js.map +1 -0
- package/dist/diagnostics/config.d.ts +4 -0
- package/dist/diagnostics/config.d.ts.map +1 -0
- package/dist/diagnostics/config.js +25 -0
- package/dist/diagnostics/config.js.map +1 -0
- package/dist/diagnostics/consistent-event-name.d.ts +4 -0
- package/dist/diagnostics/consistent-event-name.d.ts.map +1 -0
- package/dist/diagnostics/consistent-event-name.js +72 -0
- package/dist/diagnostics/consistent-event-name.js.map +1 -0
- package/dist/diagnostics/no-fabricated-fallback.d.ts +4 -0
- package/dist/diagnostics/no-fabricated-fallback.d.ts.map +1 -0
- package/dist/diagnostics/no-fabricated-fallback.js +116 -0
- package/dist/diagnostics/no-fabricated-fallback.js.map +1 -0
- package/dist/diagnostics/no-hardcoded-id-shape.d.ts +4 -0
- package/dist/diagnostics/no-hardcoded-id-shape.d.ts.map +1 -0
- package/dist/diagnostics/no-hardcoded-id-shape.js +73 -0
- package/dist/diagnostics/no-hardcoded-id-shape.js.map +1 -0
- package/dist/environment/config.d.ts +7 -0
- package/dist/environment/config.d.ts.map +1 -0
- package/dist/environment/config.js +28 -0
- package/dist/environment/config.js.map +1 -0
- package/dist/environment/no-default-for-path-env.d.ts +10 -0
- package/dist/environment/no-default-for-path-env.d.ts.map +1 -0
- package/dist/environment/no-default-for-path-env.js +124 -0
- package/dist/environment/no-default-for-path-env.js.map +1 -0
- package/dist/environment/no-single-env-read-wrapper.d.ts +10 -0
- package/dist/environment/no-single-env-read-wrapper.d.ts.map +1 -0
- package/dist/environment/no-single-env-read-wrapper.js +76 -0
- package/dist/environment/no-single-env-read-wrapper.js.map +1 -0
- package/dist/environment/no-undeclared-process-env.d.ts +11 -0
- package/dist/environment/no-undeclared-process-env.d.ts.map +1 -0
- package/dist/environment/no-undeclared-process-env.js +195 -0
- package/dist/environment/no-undeclared-process-env.js.map +1 -0
- package/dist/files.d.ts +16 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +27 -0
- package/dist/files.js.map +1 -0
- package/dist/hono/config.d.ts +3 -0
- package/dist/hono/config.d.ts.map +1 -0
- package/dist/hono/config.js +18 -0
- package/dist/hono/config.js.map +1 -0
- package/dist/hono/no-untyped-empty-json.d.ts +8 -0
- package/dist/hono/no-untyped-empty-json.d.ts.map +1 -0
- package/dist/hono/no-untyped-empty-json.js +14 -0
- package/dist/hono/no-untyped-empty-json.js.map +1 -0
- package/dist/imports/no-deepagents-agent.d.ts +3 -0
- package/dist/imports/no-deepagents-agent.d.ts.map +1 -0
- package/dist/imports/no-deepagents-agent.js +7 -0
- package/dist/imports/no-deepagents-agent.js.map +1 -0
- package/dist/imports/no-playwright-test.d.ts +3 -0
- package/dist/imports/no-playwright-test.d.ts.map +1 -0
- package/dist/imports/no-playwright-test.js +7 -0
- package/dist/imports/no-playwright-test.js.map +1 -0
- package/dist/imports/no-state-managers.d.ts +3 -0
- package/dist/imports/no-state-managers.d.ts.map +1 -0
- package/dist/imports/no-state-managers.js +15 -0
- package/dist/imports/no-state-managers.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/island/island-scope.d.ts +10 -0
- package/dist/island/island-scope.d.ts.map +1 -0
- package/dist/island/island-scope.js +21 -0
- package/dist/island/island-scope.js.map +1 -0
- package/dist/island/no-console.d.ts +9 -0
- package/dist/island/no-console.d.ts.map +1 -0
- package/dist/island/no-console.js +39 -0
- package/dist/island/no-console.js.map +1 -0
- package/dist/island/no-generic-port.d.ts +8 -0
- package/dist/island/no-generic-port.d.ts.map +1 -0
- package/dist/island/no-generic-port.js +14 -0
- package/dist/island/no-generic-port.js.map +1 -0
- package/dist/island/no-process-env.d.ts +3 -0
- package/dist/island/no-process-env.d.ts.map +1 -0
- package/dist/island/no-process-env.js +10 -0
- package/dist/island/no-process-env.js.map +1 -0
- package/dist/island/plugin.d.ts +25 -0
- package/dist/island/plugin.d.ts.map +1 -0
- package/dist/island/plugin.js +67 -0
- package/dist/island/plugin.js.map +1 -0
- package/dist/language/no-enum.d.ts +3 -0
- package/dist/language/no-enum.d.ts.map +1 -0
- package/dist/language/no-enum.js +7 -0
- package/dist/language/no-enum.js.map +1 -0
- package/dist/nx-policy/dependency-policy.d.ts +30 -0
- package/dist/nx-policy/dependency-policy.d.ts.map +1 -0
- package/dist/nx-policy/dependency-policy.js +31 -0
- package/dist/nx-policy/dependency-policy.js.map +1 -0
- package/dist/nx-policy/island-constraint.d.ts +10 -0
- package/dist/nx-policy/island-constraint.d.ts.map +1 -0
- package/dist/nx-policy/island-constraint.js +15 -0
- package/dist/nx-policy/island-constraint.js.map +1 -0
- package/dist/nx-policy/module-boundaries.d.ts +29 -0
- package/dist/nx-policy/module-boundaries.d.ts.map +1 -0
- package/dist/nx-policy/module-boundaries.js +20 -0
- package/dist/nx-policy/module-boundaries.js.map +1 -0
- package/dist/nx-project/config.d.ts +4 -0
- package/dist/nx-project/config.d.ts.map +1 -0
- package/dist/nx-project/config.js +20 -0
- package/dist/nx-project/config.js.map +1 -0
- package/dist/nx-project/no-missing-asset-input.d.ts +9 -0
- package/dist/nx-project/no-missing-asset-input.d.ts.map +1 -0
- package/dist/nx-project/no-missing-asset-input.js +209 -0
- package/dist/nx-project/no-missing-asset-input.js.map +1 -0
- package/dist/nx.d.ts +5 -0
- package/dist/nx.d.ts.map +1 -0
- package/dist/nx.js +5 -0
- package/dist/nx.js.map +1 -0
- package/dist/packaged-app/config.d.ts +4 -0
- package/dist/packaged-app/config.d.ts.map +1 -0
- package/dist/packaged-app/config.js +19 -0
- package/dist/packaged-app/config.js.map +1 -0
- package/dist/packaged-app/no-bare-spawn.d.ts +4 -0
- package/dist/packaged-app/no-bare-spawn.d.ts.map +1 -0
- package/dist/packaged-app/no-bare-spawn.js +175 -0
- package/dist/packaged-app/no-bare-spawn.js.map +1 -0
- package/dist/plugin.d.ts +14 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +48 -0
- package/dist/plugin.js.map +1 -0
- package/dist/pulumi/config.d.ts +3 -0
- package/dist/pulumi/config.d.ts.map +1 -0
- package/dist/pulumi/config.js +17 -0
- package/dist/pulumi/config.js.map +1 -0
- package/dist/pulumi/require-server-replace-guard.d.ts +4 -0
- package/dist/pulumi/require-server-replace-guard.d.ts.map +1 -0
- package/dist/pulumi/require-server-replace-guard.js +120 -0
- package/dist/pulumi/require-server-replace-guard.js.map +1 -0
- package/dist/react/config.d.ts +4 -0
- package/dist/react/config.d.ts.map +1 -0
- package/dist/react/config.js +13 -0
- package/dist/react/config.js.map +1 -0
- package/dist/react/require-combobox-popover-modal.d.ts +10 -0
- package/dist/react/require-combobox-popover-modal.d.ts.map +1 -0
- package/dist/react/require-combobox-popover-modal.js +101 -0
- package/dist/react/require-combobox-popover-modal.js.map +1 -0
- package/dist/react-router/config.d.ts +3 -0
- package/dist/react-router/config.d.ts.map +1 -0
- package/dist/react-router/config.js +34 -0
- package/dist/react-router/config.js.map +1 -0
- package/dist/react-router/no-internal-anchor.d.ts +8 -0
- package/dist/react-router/no-internal-anchor.d.ts.map +1 -0
- package/dist/react-router/no-internal-anchor.js +14 -0
- package/dist/react-router/no-internal-anchor.js.map +1 -0
- package/dist/react-router/no-raw-route-path.d.ts +9 -0
- package/dist/react-router/no-raw-route-path.d.ts.map +1 -0
- package/dist/react-router/no-raw-route-path.js +17 -0
- package/dist/react-router/no-raw-route-path.js.map +1 -0
- package/dist/react-router/require-loader-data-type-argument.d.ts +10 -0
- package/dist/react-router/require-loader-data-type-argument.d.ts.map +1 -0
- package/dist/react-router/require-loader-data-type-argument.js +16 -0
- package/dist/react-router/require-loader-data-type-argument.js.map +1 -0
- package/dist/tailwind/class-name-check.d.ts +12 -0
- package/dist/tailwind/class-name-check.d.ts.map +1 -0
- package/dist/tailwind/class-name-check.js +16 -0
- package/dist/tailwind/class-name-check.js.map +1 -0
- package/dist/tailwind/config.d.ts +3 -0
- package/dist/tailwind/config.d.ts.map +1 -0
- package/dist/tailwind/config.js +18 -0
- package/dist/tailwind/config.js.map +1 -0
- package/dist/tailwind/no-arbitrary-z-index.d.ts +3 -0
- package/dist/tailwind/no-arbitrary-z-index.d.ts.map +1 -0
- package/dist/tailwind/no-arbitrary-z-index.js +7 -0
- package/dist/tailwind/no-arbitrary-z-index.js.map +1 -0
- package/dist/tailwind/no-h-screen.d.ts +3 -0
- package/dist/tailwind/no-h-screen.d.ts.map +1 -0
- package/dist/tailwind/no-h-screen.js +7 -0
- package/dist/tailwind/no-h-screen.js.map +1 -0
- package/dist/tailwind/no-will-change.d.ts +3 -0
- package/dist/tailwind/no-will-change.d.ts.map +1 -0
- package/dist/tailwind/no-will-change.js +7 -0
- package/dist/tailwind/no-will-change.js.map +1 -0
- package/dist/test-files/config.d.ts +3 -0
- package/dist/test-files/config.d.ts.map +1 -0
- package/dist/test-files/config.js +16 -0
- package/dist/test-files/config.js.map +1 -0
- package/dist/test-files/no-test-lifecycle-hooks.d.ts +3 -0
- package/dist/test-files/no-test-lifecycle-hooks.d.ts.map +1 -0
- package/dist/test-files/no-test-lifecycle-hooks.js +9 -0
- package/dist/test-files/no-test-lifecycle-hooks.js.map +1 -0
- package/dist/test-files/require-msw-error-on-unhandled-request.d.ts +10 -0
- package/dist/test-files/require-msw-error-on-unhandled-request.d.ts.map +1 -0
- package/dist/test-files/require-msw-error-on-unhandled-request.js +16 -0
- package/dist/test-files/require-msw-error-on-unhandled-request.js.map +1 -0
- package/dist/workspace/project-manifest.d.ts +14 -0
- package/dist/workspace/project-manifest.d.ts.map +1 -0
- package/dist/workspace/project-manifest.js +45 -0
- package/dist/workspace/project-manifest.js.map +1 -0
- package/dist/workspace/workspace-root.d.ts +12 -0
- package/dist/workspace/workspace-root.d.ts.map +1 -0
- package/dist/workspace/workspace-root.js +46 -0
- package/dist/workspace/workspace-root.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { identifierName, isAstNode, isType } from "../authoring/ast.js";
|
|
2
|
+
function isProcessEnvRead(node) {
|
|
3
|
+
if (!isType(node, 'MemberExpression')) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
const object = node['object'];
|
|
7
|
+
if (!isType(object, 'MemberExpression')) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
return (identifierName(object['object']) === 'process' &&
|
|
11
|
+
identifierName(object['property']) === 'env' &&
|
|
12
|
+
object['computed'] !== true);
|
|
13
|
+
}
|
|
14
|
+
function isTrivialEnvExpression(node) {
|
|
15
|
+
if (isProcessEnvRead(node)) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (isType(node, 'LogicalExpression') &&
|
|
19
|
+
(node['operator'] === '||' || node['operator'] === '??')) {
|
|
20
|
+
return isProcessEnvRead(node['left']) && isType(node['right'], 'Literal');
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
function bodyReturnsOnlyProcessEnv(body) {
|
|
25
|
+
if (isTrivialEnvExpression(body)) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (!isType(body, 'BlockStatement')) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const statements = body['body'];
|
|
32
|
+
if (!Array.isArray(statements) || statements.length !== 1) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const [statement] = statements;
|
|
36
|
+
return (isType(statement, 'ReturnStatement') &&
|
|
37
|
+
isTrivialEnvExpression(statement['argument']));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* An accessor that only returns `process.env.X` (or `process.env.X ?? 'literal'`)
|
|
41
|
+
* hides which variable a call site reads and invites validation to grow there
|
|
42
|
+
* instead of in the startup schema. Async and generator functions change the
|
|
43
|
+
* return type, so inlining them is not equivalent and they are left alone.
|
|
44
|
+
*/
|
|
45
|
+
const rule = {
|
|
46
|
+
meta: {
|
|
47
|
+
type: 'suggestion',
|
|
48
|
+
docs: {
|
|
49
|
+
description: 'Disallow a function whose only job is to return a single process.env read — read process.env inline at the use site',
|
|
50
|
+
},
|
|
51
|
+
messages: {
|
|
52
|
+
trivialWrapper: 'Do not wrap a single process.env read in a function. Read `process.env.X` inline at the use site (env validation/transform belongs in the startup schema, not an accessor helper).',
|
|
53
|
+
},
|
|
54
|
+
schema: [],
|
|
55
|
+
},
|
|
56
|
+
create(context) {
|
|
57
|
+
function check(node) {
|
|
58
|
+
if (!isAstNode(node)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (node['async'] === true || node['generator'] === true) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (bodyReturnsOnlyProcessEnv(node['body'])) {
|
|
65
|
+
context.report({ node, messageId: 'trivialWrapper' });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
FunctionDeclaration: check,
|
|
70
|
+
FunctionExpression: check,
|
|
71
|
+
ArrowFunctionExpression: check,
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
export default rule;
|
|
76
|
+
//# sourceMappingURL=no-single-env-read-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-single-env-read-wrapper.js","sourceRoot":"","sources":["../../src/environment/no-single-env-read-wrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Rule } from 'eslint';
|
|
2
|
+
/**
|
|
3
|
+
* The startup file validates the environment once, at boot, with
|
|
4
|
+
* `const env = z.object({...})`. A `process.env` key read without being
|
|
5
|
+
* declared there skips that check: a missing or malformed value surfaces late,
|
|
6
|
+
* at the read, instead of failing the boot. The schema is parsed with the
|
|
7
|
+
* TypeScript compiler API, so the rule needs no type information.
|
|
8
|
+
*/
|
|
9
|
+
declare const rule: Rule.RuleModule;
|
|
10
|
+
export default rule;
|
|
11
|
+
//# sourceMappingURL=no-undeclared-process-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-undeclared-process-env.d.ts","sourceRoot":"","sources":["../../src/environment/no-undeclared-process-env.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAqLnC;;;;;;GAMG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA6EhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import * as ts from 'typescript';
|
|
4
|
+
import { identifierName, isAstNode, isRecord, isType, } from "../authoring/ast.js";
|
|
5
|
+
import { projectOf } from "../workspace/project-manifest.js";
|
|
6
|
+
import { relativeToWorkspace, workspaceRootOf, } from "../workspace/workspace-root.js";
|
|
7
|
+
// Keyed by absolute path. A changed mtime re-parses, so a long-lived ESLint
|
|
8
|
+
// process (an editor) picks up an edit to the schema.
|
|
9
|
+
const declaredByStartupPath = new Map();
|
|
10
|
+
function memberKey(node) {
|
|
11
|
+
const property = node['property'];
|
|
12
|
+
if (node['computed'] !== true) {
|
|
13
|
+
return identifierName(property);
|
|
14
|
+
}
|
|
15
|
+
if (isType(property, 'Literal') && typeof property['value'] === 'string') {
|
|
16
|
+
return property['value'];
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function isProcessEnvMember(node) {
|
|
21
|
+
return (isType(node, 'MemberExpression') &&
|
|
22
|
+
memberKey(node) === 'env' &&
|
|
23
|
+
identifierName(node['object']) === 'process');
|
|
24
|
+
}
|
|
25
|
+
function startupFileOption(options) {
|
|
26
|
+
const [option] = options;
|
|
27
|
+
const startupFile = isRecord(option) ? option['startupFile'] : undefined;
|
|
28
|
+
// meta.defaultOptions supplies it and the schema keeps it a string.
|
|
29
|
+
if (typeof startupFile !== 'string') {
|
|
30
|
+
throw new TypeError('no-undeclared-process-env: the startupFile option must be a string.');
|
|
31
|
+
}
|
|
32
|
+
return startupFile;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A relative `startupFile` is read from the linted file's project, so the same
|
|
36
|
+
* schema is found whether ESLint runs from the project folder (`nx lint`) or
|
|
37
|
+
* from the workspace root (an editor). An absolute one is used as is.
|
|
38
|
+
*/
|
|
39
|
+
function resolveStartupPath(context, startupFile) {
|
|
40
|
+
const filename = resolve(context.cwd, context.physicalFilename);
|
|
41
|
+
const base = projectOf(filename)?.root ??
|
|
42
|
+
workspaceRootOf(dirname(filename)) ??
|
|
43
|
+
context.cwd;
|
|
44
|
+
return resolve(base, startupFile);
|
|
45
|
+
}
|
|
46
|
+
function staticPropertyName(name) {
|
|
47
|
+
if (ts.isIdentifier(name) ||
|
|
48
|
+
ts.isStringLiteral(name) ||
|
|
49
|
+
ts.isNumericLiteral(name)) {
|
|
50
|
+
return name.text;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
function zodObjectLiteral(node) {
|
|
55
|
+
if (ts.isCallExpression(node) &&
|
|
56
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
57
|
+
ts.isIdentifier(node.expression.expression) &&
|
|
58
|
+
node.expression.expression.text === 'z' &&
|
|
59
|
+
node.expression.name.text === 'object') {
|
|
60
|
+
const [schema] = node.arguments;
|
|
61
|
+
return schema && ts.isObjectLiteralExpression(schema) ? schema : undefined;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
function parseDeclaredEnvKeys(startupPath) {
|
|
66
|
+
const source = readFileSync(startupPath, 'utf8');
|
|
67
|
+
const sourceFile = ts.createSourceFile(startupPath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
68
|
+
const keys = new Set();
|
|
69
|
+
let foundEnvSchema = false;
|
|
70
|
+
function visit(node) {
|
|
71
|
+
if (ts.isVariableDeclaration(node) &&
|
|
72
|
+
ts.isIdentifier(node.name) &&
|
|
73
|
+
node.name.text === 'env' &&
|
|
74
|
+
node.initializer) {
|
|
75
|
+
const objectLiteral = zodObjectLiteral(node.initializer);
|
|
76
|
+
if (objectLiteral) {
|
|
77
|
+
foundEnvSchema = true;
|
|
78
|
+
for (const property of objectLiteral.properties) {
|
|
79
|
+
if (ts.isPropertyAssignment(property) ||
|
|
80
|
+
ts.isShorthandPropertyAssignment(property) ||
|
|
81
|
+
ts.isMethodDeclaration(property)) {
|
|
82
|
+
const key = staticPropertyName(property.name);
|
|
83
|
+
if (key) {
|
|
84
|
+
keys.add(key);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
ts.forEachChild(node, visit);
|
|
91
|
+
}
|
|
92
|
+
visit(sourceFile);
|
|
93
|
+
if (!foundEnvSchema) {
|
|
94
|
+
throw new Error(`Could not find "const env = z.object(...)" in ${startupPath}`);
|
|
95
|
+
}
|
|
96
|
+
return keys;
|
|
97
|
+
}
|
|
98
|
+
function declaredEnvOf(startupPath) {
|
|
99
|
+
try {
|
|
100
|
+
const { mtimeMs } = statSync(startupPath);
|
|
101
|
+
const cached = declaredByStartupPath.get(startupPath);
|
|
102
|
+
if (cached && cached.mtimeMs === mtimeMs) {
|
|
103
|
+
return cached;
|
|
104
|
+
}
|
|
105
|
+
const entry = {
|
|
106
|
+
mtimeMs,
|
|
107
|
+
keys: parseDeclaredEnvKeys(startupPath),
|
|
108
|
+
};
|
|
109
|
+
declaredByStartupPath.set(startupPath, entry);
|
|
110
|
+
return entry;
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const entry = {
|
|
114
|
+
mtimeMs: -1,
|
|
115
|
+
keys: new Set(),
|
|
116
|
+
error: error instanceof Error ? error.message : String(error),
|
|
117
|
+
};
|
|
118
|
+
declaredByStartupPath.set(startupPath, entry);
|
|
119
|
+
return entry;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The startup file validates the environment once, at boot, with
|
|
124
|
+
* `const env = z.object({...})`. A `process.env` key read without being
|
|
125
|
+
* declared there skips that check: a missing or malformed value surfaces late,
|
|
126
|
+
* at the read, instead of failing the boot. The schema is parsed with the
|
|
127
|
+
* TypeScript compiler API, so the rule needs no type information.
|
|
128
|
+
*/
|
|
129
|
+
const rule = {
|
|
130
|
+
meta: {
|
|
131
|
+
type: 'problem',
|
|
132
|
+
docs: {
|
|
133
|
+
description: 'Require every process.env key to be declared in the startup env schema',
|
|
134
|
+
},
|
|
135
|
+
messages: {
|
|
136
|
+
startupUnavailable: 'Could not validate process.env usage because the startup env schema is unavailable: {{error}}',
|
|
137
|
+
undeclaredEnv: 'Declare {{key}} in {{startupFile}} before using process.env.{{key}}.',
|
|
138
|
+
},
|
|
139
|
+
schema: [
|
|
140
|
+
{
|
|
141
|
+
type: 'object',
|
|
142
|
+
additionalProperties: false,
|
|
143
|
+
properties: {
|
|
144
|
+
startupFile: {
|
|
145
|
+
type: 'string',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
defaultOptions: [{ startupFile: 'src/startup.ts' }],
|
|
151
|
+
},
|
|
152
|
+
create(context) {
|
|
153
|
+
const startupPath = resolveStartupPath(context, startupFileOption(context.options));
|
|
154
|
+
const declared = declaredEnvOf(startupPath);
|
|
155
|
+
let reportedStartupError = false;
|
|
156
|
+
return {
|
|
157
|
+
MemberExpression(node) {
|
|
158
|
+
if (!isType(node, 'MemberExpression') ||
|
|
159
|
+
!isProcessEnvMember(node['object'])) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const key = memberKey(node);
|
|
163
|
+
const property = node['property'];
|
|
164
|
+
if (!key || !isAstNode(property)) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (declared.error) {
|
|
168
|
+
if (reportedStartupError) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
reportedStartupError = true;
|
|
172
|
+
context.report({
|
|
173
|
+
node: property,
|
|
174
|
+
messageId: 'startupUnavailable',
|
|
175
|
+
data: { error: declared.error },
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (declared.keys.has(key)) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
context.report({
|
|
183
|
+
node: property,
|
|
184
|
+
messageId: 'undeclaredEnv',
|
|
185
|
+
data: {
|
|
186
|
+
key,
|
|
187
|
+
startupFile: relativeToWorkspace(startupPath),
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
export default rule;
|
|
195
|
+
//# sourceMappingURL=no-undeclared-process-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-undeclared-process-env.js","sourceRoot":"","sources":["../../src/environment/no-undeclared-process-env.ts"],"names":[],"mappings":"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"}
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const TYPESCRIPT: string[];
|
|
2
|
+
export declare const JAVASCRIPT: string[];
|
|
3
|
+
export declare const SOURCE: string[];
|
|
4
|
+
export declare const JSX: string[];
|
|
5
|
+
export declare const TESTS: string[];
|
|
6
|
+
/** Test-support scripts run top-level like tests: their state is arrange state. */
|
|
7
|
+
export declare const FIXTURES: string[];
|
|
8
|
+
/** A script's stdout is its interface. */
|
|
9
|
+
export declare const SCRIPTS: string[];
|
|
10
|
+
/** Config files run at build time on the developer's environment. */
|
|
11
|
+
export declare const CONFIG_FILES: string[];
|
|
12
|
+
export declare const PACKAGE_JSON: string[];
|
|
13
|
+
export declare const PROJECT_JSON: string[];
|
|
14
|
+
/** Flat config never reads .gitignore, so build output is ignored by name. */
|
|
15
|
+
export declare const BUILD_OUTPUT: string[];
|
|
16
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,UAAU,UAAkD,CAAC;AAC1E,eAAO,MAAM,UAAU,UAAkD,CAAC;AAC1E,eAAO,MAAM,MAAM,UAAiC,CAAC;AACrD,eAAO,MAAM,GAAG,UAA2B,CAAC;AAC5C,eAAO,MAAM,KAAK,UAAuD,CAAC;AAC1E,mFAAmF;AACnF,eAAO,MAAM,QAAQ,UAAsB,CAAC;AAC5C,0CAA0C;AAC1C,eAAO,MAAM,OAAO,UAAoB,CAAC;AACzC,qEAAqE;AACrE,eAAO,MAAM,YAAY,UAA0C,CAAC;AACpE,eAAO,MAAM,YAAY,UAAsB,CAAC;AAChD,eAAO,MAAM,YAAY,UAAsB,CAAC;AAChD,8EAA8E;AAC9E,eAAO,MAAM,YAAY,UAOxB,CAAC"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// File globs for the package's configs. Every glob starts with a `**` segment,
|
|
2
|
+
// so it means the same whichever folder the config is resolved from: a
|
|
3
|
+
// root-relative glob such as `apps/**` matches nothing once a project's own
|
|
4
|
+
// config re-exports the root config under `nx lint`.
|
|
5
|
+
export const TYPESCRIPT = ['**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts'];
|
|
6
|
+
export const JAVASCRIPT = ['**/*.js', '**/*.jsx', '**/*.cjs', '**/*.mjs'];
|
|
7
|
+
export const SOURCE = [...TYPESCRIPT, ...JAVASCRIPT];
|
|
8
|
+
export const JSX = ['**/*.tsx', '**/*.jsx'];
|
|
9
|
+
export const TESTS = ['**/*.{test,spec}.{ts,tsx,cts,mts,js,jsx,cjs,mjs}'];
|
|
10
|
+
/** Test-support scripts run top-level like tests: their state is arrange state. */
|
|
11
|
+
export const FIXTURES = ['**/*.fixture.ts'];
|
|
12
|
+
/** A script's stdout is its interface. */
|
|
13
|
+
export const SCRIPTS = ['**/scripts/**'];
|
|
14
|
+
/** Config files run at build time on the developer's environment. */
|
|
15
|
+
export const CONFIG_FILES = ['**/*.config.{js,cjs,mjs,ts,mts,cts}'];
|
|
16
|
+
export const PACKAGE_JSON = ['**/package.json'];
|
|
17
|
+
export const PROJECT_JSON = ['**/project.json'];
|
|
18
|
+
/** Flat config never reads .gitignore, so build output is ignored by name. */
|
|
19
|
+
export const BUILD_OUTPUT = [
|
|
20
|
+
'**/dist',
|
|
21
|
+
'**/out-tsc',
|
|
22
|
+
'**/build',
|
|
23
|
+
'**/.react-router',
|
|
24
|
+
'**/vite.config.*.timestamp*',
|
|
25
|
+
'**/vitest.config.*.timestamp*',
|
|
26
|
+
];
|
|
27
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,uEAAuE;AACvE,4EAA4E;AAC5E,qDAAqD;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC5C,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,kDAAkD,CAAC,CAAC;AAC1E,mFAAmF;AACnF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC5C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,eAAe,CAAC,CAAC;AACzC,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAChD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS;IACT,YAAY;IACZ,UAAU;IACV,kBAAkB;IAClB,6BAA6B;IAC7B,+BAA+B;CAChC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/hono/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AAMrD,eAAO,MAAM,IAAI,EAAE,OAYlB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { enable } from "../concept.js";
|
|
2
|
+
import { TESTS, TYPESCRIPT } from "../files.js";
|
|
3
|
+
import noUntypedEmptyJson from "./no-untyped-empty-json.js";
|
|
4
|
+
const rules = { 'no-untyped-empty-json': noUntypedEmptyJson };
|
|
5
|
+
export const hono = {
|
|
6
|
+
name: 'hono',
|
|
7
|
+
rules,
|
|
8
|
+
config: (plugins) => [
|
|
9
|
+
{
|
|
10
|
+
name: 'zukhruf/hono',
|
|
11
|
+
files: TYPESCRIPT,
|
|
12
|
+
ignores: TESTS,
|
|
13
|
+
plugins,
|
|
14
|
+
rules: enable(rules),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/hono/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAE5D,MAAM,KAAK,GAAG,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC;AAE9D,MAAM,CAAC,MAAM,IAAI,GAAY;IAC3B,IAAI,EAAE,MAAM;IACZ,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,KAAK;YACd,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A bare `c.json([])` widens the route's response to `any[]`, which a client
|
|
3
|
+
* generated from the routes can then not iterate. Matches the conventional
|
|
4
|
+
* Hono context name `c` only.
|
|
5
|
+
*/
|
|
6
|
+
declare const _default: import("eslint").Rule.RuleModule;
|
|
7
|
+
export default _default;
|
|
8
|
+
//# sourceMappingURL=no-untyped-empty-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-untyped-empty-json.d.ts","sourceRoot":"","sources":["../../src/hono/no-untyped-empty-json.ts"],"names":[],"mappings":"AAEA;;;;GAIG;;AACH,wBAQG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { selectorRule } from "../authoring/selector-rule.js";
|
|
2
|
+
/**
|
|
3
|
+
* A bare `c.json([])` widens the route's response to `any[]`, which a client
|
|
4
|
+
* generated from the routes can then not iterate. Matches the conventional
|
|
5
|
+
* Hono context name `c` only.
|
|
6
|
+
*/
|
|
7
|
+
export default selectorRule({
|
|
8
|
+
description: 'Require an empty array returned from a Hono route to state its element type',
|
|
9
|
+
selectors: [
|
|
10
|
+
"CallExpression[callee.object.name='c'][callee.property.name='json'] > ArrayExpression[elements.length=0]",
|
|
11
|
+
],
|
|
12
|
+
message: 'Empty c.json([]) widens the response type — write c.json([] satisfies Model[]) so the generated client stays typed.',
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=no-untyped-empty-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-untyped-empty-json.js","sourceRoot":"","sources":["../../src/hono/no-untyped-empty-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;;;GAIG;AACH,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,6EAA6E;IAC/E,SAAS,EAAE;QACT,0GAA0G;KAC3G;IACD,OAAO,EACL,qHAAqH;CACxH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-deepagents-agent.d.ts","sourceRoot":"","sources":["../../src/imports/no-deepagents-agent.ts"],"names":[],"mappings":";AAEA,wBAMG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { importBanRule } from "../authoring/import-ban.js";
|
|
2
|
+
export default importBanRule({
|
|
3
|
+
description: 'Disallow the legacy @deepagents/agent package; compose with @deepagents/context',
|
|
4
|
+
packages: ['@deepagents/agent'],
|
|
5
|
+
message: '@deepagents/agent is legacy. Build with @deepagents/context + the AI SDK directly.',
|
|
6
|
+
});
|
|
7
|
+
//# sourceMappingURL=no-deepagents-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-deepagents-agent.js","sourceRoot":"","sources":["../../src/imports/no-deepagents-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,eAAe,aAAa,CAAC;IAC3B,WAAW,EACT,iFAAiF;IACnF,QAAQ,EAAE,CAAC,mBAAmB,CAAC;IAC/B,OAAO,EACL,oFAAoF;CACvF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-playwright-test.d.ts","sourceRoot":"","sources":["../../src/imports/no-playwright-test.ts"],"names":[],"mappings":";AAEA,wBAIG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { importBanRule } from "../authoring/import-ban.js";
|
|
2
|
+
export default importBanRule({
|
|
3
|
+
description: 'Disallow the Playwright test runner; node:test is the runner',
|
|
4
|
+
packages: ['@playwright/test'],
|
|
5
|
+
message: 'Use node:test.',
|
|
6
|
+
});
|
|
7
|
+
//# sourceMappingURL=no-playwright-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-playwright-test.js","sourceRoot":"","sources":["../../src/imports/no-playwright-test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,eAAe,aAAa,CAAC;IAC3B,WAAW,EAAE,8DAA8D;IAC3E,QAAQ,EAAE,CAAC,kBAAkB,CAAC;IAC9B,OAAO,EAAE,gBAAgB;CAC1B,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-state-managers.d.ts","sourceRoot":"","sources":["../../src/imports/no-state-managers.ts"],"names":[],"mappings":";AAEA,wBAaG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { importBanRule } from "../authoring/import-ban.js";
|
|
2
|
+
export default importBanRule({
|
|
3
|
+
description: 'Disallow external state managers',
|
|
4
|
+
packages: [
|
|
5
|
+
'zustand',
|
|
6
|
+
'jotai',
|
|
7
|
+
'redux',
|
|
8
|
+
'@reduxjs/toolkit',
|
|
9
|
+
'react-redux',
|
|
10
|
+
'mobx',
|
|
11
|
+
'mobx-react',
|
|
12
|
+
],
|
|
13
|
+
message: 'No external state managers. Use TanStack Query (server state), React Context (shared UI state), or URL state (shareable state).',
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=no-state-managers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-state-managers.js","sourceRoot":"","sources":["../../src/imports/no-state-managers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,eAAe,aAAa,CAAC;IAC3B,WAAW,EAAE,kCAAkC;IAC/C,QAAQ,EAAE;QACR,SAAS;QACT,OAAO;QACP,OAAO;QACP,kBAAkB;QAClB,aAAa;QACb,MAAM;QACN,YAAY;KACb;IACD,OAAO,EACL,iIAAiI;CACpI,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,EACL,KAAK,YAAY,EACjB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACL,kBAAkB,EAElB,KAAK,GAGN,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Rule } from 'eslint';
|
|
2
|
+
/** Whether the linted file belongs to a project tagged `layer:island`. */
|
|
3
|
+
export declare function inIsland(context: Rule.RuleContext): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Library code: every island, plus the files `settings.island.libraries`
|
|
6
|
+
* names. Library code takes values as options and reports through what it
|
|
7
|
+
* returns or throws, so it never reads the environment or writes to console.
|
|
8
|
+
*/
|
|
9
|
+
export declare function inLibrary(context: Rule.RuleContext): boolean;
|
|
10
|
+
//# sourceMappingURL=island-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-scope.d.ts","sourceRoot":"","sources":["../../src/island/island-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAOnC,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,GAAG,OAAO,CAI3D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,GAAG,OAAO,CAa5D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isRecord, stringsAt } from "../authoring/ast.js";
|
|
2
|
+
import { matchesAnyGlob } from "../authoring/path-scope.js";
|
|
3
|
+
import { ISLAND_TAG } from "../nx-policy/island-constraint.js";
|
|
4
|
+
import { projectOf } from "../workspace/project-manifest.js";
|
|
5
|
+
/** Whether the linted file belongs to a project tagged `layer:island`. */
|
|
6
|
+
export function inIsland(context) {
|
|
7
|
+
return (projectOf(context.physicalFilename)?.tags.includes(ISLAND_TAG) ?? false);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Library code: every island, plus the files `settings.island.libraries`
|
|
11
|
+
* names. Library code takes values as options and reports through what it
|
|
12
|
+
* returns or throws, so it never reads the environment or writes to console.
|
|
13
|
+
*/
|
|
14
|
+
export function inLibrary(context) {
|
|
15
|
+
return (inIsland(context) ||
|
|
16
|
+
matchesAnyGlob(context.physicalFilename,
|
|
17
|
+
// settings.island.libraries: workspace-relative globs for library code
|
|
18
|
+
// outside islands.
|
|
19
|
+
stringsAt(isRecord(context.settings) ? context.settings['island'] : undefined, 'libraries')));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=island-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-scope.js","sourceRoot":"","sources":["../../src/island/island-scope.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D,0EAA0E;AAC1E,MAAM,UAAU,QAAQ,CAAC,OAAyB;IAChD,OAAO,CACL,SAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CACxE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,OAAyB;IACjD,OAAO,CACL,QAAQ,CAAC,OAAO,CAAC;QACjB,cAAc,CACZ,OAAO,CAAC,gBAAgB;QACxB,uEAAuE;QACvE,mBAAmB;QACnB,SAAS,CACP,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EACnE,WAAW,CACZ,CACF,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Rule } from 'eslint';
|
|
2
|
+
/**
|
|
3
|
+
* `console` output never reaches the host's log or its user; a library
|
|
4
|
+
* reports through the errors it throws and the values it returns. Resolved
|
|
5
|
+
* through scope, as core no-console does, so a local named `console` passes.
|
|
6
|
+
*/
|
|
7
|
+
declare const rule: Rule.RuleModule;
|
|
8
|
+
export default rule;
|
|
9
|
+
//# sourceMappingURL=no-console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-console.d.ts","sourceRoot":"","sources":["../../src/island/no-console.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAInC;;;;GAIG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAmChB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isRecord, isType } from "../authoring/ast.js";
|
|
2
|
+
/**
|
|
3
|
+
* `console` output never reaches the host's log or its user; a library
|
|
4
|
+
* reports through the errors it throws and the values it returns. Resolved
|
|
5
|
+
* through scope, as core no-console does, so a local named `console` passes.
|
|
6
|
+
*/
|
|
7
|
+
const rule = {
|
|
8
|
+
meta: {
|
|
9
|
+
type: 'problem',
|
|
10
|
+
docs: { description: 'Disallow writing to console in library code' },
|
|
11
|
+
schema: [],
|
|
12
|
+
messages: {
|
|
13
|
+
console: 'Library code must not write to console. Throw an error or return the value.',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
create(context) {
|
|
17
|
+
return {
|
|
18
|
+
'Program:exit'(program) {
|
|
19
|
+
const scope = context.sourceCode.getScope(program);
|
|
20
|
+
const declared = scope.set.get('console');
|
|
21
|
+
if (declared?.defs.length)
|
|
22
|
+
return;
|
|
23
|
+
const references = declared?.references ??
|
|
24
|
+
scope.through.filter(({ identifier }) => identifier.name === 'console');
|
|
25
|
+
for (const { identifier } of references) {
|
|
26
|
+
const parent = isRecord(identifier)
|
|
27
|
+
? identifier['parent']
|
|
28
|
+
: undefined;
|
|
29
|
+
if (isType(parent, 'MemberExpression') &&
|
|
30
|
+
parent['object'] === identifier) {
|
|
31
|
+
context.report({ node: parent, messageId: 'console' });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export default rule;
|
|
39
|
+
//# sourceMappingURL=no-console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-console.js","sourceRoot":"","sources":["../../src/island/no-console.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,EAAE,WAAW,EAAE,6CAA6C,EAAE;QACpE,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,OAAO,EACL,6EAA6E;SAChF;KACF;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,cAAc,CAAC,OAAO;gBACpB,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC1C,IAAI,QAAQ,EAAE,IAAI,CAAC,MAAM;oBAAE,OAAO;gBAClC,MAAM,UAAU,GACd,QAAQ,EAAE,UAAU;oBACpB,KAAK,CAAC,OAAO,CAAC,MAAM,CAClB,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,SAAS,CAClD,CAAC;gBACJ,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,UAAU,EAAE,CAAC;oBACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC;wBACjC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;wBACtB,CAAC,CAAC,SAAS,CAAC;oBACd,IACE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC;wBAClC,MAAM,CAAC,QAAQ,CAAC,KAAK,UAAU,EAC/B,CAAC;wBACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A port the host implements (a requester, a store) returns `unknown`, and
|
|
3
|
+
* each consumer narrows it where it reads it. A generic response forces every
|
|
4
|
+
* test stub to assert into T or to return `any`.
|
|
5
|
+
*/
|
|
6
|
+
declare const _default: import("eslint").Rule.RuleModule;
|
|
7
|
+
export default _default;
|
|
8
|
+
//# sourceMappingURL=no-generic-port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-generic-port.d.ts","sourceRoot":"","sources":["../../src/island/no-generic-port.ts"],"names":[],"mappings":"AAEA;;;;GAIG;;AACH,wBAQG"}
|