@doki-land/nifty 0.0.0 → 0.0.1

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/Readme.md CHANGED
@@ -1,30 +1,30 @@
1
- # @doki-land/nifty
2
-
3
- **Gitmoji is the default Nifty convention.**
4
-
5
- | Layer | Role |
6
- | --- | --- |
7
- | `@doki-land/nifty-<platform>` | Node-API `.node`(gitmoji + gix) |
8
- | `nifty-publisher` | Rust:`petgraph` 拓扑排序 + `npm publish` |
9
- | `src/cli/` | CLI 实现(`update` / `lint` / `check` / `upload` / `bump` / `publish`) |
10
- | `cli/nifty.mjs` | npm `bin` shim(jiti 加载 `src/cli`) |
11
- | `src/` | TypeScript API |
12
-
13
- Rust 侧无 `bin` / `cli`。
14
-
15
- **本仓开发**(pnpm workspace,`projects/packages/*`):
16
-
17
- ```bash
18
- pnpm install # 链接 @doki-land/nifty → node_modules/.bin/nifty
19
- pnpm run build:napi # 构建 native addon
20
- pnpm exec nifty bump
21
- pnpm exec nifty publish --dry-run
22
- ```
23
-
24
- **发布后消费**:
25
-
26
- ```bash
27
- npm install @doki-land/nifty
28
- nifty bump
29
- nifty publish --dry-run
30
- ```
1
+ # @doki-land/nifty
2
+
3
+ **Gitmoji is the default Nifty convention.**
4
+
5
+ | Layer | Role |
6
+ | --- | --- |
7
+ | `@doki-land/nifty-<platform>` | Node-API `.node`(gitmoji + gix) |
8
+ | `nifty-publisher` | Rust:`petgraph` 拓扑排序 + `npm publish` |
9
+ | `src/cli/` | CLI 实现(`update` / `lint` / `check` / `upload` / `bump` / `publish`) |
10
+ | `cli/nifty.mjs` | npm `bin` shim(jiti 加载 `src/cli`) |
11
+ | `src/` | TypeScript API |
12
+
13
+ Rust 侧无 `bin` / `cli`。
14
+
15
+ **本仓开发**(pnpm workspace,`projects/packages/*`):
16
+
17
+ ```bash
18
+ pnpm install # 链接 @doki-land/nifty → node_modules/.bin/nifty
19
+ pnpm run build:napi # 构建 native addon
20
+ pnpm exec nifty bump
21
+ pnpm exec nifty publish --dry-run
22
+ ```
23
+
24
+ **发布后消费**:
25
+
26
+ ```bash
27
+ npm install @doki-land/nifty
28
+ nifty bump
29
+ nifty publish --dry-run
30
+ ```
package/cli/nifty.mjs CHANGED
@@ -1,11 +1,11 @@
1
- #!/usr/bin/env node
2
-
3
- import { createJiti } from "jiti";
4
- import { dirname, join } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
-
7
- const here = dirname(fileURLToPath(import.meta.url));
8
- const jiti = createJiti(import.meta.url, { interopDefault: true });
9
- const { runCli } = await jiti.import(join(here, "../src/cli/main.ts"));
10
-
11
- process.exit(await runCli(process.argv.slice(2)));
1
+ #!/usr/bin/env node
2
+
3
+ import { createJiti } from "jiti";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const here = dirname(fileURLToPath(import.meta.url));
8
+ const jiti = createJiti(import.meta.url, { interopDefault: true });
9
+ const { runCli } = await jiti.import(join(here, "../src/cli/main.ts"));
10
+
11
+ process.exit(await runCli(process.argv.slice(2)));
@@ -0,0 +1,41 @@
1
+ {
2
+ "cli.intro": "nifty — gitmoji-first release tooling for hybrid cargo + npm workspaces",
3
+ "cli.cmd.update": "Bump cargo and npm dependencies",
4
+ "cli.cmd.lint": "Lint commit subjects (gitmoji rules)",
5
+ "cli.cmd.check": "Lint commit subjects and fail on errors",
6
+ "cli.cmd.upload": "Upload generic assets to GitHub Release or GitHub Pages",
7
+ "cli.cmd.install-native": "Stage matrix .node artifacts into platform npm packages",
8
+ "cli.cmd.bump": "Align workspace crate and package versions",
9
+ "cli.cmd.publish": "Publish workspace npm packages (OIDC or token + TOTP)",
10
+ "cli.cmd.trust": "Configure npm Trusted Publisher for workspace packages",
11
+ "cli.opt.cwd": "Working directory",
12
+ "cli.opt.interactive": "Prompt before applying dependency updates",
13
+ "cli.opt.from": "Start git ref for commit range",
14
+ "cli.opt.to": "End git ref for commit range",
15
+ "cli.opt.subject": "Lint a single subject string (repeatable)",
16
+ "cli.opt.release": "Upload files from --dir to the GitHub Release for --tag",
17
+ "cli.opt.pages": "Push --dir to gh-pages",
18
+ "cli.opt.both": "GitHub Release upload and GitHub Pages deploy",
19
+ "cli.opt.dir": "Directory tree for --release/--pages",
20
+ "cli.opt.from-artifacts": "Downloaded CI artifact root (default: native-artifacts or NATIVE_ARTIFACT_ROOT)",
21
+ "cli.opt.tag": "Git tag name (e.g. v0.0.1)",
22
+ "cli.opt.repo": "GitHub repo owner/name",
23
+ "cli.opt.token": "GitHub or npm token",
24
+ "cli.opt.name": "GitHub Release title",
25
+ "cli.opt.notes": "Release notes body",
26
+ "cli.opt.notes-file": "Read release notes from file",
27
+ "cli.opt.draft": "Create a draft GitHub Release",
28
+ "cli.opt.no-generate-notes": "Skip auto-generated release notes",
29
+ "cli.opt.github-action": "Read GITHUB_TOKEN, GITHUB_REPOSITORY, GITHUB_REF_NAME",
30
+ "cli.opt.dry-run": "Print actions without writing or publishing",
31
+ "cli.opt.refresh": "Ignore publish/trust cache and re-check registry",
32
+ "cli.opt.version": "Explicit semver target version",
33
+ "cli.opt.patch": "Bump patch segment",
34
+ "cli.opt.minor": "Bump minor segment",
35
+ "cli.opt.major": "Bump major segment",
36
+ "cli.opt.access": "npm publish --access",
37
+ "cli.opt.only": "Limit trust to one package name",
38
+ "cli.opt.otp": "One-time npm password (6 digits)",
39
+ "cli.opt.totp-secret": "Base32 TOTP secret (overrides env)",
40
+ "cli.opt.npm-token": "npm auth token (overrides NPM_TOKEN)"
41
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "defaultLocale": "en-US",
3
+ "locales": [{ "id": "en-US", "label": "English", "direction": "ltr" }]
4
+ }
package/package.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "nifty": "cli/nifty.mjs"
4
4
  },
5
5
  "dependencies": {
6
+ "@vmz/commander": "^0.2.0",
6
7
  "jiti": "^2.4.2"
7
8
  },
8
9
  "description": "Gitmoji-first commit conventions and release helpers (Node-API + TypeScript)",
@@ -16,20 +17,26 @@
16
17
  },
17
18
  "files": [
18
19
  "cli/nifty.mjs",
20
+ "locales",
19
21
  "src"
20
22
  ],
21
23
  "license": "MPL-2.0",
22
24
  "name": "@doki-land/nifty",
23
25
  "optionalDependencies": {
24
- "@doki-land/nifty-darwin-arm64": "0.0.0",
25
- "@doki-land/nifty-darwin-x64": "0.0.0",
26
- "@doki-land/nifty-linux-arm64": "0.0.0",
27
- "@doki-land/nifty-linux-x64": "0.0.0",
28
- "@doki-land/nifty-win32-x64": "0.0.0"
26
+ "@doki-land/nifty-darwin-arm64": "0.0.1",
27
+ "@doki-land/nifty-linux-x64": "0.0.1",
28
+ "@doki-land/nifty-win32-x64": "0.0.1"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/oovm/npm-tools.git"
29
36
  },
30
37
  "scripts": {
31
38
  "typecheck": "tsc --noEmit"
32
39
  },
33
40
  "type": "module",
34
- "version": "0.0.0"
41
+ "version": "0.0.1"
35
42
  }
@@ -1,52 +1,52 @@
1
- import { resolveNpmExecutable } from "./resolveNpm.js";
2
-
3
- export type AuthCliOptions = {
4
- otp?: string;
5
- totpSecret?: string;
6
- token?: string;
7
- npm: string;
8
- };
9
-
10
- export function parseAuthArgs(argv: string[]): AuthCliOptions {
11
- let otp: string | undefined;
12
- let totpSecret: string | undefined;
13
- let token: string | undefined;
14
-
15
- for (let i = 0; i < argv.length; i += 1) {
16
- const arg = argv[i];
17
- if (arg === "--otp") {
18
- otp = argv[++i];
19
- } else if (arg === "--totp-secret") {
20
- totpSecret = argv[++i];
21
- } else if (arg === "--token") {
22
- token = argv[++i];
23
- } else if (arg.startsWith("--otp=")) {
24
- otp = arg.slice("--otp=".length);
25
- } else if (arg.startsWith("--totp-secret=")) {
26
- totpSecret = arg.slice("--totp-secret=".length);
27
- } else if (arg.startsWith("--token=")) {
28
- token = arg.slice("--token=".length);
29
- }
30
- }
31
-
32
- return {
33
- otp,
34
- totpSecret,
35
- token,
36
- npm: resolveNpmExecutable(),
37
- };
38
- }
39
-
40
- export function authPayload(options: AuthCliOptions): {
41
- otp?: string;
42
- totpSecret?: string;
43
- token?: string;
44
- npm: string;
45
- } {
46
- return {
47
- ...(options.otp !== undefined ? { otp: options.otp } : {}),
48
- ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
49
- ...(options.token !== undefined ? { token: options.token } : {}),
50
- npm: options.npm,
51
- };
52
- }
1
+ import { resolveNpmExecutable } from "./resolveNpm.js";
2
+
3
+ export type AuthCliOptions = {
4
+ otp?: string;
5
+ totpSecret?: string;
6
+ token?: string;
7
+ npm: string;
8
+ };
9
+
10
+ export function parseAuthArgs(argv: string[]): AuthCliOptions {
11
+ let otp: string | undefined;
12
+ let totpSecret: string | undefined;
13
+ let token: string | undefined;
14
+
15
+ for (let i = 0; i < argv.length; i += 1) {
16
+ const arg = argv[i];
17
+ if (arg === "--otp") {
18
+ otp = argv[++i];
19
+ } else if (arg === "--totp-secret") {
20
+ totpSecret = argv[++i];
21
+ } else if (arg === "--token") {
22
+ token = argv[++i];
23
+ } else if (arg.startsWith("--otp=")) {
24
+ otp = arg.slice("--otp=".length);
25
+ } else if (arg.startsWith("--totp-secret=")) {
26
+ totpSecret = arg.slice("--totp-secret=".length);
27
+ } else if (arg.startsWith("--token=")) {
28
+ token = arg.slice("--token=".length);
29
+ }
30
+ }
31
+
32
+ return {
33
+ otp,
34
+ totpSecret,
35
+ token,
36
+ npm: resolveNpmExecutable(),
37
+ };
38
+ }
39
+
40
+ export function authPayload(options: AuthCliOptions): {
41
+ otp?: string;
42
+ totpSecret?: string;
43
+ token?: string;
44
+ npm: string;
45
+ } {
46
+ return {
47
+ ...(options.otp !== undefined ? { otp: options.otp } : {}),
48
+ ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
49
+ ...(options.token !== undefined ? { token: options.token } : {}),
50
+ npm: options.npm,
51
+ };
52
+ }
@@ -0,0 +1,55 @@
1
+ import type { Cli, ParsedOptions } from "@vmz/commander";
2
+
3
+ import { bumpWorkspace, printBumpReport, type BumpKind, type BumpOptions } from "./bump.js";
4
+ import { bootstrapFromOptions } from "./context.js";
5
+ import { cwdFrom, flag, str } from "./options.js";
6
+
7
+ export function registerBumpCommand(cli: Cli): void {
8
+ cli.command("bump", "cli.cmd.bump")
9
+ .option("--dry-run", "cli.opt.dry-run")
10
+ .option("--version, -v <version>", "cli.opt.version")
11
+ .option("--patch", "cli.opt.patch")
12
+ .option("--minor", "cli.opt.minor")
13
+ .option("--major", "cli.opt.major")
14
+ .action(async (options) => cmdBump(options));
15
+ }
16
+
17
+ export async function cmdBump(options: ParsedOptions): Promise<number> {
18
+ await bootstrapFromOptions(options);
19
+ const bumpOptions = bumpOptionsFromParsed(options);
20
+ const report = bumpWorkspace(bumpOptions);
21
+ printBumpReport(report, bumpOptions.dryRun);
22
+ return 0;
23
+ }
24
+
25
+ function bumpOptionsFromParsed(options: ParsedOptions): BumpOptions {
26
+ let version = str(options, "version");
27
+ let kind: BumpKind = "patch";
28
+ if (flag(options, "major")) {
29
+ kind = "major";
30
+ } else if (flag(options, "minor")) {
31
+ kind = "minor";
32
+ } else if (flag(options, "patch")) {
33
+ kind = "patch";
34
+ }
35
+ for (const positional of options._) {
36
+ if (isBumpKind(positional)) {
37
+ kind = positional;
38
+ } else if (positional) {
39
+ version = positional;
40
+ }
41
+ }
42
+ if (version && !/^\d+\.\d+\.\d+(-[\w.-]+)?$/.test(version)) {
43
+ throw new Error(`invalid version ${version}, expected semver like 0.0.0`);
44
+ }
45
+ return {
46
+ version,
47
+ kind,
48
+ cwd: cwdFrom(options),
49
+ dryRun: flag(options, "dry-run"),
50
+ };
51
+ }
52
+
53
+ function isBumpKind(value: string): value is BumpKind {
54
+ return value === "patch" || value === "minor" || value === "major";
55
+ }