@doki-land/nifty 0.1.1 → 0.1.2
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/cli/nifty.mjs +2 -2
- package/package.json +6 -6
- package/src/cli/authArgs.ts +29 -29
- package/src/cli/bump-cmd.ts +15 -15
- package/src/cli/bump.ts +79 -79
- package/src/cli/change-logs-cmd.ts +26 -26
- package/src/cli/cli.ts +3 -3
- package/src/cli/commit-cmd.ts +76 -78
- package/src/cli/commit-lint-report.ts +46 -48
- package/src/cli/context.ts +9 -9
- package/src/cli/format-cmd.ts +6 -6
- package/src/cli/format.ts +15 -15
- package/src/cli/install-native-cmd.ts +4 -4
- package/src/cli/install-native.ts +24 -24
- package/src/cli/lint-cmd.ts +11 -11
- package/src/cli/lint.ts +48 -52
- package/src/cli/options.ts +14 -14
- package/src/cli/publish-cmd.ts +12 -18
- package/src/cli/publish.ts +38 -38
- package/src/cli/resolveNpm.ts +3 -3
- package/src/cli/retime-cmd.ts +18 -18
- package/src/cli/trust-cmd.ts +11 -11
- package/src/cli/trust.ts +26 -26
- package/src/cli/update-cmd.ts +5 -5
- package/src/cli/update.ts +12 -12
- package/src/cli/upload-cmd.ts +17 -17
- package/src/cli/upload.ts +131 -131
- package/src/cli/workspace.ts +46 -46
- package/src/config/authorMap.ts +4 -8
- package/src/config/defineConfig.ts +5 -5
- package/src/config/detectProject.ts +46 -46
- package/src/config/formatPresets.ts +24 -24
- package/src/config/loadConfig.ts +35 -35
- package/src/config/trustPayload.ts +6 -6
- package/src/config/types.ts +37 -37
- package/src/git.ts +14 -14
- package/src/github.ts +54 -54
- package/src/gitmoji.ts +18 -18
- package/src/native.ts +595 -599
- package/src/nifty.ts +29 -31
- package/src/types.ts +17 -17
|
@@ -6,74 +6,74 @@ export type ProjectKind = "cargo" | "npm" | "hybrid" | "unknown";
|
|
|
6
6
|
/** Detected cargo + npm project layout. */
|
|
7
7
|
export type ProjectLayout = {
|
|
8
8
|
/** Resolved project root (git root when present). */
|
|
9
|
-
root
|
|
10
|
-
kind
|
|
9
|
+
root: string;
|
|
10
|
+
kind: ProjectKind;
|
|
11
11
|
/** Nearest `Cargo.toml` walking upward. */
|
|
12
|
-
cargoManifest
|
|
12
|
+
cargoManifest?: string;
|
|
13
13
|
/** Nearest `package.json` walking upward (skips `node_modules`). */
|
|
14
|
-
packageManifest
|
|
14
|
+
packageManifest?: string;
|
|
15
15
|
/** Directory whose `Cargo.toml` declares a `[workspace]`. */
|
|
16
|
-
cargoWorkspaceRoot
|
|
16
|
+
cargoWorkspaceRoot?: string;
|
|
17
17
|
/** Directory whose `package.json` declares npm `workspaces`. */
|
|
18
|
-
npmWorkspaceRoot
|
|
18
|
+
npmWorkspaceRoot?: string;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const CARGO_MANIFEST = "Cargo.toml";
|
|
22
22
|
const PACKAGE_MANIFEST = "package.json";
|
|
23
23
|
const GIT_DIR = ".git";
|
|
24
24
|
|
|
25
|
-
function isInsideNodeModules(path
|
|
26
|
-
return path.split(
|
|
25
|
+
function isInsideNodeModules(path: string): boolean {
|
|
26
|
+
return path.split(/[/\\]/).includes("node_modules");
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function findFileUpward(cwd
|
|
29
|
+
function findFileUpward(cwd: string, fileName: string, skipNodeModules: boolean): string | undefined {
|
|
30
30
|
let here = resolve(cwd);
|
|
31
|
-
while(true){
|
|
32
|
-
if(skipNodeModules && isInsideNodeModules(here)){
|
|
31
|
+
while (true) {
|
|
32
|
+
if (skipNodeModules && isInsideNodeModules(here)) {
|
|
33
33
|
const parent = dirname(here);
|
|
34
|
-
if(parent === here){
|
|
34
|
+
if (parent === here) {
|
|
35
35
|
return undefined;
|
|
36
36
|
}
|
|
37
37
|
here = parent;
|
|
38
38
|
continue;
|
|
39
39
|
}
|
|
40
40
|
const candidate = join(here, fileName);
|
|
41
|
-
if(existsSync(candidate)){
|
|
41
|
+
if (existsSync(candidate)) {
|
|
42
42
|
return candidate;
|
|
43
43
|
}
|
|
44
44
|
const parent = dirname(here);
|
|
45
|
-
if(parent === here){
|
|
45
|
+
if (parent === here) {
|
|
46
46
|
return undefined;
|
|
47
47
|
}
|
|
48
48
|
here = parent;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function findGitRoot(cwd
|
|
52
|
+
function findGitRoot(cwd: string): string | undefined {
|
|
53
53
|
let here = resolve(cwd);
|
|
54
|
-
while(true){
|
|
55
|
-
if(existsSync(join(here, GIT_DIR))){
|
|
54
|
+
while (true) {
|
|
55
|
+
if (existsSync(join(here, GIT_DIR))) {
|
|
56
56
|
return here;
|
|
57
57
|
}
|
|
58
58
|
const parent = dirname(here);
|
|
59
|
-
if(parent === here){
|
|
59
|
+
if (parent === here) {
|
|
60
60
|
return undefined;
|
|
61
61
|
}
|
|
62
62
|
here = parent;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
function manifestHasCargoWorkspace(manifestPath
|
|
66
|
+
function manifestHasCargoWorkspace(manifestPath: string): boolean {
|
|
67
67
|
try {
|
|
68
68
|
return readFileSync(manifestPath, "utf8")
|
|
69
|
-
.split(
|
|
70
|
-
.some((line) =>line.trim() === "[workspace]");
|
|
69
|
+
.split(/\r?\n/)
|
|
70
|
+
.some((line) => line.trim() === "[workspace]");
|
|
71
71
|
} catch {
|
|
72
72
|
return false;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function manifestHasNpmWorkspaces(manifestPath
|
|
76
|
+
function manifestHasNpmWorkspaces(manifestPath: string): boolean {
|
|
77
77
|
try {
|
|
78
78
|
return readFileSync(manifestPath, "utf8").includes('"workspaces"');
|
|
79
79
|
} catch {
|
|
@@ -81,61 +81,61 @@ function manifestHasNpmWorkspaces(manifestPath : string) : boolean {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function findCargoWorkspaceRoot(manifestPath
|
|
84
|
+
function findCargoWorkspaceRoot(manifestPath: string): string | undefined {
|
|
85
85
|
let here = dirname(resolve(manifestPath));
|
|
86
|
-
while(true){
|
|
86
|
+
while (true) {
|
|
87
87
|
const candidate = join(here, CARGO_MANIFEST);
|
|
88
|
-
if(existsSync(candidate) && manifestHasCargoWorkspace(candidate)){
|
|
88
|
+
if (existsSync(candidate) && manifestHasCargoWorkspace(candidate)) {
|
|
89
89
|
return here;
|
|
90
90
|
}
|
|
91
91
|
const parent = dirname(here);
|
|
92
|
-
if(parent === here){
|
|
92
|
+
if (parent === here) {
|
|
93
93
|
return undefined;
|
|
94
94
|
}
|
|
95
95
|
here = parent;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
function findNpmWorkspaceRoot(manifestPath
|
|
99
|
+
function findNpmWorkspaceRoot(manifestPath: string): string | undefined {
|
|
100
100
|
let here = dirname(resolve(manifestPath));
|
|
101
|
-
while(true){
|
|
101
|
+
while (true) {
|
|
102
102
|
const candidate = join(here, PACKAGE_MANIFEST);
|
|
103
|
-
if(existsSync(candidate) && manifestHasNpmWorkspaces(candidate)){
|
|
103
|
+
if (existsSync(candidate) && manifestHasNpmWorkspaces(candidate)) {
|
|
104
104
|
return here;
|
|
105
105
|
}
|
|
106
106
|
const parent = dirname(here);
|
|
107
|
-
if(parent === here){
|
|
107
|
+
if (parent === here) {
|
|
108
108
|
return undefined;
|
|
109
109
|
}
|
|
110
110
|
here = parent;
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
function classifyProject(hasCargo
|
|
115
|
-
if(hasCargo && hasNpm){
|
|
114
|
+
function classifyProject(hasCargo: boolean, hasNpm: boolean): ProjectKind {
|
|
115
|
+
if (hasCargo && hasNpm) {
|
|
116
116
|
return "hybrid";
|
|
117
117
|
}
|
|
118
|
-
if(hasCargo){
|
|
118
|
+
if (hasCargo) {
|
|
119
119
|
return "cargo";
|
|
120
120
|
}
|
|
121
|
-
if(hasNpm){
|
|
121
|
+
if (hasNpm) {
|
|
122
122
|
return "npm";
|
|
123
123
|
}
|
|
124
124
|
return "unknown";
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/** Walk upward and return the nearest `Cargo.toml`. */
|
|
128
|
-
export function findCargoManifest(cwd = process.cwd())
|
|
128
|
+
export function findCargoManifest(cwd = process.cwd()): string | undefined {
|
|
129
129
|
return findFileUpward(cwd, CARGO_MANIFEST, false);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/** Walk upward and return the nearest `package.json` (skips `node_modules`). */
|
|
133
|
-
export function findPackageManifest(cwd = process.cwd())
|
|
133
|
+
export function findPackageManifest(cwd = process.cwd()): string | undefined {
|
|
134
134
|
return findFileUpward(cwd, PACKAGE_MANIFEST, true);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
/** Detect cargo/npm/hybrid layout from `cwd`. */
|
|
138
|
-
export function detectProjectLayout(cwd = process.cwd())
|
|
138
|
+
export function detectProjectLayout(cwd = process.cwd()): ProjectLayout {
|
|
139
139
|
const start = resolve(cwd);
|
|
140
140
|
const cargoManifest = findCargoManifest(start);
|
|
141
141
|
const packageManifest = findPackageManifest(start);
|
|
@@ -161,24 +161,24 @@ export function detectProjectLayout(cwd = process.cwd()) : ProjectLayout {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/** Discover npm package directories for hybrid monorepos. */
|
|
164
|
-
export function discoverPackageDirs(layout
|
|
165
|
-
const roots = new Set<string>();
|
|
164
|
+
export function discoverPackageDirs(layout: ProjectLayout): string[] {
|
|
165
|
+
const roots = new Set < string> ();
|
|
166
166
|
|
|
167
|
-
if(layout.npmWorkspaceRoot){
|
|
167
|
+
if (layout.npmWorkspaceRoot) {
|
|
168
168
|
roots.add(layout.npmWorkspaceRoot);
|
|
169
169
|
}
|
|
170
|
-
if(layout.packageManifest){
|
|
170
|
+
if (layout.packageManifest) {
|
|
171
171
|
roots.add(dirname(layout.packageManifest));
|
|
172
172
|
}
|
|
173
|
-
if(layout.kind === "hybrid"){
|
|
173
|
+
if (layout.kind === "hybrid") {
|
|
174
174
|
const packagesDir = join(layout.root, "projects", "packages");
|
|
175
|
-
if(existsSync(packagesDir)){
|
|
176
|
-
for(const entry of readdirSync(packagesDir, { withFileTypes
|
|
177
|
-
if(!entry.isDirectory()){
|
|
175
|
+
if (existsSync(packagesDir)) {
|
|
176
|
+
for (const entry of readdirSync(packagesDir, { withFileTypes: true })) {
|
|
177
|
+
if (!entry.isDirectory()) {
|
|
178
178
|
continue;
|
|
179
179
|
}
|
|
180
180
|
const packageJson = join(packagesDir, entry.name, "package.json");
|
|
181
|
-
if(existsSync(packageJson)){
|
|
181
|
+
if (existsSync(packageJson)) {
|
|
182
182
|
roots.add(join(packagesDir, entry.name));
|
|
183
183
|
}
|
|
184
184
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { NiftyFormatConfig, NiftyFormatPreset, NiftyFormatStyleConfig } from "./types.js";
|
|
2
2
|
|
|
3
3
|
export type ResolvedFormatOptions = {
|
|
4
|
-
preset
|
|
5
|
-
includes
|
|
6
|
-
excludes
|
|
7
|
-
rust
|
|
8
|
-
javascript
|
|
9
|
-
style
|
|
4
|
+
preset: NiftyFormatPreset;
|
|
5
|
+
includes?: string[];
|
|
6
|
+
excludes?: string[];
|
|
7
|
+
rust?: boolean;
|
|
8
|
+
javascript?: boolean;
|
|
9
|
+
style: NiftyFormatStyleConfig;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const DEFAULT_FORMAT_STYLE
|
|
13
|
-
indentStyle
|
|
14
|
-
indentWidth
|
|
15
|
-
lineWidth
|
|
16
|
-
quoteStyle
|
|
12
|
+
const DEFAULT_FORMAT_STYLE: NiftyFormatStyleConfig = {
|
|
13
|
+
indentStyle: "space",
|
|
14
|
+
indentWidth: 4,
|
|
15
|
+
lineWidth: 144,
|
|
16
|
+
quoteStyle: "single",
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
const NIFTY_PRESET_INCLUDES = [
|
|
@@ -39,26 +39,26 @@ const VMZ_INCLUDES = [
|
|
|
39
39
|
"nifty.config.ts",
|
|
40
40
|
]as const;
|
|
41
41
|
|
|
42
|
-
const PRESET_INCLUDES
|
|
43
|
-
default
|
|
44
|
-
nifty
|
|
45
|
-
"npm-tools"
|
|
46
|
-
vmz
|
|
42
|
+
const PRESET_INCLUDES: Record < NiftyFormatPreset, readonly string[] | undefined > = {
|
|
43
|
+
default: undefined,
|
|
44
|
+
nifty: NIFTY_PRESET_INCLUDES,
|
|
45
|
+
"npm-tools": NIFTY_PRESET_INCLUDES,
|
|
46
|
+
vmz: VMZ_INCLUDES,
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
/** Merge `nifty.config` `format` with built-in preset defaults. */
|
|
50
|
-
export function resolveFormatConfig(format
|
|
51
|
-
const preset = format
|
|
50
|
+
export function resolveFormatConfig(format: NiftyFormatConfig | undefined): ResolvedFormatOptions {
|
|
51
|
+
const preset = format?.preset ?? "default";
|
|
52
52
|
const presetIncludes = PRESET_INCLUDES[preset];
|
|
53
53
|
return {
|
|
54
54
|
preset,
|
|
55
|
-
includes
|
|
56
|
-
excludes
|
|
57
|
-
rust
|
|
58
|
-
javascript
|
|
59
|
-
style
|
|
55
|
+
includes: format?.includes ?? (presetIncludes ? [...presetIncludes] : undefined),
|
|
56
|
+
excludes: format?.excludes,
|
|
57
|
+
rust: format?.rust,
|
|
58
|
+
javascript: format?.javascript,
|
|
59
|
+
style: {
|
|
60
60
|
...DEFAULT_FORMAT_STYLE,
|
|
61
|
-
...format
|
|
61
|
+
...format?.style,
|
|
62
62
|
},
|
|
63
63
|
};
|
|
64
64
|
}
|
package/src/config/loadConfig.ts
CHANGED
|
@@ -8,23 +8,23 @@ import { detectProjectLayout } from "./detectProject.js";
|
|
|
8
8
|
|
|
9
9
|
export type LoadConfigOptions = {
|
|
10
10
|
/** Directory to start searching from (defaults to `process.cwd()`). */
|
|
11
|
-
cwd
|
|
11
|
+
cwd?: string;
|
|
12
12
|
/** When set, skip searching and load this file directly. */
|
|
13
|
-
configFile
|
|
13
|
+
configFile?: string;
|
|
14
14
|
/** Passed to functional configs: `export default defineConfig(({ mode }) => ...)`. */
|
|
15
|
-
env
|
|
15
|
+
env?: Partial < NiftyConfigEnv> ;
|
|
16
16
|
/**
|
|
17
17
|
* When true (default), write `nifty.config.ts` at the detected project root if missing.
|
|
18
18
|
* Set false for `--dry-run` so commands only report what would happen.
|
|
19
19
|
*/
|
|
20
|
-
createIfMissing
|
|
20
|
+
createIfMissing?: boolean;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
export type LoadedNiftyConfig = {
|
|
24
|
-
config
|
|
25
|
-
configFile
|
|
24
|
+
config: NiftyConfig;
|
|
25
|
+
configFile?: string;
|
|
26
26
|
/** True when this run created a new config file. */
|
|
27
|
-
created
|
|
27
|
+
created?: boolean;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
const DEFAULT_CONFIG_TEMPLATE = `// Nifty project configuration.
|
|
@@ -32,24 +32,24 @@ const DEFAULT_CONFIG_TEMPLATE = `// Nifty project configuration.
|
|
|
32
32
|
export default {};
|
|
33
33
|
`;
|
|
34
34
|
|
|
35
|
-
const DEFAULT_ENV = (cwd
|
|
36
|
-
mode
|
|
37
|
-
command
|
|
38
|
-
layout
|
|
35
|
+
const DEFAULT_ENV = (cwd: string): NiftyConfigEnv => ({
|
|
36
|
+
mode: process.env.NODE_ENV ?? "development",
|
|
37
|
+
command: "serve",
|
|
38
|
+
layout: detectProjectLayout(cwd),
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
/** Walk upward and return the nearest existing Nifty config file. */
|
|
42
|
-
export function findConfigFile(cwd = process.cwd())
|
|
42
|
+
export function findConfigFile(cwd = process.cwd()): string | undefined {
|
|
43
43
|
let here = resolve(cwd);
|
|
44
|
-
while(true){
|
|
45
|
-
for(const name of CONFIG_FILE_NAMES){
|
|
44
|
+
while (true) {
|
|
45
|
+
for (const name of CONFIG_FILE_NAMES) {
|
|
46
46
|
const candidate = join(here, name);
|
|
47
|
-
if(existsSync(candidate)){
|
|
47
|
+
if (existsSync(candidate)) {
|
|
48
48
|
return candidate;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
const parent = dirname(here);
|
|
52
|
-
if(parent === here){
|
|
52
|
+
if (parent === here) {
|
|
53
53
|
return undefined;
|
|
54
54
|
}
|
|
55
55
|
here = parent;
|
|
@@ -57,21 +57,21 @@ export function findConfigFile(cwd = process.cwd()) : string | undefined {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/** Default config path at the detected project root (prefers `nifty.config.ts`). */
|
|
60
|
-
export function defaultConfigPath(cwd = process.cwd())
|
|
60
|
+
export function defaultConfigPath(cwd = process.cwd()): string {
|
|
61
61
|
const layout = detectProjectLayout(cwd);
|
|
62
62
|
return join(layout.root, CONFIG_FILE_NAMES[0]);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/** Warn and optionally create a default config when none exists. */
|
|
66
|
-
export function ensureConfigFile(options
|
|
66
|
+
export function ensureConfigFile(options: { cwd?: string; create?: boolean } = { }): string | undefined {
|
|
67
67
|
const cwd = options.cwd ?? process.cwd();
|
|
68
68
|
const existing = findConfigFile(cwd);
|
|
69
|
-
if(existing){
|
|
69
|
+
if (existing) {
|
|
70
70
|
return existing;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const target = defaultConfigPath(cwd);
|
|
74
|
-
if(options.create){
|
|
74
|
+
if (options.create) {
|
|
75
75
|
writeFileSync(target, DEFAULT_CONFIG_TEMPLATE, "utf8");
|
|
76
76
|
console.warn(`nifty: no config found, created default ${target}`);
|
|
77
77
|
return target;
|
|
@@ -81,40 +81,40 @@ export function ensureConfigFile(options : { cwd ? : string; create ? : boolean
|
|
|
81
81
|
return undefined;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function normalizeExport(raw
|
|
85
|
-
if(raw && typeof raw === "object" && "default" in raw){
|
|
86
|
-
return(raw as { default
|
|
84
|
+
function normalizeExport(raw: unknown): NiftyConfigExport {
|
|
85
|
+
if (raw && typeof raw === "object" && "default" in raw) {
|
|
86
|
+
return(raw as { default: NiftyConfigExport }).default;
|
|
87
87
|
}
|
|
88
88
|
return raw as NiftyConfigExport;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
async function resolveExport(exported
|
|
92
|
-
if(typeof exported === "function"){
|
|
91
|
+
async function resolveExport(exported: NiftyConfigExport, env: NiftyConfigEnv): Promise < NiftyConfig> {
|
|
92
|
+
if (typeof exported === "function") {
|
|
93
93
|
return await exported(env);
|
|
94
94
|
}
|
|
95
95
|
return exported;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/** Load `nifty.config.ts/js`, creating a default file at the project root when missing. */
|
|
99
|
-
export async function loadConfig(options
|
|
99
|
+
export async function loadConfig(options: LoadConfigOptions = { }): Promise < LoadedNiftyConfig> {
|
|
100
100
|
const cwd = options.cwd ?? process.cwd();
|
|
101
101
|
let configFile = options.configFile ?? findConfigFile(cwd);
|
|
102
102
|
let created = false;
|
|
103
103
|
|
|
104
|
-
if(!configFile && options.createIfMissing!== false){
|
|
105
|
-
configFile = ensureConfigFile({ cwd, create
|
|
104
|
+
if (!configFile && options.createIfMissing !== false) {
|
|
105
|
+
configFile = ensureConfigFile({ cwd, create: true });
|
|
106
106
|
created = Boolean(configFile);
|
|
107
|
-
} else if(!configFile){
|
|
108
|
-
ensureConfigFile({ cwd, create
|
|
109
|
-
return { config
|
|
107
|
+
} else if (!configFile) {
|
|
108
|
+
ensureConfigFile({ cwd, create: false });
|
|
109
|
+
return { config: { } };
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
if(!configFile){
|
|
113
|
-
return { config
|
|
112
|
+
if (!configFile) {
|
|
113
|
+
return { config: { } };
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
const env
|
|
117
|
-
const jiti = createJiti(import.meta.url, { interopDefault
|
|
116
|
+
const env: NiftyConfigEnv = { ...DEFAULT_ENV(cwd), ...options.env };
|
|
117
|
+
const jiti = createJiti(import.meta.url, { interopDefault: true });
|
|
118
118
|
const mod = await jiti.import(configFile);
|
|
119
119
|
const config = await resolveExport(normalizeExport(mod), env);
|
|
120
120
|
return { config, configFile, created };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { NiftyConfig } from "./types.js";
|
|
2
2
|
|
|
3
3
|
/** Map `nifty.config` `trust.npm` into native publisher options. */
|
|
4
|
-
export function trustPayloadFromConfig(config
|
|
5
|
-
const npm = config.trust
|
|
6
|
-
if(!npm){
|
|
4
|
+
export function trustPayloadFromConfig(config: NiftyConfig) {
|
|
5
|
+
const npm = config.trust?.npm;
|
|
6
|
+
if (!npm) {
|
|
7
7
|
return { };
|
|
8
8
|
}
|
|
9
9
|
return {
|
|
10
|
-
...(npm.repo ? { trustRepo
|
|
11
|
-
...(npm.file ? { trustFile
|
|
12
|
-
...(npm.environment ? { trustEnvironment
|
|
10
|
+
...(npm.repo ? { trustRepo: npm.repo } : { }),
|
|
11
|
+
...(npm.file ? { trustFile: npm.file } : { }),
|
|
12
|
+
...(npm.environment ? { trustEnvironment: npm.environment } : { }),
|
|
13
13
|
};
|
|
14
14
|
}
|
package/src/config/types.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** One email → GitHub author row in `author-github.json`. */
|
|
2
2
|
export type NiftyAuthorEntry = {
|
|
3
|
-
id
|
|
4
|
-
login
|
|
3
|
+
id?: number;
|
|
4
|
+
login?: string;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
/** Built-in workspace format presets (`nifty.config` `format.preset`). */
|
|
@@ -10,97 +10,97 @@ export type NiftyFormatPreset = "default" | "nifty" | "npm-tools" | "vmz";
|
|
|
10
10
|
/** Oak formatter style knobs (`nifty.config` `format.style`). */
|
|
11
11
|
export type NiftyFormatStyleConfig = {
|
|
12
12
|
/** Indent with spaces or tabs (default: `space`). */
|
|
13
|
-
indentStyle
|
|
13
|
+
indentStyle?: "space" | "tab";
|
|
14
14
|
/** Spaces or tabs per indent level (default: `4`). */
|
|
15
|
-
indentWidth
|
|
15
|
+
indentWidth?: number;
|
|
16
16
|
/** Soft line width (default: `144`). */
|
|
17
|
-
lineWidth
|
|
17
|
+
lineWidth?: number;
|
|
18
18
|
/** String quote preference (default: `single`). */
|
|
19
|
-
quoteStyle
|
|
19
|
+
quoteStyle?: "single" | "double";
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
/** npm Trusted Publisher target for `nifty trust` (GitHub Actions OIDC). */
|
|
23
23
|
export type NiftyTrustNpmConfig = {
|
|
24
24
|
/** GitHub `owner/repo` for the publishing workflow. */
|
|
25
|
-
repo
|
|
25
|
+
repo?: string;
|
|
26
26
|
/** Workflow filename, e.g. `release-npm.yml`. */
|
|
27
|
-
file
|
|
27
|
+
file?: string;
|
|
28
28
|
/** GitHub Environment name, e.g. `NPM_PUBLISH`. */
|
|
29
|
-
environment
|
|
29
|
+
environment?: string;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
/** Trusted publisher wiring (`nifty trust`). Only `npm` is supported today. */
|
|
33
33
|
export type NiftyTrustConfig = {
|
|
34
|
-
npm
|
|
34
|
+
npm?: NiftyTrustNpmConfig;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
/** Workspace format options (`nifty format` reads `nifty.config` `format`). */
|
|
38
38
|
export type NiftyFormatConfig = {
|
|
39
39
|
/** Select built-in include roots for Nifty hybrid monorepos. */
|
|
40
|
-
preset
|
|
40
|
+
preset?: NiftyFormatPreset;
|
|
41
41
|
/** Extra include globs (override preset list when set alone). */
|
|
42
|
-
includes
|
|
42
|
+
includes?: string[];
|
|
43
43
|
/** Skip paths under these globs after includes expand. */
|
|
44
|
-
excludes
|
|
44
|
+
excludes?: string[];
|
|
45
45
|
/** Run `cargo fmt` (default: true when a Cargo workspace is detected). */
|
|
46
|
-
rust
|
|
46
|
+
rust?: boolean;
|
|
47
47
|
/** Run Oak formatting on JS/TS targets (default: true). */
|
|
48
|
-
javascript
|
|
48
|
+
javascript?: boolean;
|
|
49
49
|
/** Inline Oak formatter style (not an external config file path). */
|
|
50
|
-
style
|
|
50
|
+
style?: NiftyFormatStyleConfig;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
/** Nifty project configuration (`nifty.config.ts` / `nifty.config.js`). */
|
|
54
54
|
export type NiftyConfig = {
|
|
55
55
|
/** GitHub personal access token for email search / profile fetch. */
|
|
56
|
-
githubToken
|
|
56
|
+
githubToken?: string;
|
|
57
57
|
/** Path to `author-github.json` (default: `documentation/maintenance/author-github.json`). */
|
|
58
|
-
authorMap
|
|
58
|
+
authorMap?: string;
|
|
59
59
|
/** Repository root override when discovering git metadata. */
|
|
60
|
-
repoRoot
|
|
60
|
+
repoRoot?: string;
|
|
61
61
|
/** Cargo workspace / crate root override. */
|
|
62
|
-
cargoRoot
|
|
62
|
+
cargoRoot?: string;
|
|
63
63
|
/** npm package root override. */
|
|
64
|
-
npmRoot
|
|
64
|
+
npmRoot?: string;
|
|
65
65
|
/** npm publish / Trusted Publisher (CI uses publish-npm.yml). */
|
|
66
|
-
publish
|
|
66
|
+
publish?: {
|
|
67
67
|
/**
|
|
68
68
|
* Optional narrow subset for `nifty publish` / `nifty trust`.
|
|
69
69
|
* Default: every workspace package that is not `private: true` (and not blocked by a private dep).
|
|
70
70
|
*/
|
|
71
|
-
packages
|
|
71
|
+
packages?: string[];
|
|
72
72
|
};
|
|
73
73
|
/**
|
|
74
74
|
* Trusted publisher wiring for `nifty trust`.
|
|
75
75
|
* Prefer `trust.npm` over `NIFTY_TRUST_*` env vars. `nifty trust` uses the npm registry API.
|
|
76
76
|
*/
|
|
77
|
-
trust
|
|
77
|
+
trust?: NiftyTrustConfig;
|
|
78
78
|
/** Release reference changelog defaults (`nifty change-logs`). */
|
|
79
|
-
changelog
|
|
79
|
+
changelog?: {
|
|
80
80
|
/** GitHub `owner/repo` for contrib.rocks (default: parse `origin`). */
|
|
81
|
-
repo
|
|
81
|
+
repo?: string;
|
|
82
82
|
/** `--write` output directory (default: `documentation/maintenance/releases`). */
|
|
83
|
-
releasesDir
|
|
83
|
+
releasesDir?: string;
|
|
84
84
|
};
|
|
85
85
|
/** Rule-based lint configuration. */
|
|
86
|
-
lint
|
|
87
|
-
rules
|
|
88
|
-
id
|
|
89
|
-
enabled
|
|
90
|
-
severity
|
|
86
|
+
lint?: {
|
|
87
|
+
rules?: Array < {
|
|
88
|
+
id: string;
|
|
89
|
+
enabled?: boolean;
|
|
90
|
+
severity?: "error" | "warning" | "info";
|
|
91
91
|
}>;
|
|
92
92
|
};
|
|
93
93
|
/** Workspace format targets and engines (`nifty format`). */
|
|
94
|
-
format
|
|
94
|
+
format?: NiftyFormatConfig;
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
-
export type NiftyConfigExport = NiftyConfig | ((env
|
|
97
|
+
export type NiftyConfigExport = NiftyConfig | ((env: NiftyConfigEnv) => NiftyConfig | Promise < NiftyConfig> );
|
|
98
98
|
|
|
99
99
|
export type NiftyConfigEnv = {
|
|
100
|
-
mode
|
|
101
|
-
command
|
|
100
|
+
mode: string;
|
|
101
|
+
command: string;
|
|
102
102
|
/** Detected cargo + npm project layout for hybrid monorepos. */
|
|
103
|
-
layout
|
|
103
|
+
layout: import("./detectProject.js").ProjectLayout;
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
export const CONFIG_FILE_NAMES = [
|
package/src/git.ts
CHANGED
|
@@ -2,60 +2,60 @@ import type { CommitRecord, RangeInfo, TagInfo } from "./types.js";
|
|
|
2
2
|
import { loadNiftyNative, mapCommitRecord, mapRangeInfo, mapTagInfo, type GitExports } from "./native.js";
|
|
3
3
|
|
|
4
4
|
export type ResolveRangeOptions = {
|
|
5
|
-
version
|
|
6
|
-
fromRef
|
|
7
|
-
toRef
|
|
5
|
+
version?: string;
|
|
6
|
+
fromRef?: string;
|
|
7
|
+
toRef?: string;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Read-only git repository helpers (gix via Node-API, no `git` subprocess).
|
|
12
12
|
*/
|
|
13
13
|
export class Git {
|
|
14
|
-
constructor(private readonly wasm
|
|
14
|
+
constructor(private readonly wasm: GitExports) { }
|
|
15
15
|
|
|
16
|
-
static open()
|
|
16
|
+
static open(): Git {
|
|
17
17
|
const native = loadNiftyNative();
|
|
18
18
|
return new Git(native.git);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/** Walk upward from `startPath` to find the working tree root containing `.git`. */
|
|
22
|
-
discoverRoot(startPath
|
|
22
|
+
discoverRoot(startPath: string): string {
|
|
23
23
|
return this.wasm["discover-root"](startPath);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/** List `v*` tags sorted by semver. */
|
|
27
|
-
listVersionTags(repoRoot
|
|
27
|
+
listVersionTags(repoRoot: string): string[] {
|
|
28
28
|
return this.wasm["list-version-tags"](repoRoot);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
listTagInfos(repoRoot
|
|
31
|
+
listTagInfos(repoRoot: string): TagInfo[] {
|
|
32
32
|
return this.wasm["list-tag-infos"](repoRoot).map(mapTagInfo);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
formatTagList(repoRoot
|
|
35
|
+
formatTagList(repoRoot: string): string {
|
|
36
36
|
return this.wasm["format-tag-list"](repoRoot);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
resolveRange(repoRoot
|
|
39
|
+
resolveRange(repoRoot: string, options: ResolveRangeOptions = { }): RangeInfo {
|
|
40
40
|
return mapRangeInfo(
|
|
41
41
|
this.wasm["resolve-range"](repoRoot, options.version, options.fromRef, options.toRef),
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/** Collect non-merge commits in `fromRef..toRef` (exclusive..inclusive). */
|
|
46
|
-
collectCommits(repoRoot
|
|
46
|
+
collectCommits(repoRoot: string, fromRef: string | undefined, toRef: string): CommitRecord[] {
|
|
47
47
|
return this.wasm["collect-commits"](repoRoot, fromRef, toRef).map(mapCommitRecord);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
detectGithubRepo(repoRoot
|
|
50
|
+
detectGithubRepo(repoRoot: string): string | undefined {
|
|
51
51
|
return this.wasm["detect-github-repo"](repoRoot);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
parseGithubRemote(url
|
|
54
|
+
parseGithubRemote(url: string): string | undefined {
|
|
55
55
|
return this.wasm["parse-github-remote"](url);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export function createGit()
|
|
59
|
+
export function createGit(): Git {
|
|
60
60
|
return Git.open();
|
|
61
61
|
}
|