@clipboard-health/nx-plugin 0.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/.eslintrc.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "extends": ["../../.eslintrc.json"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "overrides": [
5
+ {
6
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
+ "rules": {}
8
+ },
9
+ {
10
+ "files": ["*.ts", "*.tsx"],
11
+ "rules": {}
12
+ },
13
+ {
14
+ "files": ["*.js", "*.jsx"],
15
+ "rules": {}
16
+ },
17
+ {
18
+ "files": ["*.json"],
19
+ "parser": "jsonc-eslint-parser",
20
+ "rules": {
21
+ "@nx/dependency-checks": "error"
22
+ }
23
+ },
24
+ {
25
+ "files": ["./package.json", "./generators.json"],
26
+ "parser": "jsonc-eslint-parser",
27
+ "rules": {
28
+ "@nx/nx-plugin-checks": "error"
29
+ }
30
+ }
31
+ ]
32
+ }
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # @clipboard-health/nx-plugin
2
+
3
+ Clipboard Health's Nx plugin contains generators to manage libraries within an Nx workspace.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Table of Contents](#table-of-contents)
8
+ - [Install](#install)
9
+ - [Usage](#usage)
10
+ - [Adding new libraries](#adding-new-libraries)
11
+ - [Porting existing libraries](#porting-existing-libraries)
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install @clipboard-health/nx-plugin
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Adding new libraries
22
+
23
+ Libraries version and publish separately. We use [Nx Local Generators](https://nx.dev/recipes/generators/local-generators) to generate library stubs that successfully build, lint, and test. The `--publishable` flag sets up semantic versioning from commit messages, GitHub Release creation, and NPM publishing on merges to `main` (but only if the code within your library package changed, thanks to Nx's dependency graph).
24
+
25
+ ```bash
26
+ # Optionally, include the --publishable flag to publish to NPM.
27
+ npx nx generate @clipboard-health/nx-plugin:node-lib [PROJECT_NAME]
28
+
29
+ # Change your mind? Remove it just as easily...
30
+ npx nx generate @nx/workspace:remove --projectName [PROJECT_NAME]
31
+
32
+ # ...or rename it. Note: after running this command, perform a find/replace for remaining references
33
+ # to the old name.
34
+ npx nx generate @nx/workspace:move --projectName [PROJECT_NAME] --destination [NEW_PROJECT_NAME]
35
+ ```
36
+
37
+ ### Porting existing libraries
38
+
39
+ Follow [Adding new libraries](#adding-new-libraries) to generate a new package and copy the code from the existing library into it.
40
+
41
+ To keep the same project name while avoiding publishing version conflicts, create a `git tag` from the last commit on `main` with the project name and version:
42
+
43
+ ```bash
44
+ git checkout main
45
+
46
+ # Where [VERSION] is the current version of the project
47
+ git tag --annotate [PROJECT_NAME]-[VERSION] --message "Port from [OLD_LOCATION]"
48
+
49
+ git push origin [PROJECT_NAME]-[VERSION]
50
+ ```
@@ -0,0 +1,9 @@
1
+ {
2
+ "generators": {
3
+ "node-lib": {
4
+ "factory": "./src/generators/node-lib/generator",
5
+ "schema": "./src/generators/node-lib/schema.json",
6
+ "description": "Create a Node.js library."
7
+ }
8
+ }
9
+ }
package/jest.config.ts ADDED
@@ -0,0 +1,20 @@
1
+ /* eslint-disable */
2
+ export default {
3
+ coverageDirectory: "../../coverage/packages/nx-plugin",
4
+ coveragePathIgnorePatterns: [],
5
+ coverageThreshold: {
6
+ global: {
7
+ branches: 80,
8
+ functions: 100,
9
+ lines: 95,
10
+ statements: 95,
11
+ },
12
+ },
13
+ displayName: "nx-plugin",
14
+ moduleFileExtensions: ["ts", "js"],
15
+ preset: "../../jest.preset.js",
16
+ testEnvironment: "node",
17
+ transform: {
18
+ "^.+\\.[tj]s$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.spec.json" }],
19
+ },
20
+ };
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@clipboard-health/nx-plugin",
3
+ "description": "Clipboard Health's Nx plugin contains generators to manage applications within an Nx workspace.",
4
+ "version": "0.0.0",
5
+ "bugs": "https://github.com/clipboardhealth/core-utils/issues",
6
+ "dependencies": {
7
+ "@nx/devkit": "19.5.6",
8
+ "@nx/js": "19.5.6",
9
+ "tslib": "2.6.3"
10
+ },
11
+ "generators": "./generators.json",
12
+ "keywords": [
13
+ "Generator",
14
+ "Library",
15
+ "Node",
16
+ "Nx",
17
+ "Plugin",
18
+ "TypeScript"
19
+ ],
20
+ "license": "MIT",
21
+ "main": "./src/index.js",
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/clipboardhealth/core-utils.git",
28
+ "directory": "packages/nx-plugin"
29
+ },
30
+ "type": "commonjs",
31
+ "typings": "./src/index.d.ts"
32
+ }
package/project.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
3
+ "name": "nx-plugin",
4
+ "projectType": "library",
5
+ "sourceRoot": "packages/nx-plugin/src",
6
+ "tags": [],
7
+ "targets": {
8
+ "build": {
9
+ "executor": "@nx/js:tsc",
10
+ "options": {
11
+ "assets": [
12
+ "packages/nx-plugin/*.md",
13
+ {
14
+ "input": "./packages/nx-plugin/src",
15
+ "glob": "**/!(*.ts)",
16
+ "output": "./src"
17
+ },
18
+ {
19
+ "input": "./packages/nx-plugin/src",
20
+ "glob": "**/*.d.ts",
21
+ "output": "./src"
22
+ },
23
+ {
24
+ "input": "./packages/nx-plugin",
25
+ "glob": "generators.json",
26
+ "output": "."
27
+ }
28
+ ],
29
+ "main": "packages/nx-plugin/src/index.ts",
30
+ "outputPath": "dist/packages/nx-plugin",
31
+ "tsConfig": "packages/nx-plugin/tsconfig.lib.json"
32
+ },
33
+ "outputs": ["{options.outputPath}"]
34
+ },
35
+ "lint": {
36
+ "executor": "@nx/eslint:lint",
37
+ "options": {
38
+ "maxWarnings": 0
39
+ }
40
+ },
41
+ "test": {
42
+ "executor": "@nx/jest:jest",
43
+ "options": {
44
+ "jestConfig": "packages/nx-plugin/jest.config.ts",
45
+ "passWithNoTests": false
46
+ },
47
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"]
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": ["<%= offsetFromRoot %>.eslintrc.json"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "parserOptions": {
5
+ "project": "tsconfig.lint.json",
6
+ "tsconfigRootDir": "packages/<%= projectName %>"
7
+ }
8
+ }
@@ -0,0 +1,21 @@
1
+ # <%= importPath %>
2
+
3
+ TODO
4
+
5
+ ## Table of Contents
6
+
7
+ - [Install](#install)
8
+ - [Usage](#usage)
9
+ - [Local development commands](#local-development-commands)
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install <%= importPath %>
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ## Local development commands
20
+
21
+ See [`package.json`](./package.json) `scripts` for a list of commands.
@@ -0,0 +1,19 @@
1
+ export default {
2
+ coverageDirectory: "../../coverage/packages/<%= projectName %>",
3
+ coveragePathIgnorePatterns: [],
4
+ coverageThreshold: {
5
+ global: {
6
+ branches: 100,
7
+ functions: 100,
8
+ lines: 100,
9
+ statements: 100,
10
+ },
11
+ },
12
+ displayName: "<%= projectName %>",
13
+ moduleFileExtensions: ["ts", "js"],
14
+ preset: "<%= offsetFromRoot %>jest.preset.js",
15
+ testEnvironment: "node",
16
+ transform: {
17
+ "^.+\\.[tj]s$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.spec.json" }],
18
+ },
19
+ };
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "<%= importPath %>",
3
+ "version": "0.0.1",
4
+ "dependencies": {
5
+ "tslib": "2.6.3"
6
+ },
7
+ "main": "./src/index.js",
8
+ "type": "commonjs",
9
+ "typings": "./src/index.d.ts"
10
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
3
+ "name": "<%= projectName %>",
4
+ "projectType": "library",
5
+ "sourceRoot": "packages/<%= projectName %>/src",<% if (publishable) { %>
6
+ "release": {
7
+ "version": {
8
+ "generatorOptions": {
9
+ "packageRoot": "dist/{projectRoot}",
10
+ "currentVersionResolver": "git-tag"
11
+ }
12
+ }
13
+ },<% } %>
14
+ "tags": [],
15
+ "targets": {
16
+ "build": {
17
+ "executor": "@nx/js:tsc",
18
+ "options": {
19
+ "assets": ["packages/<%= projectName %>/*.md"],
20
+ "main": "packages/<%= projectName %>/src/index.js",
21
+ "outputPath": "dist/packages/<%= projectName %>",
22
+ "tsConfig": "packages/<%= projectName %>/tsconfig.lib.json"
23
+ },
24
+ "outputs": ["{options.outputPath}"]
25
+ },
26
+ "lint": {
27
+ "executor": "@nx/eslint:lint",
28
+ "options": {
29
+ "lintFilePatterns": ["packages/<%= projectName %>/**/*.[jt]s"],
30
+ "maxWarnings": 0
31
+ },
32
+ "outputs": ["{options.outputFile}"]
33
+ },<% if (publishable) { %>
34
+ "nx-release-publish": {
35
+ "options": {
36
+ "packageRoot": "dist/{projectRoot}"
37
+ }
38
+ },<% } %>
39
+ "test": {
40
+ "executor": "@nx/jest:jest",
41
+ "options": {
42
+ "jestConfig": "packages/<%= projectName %>/jest.config.ts"
43
+ }
44
+ }
45
+ }
46
+ }
@@ -0,0 +1 @@
1
+ export * from "./lib/rename-me";
@@ -0,0 +1,7 @@
1
+ import { deleteMe } from "./rename-me";
2
+
3
+ describe("deleteMe", () => {
4
+ it("works", () => {
5
+ expect(deleteMe()).toBe("hello");
6
+ });
7
+ });
@@ -0,0 +1,3 @@
1
+ export function deleteMe(): string {
2
+ return "hello";
3
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "extends": "<%= offsetFromRoot %>tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc"
5
+ },
6
+ "files": [],
7
+ "include": [],
8
+ "references": [
9
+ {
10
+ "path": "./tsconfig.lib.json"
11
+ },
12
+ {
13
+ "path": "./tsconfig.lint.json"
14
+ },
15
+ {
16
+ "path": "./tsconfig.spec.json"
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "types": ["node"]
6
+ },
7
+ "include": ["src/**/*.ts"],
8
+ "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
9
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["jest", "node"]
5
+ },
6
+ "include": ["."]
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["jest", "node"]
5
+ },
6
+ "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"]
7
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["../../typedoc.base.json"],
3
+ "entryPoints": ["src/index.ts"]
4
+ }
@@ -0,0 +1,19 @@
1
+ import { readProjectConfiguration, type Tree } from "@nx/devkit";
2
+ import { createTreeWithEmptyWorkspace } from "@nx/devkit/testing";
3
+
4
+ import generator from "./generator";
5
+
6
+ describe("generator", () => {
7
+ let appTree: Tree;
8
+
9
+ beforeEach(() => {
10
+ appTree = createTreeWithEmptyWorkspace({ layout: "apps-libs" });
11
+ });
12
+
13
+ it("runs successfully", async () => {
14
+ const name = "test";
15
+ await generator(appTree, { name });
16
+ const config = readProjectConfiguration(appTree, name);
17
+ expect(config).toBeDefined();
18
+ });
19
+ });
@@ -0,0 +1,85 @@
1
+ import { join } from "node:path";
2
+
3
+ import {
4
+ formatFiles,
5
+ generateFiles,
6
+ getWorkspaceLayout,
7
+ joinPathFragments,
8
+ names,
9
+ offsetFromRoot,
10
+ type Tree,
11
+ updateJson,
12
+ } from "@nx/devkit";
13
+ import { getImportPath } from "@nx/js/src/utils/get-import-path";
14
+
15
+ import type { NxPluginGeneratorSchema } from "./schema";
16
+
17
+ const ROOT_TS_CONFIG = "tsconfig.base.json";
18
+
19
+ type NormalizedSchema = NxPluginGeneratorSchema & {
20
+ importPath: string;
21
+ projectName: string;
22
+ projectRoot: string;
23
+ projectDirectory: string;
24
+ };
25
+
26
+ function normalizeOptions(tree: Tree, options: NxPluginGeneratorSchema): NormalizedSchema {
27
+ const name = names(options.name).fileName;
28
+ const projectDirectory = name;
29
+ return {
30
+ ...options,
31
+ publishable: options.publishable ?? false,
32
+ importPath: getImportPath(tree, projectDirectory),
33
+ projectName: name.replaceAll("/", "-"),
34
+ projectRoot: `${getWorkspaceLayout(tree).libsDir}/${name}`,
35
+ projectDirectory,
36
+ };
37
+ }
38
+
39
+ function getRelativePathToRootTsConfig(targetPath: string): string {
40
+ return `${offsetFromRoot(targetPath)}${ROOT_TS_CONFIG}`;
41
+ }
42
+
43
+ function addFiles(tree: Tree, options: NormalizedSchema) {
44
+ generateFiles(tree, join(__dirname, "files"), options.projectRoot, {
45
+ ...options,
46
+ ...names(options.name),
47
+ offsetFromRoot: offsetFromRoot(options.projectRoot),
48
+ rootTsConfigPath: getRelativePathToRootTsConfig(options.projectRoot),
49
+ template: "",
50
+ });
51
+ }
52
+
53
+ function updateRootTsConfig(
54
+ host: Tree,
55
+ options: {
56
+ name: string;
57
+ importPath: string;
58
+ projectRoot: string;
59
+ },
60
+ ) {
61
+ updateJson<{ compilerOptions: { paths: Record<string, string[]> } }>(
62
+ host,
63
+ ROOT_TS_CONFIG,
64
+ (json) => {
65
+ const c = json.compilerOptions;
66
+ c.paths ||= {};
67
+ delete c.paths[options.name];
68
+
69
+ if (c.paths[options.importPath]) {
70
+ throw new Error(`There is already a library with import path "${options.importPath}".`);
71
+ }
72
+
73
+ c.paths[options.importPath] = [joinPathFragments(options.projectRoot, "./src", "index.ts")];
74
+
75
+ return json;
76
+ },
77
+ );
78
+ }
79
+
80
+ export default async function generate(tree: Tree, options: NxPluginGeneratorSchema) {
81
+ const normalizedOptions = normalizeOptions(tree, options);
82
+ addFiles(tree, normalizedOptions);
83
+ updateRootTsConfig(tree, normalizedOptions);
84
+ await formatFiles(tree);
85
+ }
@@ -0,0 +1,4 @@
1
+ export interface NxPluginGeneratorSchema {
2
+ name: string;
3
+ publishable?: boolean;
4
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NodeLib",
4
+ "title": "Create a Node.js library.",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "Library name.",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ },
14
+ "x-prompt": "Library name?",
15
+ "pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$"
16
+ },
17
+ "publishable": {
18
+ "type": "boolean",
19
+ "default": false,
20
+ "description": "Create a publishable library.",
21
+ "x-priority": "important"
22
+ }
23
+ },
24
+ "required": ["name"]
25
+ }
package/src/index.ts ADDED
File without changes
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "module": "commonjs",
5
+ "outDir": "../../dist/out-tsc"
6
+ },
7
+ "files": [],
8
+ "include": [],
9
+ "references": [
10
+ {
11
+ "path": "./tsconfig.lib.json"
12
+ },
13
+ {
14
+ "path": "./tsconfig.spec.json"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "types": ["node"]
6
+ },
7
+ "include": ["src/**/*.ts"],
8
+ "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
9
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["jest", "node"]
5
+ },
6
+ "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"]
7
+ }
package/typedoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["../../typedoc.base.json"],
3
+ "entryPoints": ["src/index.ts"]
4
+ }