Skip to content

Commit

Permalink
🎉 Feat(@betternpm/validate-npm-package-name): add
Browse files Browse the repository at this point in the history
ameValidator, isScopedPackage Functions and SCOPED_PACKAGE_PATTERN, MyErrorList, BLACK_LIST to exports!
  • Loading branch information
INeedJobToStartWork committed Sep 1, 2024
1 parent e8e444e commit a8516bc
Show file tree
Hide file tree
Showing 23 changed files with 8,497 additions and 797 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ About packages:
- ♻️ Minified
- ⚠️ Error Handler (Custom - `oh-my-error`, why this?)
- ✅ Support JS/TS & CJS/ESM
- 🐒 Rewriten Test units from tap -> vitest
- 📝 Debug Logging (Only for CLI commands)

## Packages
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@
"pre": "turbo pre",
"pre:husky": "git add . && lint-staged",
"prepare": "husky",
"test": "echo \"Error: no test specified\""
"test": "turbo test"
},
"devDependencies": {
"@changesets/cli": "^2.27.7",
"@types/lint-staged": "~13.3.0",
"commitsmile": "^0.6.1",
"globals": "^15.9.0",
"husky": "^9.1.5",
Expand Down
1 change: 1 addition & 0 deletions packages/validate-npm-package-name/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ESLINT_USE_FLAT_CONFIG = true
2 changes: 2 additions & 0 deletions packages/validate-npm-package-name/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.npmignore
.npmrc
3 changes: 3 additions & 0 deletions packages/validate-npm-package-name/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
registry=https://registry.npmjs.org/
always-auth=true
37 changes: 37 additions & 0 deletions packages/validate-npm-package-name/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# @myutilia/env

## 1.0.0

### Major Changes

- Release!

## 0.1.1

### Patch Changes

- change img in readme

## 0.1.0

### Minor Changes

- add `isPortFree` function!

## 0.1.2

### Patch Changes

- add Readme.MD

## 0.1.1

### Patch Changes

- remove unnecessary files

## 0.1.0

### Minor Changes

- add `os` function!
71 changes: 71 additions & 0 deletions packages/validate-npm-package-name/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
![image](https://github.com/user-attachments/assets/985f8c86-4dad-400f-a5fa-16f57d0546d8)

<h1 align="center"> NPM package name Validator</h1>
<p align="center">validate-npm-package-name</p>
<p align="center">This package exports functions and few elements.</p>

<!-- <img alt="Crates.io Size" src="https://img.shields.io/bundlephobia/size/@better/validate-npm-package-name"> -->
<hr/>

## **nameValidator**

```typescript
import { nameValidator } from "@betternpm/validate-npm-package-name";
nameValidator("examplename");
nameValidator("some-package");
nameValidator("example.com");
nameValidator("under_score");
nameValidator("123numeric");
nameValidator("@npm/thingy");
nameValidator("@jane/foo.js");
```

```typescript
{
validForNewPackages: boolean;
validForOldPackages: boolean;
errors?:TMyError[]
warnings?:TMyError[]
}
```

<hr/>

## List of Contents

- [**nameValidator**](#namevalidator)
- [List of Contents](#list-of-contents)
- [Exports](#exports)
- [Naming Rules (Error Codes and Descriptions)](#naming-rules-error-codes-and-descriptions)

## Exports

| Export | Description | Return Type |
| ---------------------- | ---------------------------------------------- | --------------------------------- |
| nameValidator | NPM package name Validator | `object` |
| isScopedPackage | NPM package name Scope Validator | `boolean` |
| SCOPED_PACKAGE_PATTERN | RegExp pattern checking Scope | `RegExp` |
| MyErrorList | List of Errors which `nameValidator` can throw | `as const satisfies TMyErrorList` |
| BLACK_LIST | Black listed Names | `Set<string>` |

nameValidator MyErrorList BLACK_LIST SCOPED_PACKAGE_PATTERN

## Naming Rules (Error Codes and Descriptions)

Below is a table of errors that indicate when invalid `npm` package names do not conform to the required rules:

| Error Code | Description | Don't |
| ------------------------------ | ------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
| `NULL_NAME` | Package name cannot be null. | `null` |
| `UNDEFINED_NAME` | Package name cannot be undefined. | `undefined` \| `void 0` |
| `INVALID_TYPE` | Package name must be a string. | Non-string types (e.g., numbers) |
| `TOO_SHORT_LENGTH_NAME` | Package name length should be greater than zero. | An empty string |
| `TOO_LONG_LENGTH_NAME` | Package name length cannot exceed 214 characters. | Names longer than 214 characters |
| `CANNOT_START_WITH_PERIOD` | Package name cannot start with a period. | Names starting with `.` |
| `CANNOT_START_WITH_UNDERSCORE` | Package name cannot start with an underscore. | Names starting with `_` |
| `CANNOT_HAVE_SPACES` | Package name cannot contain spaces. | Names with any spaces |
| `CORE_MODULE_NAME` | Package name _cannot_ be the same as a node.js/io.js core module or a reserved name. | Names like `http`, `stream`, `node_modules`, `favicon.ico` |
| `NO_CAPITAL_LETTERS` | All characters in the package name must be lowercase. | Uppercase or mixed case names |
| `SPECIAL_CHARACTERS` | Package name cannot contain special characters (~'!()\*). | Names containing any of these characters: `~'!()*` |
| `URL_FRIENDLY` | Package name must only contain URL-friendly characters. | Names with non-URL-friendly characters |
| `BLACK_LISTED` | Package name cannot be on the blacklist of prohibited names. | Names that are explicitly prohibited |
21 changes: 21 additions & 0 deletions packages/validate-npm-package-name/clean-package.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"indent": 4,
"remove": ["devDependencies", "lint-staged", "bin"],
"replace": {
"type": "commonjs",
"scripts": {
"npm:postpack": "clean-package restore"
},
"exports": {
".": {
"types": {
"import": "./index.d.mts",
"require": "./index.d.ts"
},
"import": "./index.mjs",
"require": "./index.js",
"*": "./*"
}
}
}
}
25 changes: 25 additions & 0 deletions packages/validate-npm-package-name/config/tsuprc/tsup.base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineConfig } from "tsup";

export default defineConfig({
entry: ["src/index.ts"],
target: "es2022",
format: ["esm"],
clean: true,
splitting: false,
platform: "node",
keepNames: true,

dts: true,
tsconfig: "./tsconfig.json",

banner: ({ format }) => {
if (format === "esm") {
const banner = `
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
`;

return { js: banner };
}
}
});
8 changes: 8 additions & 0 deletions packages/validate-npm-package-name/config/tsuprc/tsup.dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import config from "./tsup.base";
import { defineConfig } from "tsup";

export default defineConfig({
...config,
outDir: "lib",
watch: ["src"]
});
37 changes: 37 additions & 0 deletions packages/validate-npm-package-name/config/tsuprc/tsup.prod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import config from "./tsup.base";
import { copy } from "esbuild-plugin-copy";
import { defineConfig } from "tsup";

export default defineConfig({
...config,

bundle: true,
splitting: true,
minify: true,
shims: true,
sourcemap: true,

minifyIdentifiers: true,
minifySyntax: true,
minifyWhitespace: true,

metafile: false,
treeshake: true,
external: ["oh-my-error"],

outDir: "dist",

format: ["esm", "cjs"],

esbuildPlugins: [
copy({
assets: [
{ from: "./package.json", to: "./package.json" },
{ from: "./.npmrc", to: "./.npmrc" },
{ from: "./.npmignore", to: "./.npmignore" },
{ from: "./README.md", to: "./README.md" }
]
})
]
// external: ['eslint'],
});
39 changes: 39 additions & 0 deletions packages/validate-npm-package-name/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import ineedj from "@ineedj/eslintrc";

Check failure on line 1 in packages/validate-npm-package-name/eslint.config.js

View workflow job for this annotation

GitHub Actions / Deploy

Parse errors in imported module '@ineedj/eslintrc': parserPath or languageOptions.parser is required! (undefined:undefined)

Check failure on line 1 in packages/validate-npm-package-name/eslint.config.js

View workflow job for this annotation

GitHub Actions / Deploy

Parse errors in imported module '@ineedj/eslintrc': parserPath or languageOptions.parser is required! (undefined:undefined)

export default ineedj({
formatters: {
json: true,
stylistic: false,
stylisticJSX: false,
stylisticTS: false,
perfectionistSorters: false
},
modifiers: {
commands: true
},
syntax: {
mdx: true,
vitest: false,
eslint: true,
jsx: false,
next: false,
node: true,
react: false,
storybook: false,
tailwindcss: false,
typescript: true,
toml: true,
yaml: true,
turbo: false,
ignoreGlobalFiles: {
gitIgnore: true,
basicIgnores: true
}
}
}).removeRules(
"@EslintSecurity/detect-object-injection",
"@typescript-eslint/no-throw-literal",
"@EslintImports/namespace"
);

// export default [];
68 changes: 68 additions & 0 deletions packages/validate-npm-package-name/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"name": "@betternpm/validate-npm-package-name",
"version": "1.0.0",
"private": "true",
"description": "NPMs utility module",
"keywords": [
"utils",
"betternpm",
"validate-npm-package-name",
"npm name",
"package",
"names",
"validation"
],
"homepage": "https://github.com/INeedJobToStartWork/MyUtilia",
"bugs": "https://github.com/INeedJobToStartWork/MyUtilia/issues/new/choose",
"repository": {
"type": "git",
"url": "git+https://github.com/INeedJobToStartWork/MyUtilia",
"directory": "packages/npm"
},
"license": "MIT",
"author": "ineedjobtostartwork",
"type": "module",
"main": "index.js",
"scripts": {
"build": "pnpm tsup --config ./config/tsuprc/tsup.prod.ts ",
"build:npm": "pnpm npm:prepack && pnpm tsup --config ./config/tsuprc/tsup.prod.ts && pnpm npm:postpack",
"dev": "pnpm tsup --config ./config/tsuprc/tsup.dev.ts",
"format": "pnpm prettier . --write && pnpm prettier . --check",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"npm:postpack": "clean-package restore",
"npm:prepack": "clean-package",
"prepublishOnly": "pnpm build:npm",
"test": "vitest"
},
"lint-staged": {
"*": [
"pnpm format --",
"pnpm lint:fix --",
"pnpm lint --"
]
},
"dependencies": {
"oh-my-error": "1.1.1"
},
"devDependencies": {
"@ineedj/eslintrc": "~1.2.0",
"@ineedj/prettierrc": "^2.0.0",
"@ineedj/tsconfig": "^1.0.0",
"@types/eslint": "~8.56.12",
"@types/node": "^22.2.0",
"clean-package": "^2.2.0",
"esbuild-plugin-copy": "^2.1.1",
"eslint": "~8.57.0",
"prettier": "^3.3.3",
"tsup": "^8.1.0",
"typescript": "^5.5.4",
"vitest": "^2.0.5"
},
"publishConfig": {
"access": "public",
"directory": "dist",
"provenance": true,
"tag": "latest"
}
}
4 changes: 4 additions & 0 deletions packages/validate-npm-package-name/prettier.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import prettierConfig from "@ineedj/prettierrc";
export default {
...prettierConfig
};
1 change: 1 addition & 0 deletions packages/validate-npm-package-name/src/functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./name";
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './nameValidator';
export * from './isScopedPackage';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* RexExp for checking string is SCOPED package.
* The pattern captures the scope (if present) and the package name itself.
*/
// eslint-disable-next-line @EslintSecurity/detect-unsafe-regex
export const SCOPED_PACKAGE_PATTERN = /^(?:@([^/]+?)\/)?([^/]+?)$/u;

/**
*
* NPM package name Scope Validator
*
* @example isScopedPackage("@scope/example")

Check failure on line 12 in packages/validate-npm-package-name/src/functions/name/isScopedPackage.ts

View workflow job for this annotation

GitHub Actions / Deploy

tsdoc-at-sign-in-word: The "@" character looks like part of a TSDoc tag; use a backslash to escape it
* @param name - NPM package name
* @returns Boolean
*/

export const isScopedPackage = (name: string): boolean => {
const nameMatch = SCOPED_PACKAGE_PATTERN.exec(name);
return Boolean(
nameMatch && encodeURIComponent(nameMatch[1]) === nameMatch[1] && encodeURIComponent(nameMatch[2]) === nameMatch[2]
);
};
export default isScopedPackage;
Loading

0 comments on commit a8516bc

Please sign in to comment.