Licence
MIT
Version
0.1.0
Deps
0
Size
27 kB
Vulns
0
Weekly
0
synth-project-name
Zero-config project name generation, validation, and uniqueness tracking.
Generate adj-noun names from your own pools, validate against constraints, track uniqueness — all without hardcoded data.
Table of Contents
Install
npm install synth-project-nameQuick Start
import { uniqueFromPool, createMemoryStore } from "synth-project-name";
const store = createMemoryStore();
const name = await uniqueFromPool(store, {
adjectives: ["fast", "cool", "bold"],
nouns: ["api", "core", "node"],
});
// → "bold-core"Modules
name.ts — Generate
Generate adj-noun names from caller-provided pools. Supports language-specific noun overrides.
import { generateName, generateShortName, sanitizeKebabName, randomSuffix } from "synth-project-name";
const pools = { adjectives: ["fast", "cool"], nouns: ["api", "core"] };
generateShortName(pools);
// → "fast-core"
generateName(
{ pools, langNouns: { TypeScript: ["vault", "prism"] }, fallbackLang: "TypeScript" },
"TypeScript"
);
// → "cool-vault"
sanitizeKebabName("My Cool App!");
// → "my-cool-app"
randomSuffix(4);
// → "a3f1"unique.ts — Uniqueness
Track used names via a pluggable NameStore interface. Built-in memory store for testing.
import { uniqueName, uniqueFromPool, createMemoryStore } from "synth-project-name";
const store = createMemoryStore();
await uniqueName(store, "my-app");
// → "my-app"
await uniqueName(store, "my-app");
// → "my-app-3a7f"| Function | Description |
|---|---|
uniqueName(store, candidate) |
Returns candidate if unique, appends suffix otherwise |
uniqueFromPool(store, pools) |
Random pick from pool, falls back to suffix on collision |
createMemoryStore() |
In-memory store for tests |
filter.ts — Filtering
Composable pattern-based filters with negate, combine, and compound modes.
import { createCompoundFilter, negateFilter } from "synth-project-name";
const isSuspicious = createCompoundFilter({
exclude: [/internal/i, /debug/i],
minLength: 5,
allowedChars: /^[a-z0-9-]+$/,
});
isSuspicious("my-app"); // → true
isSuspicious("internal-x"); // → false
const isClean = negateFilter(isSuspicious);| Function | Logic |
|---|---|
createPatternFilter(patterns) |
any pattern matches |
createAllPatternFilter(patterns) |
all patterns match |
createCompoundFilter(opts) |
include → exclude → length → chars → custom |
negateFilter(filter) |
Inverts result |
combineFilters(...filters) |
AND logic |
validate.ts — Validation
Constraint-based validation with structured error reporting.
import { validateName, isValidName } from "synth-project-name";
isValidName("my-app", { minLength: 3, allowedChars: /^[a-z-]+$/ });
// → true
validateName("ab", { minLength: 3 });
// → { valid: false, errors: [{ rule: "minLength", message: "..." }] }Supported constraints:
| Constraint | Type | Description |
|---|---|---|
minLength |
number |
Minimum character count |
maxLength |
number |
Maximum character count |
pattern |
RegExp |
Must match |
allowedChars |
RegExp |
Every character must pass |
blockPatterns |
RegExp[] |
Must not match any |
requirePatterns |
RegExp[] |
Must match at least one |
prefix |
string |
Must start with |
suffix |
string |
Must end with |
allowedCases |
string[] |
kebab, snake, camel, pascal, upper, lower |
transform.ts — Transform
Case conversion, smart truncation, and prefix/suffix helpers.
import { normalizeName, truncateName, addAffix } from "synth-project-name";
normalizeName("My Cool App", { caseStyle: "camel" });
// → "myCoolApp"
truncateName("my-cool-app-name", 10, "smart");
// → "my-cool"
addAffix("core", { prefix: "my-", suffix: "-app" });
// → "my-core-app"| Case Style | Input | Output |
|---|---|---|
kebab |
My Cool App |
my-cool-app |
snake |
My Cool App |
my_cool_app |
camel |
My Cool App |
myCoolApp |
pascal |
My Cool App |
MyCoolApp |
lower |
My Cool App |
mycoolapp |
upper |
My Cool App |
MYCOOLAPP |
pool.ts — Sampling
Random sampling, weighted picks, and shuffling.
import { samplePool, weightedPickPool, shuffle } from "synth-project-name";
samplePool(["a", "b", "c"], 2);
// → ["c", "a"]
weightedPickPool([
{ item: "a", weight: 10 },
{ item: "b", weight: 1 },
]);
// → "a" (91% probability)
shuffle([1, 2, 3]);
// → [2, 3, 1] (random order)| Function | Description |
|---|---|
samplePool(pool, count) |
Sample with replacement |
sampleUniquePool(pool, count) |
Sample without replacement |
weightedPickPool(items) |
Weighted single pick |
weightedSamplePool(items, count) |
Weighted with replacement |
shuffle(arr) |
Fisher-Yates shuffle |
pickRandom(pool) |
Single random pick |
API Reference
All exports and type definitions are in src/index.ts. See source for full type signatures.