chore(repo): add conformance rule for our package.json files (#29078)
This commit is contained in:
parent
2eb524307b
commit
dfd5014792
40
nx.json
40
nx.json
@ -246,5 +246,43 @@
|
|||||||
"nxCloudUrl": "https://staging.nx.app",
|
"nxCloudUrl": "https://staging.nx.app",
|
||||||
"parallel": 1,
|
"parallel": 1,
|
||||||
"bust": 1,
|
"bust": 1,
|
||||||
"defaultBase": "master"
|
"defaultBase": "master",
|
||||||
|
"conformance": {
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"rule": "@nx/workspace-plugin/conformance-rules/project-package-json",
|
||||||
|
"projects": [
|
||||||
|
"!.",
|
||||||
|
"!create-nx-*",
|
||||||
|
"!cypress",
|
||||||
|
"!detox",
|
||||||
|
"!devkit",
|
||||||
|
"!esbuild",
|
||||||
|
"!eslint-plugin",
|
||||||
|
"!eslint",
|
||||||
|
"!expo",
|
||||||
|
"!express",
|
||||||
|
"!jest",
|
||||||
|
"!js",
|
||||||
|
"!module-federation",
|
||||||
|
"!nest",
|
||||||
|
"!next",
|
||||||
|
"!node",
|
||||||
|
"!nuxt",
|
||||||
|
"!packages/nx/**",
|
||||||
|
"!plugin",
|
||||||
|
"!react-native",
|
||||||
|
"!react",
|
||||||
|
"!rollup",
|
||||||
|
"!rsbuild",
|
||||||
|
"!rspack",
|
||||||
|
"!storybook",
|
||||||
|
"!vue",
|
||||||
|
"!web",
|
||||||
|
"!webpack",
|
||||||
|
"!workspace"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
package.json
24
package.json
@ -50,9 +50,9 @@
|
|||||||
"@eslint/eslintrc": "^2.1.1",
|
"@eslint/eslintrc": "^2.1.1",
|
||||||
"@eslint/js": "^8.48.0",
|
"@eslint/js": "^8.48.0",
|
||||||
"@floating-ui/react": "0.26.6",
|
"@floating-ui/react": "0.26.6",
|
||||||
"@jest/reporters": "^29.4.1",
|
"@jest/reporters": "29.7.0",
|
||||||
"@jest/test-result": "^29.4.1",
|
"@jest/test-result": "29.7.0",
|
||||||
"@jest/types": "^29.4.1",
|
"@jest/types": "29.6.3",
|
||||||
"@module-federation/enhanced": "0.7.6",
|
"@module-federation/enhanced": "0.7.6",
|
||||||
"@module-federation/sdk": "0.7.6",
|
"@module-federation/sdk": "0.7.6",
|
||||||
"@monodon/rust": "2.1.1",
|
"@monodon/rust": "2.1.1",
|
||||||
@ -79,9 +79,9 @@
|
|||||||
"@nx/js": "20.3.0-beta.0",
|
"@nx/js": "20.3.0-beta.0",
|
||||||
"@nx/next": "20.3.0-beta.0",
|
"@nx/next": "20.3.0-beta.0",
|
||||||
"@nx/playwright": "20.3.0-beta.0",
|
"@nx/playwright": "20.3.0-beta.0",
|
||||||
"@nx/powerpack-conformance": "1.1.0-beta.9",
|
"@nx/powerpack-conformance": "1.1.1-alpha.1",
|
||||||
"@nx/powerpack-enterprise-cloud": "1.1.0-beta.9",
|
"@nx/powerpack-enterprise-cloud": "1.1.1-alpha.1",
|
||||||
"@nx/powerpack-license": "1.1.0-beta.9",
|
"@nx/powerpack-license": "1.1.1-alpha.1",
|
||||||
"@nx/react": "20.3.0-beta.0",
|
"@nx/react": "20.3.0-beta.0",
|
||||||
"@nx/rsbuild": "20.3.0-beta.0",
|
"@nx/rsbuild": "20.3.0-beta.0",
|
||||||
"@nx/rspack": "20.3.0-beta.0",
|
"@nx/rspack": "20.3.0-beta.0",
|
||||||
@ -219,13 +219,13 @@
|
|||||||
"jasmine-core": "~2.99.1",
|
"jasmine-core": "~2.99.1",
|
||||||
"jasmine-spec-reporter": "~4.2.1",
|
"jasmine-spec-reporter": "~4.2.1",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-config": "^29.4.1",
|
"jest-config": "29.7.0",
|
||||||
"jest-diff": "^29.4.1",
|
"jest-diff": "29.7.0",
|
||||||
"jest-environment-jsdom": "29.7.0",
|
"jest-environment-jsdom": "29.7.0",
|
||||||
"jest-environment-node": "^29.4.1",
|
"jest-environment-node": "29.7.0",
|
||||||
"jest-resolve": "^29.4.1",
|
"jest-resolve": "29.7.0",
|
||||||
"jest-runtime": "^29.4.1",
|
"jest-runtime": "29.7.0",
|
||||||
"jest-util": "^29.4.1",
|
"jest-util": "29.7.0",
|
||||||
"js-tokens": "^4.0.0",
|
"js-tokens": "^4.0.0",
|
||||||
"jsonc-eslint-parser": "^2.1.0",
|
"jsonc-eslint-parser": "^2.1.0",
|
||||||
"jsonc-parser": "3.2.0",
|
"jsonc-parser": "3.2.0",
|
||||||
|
|||||||
@ -60,5 +60,8 @@
|
|||||||
},
|
},
|
||||||
"nx-migrations": {
|
"nx-migrations": {
|
||||||
"migrations": "./migrations.json"
|
"migrations": "./migrations.json"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
643
pnpm-lock.yaml
generated
643
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -63,7 +63,10 @@ module.exports = function (path, options) {
|
|||||||
}
|
}
|
||||||
// Try to use the defaultResolver
|
// Try to use the defaultResolver
|
||||||
try {
|
try {
|
||||||
if (path.startsWith('@nx/')) throw new Error('custom resolution');
|
// powerpack packages are installed via npm and resolved like any other packages
|
||||||
|
if (path.startsWith('@nx/') && !path.startsWith('@nx/powerpack-')) {
|
||||||
|
throw new Error('custom resolution');
|
||||||
|
}
|
||||||
if (path.startsWith('nx/')) throw new Error('custom resolution');
|
if (path.startsWith('nx/')) throw new Error('custom resolution');
|
||||||
|
|
||||||
if (path.indexOf('@nx/workspace') > -1) {
|
if (path.indexOf('@nx/workspace') > -1) {
|
||||||
|
|||||||
@ -0,0 +1,289 @@
|
|||||||
|
const mockExistsSync = jest.fn();
|
||||||
|
jest.mock('node:fs', () => {
|
||||||
|
return {
|
||||||
|
...jest.requireActual('node:fs'),
|
||||||
|
existsSync: mockExistsSync,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
import { validateProjectPackageJson } from './index';
|
||||||
|
|
||||||
|
const VALID_PACKAGE_JSON_BASE = {
|
||||||
|
name: '@nx/test-project',
|
||||||
|
publishConfig: {
|
||||||
|
access: 'public',
|
||||||
|
},
|
||||||
|
exports: {
|
||||||
|
'./package.json': './package.json',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('project-package-json', () => {
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Unit test the core implementation details of validating the project package.json
|
||||||
|
describe('validateProjectPackageJson()', () => {
|
||||||
|
it('should return no violations for a valid project package.json', () => {
|
||||||
|
const packageJson = {
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
};
|
||||||
|
const sourceProject = 'test-project';
|
||||||
|
const sourceProjectRoot = '/path/to/test-project';
|
||||||
|
const violations = validateProjectPackageJson(
|
||||||
|
packageJson,
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
);
|
||||||
|
expect(violations).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a violation if the name is not a string', () => {
|
||||||
|
const packageJson = {
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
};
|
||||||
|
delete packageJson.name;
|
||||||
|
|
||||||
|
const sourceProject = 'test-project';
|
||||||
|
const sourceProjectRoot = '/path/to/test-project';
|
||||||
|
const violations = validateProjectPackageJson(
|
||||||
|
packageJson,
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
);
|
||||||
|
expect(violations).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "/path/to/test-project/package.json",
|
||||||
|
"message": "The project package.json should have a "name" field",
|
||||||
|
"sourceProject": "test-project",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a violation if the name is not scoped an org that is not @nx', () => {
|
||||||
|
const sourceProject = 'test-project';
|
||||||
|
const sourceProjectRoot = '/path/to/test-project';
|
||||||
|
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
// Should be fine, as not scoped
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
name: 'test-project',
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toEqual([]);
|
||||||
|
|
||||||
|
// Should return a violation, as scoped to an org that is not @nx
|
||||||
|
const packageJsonWithScope = {
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
name: '@nx-labs/test-project',
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
packageJsonWithScope,
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "/path/to/test-project/package.json",
|
||||||
|
"message": "The package name should be scoped to the @nx org",
|
||||||
|
"sourceProject": "test-project",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a violation if a public package does not have publishConfig.access set to public', () => {
|
||||||
|
const sourceProject = 'some-project-name';
|
||||||
|
const sourceProjectRoot = '/path/to/some-project-name';
|
||||||
|
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
// Should be fine, as private
|
||||||
|
{
|
||||||
|
private: true,
|
||||||
|
name: 'test-project',
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toEqual([]);
|
||||||
|
|
||||||
|
// Should return a violation, as not private
|
||||||
|
const packageJsonWithoutPublicAccess = {
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
};
|
||||||
|
delete packageJsonWithoutPublicAccess.publishConfig;
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
packageJsonWithoutPublicAccess,
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "/path/to/some-project-name/package.json",
|
||||||
|
"message": "Public packages should have "publishConfig": { "access": "public" } set in their package.json",
|
||||||
|
"sourceProject": "some-project-name",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a violation if the project has an executors.json but does not reference it in the package.json', () => {
|
||||||
|
const sourceProject = 'some-project-name';
|
||||||
|
const sourceProjectRoot = '/path/to/some-project-name';
|
||||||
|
|
||||||
|
// The project does not have an executors.json, so no violation
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toEqual([]);
|
||||||
|
|
||||||
|
// The project has an executors.json
|
||||||
|
mockExistsSync.mockImplementation((path) => {
|
||||||
|
if (path.endsWith('executors.json')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// The project references the executors.json in the package.json, so no violation
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
executors: './executors.json',
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toEqual([]);
|
||||||
|
|
||||||
|
// The project does not reference the executors.json in the package.json, so a violation is returned
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "/path/to/some-project-name/package.json",
|
||||||
|
"message": "The project has an executors.json, but does not reference "./executors.json" in the "executors" field of its package.json",
|
||||||
|
"sourceProject": "some-project-name",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a violation if the project has an generators.json but does not reference it in the package.json', () => {
|
||||||
|
const sourceProject = 'some-project-name';
|
||||||
|
const sourceProjectRoot = '/path/to/some-project-name';
|
||||||
|
|
||||||
|
// The project does not have an generators.json, so no violation
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toEqual([]);
|
||||||
|
|
||||||
|
// The project has an generators.json
|
||||||
|
mockExistsSync.mockImplementation((path) => {
|
||||||
|
if (path.endsWith('generators.json')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// The project references the generators.json in the package.json, so no violation
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
generators: './generators.json',
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toEqual([]);
|
||||||
|
|
||||||
|
// The project does not reference the generators.json in the package.json, so a violation is returned
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "/path/to/some-project-name/package.json",
|
||||||
|
"message": "The project has an generators.json, but does not reference "./generators.json" in the "generators" field of its package.json",
|
||||||
|
"sourceProject": "some-project-name",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a violation if the project does not specify an exports object in the package.json', () => {
|
||||||
|
const sourceProject = 'test-project';
|
||||||
|
const sourceProjectRoot = '/path/to/test-project';
|
||||||
|
|
||||||
|
expect(
|
||||||
|
validateProjectPackageJson(
|
||||||
|
{
|
||||||
|
...VALID_PACKAGE_JSON_BASE,
|
||||||
|
exports: undefined,
|
||||||
|
},
|
||||||
|
sourceProject,
|
||||||
|
sourceProjectRoot,
|
||||||
|
`${sourceProjectRoot}/package.json`
|
||||||
|
)
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "/path/to/test-project/package.json",
|
||||||
|
"message": "The project package.json should have an "exports" object specified",
|
||||||
|
"sourceProject": "test-project",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
import { readJsonFile, workspaceRoot } from '@nx/devkit';
|
||||||
|
import {
|
||||||
|
createConformanceRule,
|
||||||
|
type ProjectFilesViolation,
|
||||||
|
} from '@nx/powerpack-conformance';
|
||||||
|
import { existsSync } from 'node:fs';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
|
||||||
|
export default createConformanceRule<object>({
|
||||||
|
name: 'project-package-json',
|
||||||
|
category: 'consistency',
|
||||||
|
description:
|
||||||
|
'Ensures consistency across our project package.json files within the Nx repo',
|
||||||
|
reporter: 'project-files-reporter',
|
||||||
|
implementation: async ({ projectGraph }) => {
|
||||||
|
const violations: ProjectFilesViolation[] = [];
|
||||||
|
|
||||||
|
for (const project of Object.values(projectGraph.nodes)) {
|
||||||
|
const projectPackageJsonPath = join(
|
||||||
|
workspaceRoot,
|
||||||
|
project.data.root,
|
||||||
|
'package.json'
|
||||||
|
);
|
||||||
|
if (existsSync(projectPackageJsonPath)) {
|
||||||
|
const projectPackageJson = readJsonFile(projectPackageJsonPath);
|
||||||
|
violations.push(
|
||||||
|
...validateProjectPackageJson(
|
||||||
|
projectPackageJson,
|
||||||
|
project.name,
|
||||||
|
project.data.root,
|
||||||
|
projectPackageJsonPath
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
severity: 'medium',
|
||||||
|
details: {
|
||||||
|
violations,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function validateProjectPackageJson(
|
||||||
|
projectPackageJson: Record<string, unknown>,
|
||||||
|
sourceProject: string,
|
||||||
|
sourceProjectRoot: string,
|
||||||
|
projectPackageJsonPath: string
|
||||||
|
): ProjectFilesViolation[] {
|
||||||
|
const violations: ProjectFilesViolation[] = [];
|
||||||
|
|
||||||
|
// Private packages are exempt from this rule
|
||||||
|
if (projectPackageJson.private === true) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof projectPackageJson.name !== 'string') {
|
||||||
|
violations.push({
|
||||||
|
message: 'The project package.json should have a "name" field',
|
||||||
|
sourceProject,
|
||||||
|
file: projectPackageJsonPath,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Ensure that if a scope is used, it is only the @nx scope
|
||||||
|
if (
|
||||||
|
projectPackageJson.name.startsWith('@') &&
|
||||||
|
!projectPackageJson.name.startsWith('@nx/')
|
||||||
|
) {
|
||||||
|
violations.push({
|
||||||
|
message: 'The package name should be scoped to the @nx org',
|
||||||
|
sourceProject,
|
||||||
|
file: projectPackageJsonPath,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish config
|
||||||
|
if ((projectPackageJson.publishConfig as any)?.access !== 'public') {
|
||||||
|
violations.push({
|
||||||
|
message:
|
||||||
|
'Public packages should have "publishConfig": { "access": "public" } set in their package.json',
|
||||||
|
sourceProject,
|
||||||
|
file: projectPackageJsonPath,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nx config properties
|
||||||
|
if (existsSync(join(sourceProjectRoot, 'executors.json'))) {
|
||||||
|
if (projectPackageJson.executors !== './executors.json') {
|
||||||
|
violations.push({
|
||||||
|
message:
|
||||||
|
'The project has an executors.json, but does not reference "./executors.json" in the "executors" field of its package.json',
|
||||||
|
sourceProject,
|
||||||
|
file: projectPackageJsonPath,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (existsSync(join(sourceProjectRoot, 'generators.json'))) {
|
||||||
|
if (projectPackageJson.generators !== './generators.json') {
|
||||||
|
violations.push({
|
||||||
|
message:
|
||||||
|
'The project has an generators.json, but does not reference "./generators.json" in the "generators" field of its package.json',
|
||||||
|
sourceProject,
|
||||||
|
file: projectPackageJsonPath,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasExportsEntries =
|
||||||
|
typeof projectPackageJson.exports === 'object' &&
|
||||||
|
Object.keys(projectPackageJson.exports ?? {}).length > 0;
|
||||||
|
|
||||||
|
if (!hasExportsEntries) {
|
||||||
|
violations.push({
|
||||||
|
message:
|
||||||
|
'The project package.json should have an "exports" object specified',
|
||||||
|
sourceProject,
|
||||||
|
file: projectPackageJsonPath,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return violations;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
@ -152,6 +152,9 @@
|
|||||||
"@nx/webpack/*": ["packages/webpack/*"],
|
"@nx/webpack/*": ["packages/webpack/*"],
|
||||||
"@nx/workspace": ["packages/workspace"],
|
"@nx/workspace": ["packages/workspace"],
|
||||||
"@nx/workspace-plugin": ["tools/workspace-plugin/src/index.ts"],
|
"@nx/workspace-plugin": ["tools/workspace-plugin/src/index.ts"],
|
||||||
|
"@nx/workspace-plugin/conformance-rules/*": [
|
||||||
|
"tools/workspace-plugin/src/conformance-rules/*"
|
||||||
|
],
|
||||||
"@nx/workspace/*": ["packages/workspace/*"],
|
"@nx/workspace/*": ["packages/workspace/*"],
|
||||||
"create-nx-workspace": ["packages/create-nx-workspace/index.ts"],
|
"create-nx-workspace": ["packages/create-nx-workspace/index.ts"],
|
||||||
"create-nx-workspace/*": ["packages/create-nx-workspace/*"],
|
"create-nx-workspace/*": ["packages/create-nx-workspace/*"],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user