@funish/basis 0.0.1 → 0.0.3

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.
Files changed (58) hide show
  1. package/README.md +120 -31
  2. package/dist/chunks/config.cjs +1 -1
  3. package/dist/chunks/config.mjs +1 -1
  4. package/dist/chunks/git.cjs +1 -0
  5. package/dist/chunks/git.mjs +1 -0
  6. package/dist/chunks/init.cjs +1 -1
  7. package/dist/chunks/init.mjs +1 -1
  8. package/dist/chunks/lint.cjs +1 -1
  9. package/dist/chunks/lint.mjs +1 -1
  10. package/dist/chunks/publish.cjs +1 -1
  11. package/dist/chunks/publish.mjs +1 -1
  12. package/dist/chunks/version.cjs +1 -1
  13. package/dist/chunks/version.mjs +1 -1
  14. package/dist/cli.cjs +1 -1
  15. package/dist/cli.mjs +1 -1
  16. package/dist/config.cjs +1 -1
  17. package/dist/config.d.cts +1 -1
  18. package/dist/config.d.mts +1 -1
  19. package/dist/config.d.ts +1 -1
  20. package/dist/config.mjs +1 -1
  21. package/dist/index.cjs +1 -1
  22. package/dist/index.d.cts +188 -25
  23. package/dist/index.d.mts +188 -25
  24. package/dist/index.d.ts +188 -25
  25. package/dist/index.mjs +1 -1
  26. package/dist/shared/basis.0WCUjjhy.mjs +1 -0
  27. package/dist/shared/basis.1ZgFrMJb.mjs +7 -0
  28. package/dist/shared/basis.B4p52ive.cjs +1 -0
  29. package/dist/shared/basis.BEOfVK6U.cjs +3 -0
  30. package/dist/shared/basis.BJhSbOyA.cjs +1 -0
  31. package/dist/shared/basis.BvLeB_5F.d.cts +253 -0
  32. package/dist/shared/basis.BvLeB_5F.d.mts +253 -0
  33. package/dist/shared/basis.BvLeB_5F.d.ts +253 -0
  34. package/dist/shared/basis.C8S2dWvt.cjs +7 -0
  35. package/dist/shared/basis.CHVACS4W.cjs +1 -0
  36. package/dist/shared/basis.CkZpidFZ.mjs +1 -0
  37. package/dist/shared/basis.DcC8NBqt.mjs +3 -0
  38. package/dist/shared/basis.DzMHJtq5.mjs +10 -0
  39. package/dist/shared/basis.plLH3j3N.mjs +1 -0
  40. package/dist/shared/basis.sOTOmfHG.cjs +10 -0
  41. package/package.json +7 -3
  42. package/dist/chunks/githooks.cjs +0 -1
  43. package/dist/chunks/githooks.mjs +0 -1
  44. package/dist/shared/basis.ByJ8R9TE.cjs +0 -1
  45. package/dist/shared/basis.C0E7mwQ6.mjs +0 -1
  46. package/dist/shared/basis.C5wlo6IO.mjs +0 -1
  47. package/dist/shared/basis.CBZIV3-V.mjs +0 -19
  48. package/dist/shared/basis.CSSuyvpq.cjs +0 -1
  49. package/dist/shared/basis.CgpyxNW3.cjs +0 -1
  50. package/dist/shared/basis.D57HxVvD.cjs +0 -4
  51. package/dist/shared/basis.DeKfEQsQ.cjs +0 -5
  52. package/dist/shared/basis.DweCjqFb.cjs +0 -19
  53. package/dist/shared/basis.O4so-uuj.mjs +0 -5
  54. package/dist/shared/basis.dc3ybBoz.mjs +0 -1
  55. package/dist/shared/basis.iRZ1Ylu8.d.cts +0 -127
  56. package/dist/shared/basis.iRZ1Ylu8.d.mts +0 -127
  57. package/dist/shared/basis.iRZ1Ylu8.d.ts +0 -127
  58. package/dist/shared/basis.rDVxD7qf.mjs +0 -4
@@ -0,0 +1,253 @@
1
+ interface BasisConfig {
2
+ lint?: LintConfig;
3
+ git?: GitConfig;
4
+ packageManager?: PackageManagerConfig;
5
+ version?: VersionConfig;
6
+ publish?: PublishConfig;
7
+ }
8
+ interface LintConfig {
9
+ staged?: Record<string, string>;
10
+ project?: Record<string, string>;
11
+ dependencies?: {
12
+ checkOutdated?: boolean;
13
+ checkSecurity?: boolean;
14
+ allowedLicenses?: string[];
15
+ blockedPackages?: string[];
16
+ };
17
+ structure?: {
18
+ requiredFiles?: string[];
19
+ requiredDirs?: string[];
20
+ naming?: Array<{
21
+ path: string;
22
+ files?: string;
23
+ directories?: string;
24
+ description?: string;
25
+ }>;
26
+ };
27
+ docs?: {
28
+ checkReadme?: boolean;
29
+ checkChangelog?: boolean;
30
+ };
31
+ }
32
+ interface GitConfig {
33
+ hooks?: Partial<Record<ValidGitHook, string>>;
34
+ config?: {
35
+ core?: {
36
+ editor?: string;
37
+ autocrlf?: boolean | "input";
38
+ eol?: "lf" | "crlf" | "native";
39
+ ignorecase?: boolean;
40
+ filemode?: boolean;
41
+ bare?: boolean;
42
+ logallrefupdates?: boolean;
43
+ repositoryformatversion?: number;
44
+ sharedrepository?: boolean | "group" | "all" | "world" | "everybody";
45
+ worktree?: string;
46
+ precomposeunicode?: boolean;
47
+ protecthfs?: boolean;
48
+ protectntfs?: boolean;
49
+ };
50
+ user?: {
51
+ name?: string;
52
+ email?: string;
53
+ signingkey?: string;
54
+ };
55
+ init?: {
56
+ defaultBranch?: string;
57
+ };
58
+ branch?: {
59
+ autosetupmerge?: boolean | "always";
60
+ autosetuprebase?: "never" | "local" | "remote" | "always";
61
+ };
62
+ push?: {
63
+ default?: "nothing" | "current" | "upstream" | "simple" | "matching";
64
+ followTags?: boolean;
65
+ autoSetupRemote?: boolean;
66
+ };
67
+ pull?: {
68
+ rebase?: boolean | "preserve" | "merges" | "interactive";
69
+ ff?: boolean | "only";
70
+ };
71
+ merge?: {
72
+ tool?: string;
73
+ conflictstyle?: "merge" | "diff3";
74
+ ff?: boolean | "only";
75
+ log?: boolean | number;
76
+ };
77
+ rebase?: {
78
+ autoSquash?: boolean;
79
+ autoStash?: boolean;
80
+ updateRefs?: boolean;
81
+ };
82
+ fetch?: {
83
+ prune?: boolean;
84
+ pruneTags?: boolean;
85
+ fsckobjects?: boolean;
86
+ };
87
+ remote?: {
88
+ [remoteName: string]: {
89
+ url?: string;
90
+ fetch?: string;
91
+ };
92
+ };
93
+ diff?: {
94
+ tool?: string;
95
+ algorithm?: "myers" | "minimal" | "patience" | "histogram";
96
+ renames?: boolean | "copy" | "copies";
97
+ mnemonicprefix?: boolean;
98
+ };
99
+ status?: {
100
+ showUntrackedFiles?: "no" | "normal" | "all";
101
+ branch?: boolean;
102
+ short?: boolean;
103
+ };
104
+ commit?: {
105
+ cleanup?: "strip" | "whitespace" | "verbatim" | "scissors" | "default";
106
+ gpgsign?: boolean;
107
+ template?: string;
108
+ verbose?: boolean;
109
+ };
110
+ log?: {
111
+ abbrevCommit?: boolean;
112
+ decorate?: boolean | "short" | "full" | "auto" | "no";
113
+ showSignature?: boolean;
114
+ };
115
+ transfer?: {
116
+ fsckobjects?: boolean;
117
+ };
118
+ receive?: {
119
+ fsckObjects?: boolean;
120
+ };
121
+ gc?: {
122
+ auto?: number;
123
+ autopacklimit?: number;
124
+ autodetach?: boolean;
125
+ };
126
+ alias?: {
127
+ [aliasName: string]: string;
128
+ };
129
+ url?: {
130
+ [pattern: string]: {
131
+ insteadOf?: string;
132
+ pushInsteadOf?: string;
133
+ };
134
+ };
135
+ };
136
+ commitMsg?: CommitMsgConfig;
137
+ autoSetup?: boolean;
138
+ autoInitGit?: boolean;
139
+ skipGitCheck?: boolean;
140
+ force?: boolean;
141
+ }
142
+ interface CommitMsgConfig {
143
+ types?: string[];
144
+ maxLength?: number;
145
+ minLength?: number;
146
+ scopeRequired?: boolean;
147
+ allowedScopes?: string[];
148
+ }
149
+ interface CommitMessage {
150
+ type: string;
151
+ scope?: string;
152
+ description: string;
153
+ body?: string;
154
+ footer?: string;
155
+ isBreaking: boolean;
156
+ }
157
+ declare const VALID_GIT_HOOKS: readonly ["applypatch-msg", "pre-applypatch", "post-applypatch", "pre-commit", "pre-merge-commit", "prepare-commit-msg", "commit-msg", "post-commit", "pre-rebase", "post-checkout", "post-merge", "pre-push", "pre-receive", "update", "proc-receive", "post-receive", "post-update", "reference-transaction", "push-to-checkout", "pre-auto-gc", "post-rewrite", "sendemail-validate", "fsmonitor-watchman", "p4-changelist", "p4-prepare-changelist", "p4-post-changelist", "p4-pre-submit", "post-index-change"];
158
+ type ValidGitHook = (typeof VALID_GIT_HOOKS)[number];
159
+ type GitConfigValue = string | number | boolean;
160
+ type GitConfigSection = Record<string, GitConfigValue>;
161
+ type GitConfigData = Record<string, GitConfigSection>;
162
+ interface PackageManagerConfig {
163
+ /** Preferred package manager (aligned with nypm support) */
164
+ preferred?: "npm" | "yarn" | "pnpm" | "bun" | "deno";
165
+ /** Auto-detect package manager from project */
166
+ autoDetect?: boolean;
167
+ /** NPM registry URL */
168
+ registry?: string;
169
+ }
170
+ interface VersionConfig {
171
+ /** Git tag prefix */
172
+ tagPrefix?: string;
173
+ /** Auto commit version changes */
174
+ autoCommit?: boolean;
175
+ /** Auto create git tag */
176
+ autoTag?: boolean;
177
+ /** Auto push changes to remote */
178
+ autoPush?: boolean;
179
+ /** Prerelease identifier (alpha, beta, rc) */
180
+ prereleaseId?: string;
181
+ /** Commit message template */
182
+ commitMessage?: string;
183
+ }
184
+ interface PublishConfig {
185
+ /** NPM registry URL */
186
+ registry?: string;
187
+ /** Package access level */
188
+ access?: "public" | "private";
189
+ /** Default publish tag (for non-stable releases) */
190
+ defaultTag?: string;
191
+ /** Stable release tag */
192
+ stableTag?: string;
193
+ /** Build command before publish */
194
+ buildCommand?: string;
195
+ /** Test command before publish */
196
+ testCommand?: string;
197
+ /** Check git working directory is clean */
198
+ checkGitClean?: boolean;
199
+ /** Run tests before publish */
200
+ checkTests?: boolean;
201
+ /** Auto push git changes after publish */
202
+ autoGitPush?: boolean;
203
+ /** Create git tag after publish */
204
+ createGitTag?: boolean;
205
+ }
206
+ interface InitOptions {
207
+ force?: boolean;
208
+ skipGitCheck?: boolean;
209
+ skipInstall?: boolean;
210
+ }
211
+ interface VersionOptions {
212
+ version?: string;
213
+ preid?: string;
214
+ prerelease?: boolean;
215
+ major?: boolean;
216
+ minor?: boolean;
217
+ patch?: boolean;
218
+ tag?: string;
219
+ message?: string;
220
+ }
221
+ interface PublishOptions {
222
+ tag?: string;
223
+ stable?: boolean;
224
+ latest?: boolean;
225
+ dryRun?: boolean;
226
+ access?: "public" | "private";
227
+ registry?: string;
228
+ skipBuild?: boolean;
229
+ skipTests?: boolean;
230
+ }
231
+ interface VersionUpdateResult {
232
+ oldVersion: string;
233
+ newVersion: string;
234
+ tagName?: string;
235
+ }
236
+ interface PublishResult {
237
+ packageName: string;
238
+ version: string;
239
+ publishTag: string;
240
+ dryRun: boolean;
241
+ }
242
+
243
+ /**
244
+ * Define a Basis configuration
245
+ */
246
+ declare function defineBasisConfig(config: BasisConfig): BasisConfig;
247
+ /**
248
+ * Default configuration
249
+ */
250
+ declare const defaultConfig: BasisConfig;
251
+
252
+ export { defineBasisConfig as d, defaultConfig as e, VALID_GIT_HOOKS as g };
253
+ export type { BasisConfig as B, CommitMessage as C, GitConfig as G, InitOptions as I, LintConfig as L, PublishOptions as P, VersionOptions as V, VersionUpdateResult as a, PublishResult as b, GitConfigData as c, CommitMsgConfig as f, ValidGitHook as h, GitConfigValue as i, GitConfigSection as j, PackageManagerConfig as k, VersionConfig as l, PublishConfig as m };
@@ -0,0 +1,253 @@
1
+ interface BasisConfig {
2
+ lint?: LintConfig;
3
+ git?: GitConfig;
4
+ packageManager?: PackageManagerConfig;
5
+ version?: VersionConfig;
6
+ publish?: PublishConfig;
7
+ }
8
+ interface LintConfig {
9
+ staged?: Record<string, string>;
10
+ project?: Record<string, string>;
11
+ dependencies?: {
12
+ checkOutdated?: boolean;
13
+ checkSecurity?: boolean;
14
+ allowedLicenses?: string[];
15
+ blockedPackages?: string[];
16
+ };
17
+ structure?: {
18
+ requiredFiles?: string[];
19
+ requiredDirs?: string[];
20
+ naming?: Array<{
21
+ path: string;
22
+ files?: string;
23
+ directories?: string;
24
+ description?: string;
25
+ }>;
26
+ };
27
+ docs?: {
28
+ checkReadme?: boolean;
29
+ checkChangelog?: boolean;
30
+ };
31
+ }
32
+ interface GitConfig {
33
+ hooks?: Partial<Record<ValidGitHook, string>>;
34
+ config?: {
35
+ core?: {
36
+ editor?: string;
37
+ autocrlf?: boolean | "input";
38
+ eol?: "lf" | "crlf" | "native";
39
+ ignorecase?: boolean;
40
+ filemode?: boolean;
41
+ bare?: boolean;
42
+ logallrefupdates?: boolean;
43
+ repositoryformatversion?: number;
44
+ sharedrepository?: boolean | "group" | "all" | "world" | "everybody";
45
+ worktree?: string;
46
+ precomposeunicode?: boolean;
47
+ protecthfs?: boolean;
48
+ protectntfs?: boolean;
49
+ };
50
+ user?: {
51
+ name?: string;
52
+ email?: string;
53
+ signingkey?: string;
54
+ };
55
+ init?: {
56
+ defaultBranch?: string;
57
+ };
58
+ branch?: {
59
+ autosetupmerge?: boolean | "always";
60
+ autosetuprebase?: "never" | "local" | "remote" | "always";
61
+ };
62
+ push?: {
63
+ default?: "nothing" | "current" | "upstream" | "simple" | "matching";
64
+ followTags?: boolean;
65
+ autoSetupRemote?: boolean;
66
+ };
67
+ pull?: {
68
+ rebase?: boolean | "preserve" | "merges" | "interactive";
69
+ ff?: boolean | "only";
70
+ };
71
+ merge?: {
72
+ tool?: string;
73
+ conflictstyle?: "merge" | "diff3";
74
+ ff?: boolean | "only";
75
+ log?: boolean | number;
76
+ };
77
+ rebase?: {
78
+ autoSquash?: boolean;
79
+ autoStash?: boolean;
80
+ updateRefs?: boolean;
81
+ };
82
+ fetch?: {
83
+ prune?: boolean;
84
+ pruneTags?: boolean;
85
+ fsckobjects?: boolean;
86
+ };
87
+ remote?: {
88
+ [remoteName: string]: {
89
+ url?: string;
90
+ fetch?: string;
91
+ };
92
+ };
93
+ diff?: {
94
+ tool?: string;
95
+ algorithm?: "myers" | "minimal" | "patience" | "histogram";
96
+ renames?: boolean | "copy" | "copies";
97
+ mnemonicprefix?: boolean;
98
+ };
99
+ status?: {
100
+ showUntrackedFiles?: "no" | "normal" | "all";
101
+ branch?: boolean;
102
+ short?: boolean;
103
+ };
104
+ commit?: {
105
+ cleanup?: "strip" | "whitespace" | "verbatim" | "scissors" | "default";
106
+ gpgsign?: boolean;
107
+ template?: string;
108
+ verbose?: boolean;
109
+ };
110
+ log?: {
111
+ abbrevCommit?: boolean;
112
+ decorate?: boolean | "short" | "full" | "auto" | "no";
113
+ showSignature?: boolean;
114
+ };
115
+ transfer?: {
116
+ fsckobjects?: boolean;
117
+ };
118
+ receive?: {
119
+ fsckObjects?: boolean;
120
+ };
121
+ gc?: {
122
+ auto?: number;
123
+ autopacklimit?: number;
124
+ autodetach?: boolean;
125
+ };
126
+ alias?: {
127
+ [aliasName: string]: string;
128
+ };
129
+ url?: {
130
+ [pattern: string]: {
131
+ insteadOf?: string;
132
+ pushInsteadOf?: string;
133
+ };
134
+ };
135
+ };
136
+ commitMsg?: CommitMsgConfig;
137
+ autoSetup?: boolean;
138
+ autoInitGit?: boolean;
139
+ skipGitCheck?: boolean;
140
+ force?: boolean;
141
+ }
142
+ interface CommitMsgConfig {
143
+ types?: string[];
144
+ maxLength?: number;
145
+ minLength?: number;
146
+ scopeRequired?: boolean;
147
+ allowedScopes?: string[];
148
+ }
149
+ interface CommitMessage {
150
+ type: string;
151
+ scope?: string;
152
+ description: string;
153
+ body?: string;
154
+ footer?: string;
155
+ isBreaking: boolean;
156
+ }
157
+ declare const VALID_GIT_HOOKS: readonly ["applypatch-msg", "pre-applypatch", "post-applypatch", "pre-commit", "pre-merge-commit", "prepare-commit-msg", "commit-msg", "post-commit", "pre-rebase", "post-checkout", "post-merge", "pre-push", "pre-receive", "update", "proc-receive", "post-receive", "post-update", "reference-transaction", "push-to-checkout", "pre-auto-gc", "post-rewrite", "sendemail-validate", "fsmonitor-watchman", "p4-changelist", "p4-prepare-changelist", "p4-post-changelist", "p4-pre-submit", "post-index-change"];
158
+ type ValidGitHook = (typeof VALID_GIT_HOOKS)[number];
159
+ type GitConfigValue = string | number | boolean;
160
+ type GitConfigSection = Record<string, GitConfigValue>;
161
+ type GitConfigData = Record<string, GitConfigSection>;
162
+ interface PackageManagerConfig {
163
+ /** Preferred package manager (aligned with nypm support) */
164
+ preferred?: "npm" | "yarn" | "pnpm" | "bun" | "deno";
165
+ /** Auto-detect package manager from project */
166
+ autoDetect?: boolean;
167
+ /** NPM registry URL */
168
+ registry?: string;
169
+ }
170
+ interface VersionConfig {
171
+ /** Git tag prefix */
172
+ tagPrefix?: string;
173
+ /** Auto commit version changes */
174
+ autoCommit?: boolean;
175
+ /** Auto create git tag */
176
+ autoTag?: boolean;
177
+ /** Auto push changes to remote */
178
+ autoPush?: boolean;
179
+ /** Prerelease identifier (alpha, beta, rc) */
180
+ prereleaseId?: string;
181
+ /** Commit message template */
182
+ commitMessage?: string;
183
+ }
184
+ interface PublishConfig {
185
+ /** NPM registry URL */
186
+ registry?: string;
187
+ /** Package access level */
188
+ access?: "public" | "private";
189
+ /** Default publish tag (for non-stable releases) */
190
+ defaultTag?: string;
191
+ /** Stable release tag */
192
+ stableTag?: string;
193
+ /** Build command before publish */
194
+ buildCommand?: string;
195
+ /** Test command before publish */
196
+ testCommand?: string;
197
+ /** Check git working directory is clean */
198
+ checkGitClean?: boolean;
199
+ /** Run tests before publish */
200
+ checkTests?: boolean;
201
+ /** Auto push git changes after publish */
202
+ autoGitPush?: boolean;
203
+ /** Create git tag after publish */
204
+ createGitTag?: boolean;
205
+ }
206
+ interface InitOptions {
207
+ force?: boolean;
208
+ skipGitCheck?: boolean;
209
+ skipInstall?: boolean;
210
+ }
211
+ interface VersionOptions {
212
+ version?: string;
213
+ preid?: string;
214
+ prerelease?: boolean;
215
+ major?: boolean;
216
+ minor?: boolean;
217
+ patch?: boolean;
218
+ tag?: string;
219
+ message?: string;
220
+ }
221
+ interface PublishOptions {
222
+ tag?: string;
223
+ stable?: boolean;
224
+ latest?: boolean;
225
+ dryRun?: boolean;
226
+ access?: "public" | "private";
227
+ registry?: string;
228
+ skipBuild?: boolean;
229
+ skipTests?: boolean;
230
+ }
231
+ interface VersionUpdateResult {
232
+ oldVersion: string;
233
+ newVersion: string;
234
+ tagName?: string;
235
+ }
236
+ interface PublishResult {
237
+ packageName: string;
238
+ version: string;
239
+ publishTag: string;
240
+ dryRun: boolean;
241
+ }
242
+
243
+ /**
244
+ * Define a Basis configuration
245
+ */
246
+ declare function defineBasisConfig(config: BasisConfig): BasisConfig;
247
+ /**
248
+ * Default configuration
249
+ */
250
+ declare const defaultConfig: BasisConfig;
251
+
252
+ export { defineBasisConfig as d, defaultConfig as e, VALID_GIT_HOOKS as g };
253
+ export type { BasisConfig as B, CommitMessage as C, GitConfig as G, InitOptions as I, LintConfig as L, PublishOptions as P, VersionOptions as V, VersionUpdateResult as a, PublishResult as b, GitConfigData as c, CommitMsgConfig as f, ValidGitHook as h, GitConfigValue as i, GitConfigSection as j, PackageManagerConfig as k, VersionConfig as l, PublishConfig as m };
@@ -0,0 +1,7 @@
1
+ "use strict";const update=require("c12/update"),consola=require("consola"),magicast=require("magicast"),nypm=require("nypm"),pathe=require("pathe"),pkgTypes=require("pkg-types"),utils=require("./basis.BJhSbOyA.cjs"),git=require("./basis.sOTOmfHG.cjs"),o={ts:{ext:"ts",label:"TypeScript"},mjs:{ext:"mjs",label:"ES Module"},cjs:{ext:"cjs",label:"CommonJS"}};function D(e){const i=magicast.parseModule("");if(e==="cjs"){i.imports.$prepend({from:"@funish/basis",imported:"defineBasisConfig",local:"defineBasisConfig"}),i.exports.default=magicast.builders.functionCall("defineBasisConfig",{});const t=i.exports.default.$args[0];t.$ast.leadingComments=[{type:"Block",value:`
2
+ Configure your project here
3
+ See: https://github.com/funish/basis/tree/main/packages/basis#configuration
4
+ `}]}else{i.imports.$prepend({from:"@funish/basis",imported:"defineBasisConfig",local:"defineBasisConfig"}),i.exports.default=magicast.builders.functionCall("defineBasisConfig",{});const t=i.exports.default.$args[0];t.$ast.leadingComments=[{type:"Block",value:`
5
+ Configure your project here
6
+ See: https://github.com/funish/basis/tree/main/packages/basis#configuration
7
+ `}]}return magicast.generateCode(i).code}async function B(e){if(await utils.fileExists(pathe.resolve(e,"tsconfig.json")))return"ts";try{if((await pkgTypes.readPackageJSON(e)).type==="module")return"mjs"}catch{}return"ts"}async function init(e=process.cwd(),i={}){const{force:t=!1,skipGitCheck:f=!1,skipInstall:l=!1}=i;consola.consola.start("Initializing basis configuration...");const c=await B(e),d=await consola.consola.prompt("Choose config file format:",{type:"select",initial:c,options:[{value:"ts",label:`${o.ts.label} (${o.ts.ext}) ${c==="ts"?"(recommended)":""}`},{value:"mjs",label:`${o.mjs.label} (${o.mjs.ext}) ${c==="mjs"?"(recommended)":""}`},{value:"cjs",label:`${o.cjs.label} (${o.cjs.ext}) ${c==="cjs"?"(recommended)":""}`}]}),u=o[d].ext,n=`basis.config.${u}`,g=pathe.resolve(e,n);if(await utils.fileExists(g)&&!t)return consola.consola.error(`${n} already exists. Use --force to overwrite.`),!1;let r=!1;if(!f){if(await utils.fileExists(pathe.resolve(e,".git")))r=await consola.consola.prompt("Setup Git hooks and configuration?",{type:"confirm",initial:!0});else if(consola.consola.warn("No .git directory found. Git hooks will not work properly."),!await consola.consola.prompt("Continue anyway?",{type:"confirm",initial:!1}))return consola.consola.info("Initialization cancelled."),!1}const p=(await nypm.detectPackageManager(e))?.name||"npm";consola.consola.info(`Detected package manager: ${p}`),await update.updateConfig({cwd:e,configFile:"basis.config",createExtension:u,onCreate:()=>(consola.consola.info(`Creating ${n}...`),D(d))}),consola.consola.success(`Created ${n}`);try{const s=await pkgTypes.readPackageJSON(e),m=!!(s.workspaces||await utils.fileExists(pathe.resolve(e,"pnpm-workspace.yaml")));l?!s.devDependencies?.["@funish/basis"]&&!s.dependencies?.["@funish/basis"]&&(s.devDependencies=s.devDependencies||{},s.devDependencies["@funish/basis"]="latest",consola.consola.info("Added @funish/basis to devDependencies")):(await nypm.addDevDependency("@funish/basis",{cwd:e,silent:!1,workspace:m}),consola.consola.success("Added @funish/basis to devDependencies"));const a="basis git --setup";s.scripts=s.scripts||{},p==="pnpm"?s.scripts.postinstall?s.scripts.postinstall.includes(a)||(s.scripts.postinstall=`${s.scripts.postinstall} && ${a}`):s.scripts.postinstall=a:p==="yarn"?s.scripts.prepare?s.scripts.prepare.includes(a)||(s.scripts.prepare=`${s.scripts.prepare} && ${a}`):s.scripts.prepare=a:s.scripts.postinstall?s.scripts.postinstall.includes(a)||(s.scripts.postinstall=`${s.scripts.postinstall} && ${a}`):s.scripts.postinstall=a,await pkgTypes.writePackageJSON(pathe.resolve(e,"package.json"),s),consola.consola.success(`Updated package.json scripts${l?" and dependencies":""}`),l?(consola.consola.info("Skipped dependency installation"),consola.consola.info("Run your package manager's install command to complete setup")):(consola.consola.start("Installing dependencies..."),await nypm.installDependencies({cwd:e,silent:!1}),consola.consola.success("Dependencies installed successfully"))}catch(s){return consola.consola.error("Failed to setup dependencies:",s),!1}return r&&(consola.consola.start("Setting up Git hooks and configuration..."),await git.setupGit(e)?consola.consola.success("Git setup completed!"):consola.consola.warn("Git setup failed, but basis config was created successfully")),consola.consola.success("Basis initialization completed!"),consola.consola.info("You can now:"),consola.consola.info(` - Edit ${n} to customize your configuration`),r||consola.consola.info(" - Run `basis git --setup` to install git hooks"),!0}exports.init=init;
@@ -0,0 +1 @@
1
+ "use strict";const node_child_process=require("node:child_process"),consola=require("consola"),pkgTypes=require("pkg-types"),g=require("semver"),utils=require("./basis.BJhSbOyA.cjs");function _interopDefaultCompat(e){return e&&typeof e=="object"&&"default"in e?e.default:e}const g__default=_interopDefaultCompat(g);async function updatePackageVersion(e,t={}){const{config:u}=await utils.loadConfig({cwd:e}),r=u.version||{},i=await pkgTypes.readPackageJSON(e),s=i.version;if(!s)throw new Error("No version found in package.json");const c=t.version?g__default.valid(t.version)?t.version:(()=>{throw new Error(`Invalid version format: ${t.version}`)})():(()=>{if(!g__default.valid(s))throw new Error(`Invalid current version format: ${s}`);const o=g__default.prerelease(s),n=t.preid||(o&&typeof o[0]=="string"?o[0]:null)||r.prereleaseId||"edge";let a;t.major?a="major":t.minor?a="minor":t.prerelease?a=o?"prerelease":"prepatch":a=o?"prerelease":"patch";const d=a==="prerelease"||a.startsWith("pre")?g__default.inc(s,a,n):g__default.inc(s,a);if(!d)throw new Error("Failed to calculate new version");return d})();consola.consola.info(`Updating version: ${s} \u2192 ${c}`);const p=await pkgTypes.resolvePackageJSON(e);await pkgTypes.writePackageJSON(p,{...i,version:c});const l={oldVersion:s,newVersion:c};if(r.autoCommit){const o=t.message||r.commitMessage?.replace("{version}",c)||`chore: release v${c}`;try{node_child_process.execSync("git add package.json",{cwd:e}),node_child_process.execSync(`git commit -m "${o}"`,{cwd:e}),consola.consola.success(`Committed version update: ${o}`)}catch(n){consola.consola.warn("Failed to commit changes:",n)}}if(r.autoTag){const o=`${r.tagPrefix||"v"}${c}`;try{node_child_process.execSync(`git tag ${o}`,{cwd:e}),consola.consola.success(`Created git tag: ${o}`),l.tagName=o}catch(n){consola.consola.warn("Failed to create git tag:",n)}}if(r.autoPush)try{node_child_process.execSync("git push",{cwd:e}),r.autoTag&&node_child_process.execSync("git push --tags",{cwd:e}),consola.consola.success("Pushed changes to remote")}catch(o){consola.consola.warn("Failed to push changes:",o)}return l}exports.updatePackageVersion=updatePackageVersion;
@@ -0,0 +1 @@
1
+ import{access as t}from"node:fs/promises";import{loadConfig as e}from"c12";import{defaultConfig as d}from"../config.mjs";async function u(a={}){return await e({name:"basis",cwd:process.cwd(),...a,defaults:{...d,...a.defaults}})}async function n(a){try{return await t(a),!0}catch{return!1}}function o(a){switch(a){case"yarn":return{outdated:"yarn outdated --json",audit:"yarn audit --level moderate"};case"pnpm":return{outdated:"pnpm outdated --format table",audit:"pnpm audit --audit-level moderate"};case"bun":return{outdated:"bun outdated",audit:"bun audit --audit-level moderate"};default:return{outdated:"npm outdated --json",audit:"npm audit --audit-level moderate"}}}export{n as f,o as g,u as l};
@@ -0,0 +1,3 @@
1
+ import{execSync as p}from"node:child_process";import{consola as e}from"consola";import S from"fast-glob";import N from"micromatch";import{detectPackageManager as O}from"nypm";import{resolve as w}from"pathe";import{readPackageJSON as P}from"pkg-types";import{l as h,f as k,g as C}from"./basis.CkZpidFZ.mjs";function j(){try{const t=p("git diff --cached --name-only",{encoding:"utf8"}).trim().split(`
2
+ `).filter(Boolean),o=p("git diff --cached --name-only --diff-filter=D",{encoding:"utf8"}),s=new Set(o.trim().split(`
3
+ `).filter(Boolean));return t.filter(i=>!s.has(i))}catch{return[]}}async function v(t,o=["**/*"],s=["node_modules/**","dist/**","build/**",".git/**"]){try{return await S(o,{cwd:t,ignore:s,onlyFiles:!0,dot:!1,absolute:!1})}catch(i){return e.warn("Failed to scan project files:",i),[]}}async function q(t=process.cwd(),o){const{config:s}=await h({cwd:t,overrides:o?{lint:{staged:o}}:void 0}),i=s.lint?.staged||{},c=j();if(c.length===0)return e.info("No staged files to lint"),!0;if(Object.keys(i).length===0)return e.warn("No staged lint configuration found"),!0;let n=!1;const r=new Set;for(const[f,u]of Object.entries(i)){const a=c.filter(l=>!r.has(l)&&N.isMatch(l.split("/").pop()||l,f));if(a.length!==0){e.start(`Linting ${a.length} files: ${f}`);try{const l=`${u} ${a.join(" ")}`;p(l,{stdio:"inherit",cwd:t});const g=[];for(const d of a)await k(w(t,d))&&g.push(d);g.length>0&&p(`git add ${g.join(" ")}`,{stdio:"inherit",cwd:t}),a.forEach(d=>r.add(d)),e.success(`${f}`)}catch(l){n=!0,e.error(`${f} failed:`,l)}}}return!n}async function E(t=process.cwd(),o){const{config:s}=await h({cwd:t,overrides:o?{lint:{project:o}}:void 0}),i=s.lint?.project||{};if(Object.keys(i).length===0)return e.warn("No project lint configuration found"),!0;e.start("Running project-wide linting...");let c=!1;for(const[n,r]of Object.entries(i)){e.start(`Running project lint: ${n}`);try{p(r,{stdio:"inherit",cwd:t}),e.success(`${n}`)}catch(f){c=!0,e.error(`${n} failed:`,f)}}return!c}async function A(t=process.cwd(),o){const{config:s}=await h({cwd:t,overrides:o?{lint:{dependencies:o}}:void 0}),i=s.lint?.dependencies||{};let c=!1;try{const n=await P(t),r={...n.dependencies,...n.devDependencies},f=(await O(t))?.name||"npm",u=C(f);if(e.start("Checking dependencies..."),i.blockedPackages&&i.blockedPackages.length>0){const a=Object.keys(r).filter(l=>i.blockedPackages?.includes(l));a.length>0?(e.error(`Blocked packages found: ${a.join(", ")}`),c=!0):e.success("No blocked packages found")}if(i.checkOutdated)try{p(u.outdated,{cwd:t,stdio:"pipe"}),e.success("All dependencies are up to date")}catch(a){e.warn("\u26A0 Some dependencies are outdated:",a)}if(i.checkSecurity)try{p(u.audit,{cwd:t,stdio:"pipe"}),e.success("No security vulnerabilities found")}catch(a){e.error("Security vulnerabilities detected:",a),c=!0}i.allowedLicenses&&i.allowedLicenses.length>0&&e.info("\u{1F4DD} License checking requires manual review or additional tooling")}catch(n){e.error("Failed to check dependencies:",n),c=!0}return!c}async function R(t=process.cwd(),o){const{config:s}=await h({cwd:t,overrides:o?{lint:{structure:o}}:void 0}),i=s.lint?.structure||{};let c=!1;if(e.start("Checking project structure..."),i.requiredFiles)for(const n of i.requiredFiles){const r=w(t,n);await k(r)?e.success(`Required file found: ${n}`):(e.error(`Required file missing: ${n}`),c=!0)}if(i.requiredDirs)for(const n of i.requiredDirs){const r=w(t,n);await k(r)?e.success(`Required directory found: ${n}`):(e.error(`Required directory missing: ${n}`),c=!0)}if(i.naming&&i.naming.length>0)for(const n of i.naming){const{path:r,files:f,directories:u,description:a}=n;e.start(`Checking naming rule: ${a||r}`);const l=await v(t,[r]);if(f){const g=new RegExp(f),d=l.filter(y=>{const m=y.split("/").pop()||"";return!g.test(m)});d.length>0?(e.error(`Files with invalid naming in ${r}: ${d.slice(0,3).join(", ")}${d.length>3?"...":""}`),c=!0):l.length>0&&e.success(`All files in ${r} follow naming convention`)}if(u){const g=new RegExp(u),d=new Set;l.forEach(m=>{const $=m.split("/");$.pop(),$.forEach(D=>d.add(D))});const y=Array.from(d).filter(m=>!g.test(m));y.length>0?(e.error(`Directories with invalid naming in ${r}: ${y.slice(0,3).join(", ")}`),c=!0):d.size>0&&e.success(`All directories in ${r} follow naming convention`)}}return!c}async function b(t=process.cwd(),o){const{config:s}=await h({cwd:t,overrides:o?{lint:{docs:o}}:void 0}),i=s.lint?.docs||{};let c=!1;if(e.start("Checking documentation..."),i.checkReadme!==!1){const n=["README.md","README.rst","README.txt","readme.md"];(await Promise.all(n.map(r=>k(w(t,r))))).some(r=>r)?e.success("README file found"):(e.error("No README file found"),c=!0)}if(i.checkChangelog){const n=["CHANGELOG.md","CHANGELOG.rst","HISTORY.md","changelog.md"];(await Promise.all(n.map(r=>k(w(t,r))))).some(r=>r)?e.success("CHANGELOG file found"):(e.error("No CHANGELOG file found"),c=!0)}return!c}async function F(t=process.cwd()){const{config:o}=await h({cwd:t}),s=o.lint||{};e.start("Running comprehensive project lint...");const i=(await Promise.allSettled([E(t,s.project),A(t,s.dependencies),R(t,s.structure),b(t,s.docs)])).filter(c=>c.status==="rejected"||c.status==="fulfilled"&&!c.value);return i.length===0?(e.success("All lint checks passed!"),!0):(e.error(`${i.length} lint check(s) failed`),!1)}export{E as a,A as b,R as c,b as d,F as e,v as f,j as g,q as l};
@@ -0,0 +1,10 @@
1
+ import{execSync as p}from"node:child_process";import{readFile as G,unlink as k,writeFile as v,copyFile as I}from"node:fs/promises";import{updateConfig as x}from"c12/update";import{consola as s}from"consola";import{defu as M}from"defu";import b from"ini";import{resolve as l}from"pathe";import{l as d,f as g}from"./basis.CkZpidFZ.mjs";async function $(i,o=!1,r=!1){try{return await x({cwd:i,configFile:"basis.config",onUpdate:t=>{t.git&&(o&&t.git.hooks&&(delete t.git.hooks,s.success("Removed hooks configuration from basis.config.ts")),r&&t.git.config&&(delete t.git.config,s.success("Removed git config from basis.config.ts")),Object.keys(t.git).length===0&&(delete t.git,s.success("Removed empty git section from basis.config.ts")))}}),!0}catch{return!1}}const S=["feat","fix","docs","style","refactor","perf","test","build","ci","chore","revert"];function F(i){const o=i.trim().split(`
2
+ `),r=o[0].match(/^(\w+)(\(([^)]+)\))?(!)?:\s*(.+)$/);if(!r)return null;const[,t,,e,c,n]=r,a=o.slice(1).find(u=>u.trim())?.trim(),f=o.slice(-1)[0]?.trim();return{type:t,scope:e,description:n,body:a,footer:f,isBreaking:!!c||i.includes("BREAKING CHANGE:")}}function j(i,o={}){const r=[],{types:t=S,maxLength:e=72,minLength:c=10,scopeRequired:n=!1,allowedScopes:a=[]}=o,f=F(i);if(!f)return{valid:!1,errors:["Invalid commit format. Expected: type(scope): description"]};t.includes(f.type)||r.push(`Invalid type '${f.type}'. Allowed: ${t.join(", ")}`);const u=i.split(`
3
+ `)[0];return u.length>e&&r.push(`Header too long (${u.length}). Max: ${e}`),u.length<c&&r.push(`Header too short (${u.length}). Min: ${c}`),n&&!f.scope&&r.push("Scope is required"),f.scope&&a.length>0&&!a.includes(f.scope)&&r.push(`Invalid scope '${f.scope}'. Allowed: ${a.join(", ")}`),{valid:r.length===0,errors:r}}async function E(i=process.cwd(),o){const{config:r}=await d({cwd:i,overrides:o?{git:{commitMsg:o}}:void 0}),t=r.git?.commitMsg||{};let e;try{const n=l(".git/COMMIT_EDITMSG");await g(n)?e=(await G(n)).toString("utf8"):e=p("git log -1 --pretty=%B",{encoding:"utf8"}).trim()}catch(n){return s.error("Failed to read commit message:",n),!1}const c=j(e,t);return c.valid?(s.success("Commit message is valid"),!0):(s.error("Invalid commit message:"),c.errors.forEach(n=>s.error(` ${n}`)),!1)}async function C(i){const o=l(i,".git/config");if(!await g(o))return null;const r=new Date().toISOString().replace(/[:.]/g,"-"),t=l(i,`.git/config.backup.${r}`);try{return await I(o,t),s.info(`\u{1F4C4} Created backup: ${t}`),t}catch(e){return s.warn("Failed to create Git config backup:",e),null}}async function m(i=process.cwd()){const o=l(i,".git/config");if(!await g(o))return s.info("No .git/config found, will create new one"),{};try{const r=await G(o,"utf8"),t=b.parse(r);return s.success(`Read existing Git configuration from ${o}`),t}catch(r){return s.warn("Failed to read .git/config:",r),{}}}async function w(i,o=process.cwd()){const r=l(o,".git/config");try{let t=b.stringify(i,{whitespace:!0});t=t.split(`
4
+ `).map(e=>e&&!e.startsWith("[")&&e.includes("=")?` ${e}`:e).join(`
5
+ `),await v(r,t,"utf8"),s.success(`Git configuration written to ${r}`)}catch(t){throw s.error("Failed to write .git/config:",t),t}}function R(i,o){if(!o)return!0;for(const[r,t]of Object.entries(o)){if(typeof t!="object"||!t)continue;const e=i[r];if(!e||typeof e!="object")return!1;for(const[c,n]of Object.entries(t))if(n!==void 0&&e[c]!==n)return!1}return!0}async function h(i=process.cwd(),o){const{config:r}=await d({cwd:i,overrides:o?{git:{config:o}}:void 0}),t=r.git?.config||{};if(Object.keys(t).length===0)return s.info("No Git configuration settings to apply"),!0;try{const e=await m(i);if(R(e,t))return s.success("Git configuration is already up to date"),!0;const c=await C(i),n=M(e,t);return await w(n,i),s.success("Git configuration setup completed"),c&&s.info(`\u{1F4BE} Original config backed up to: ${c.split("/").pop()}`),!0}catch(e){return s.error("Failed to setup Git configuration:",e),!1}}async function B(i=process.cwd(),o=!0,r={}){try{const t=await C(i),e=await m(i);if(!e||Object.keys(e).length===0)return s.info("No Git configuration found to reset"),!0;const c={};if(o&&e.user&&(c.user=e.user,s.info("\u{1F512} Keeping user configuration (name, email)")),e.core){const n=["repositoryformatversion","filemode","bare","logallrefupdates"],a={};n.forEach(f=>{e.core[f]!==void 0&&(a[f]=e.core[f])}),Object.keys(a).length>0&&(c.core=a,s.info("\u{1F512} Keeping essential core Git settings"))}return await w(c,i),s.success("Git configuration reset completed"),t&&s.info(`\u{1F4BE} Original config backed up to: ${t.split("/").pop()}`),r.updateConfig?await $(i,!1,!0):!0}catch(t){return s.error("Failed to reset Git configuration:",t),!1}}async function y(i=process.cwd(),o){const{config:r}=await d({cwd:i,overrides:o?{git:{hooks:o}}:void 0}),t=r.git?.hooks||{},e=l(i,".git/hooks");if(!await g(e))return s.error("Git hooks directory not found. Is this a Git repository?"),!1;let c=!0;for(const[n,a]of Object.entries(t)){const f=l(e,n);try{let u=`#!/bin/sh
6
+
7
+ `;if(typeof a=="string")u+=`${a}
8
+ `;else if(a&&typeof a=="object"&&"commands"in a){const O=a.commands;u+=`${O.join(`
9
+ `)}
10
+ `}await v(f,u,{mode:493}),s.success(`Setup ${n} hook`)}catch(u){s.error(`Failed to setup ${n} hook:`,u),c=!1}}return c}async function H(i=process.cwd()){try{try{p("git rev-parse --git-dir",{cwd:i,stdio:"pipe"}),s.info("Git repository already exists")}catch{p("git init",{cwd:i,stdio:"inherit"}),s.success("Initialized Git repository")}const o=await h(i),r=await y(i);return o&&r}catch(o){return s.error("Failed to initialize Git repository:",o),!1}}async function N(i=process.cwd()){const{config:o}=await d({cwd:i}),r=o.git||{};s.start("Setting up Git configuration...");const t=(await Promise.allSettled([h(i,r.config),y(i,r.hooks)])).filter(e=>e.status==="rejected"||e.status==="fulfilled"&&!e.value);return t.length===0?(s.success("Git setup completed successfully!"),!0):(s.error(`${t.length} Git setup step(s) failed`),!1)}async function A(i=process.cwd(),o,r={}){const t=l(i,".git/hooks");if(!await g(t))return s.warn("Git hooks directory not found. Is this a Git repository?"),!0;let e=!0;if(o&&o.length>0)for(const c of o){const n=l(t,c);if(await g(n))try{await k(n),s.success(`Removed ${c} hook`)}catch(a){s.error(`Failed to remove ${c} hook:`,a),e=!1}}else{const{config:c}=await d({cwd:i}),n=c.git?.hooks||{};for(const a of Object.keys(n)){const f=l(t,a);if(await g(f))try{await k(f),s.success(`Removed ${a} hook`)}catch(u){s.error(`Failed to remove ${a} hook:`,u),e=!1}}if(r.updateConfig){const a=await $(i,!0,!1);e=e&&a}}return e}export{h as a,N as b,B as c,m as d,H as i,E as l,F as p,A as r,y as s,j as v,w};
@@ -0,0 +1 @@
1
+ import{execSync as d}from"node:child_process";import{consola as a}from"consola";import{detectPackageManager as y,runScript as p}from"nypm";import{readPackageJSON as $}from"pkg-types";import h from"semver";import{l as b}from"./basis.CkZpidFZ.mjs";async function k(e,t,n){if(t.checkGitClean&&!n.skipTests)try{if(d("git status --porcelain",{cwd:e,encoding:"utf8"}).trim())throw new Error("Working directory is not clean. Commit your changes first.")}catch(i){a.warn("Could not check git status:",i)}if(t.checkTests&&!n.skipTests){a.start("Running tests...");try{t.testCommand?d(t.testCommand,{cwd:e,stdio:"inherit"}):await p("test",{cwd:e,silent:!1}),a.success("Tests passed")}catch(i){throw a.error("Tests failed"),i}}if(t.buildCommand&&!n.skipBuild){a.start("Building package...");try{t.buildCommand.includes(" ")?d(t.buildCommand,{cwd:e,stdio:"inherit"}):await p(t.buildCommand,{cwd:e,silent:!1}),a.success("Build completed")}catch(i){throw a.error("Build failed"),i}}}async function C(e,t){if(t.autoGitPush)try{d("git push",{cwd:e}),t.createGitTag&&d("git push --tags",{cwd:e}),a.success("Pushed changes to remote")}catch(n){a.warn("Failed to push changes:",n)}}async function T(e,t={}){const{config:n}=await b({cwd:e}),i=n.publish||{},f=await $(e),{name:o,version:r}=f;if(!o||!r)throw new Error("Missing name or version in package.json");if(!h.valid(r))throw new Error(`Invalid version format in package.json: ${r}`);const m=await y(e),u=m?.command||"npm";await k(e,i,t);let c;if(t.tag)c=t.tag;else if(t.stable||t.latest)c=i.stableTag||"latest";else if(h.prerelease(r)){const s=h.prerelease(r);c=s&&s[0]||i.defaultTag||"edge"}else c=i.stableTag||"latest";a.info(`Publishing ${o}@${r} to tag: ${c}`);const g=["publish","--tag",c,"--access",t.access||i.access||"public"];(t.registry||i.registry)&&g.push("--registry",t.registry||i.registry||""),t.dryRun&&g.push("--dry-run");const w=`${u} ${g.join(" ")}`;a.start("Publishing package...");try{if(d(w,{cwd:e,stdio:"inherit"}),t.dryRun)a.success("Dry run completed successfully");else{a.success(`Published ${o}@${r} to ${c}`);const s=i.defaultTag||"edge";if(c!==s){a.start(`Also publishing to ${s} tag...`);try{let l;m?.name==="yarn"?l=`${u} tag add ${o}@${r} ${s}`:l=`${u} dist-tag add ${o}@${r} ${s}`,d(l,{cwd:e,stdio:"inherit"}),a.success(`Also published ${o}@${r} to ${s}`)}catch(l){a.warn(`Failed to add ${s} tag:`,l)}}await C(e,i)}return{packageName:o,version:r,publishTag:c,dryRun:t.dryRun||!1}}catch(s){throw a.error("Failed to publish package:",s),s}}export{T as p};
@@ -0,0 +1,10 @@
1
+ "use strict";const node_child_process=require("node:child_process"),promises=require("node:fs/promises"),update=require("c12/update"),consola=require("consola"),defu=require("defu"),k=require("ini"),pathe=require("pathe"),utils=require("./basis.BJhSbOyA.cjs");function _interopDefaultCompat(t){return t&&typeof t=="object"&&"default"in t?t.default:t}const k__default=_interopDefaultCompat(k);async function G(t,i=!1,s=!1){try{return await update.updateConfig({cwd:t,configFile:"basis.config",onUpdate:e=>{e.git&&(i&&e.git.hooks&&(delete e.git.hooks,consola.consola.success("Removed hooks configuration from basis.config.ts")),s&&e.git.config&&(delete e.git.config,consola.consola.success("Removed git config from basis.config.ts")),Object.keys(e.git).length===0&&(delete e.git,consola.consola.success("Removed empty git section from basis.config.ts")))}}),!0}catch{return!1}}const P=["feat","fix","docs","style","refactor","perf","test","build","ci","chore","revert"];function parseCommitMessage(t){const i=t.trim().split(`
2
+ `),s=i[0].match(/^(\w+)(\(([^)]+)\))?(!)?:\s*(.+)$/);if(!s)return null;const[,e,,o,c,n]=s,r=i.slice(1).find(l=>l.trim())?.trim(),a=i.slice(-1)[0]?.trim();return{type:e,scope:o,description:n,body:r,footer:a,isBreaking:!!c||t.includes("BREAKING CHANGE:")}}function validateCommitMessage(t,i={}){const s=[],{types:e=P,maxLength:o=72,minLength:c=10,scopeRequired:n=!1,allowedScopes:r=[]}=i,a=parseCommitMessage(t);if(!a)return{valid:!1,errors:["Invalid commit format. Expected: type(scope): description"]};e.includes(a.type)||s.push(`Invalid type '${a.type}'. Allowed: ${e.join(", ")}`);const l=t.split(`
3
+ `)[0];return l.length>o&&s.push(`Header too long (${l.length}). Max: ${o}`),l.length<c&&s.push(`Header too short (${l.length}). Min: ${c}`),n&&!a.scope&&s.push("Scope is required"),a.scope&&r.length>0&&!r.includes(a.scope)&&s.push(`Invalid scope '${a.scope}'. Allowed: ${r.join(", ")}`),{valid:s.length===0,errors:s}}async function lintCommitMessage(t=process.cwd(),i){const{config:s}=await utils.loadConfig({cwd:t,overrides:i?{git:{commitMsg:i}}:void 0}),e=s.git?.commitMsg||{};let o;try{const n=pathe.resolve(".git/COMMIT_EDITMSG");await utils.fileExists(n)?o=(await promises.readFile(n)).toString("utf8"):o=node_child_process.execSync("git log -1 --pretty=%B",{encoding:"utf8"}).trim()}catch(n){return consola.consola.error("Failed to read commit message:",n),!1}const c=validateCommitMessage(o,e);return c.valid?(consola.consola.success("Commit message is valid"),!0):(consola.consola.error("Invalid commit message:"),c.errors.forEach(n=>consola.consola.error(` ${n}`)),!1)}async function b(t){const i=pathe.resolve(t,".git/config");if(!await utils.fileExists(i))return null;const s=new Date().toISOString().replace(/[:.]/g,"-"),e=pathe.resolve(t,`.git/config.backup.${s}`);try{return await promises.copyFile(i,e),consola.consola.info(`\u{1F4C4} Created backup: ${e}`),e}catch(o){return consola.consola.warn("Failed to create Git config backup:",o),null}}async function readGitConfig(t=process.cwd()){const i=pathe.resolve(t,".git/config");if(!await utils.fileExists(i))return consola.consola.info("No .git/config found, will create new one"),{};try{const s=await promises.readFile(i,"utf8"),e=k__default.parse(s);return consola.consola.success(`Read existing Git configuration from ${i}`),e}catch(s){return consola.consola.warn("Failed to read .git/config:",s),{}}}async function writeGitConfig(t,i=process.cwd()){const s=pathe.resolve(i,".git/config");try{let e=k__default.stringify(t,{whitespace:!0});e=e.split(`
4
+ `).map(o=>o&&!o.startsWith("[")&&o.includes("=")?` ${o}`:o).join(`
5
+ `),await promises.writeFile(s,e,"utf8"),consola.consola.success(`Git configuration written to ${s}`)}catch(e){throw consola.consola.error("Failed to write .git/config:",e),e}}function x(t,i){if(!i)return!0;for(const[s,e]of Object.entries(i)){if(typeof e!="object"||!e)continue;const o=t[s];if(!o||typeof o!="object")return!1;for(const[c,n]of Object.entries(e))if(n!==void 0&&o[c]!==n)return!1}return!0}async function setupGitConfig(t=process.cwd(),i){const{config:s}=await utils.loadConfig({cwd:t,overrides:i?{git:{config:i}}:void 0}),e=s.git?.config||{};if(Object.keys(e).length===0)return consola.consola.info("No Git configuration settings to apply"),!0;try{const o=await readGitConfig(t);if(x(o,e))return consola.consola.success("Git configuration is already up to date"),!0;const c=await b(t),n=defu.defu(o,e);return await writeGitConfig(n,t),consola.consola.success("Git configuration setup completed"),c&&consola.consola.info(`\u{1F4BE} Original config backed up to: ${c.split("/").pop()}`),!0}catch(o){return consola.consola.error("Failed to setup Git configuration:",o),!1}}async function resetGitConfig(t=process.cwd(),i=!0,s={}){try{const e=await b(t),o=await readGitConfig(t);if(!o||Object.keys(o).length===0)return consola.consola.info("No Git configuration found to reset"),!0;const c={};if(i&&o.user&&(c.user=o.user,consola.consola.info("\u{1F512} Keeping user configuration (name, email)")),o.core){const n=["repositoryformatversion","filemode","bare","logallrefupdates"],r={};n.forEach(a=>{o.core[a]!==void 0&&(r[a]=o.core[a])}),Object.keys(r).length>0&&(c.core=r,consola.consola.info("\u{1F512} Keeping essential core Git settings"))}return await writeGitConfig(c,t),consola.consola.success("Git configuration reset completed"),e&&consola.consola.info(`\u{1F4BE} Original config backed up to: ${e.split("/").pop()}`),s.updateConfig?await G(t,!1,!0):!0}catch(e){return consola.consola.error("Failed to reset Git configuration:",e),!1}}async function setupGitHooks(t=process.cwd(),i){const{config:s}=await utils.loadConfig({cwd:t,overrides:i?{git:{hooks:i}}:void 0}),e=s.git?.hooks||{},o=pathe.resolve(t,".git/hooks");if(!await utils.fileExists(o))return consola.consola.error("Git hooks directory not found. Is this a Git repository?"),!1;let c=!0;for(const[n,r]of Object.entries(e)){const a=pathe.resolve(o,n);try{let l=`#!/bin/sh
6
+
7
+ `;if(typeof r=="string")l+=`${r}
8
+ `;else if(r&&typeof r=="object"&&"commands"in r){const f=r.commands;l+=`${f.join(`
9
+ `)}
10
+ `}await promises.writeFile(a,l,{mode:493}),consola.consola.success(`Setup ${n} hook`)}catch(l){consola.consola.error(`Failed to setup ${n} hook:`,l),c=!1}}return c}async function initGitRepo(t=process.cwd()){try{try{node_child_process.execSync("git rev-parse --git-dir",{cwd:t,stdio:"pipe"}),consola.consola.info("Git repository already exists")}catch{node_child_process.execSync("git init",{cwd:t,stdio:"inherit"}),consola.consola.success("Initialized Git repository")}const i=await setupGitConfig(t),s=await setupGitHooks(t);return i&&s}catch(i){return consola.consola.error("Failed to initialize Git repository:",i),!1}}async function setupGit(t=process.cwd()){const{config:i}=await utils.loadConfig({cwd:t}),s=i.git||{};consola.consola.start("Setting up Git configuration...");const e=(await Promise.allSettled([setupGitConfig(t,s.config),setupGitHooks(t,s.hooks)])).filter(o=>o.status==="rejected"||o.status==="fulfilled"&&!o.value);return e.length===0?(consola.consola.success("Git setup completed successfully!"),!0):(consola.consola.error(`${e.length} Git setup step(s) failed`),!1)}async function removeGitHooks(t=process.cwd(),i,s={}){const e=pathe.resolve(t,".git/hooks");if(!await utils.fileExists(e))return consola.consola.warn("Git hooks directory not found. Is this a Git repository?"),!0;let o=!0;if(i&&i.length>0)for(const c of i){const n=pathe.resolve(e,c);if(await utils.fileExists(n))try{await promises.unlink(n),consola.consola.success(`Removed ${c} hook`)}catch(r){consola.consola.error(`Failed to remove ${c} hook:`,r),o=!1}}else{const{config:c}=await utils.loadConfig({cwd:t}),n=c.git?.hooks||{};for(const r of Object.keys(n)){const a=pathe.resolve(e,r);if(await utils.fileExists(a))try{await promises.unlink(a),consola.consola.success(`Removed ${r} hook`)}catch(l){consola.consola.error(`Failed to remove ${r} hook:`,l),o=!1}}if(s.updateConfig){const r=await G(t,!0,!1);o=o&&r}}return o}exports.initGitRepo=initGitRepo,exports.lintCommitMessage=lintCommitMessage,exports.parseCommitMessage=parseCommitMessage,exports.readGitConfig=readGitConfig,exports.removeGitHooks=removeGitHooks,exports.resetGitConfig=resetGitConfig,exports.setupGit=setupGit,exports.setupGitConfig=setupGitConfig,exports.setupGitHooks=setupGitHooks,exports.validateCommitMessage=validateCommitMessage,exports.writeGitConfig=writeGitConfig;
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@funish/basis",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A unified development toolkit with CLI for package management, versioning, publishing, linting, and git hooks management for JavaScript/TypeScript projects.",
5
5
  "main": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
- "dist",
9
- "templates"
8
+ "dist"
10
9
  ],
11
10
  "bin": {
12
11
  "basis": "dist/cli.mjs"
@@ -61,6 +60,10 @@
61
60
  "c12": "3.0.4",
62
61
  "citty": "0.1.6",
63
62
  "consola": "3.4.2",
63
+ "defu": "6.1.4",
64
+ "fast-glob": "3.3.3",
65
+ "ini": "5.0.0",
66
+ "magicast": "0.3.5",
64
67
  "micromatch": "4.0.8",
65
68
  "nypm": "0.6.0",
66
69
  "pathe": "2.0.3",
@@ -68,6 +71,7 @@
68
71
  "semver": "7.7.2"
69
72
  },
70
73
  "devDependencies": {
74
+ "@types/ini": "4.1.1",
71
75
  "@types/micromatch": "4.0.9",
72
76
  "@types/semver": "7.7.0"
73
77
  },
@@ -1 +0,0 @@
1
- "use strict";const citty=require("citty"),consola=require("consola"),githooks$1=require("../shared/basis.DeKfEQsQ.cjs");require("node:child_process"),require("node:fs/promises"),require("pathe"),require("../shared/basis.CSSuyvpq.cjs"),require("c12"),require("../config.cjs");const githooks=citty.defineCommand({meta:{name:"hooks",description:"Manage git hooks"},subCommands:{install:citty.defineCommand({meta:{name:"install",description:"Install git hooks"},args:{"auto-init-git":{type:"boolean",description:"Automatically initialize git repository if not found"},"skip-git-check":{type:"boolean",description:"Skip git command availability check"},force:{type:"boolean",alias:"f",description:"Force operation even if git is not available"}},async run({args:i}){try{let o;(i["auto-init-git"]!==void 0||i["skip-git-check"]!==void 0||i.force!==void 0)&&(o={},i["auto-init-git"]!==void 0&&(o.autoInitGit=!!i["auto-init-git"]),i["skip-git-check"]!==void 0&&(o.skipGitCheck=!!i["skip-git-check"]),i.force!==void 0&&(o.force=!!i.force)),await githooks$1.installHooks(process.cwd(),o)}catch(o){consola.consola.error("Failed to install hooks:",o),process.exit(1)}}}),uninstall:citty.defineCommand({meta:{name:"uninstall",description:"Uninstall git hooks"},args:{"skip-git-check":{type:"boolean",description:"Skip git command availability check"},force:{type:"boolean",alias:"f",description:"Force operation even if git is not available"}},async run({args:i}){try{let o;(i["skip-git-check"]!==void 0||i.force!==void 0)&&(o={},i["skip-git-check"]!==void 0&&(o.skipGitCheck=!!i["skip-git-check"]),i.force!==void 0&&(o.force=!!i.force)),await githooks$1.uninstallHooks(process.cwd(),o)}catch(o){consola.consola.error("Failed to uninstall hooks:",o),process.exit(1)}}}),list:citty.defineCommand({meta:{name:"list",description:"List configured hooks"},async run(){await githooks$1.listHooks()}})}});exports.default=githooks;
@@ -1 +0,0 @@
1
- import{defineCommand as t}from"citty";import{consola as e}from"consola";import{l as a,u as s,i as c}from"../shared/basis.O4so-uuj.mjs";import"node:child_process";import"node:fs/promises";import"pathe";import"../shared/basis.C0E7mwQ6.mjs";import"c12";import"../config.mjs";const n=t({meta:{name:"hooks",description:"Manage git hooks"},subCommands:{install:t({meta:{name:"install",description:"Install git hooks"},args:{"auto-init-git":{type:"boolean",description:"Automatically initialize git repository if not found"},"skip-git-check":{type:"boolean",description:"Skip git command availability check"},force:{type:"boolean",alias:"f",description:"Force operation even if git is not available"}},async run({args:i}){try{let o;(i["auto-init-git"]!==void 0||i["skip-git-check"]!==void 0||i.force!==void 0)&&(o={},i["auto-init-git"]!==void 0&&(o.autoInitGit=!!i["auto-init-git"]),i["skip-git-check"]!==void 0&&(o.skipGitCheck=!!i["skip-git-check"]),i.force!==void 0&&(o.force=!!i.force)),await c(process.cwd(),o)}catch(o){e.error("Failed to install hooks:",o),process.exit(1)}}}),uninstall:t({meta:{name:"uninstall",description:"Uninstall git hooks"},args:{"skip-git-check":{type:"boolean",description:"Skip git command availability check"},force:{type:"boolean",alias:"f",description:"Force operation even if git is not available"}},async run({args:i}){try{let o;(i["skip-git-check"]!==void 0||i.force!==void 0)&&(o={},i["skip-git-check"]!==void 0&&(o.skipGitCheck=!!i["skip-git-check"]),i.force!==void 0&&(o.force=!!i.force)),await s(process.cwd(),o)}catch(o){e.error("Failed to uninstall hooks:",o),process.exit(1)}}}),list:t({meta:{name:"list",description:"List configured hooks"},async run(){await a()}})}});export{n as default};