airyhooks 0.3.0 → 0.4.0
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 +8 -8
- package/dist/commands/add.js +35 -8
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/entry.js +12 -3
- package/dist/commands/entry.js.map +1 -1
- package/dist/commands/init.js +14 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/index.js +25 -7
- package/dist/index.js.map +1 -1
- package/dist/utils/config.js +31 -2
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/hook-templates.js +1135 -0
- package/dist/utils/hook-templates.js.map +1 -1
- package/dist/utils/parse-command-options.js +15 -0
- package/dist/utils/parse-command-options.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Add production-ready zero-dependency React hooks without package installation di
|
|
|
10
10
|
pnpm dlx airyhooks
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Quick Start
|
|
14
14
|
|
|
15
15
|
### 1. Initialize
|
|
16
16
|
|
|
@@ -20,10 +20,10 @@ Create the configuration file and set your hooks directory:
|
|
|
20
20
|
pnpm dlx airyhooks init
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
This creates `airyhooks.json` in your project root and prompts you for the hooks directory path (default:
|
|
23
|
+
This creates `airyhooks.json` in your project root and prompts you for the hooks directory path (default: `src/hooks`).
|
|
24
24
|
|
|
25
25
|
> [!NOTE]
|
|
26
|
-
> You can use `airyhooks` without initialization. It will use the [default configuration](
|
|
26
|
+
> You can use `airyhooks` without initialization. It will use the [default configuration](#configuration).
|
|
27
27
|
|
|
28
28
|
### 2. Start Adding Hooks
|
|
29
29
|
|
|
@@ -68,7 +68,7 @@ export function SearchComponent() {
|
|
|
68
68
|
}
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
##
|
|
71
|
+
## Available Hooks
|
|
72
72
|
|
|
73
73
|
| Hook | Description |
|
|
74
74
|
| ------------------------- | ------------------------------------------------------- |
|
|
@@ -100,7 +100,7 @@ export function SearchComponent() {
|
|
|
100
100
|
| `useUnmount` | Call a callback on component unmount |
|
|
101
101
|
| `useWindowSize` | Track window dimensions |
|
|
102
102
|
|
|
103
|
-
##
|
|
103
|
+
## Commands
|
|
104
104
|
|
|
105
105
|
### `airyhooks init`
|
|
106
106
|
|
|
@@ -149,7 +149,7 @@ List all available hooks with descriptions.
|
|
|
149
149
|
pnpm dlx airyhooks list
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
-
##
|
|
152
|
+
## Usage Example
|
|
153
153
|
|
|
154
154
|
Here's a complete example using `useDebounce` for a search input:
|
|
155
155
|
|
|
@@ -174,7 +174,7 @@ export function App() {
|
|
|
174
174
|
}
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
##
|
|
177
|
+
## Configuration
|
|
178
178
|
|
|
179
179
|
The `airyhooks.json` file stores your configuration:
|
|
180
180
|
|
|
@@ -278,7 +278,7 @@ You can enable this by setting it in `airyhooks.json`:
|
|
|
278
278
|
|
|
279
279
|
You can also override this per-command with the CLI flag: `airyhooks add <hook-name> --include-tests`.
|
|
280
280
|
|
|
281
|
-
##
|
|
281
|
+
## Package Managers
|
|
282
282
|
|
|
283
283
|
airyhooks works with all major package managers:
|
|
284
284
|
|
package/dist/commands/add.js
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import pc from "picocolors";
|
|
4
|
+
import prompts from "prompts";
|
|
5
|
+
import * as v from "valibot";
|
|
4
6
|
import { getConfig } from "../utils/config.js";
|
|
5
7
|
import { getFileExtension } from "../utils/get-file-extension.js";
|
|
6
8
|
import { getHookFileBaseName } from "../utils/get-hook-filename.js";
|
|
7
9
|
import { getHookTemplate, getHookTestTemplate, } from "../utils/get-hook-template.js";
|
|
10
|
+
import { parseCommandOptions } from "../utils/parse-command-options.js";
|
|
8
11
|
import { registry } from "../utils/registry.js";
|
|
9
|
-
export
|
|
10
|
-
|
|
12
|
+
export const AddOptionsSchema = v.object({
|
|
13
|
+
debug: v.optional(v.boolean()),
|
|
14
|
+
force: v.optional(v.boolean()),
|
|
15
|
+
includeTests: v.optional(v.boolean()),
|
|
16
|
+
kebab: v.optional(v.boolean()),
|
|
17
|
+
path: v.optional(v.string()),
|
|
18
|
+
raw: v.optional(v.boolean()),
|
|
19
|
+
});
|
|
20
|
+
export async function add(hookName, commandOptions = {}) {
|
|
21
|
+
const options = parseCommandOptions(AddOptionsSchema, commandOptions);
|
|
22
|
+
if (commandOptions.debug) {
|
|
23
|
+
console.debug("Parsed command options:");
|
|
24
|
+
console.debug(commandOptions);
|
|
25
|
+
}
|
|
11
26
|
const hook = registry.find((h) => h.name.toLowerCase() === hookName.toLowerCase());
|
|
12
27
|
if (!hook) {
|
|
13
28
|
console.log(pc.red(`✗ Hook "${hookName}" not found.`));
|
|
@@ -15,24 +30,36 @@ export async function add(hookName, options = {}) {
|
|
|
15
30
|
process.exit(1);
|
|
16
31
|
}
|
|
17
32
|
const config = await getConfig({
|
|
18
|
-
...(kebab ? { casing: "kebab-case" } : {}),
|
|
33
|
+
...(options.kebab ? { casing: "kebab-case" } : {}),
|
|
19
34
|
...(options.includeTests ? { includeTests: true } : {}),
|
|
35
|
+
...(options.path ? { hooksPath: options.path } : {}),
|
|
20
36
|
});
|
|
37
|
+
if (commandOptions.debug) {
|
|
38
|
+
console.debug("Resolved configuration:");
|
|
39
|
+
console.debug(config);
|
|
40
|
+
}
|
|
21
41
|
const hooksDir = path.join(process.cwd(), config.hooksPath);
|
|
22
42
|
const casedHookName = getHookFileBaseName(hook.name, config.casing);
|
|
23
43
|
const hookTargetDir = path.join(hooksDir, config.structure === "nested" ? casedHookName : "");
|
|
24
44
|
const template = getHookTemplate(hook.name);
|
|
25
45
|
const testTemplate = getHookTestTemplate(hook.name);
|
|
26
|
-
if (!raw) {
|
|
46
|
+
if (!options.raw) {
|
|
27
47
|
// Ensure hook subdirectory exists
|
|
28
48
|
await fs.ensureDir(hookTargetDir);
|
|
29
49
|
const hookFilePath = path.join(hookTargetDir, `${casedHookName}.ts`);
|
|
30
50
|
const hookTestFilePath = path.join(hookTargetDir, `${casedHookName}.test.ts`);
|
|
31
51
|
// Check if hook already exists
|
|
32
|
-
if (!force && (await fs.pathExists(hookFilePath))) {
|
|
33
|
-
console.log(pc.yellow(`⚠ ${casedHookName} already exists
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
if (!options.force && (await fs.pathExists(hookFilePath))) {
|
|
53
|
+
console.log(pc.yellow(`⚠ ${casedHookName} already exists.`));
|
|
54
|
+
const response = await prompts({
|
|
55
|
+
message: "Overwrite existing hook?",
|
|
56
|
+
name: "overwrite",
|
|
57
|
+
type: "confirm",
|
|
58
|
+
});
|
|
59
|
+
if (!response.overwrite) {
|
|
60
|
+
console.log(pc.dim(`Use "--force" to overwrite existing hooks.`));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
36
63
|
}
|
|
37
64
|
const barrelFilePath = path.join(hookTargetDir, "index.ts");
|
|
38
65
|
const hookImportExtension = getFileExtension(config.importExtension);
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/entry.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
1
2
|
import prompts from "prompts";
|
|
3
|
+
import { getConfigPath } from "../utils/config.js";
|
|
4
|
+
import { parseCommandOptions } from "../utils/parse-command-options.js";
|
|
2
5
|
import { registry } from "../utils/registry.js";
|
|
3
|
-
import { add } from "./add.js";
|
|
4
|
-
export async function entry() {
|
|
6
|
+
import { add, AddOptionsSchema } from "./add.js";
|
|
7
|
+
export async function entry(commandOptions = {}) {
|
|
8
|
+
const options = parseCommandOptions(AddOptionsSchema, commandOptions);
|
|
5
9
|
const response = await prompts({
|
|
6
10
|
choices: registry.map((hook) => ({
|
|
7
11
|
description: hook.description,
|
|
@@ -22,6 +26,11 @@ export async function entry() {
|
|
|
22
26
|
if (!hookName) {
|
|
23
27
|
return;
|
|
24
28
|
}
|
|
25
|
-
|
|
29
|
+
if (!getConfigPath()) {
|
|
30
|
+
console.log(pc.yellow("No airyhooks.json configuration file found. Using default configuration."));
|
|
31
|
+
console.log(pc.dim("It is recommended to create a configuration file. Run `airyhooks init`."));
|
|
32
|
+
console.log("");
|
|
33
|
+
}
|
|
34
|
+
await add(hookName, options);
|
|
26
35
|
}
|
|
27
36
|
//# sourceMappingURL=entry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/commands/entry.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/commands/entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAmB,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,iBAA6B,EAAE;IACzD,MAAM,OAAO,GAAG,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;IAEtE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,KAAK,EAAE,IAAI,CAAC,IAAI;SACjB,CAAC,CAAC;QACH,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,uBAAuB;QAChC,IAAI,EAAE,UAAU;QAChB,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,OAAO;YAClC,OAAO,OAAO,CAAC,OAAO,CACpB,OAAO;iBACJ,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CACjB,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CACzD;iBACA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAClD,CAAC;QACJ,CAAC;QACD,IAAI,EAAE,cAAc;KACrB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAA8B,CAAC;IAEzD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,MAAM,CACP,0EAA0E,CAC3E,CACF,CAAC;QACF,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,GAAG,CACJ,yEAAyE,CAC1E,CACF,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC/B,CAAC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "fs-extra";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import pc from "picocolors";
|
|
4
4
|
import prompts from "prompts";
|
|
5
|
-
import { DEFAULT_CONFIG
|
|
5
|
+
import { DEFAULT_CONFIG } from "../utils/config.js";
|
|
6
6
|
export async function init() {
|
|
7
7
|
const configPath = path.join(process.cwd(), "airyhooks.json");
|
|
8
8
|
if (await fs.pathExists(configPath)) {
|
|
@@ -42,19 +42,28 @@ export async function init() {
|
|
|
42
42
|
name: "casing",
|
|
43
43
|
type: "select",
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
active: "yes",
|
|
47
|
+
inactive: "no",
|
|
48
|
+
initial: DEFAULT_CONFIG.includeTests,
|
|
49
|
+
message: "Would you like to include test files for your hooks?",
|
|
50
|
+
name: "includeTests",
|
|
51
|
+
type: "toggle",
|
|
52
|
+
},
|
|
45
53
|
]);
|
|
46
54
|
const hooksPath = response.hooksPath;
|
|
47
55
|
const casing = response.casing;
|
|
48
|
-
|
|
56
|
+
const includeTests = response.includeTests;
|
|
57
|
+
if (!hooksPath || !casing || includeTests === undefined) {
|
|
49
58
|
console.log(pc.yellow("Initialization cancelled."));
|
|
50
59
|
return;
|
|
51
60
|
}
|
|
52
|
-
const
|
|
53
|
-
...DEFAULT_CONFIG,
|
|
61
|
+
const userConfig = {
|
|
54
62
|
casing,
|
|
55
63
|
hooksPath,
|
|
64
|
+
includeTests,
|
|
56
65
|
};
|
|
57
|
-
await fs.writeJson(configPath,
|
|
66
|
+
await fs.writeJson(configPath, userConfig, { spaces: 2 });
|
|
58
67
|
console.log(pc.green("✓ Created airyhooks.json"));
|
|
59
68
|
console.log(pc.dim(` Hooks will be added to ${hooksPath}`));
|
|
60
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAwB,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAE9D,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;YAC7B,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,2CAA2C;YACpD,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,SAAS;SAChB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B;YACE,OAAO,EAAE,cAAc,CAAC,SAAS;YACjC,OAAO,EAAE,2CAA2C;YACpD,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,MAAM;SACb;QACD;YACE,OAAO,EAAE;gBACP;oBACE,WAAW,EAAE,iDAAiD;oBAC9D,KAAK,EAAE,aAAa;oBACpB,KAAK,EAAE,WAAW;iBACnB;gBACD;oBACE,WAAW,EAAE,kDAAkD;oBAC/D,KAAK,EAAE,cAAc;oBACrB,KAAK,EAAE,YAAY;iBACpB;aACF;YACD,OAAO,EAAE,CAAC;YACV,OAAO,EACL,mFAAmF;YACrF,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;SACf;QACD;YACE,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,cAAc,CAAC,YAAY;YACpC,OAAO,EAAE,sDAAsD;YAC/D,IAAI,EAAE,cAAc;YACpB,IAAI,EAAE,QAAQ;SACf;KACF,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,QAAQ,CAAC,SAEd,CAAC;IACd,MAAM,MAAM,GAAG,QAAQ,CAAC,MAA+C,CAAC;IACxE,MAAM,YAAY,GAAG,QAAQ,CAAC,YAEjB,CAAC;IAEd,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAA6B;QAC3C,MAAM;QACN,SAAS;QACT,YAAY;KACb,CAAC;IAEF,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAE1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,4BAA4B,SAAS,EAAE,CAAC,CAAC,CAAC;AAC/D,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Command } from "commander";
|
|
2
|
+
import { Command, Option } from "commander";
|
|
3
3
|
import packageJson from "../package.json" with { type: "json" };
|
|
4
4
|
import { add } from "./commands/add.js";
|
|
5
5
|
import { entry } from "./commands/entry.js";
|
|
6
6
|
import { init } from "./commands/init.js";
|
|
7
7
|
import { list } from "./commands/list.js";
|
|
8
|
+
const options = {
|
|
9
|
+
debug: new Option("--debug", "Enable debug logging").default(false),
|
|
10
|
+
force: new Option("-f, --force", "Force overwrite if the hook file already exists").default(false),
|
|
11
|
+
includeTests: new Option("--include-tests", "Include test files when adding hooks. Overrides the default setting in config.").default(false),
|
|
12
|
+
kebab: new Option("-k, --kebab", "Use kebab-case for the hook file and directory names. Overrides the default casing in config.").default(false),
|
|
13
|
+
path: new Option("-p, --path <directory>", "Specify the target directory to add hooks into. Overrides the default hooksPath in config."),
|
|
14
|
+
raw: new Option("-r, --raw", "Output only the raw hook template to console").default(false),
|
|
15
|
+
};
|
|
8
16
|
const program = new Command();
|
|
9
17
|
program
|
|
10
18
|
.name("airyhooks")
|
|
11
19
|
.description("Add React hooks to your project")
|
|
12
|
-
.action(entry)
|
|
13
|
-
.alias("search")
|
|
14
20
|
.version(packageJson.version, "-v, --version");
|
|
21
|
+
program // runs when no sub-command is provided
|
|
22
|
+
.command("search", { isDefault: true })
|
|
23
|
+
.description("Add React hooks to your project")
|
|
24
|
+
.addOption(options.debug)
|
|
25
|
+
.addOption(options.force)
|
|
26
|
+
.addOption(options.includeTests)
|
|
27
|
+
.addOption(options.kebab)
|
|
28
|
+
.addOption(options.path)
|
|
29
|
+
.addOption(options.raw)
|
|
30
|
+
.action(entry);
|
|
15
31
|
program
|
|
16
32
|
.command("init")
|
|
17
33
|
.description("Initialize airyhooks configuration")
|
|
@@ -20,10 +36,12 @@ program
|
|
|
20
36
|
.command("add")
|
|
21
37
|
.description("Add a hook to your project")
|
|
22
38
|
.argument("<hook>", "Name of the hook to add (e.g., useDebounce)")
|
|
23
|
-
.
|
|
24
|
-
.
|
|
25
|
-
.
|
|
26
|
-
.
|
|
39
|
+
.addOption(options.debug)
|
|
40
|
+
.addOption(options.force)
|
|
41
|
+
.addOption(options.includeTests)
|
|
42
|
+
.addOption(options.kebab)
|
|
43
|
+
.addOption(options.path)
|
|
44
|
+
.addOption(options.raw)
|
|
27
45
|
.action(add);
|
|
28
46
|
program.command("list").description("List all available hooks").action(list);
|
|
29
47
|
program.parse();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChE,OAAO,EAAE,GAAG,EAAmB,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,MAAM,OAAO,GAAqC;IAChD,KAAK,EAAE,IAAI,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACnE,KAAK,EAAE,IAAI,MAAM,CACf,aAAa,EACb,iDAAiD,CAClD,CAAC,OAAO,CAAC,KAAK,CAAC;IAChB,YAAY,EAAE,IAAI,MAAM,CACtB,iBAAiB,EACjB,gFAAgF,CACjF,CAAC,OAAO,CAAC,KAAK,CAAC;IAChB,KAAK,EAAE,IAAI,MAAM,CACf,aAAa,EACb,+FAA+F,CAChG,CAAC,OAAO,CAAC,KAAK,CAAC;IAChB,IAAI,EAAE,IAAI,MAAM,CACd,wBAAwB,EACxB,4FAA4F,CAC7F;IACD,GAAG,EAAE,IAAI,MAAM,CACb,WAAW,EACX,8CAA8C,CAC/C,CAAC,OAAO,CAAC,KAAK,CAAC;CACR,CAAC;AAEX,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAEjD,OAAO,CAAC,uCAAuC;KAC5C,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACtC,WAAW,CAAC,iCAAiC,CAAC;KAC9C,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;KACxB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;KACxB,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC;KAC/B,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;KACxB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;KACvB,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;KACtB,MAAM,CAAC,KAAK,CAAC,CAAC;AAEjB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,IAAI,CAAC,CAAC;AAEhB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,4BAA4B,CAAC;KACzC,QAAQ,CAAC,QAAQ,EAAE,6CAA6C,CAAC;KACjE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;KACxB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;KACxB,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC;KAC/B,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;KACxB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;KACvB,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;KACtB,MAAM,CAAC,GAAG,CAAC,CAAC;AAEf,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAE7E,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/utils/config.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import * as v from "valibot";
|
|
5
|
+
const configSchema = v.object({
|
|
6
|
+
casing: v.optional(v.picklist(["camelCase", "kebab-case"]), "camelCase"),
|
|
7
|
+
hooksPath: v.optional(v.string(), "src/hooks"),
|
|
8
|
+
importExtension: v.optional(v.picklist(["js", "none", "ts"]), "none"),
|
|
9
|
+
includeTests: v.optional(v.boolean(), false),
|
|
10
|
+
structure: v.optional(v.picklist(["flat", "nested"]), "nested"),
|
|
11
|
+
});
|
|
3
12
|
export const DEFAULT_CONFIG = {
|
|
4
13
|
casing: "camelCase",
|
|
5
14
|
hooksPath: "src/hooks",
|
|
@@ -8,11 +17,31 @@ export const DEFAULT_CONFIG = {
|
|
|
8
17
|
structure: "nested",
|
|
9
18
|
};
|
|
10
19
|
export async function getConfig(overrides) {
|
|
11
|
-
const configPath =
|
|
12
|
-
if (
|
|
20
|
+
const configPath = getConfigPath();
|
|
21
|
+
if (configPath) {
|
|
13
22
|
const userConfig = (await fs.readJson(configPath));
|
|
23
|
+
const parsedUserConfig = v.safeParse(v.optional(configSchema), userConfig);
|
|
24
|
+
if (!parsedUserConfig.success) {
|
|
25
|
+
console.log(pc.red("✗ Invalid airyhooks.json configuration:"));
|
|
26
|
+
parsedUserConfig.issues.forEach((issue) => {
|
|
27
|
+
const path = v.getDotPath(issue) ?? "";
|
|
28
|
+
console.log(pc.red(`- ${path}: ${issue.message}`));
|
|
29
|
+
});
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
14
32
|
return { ...DEFAULT_CONFIG, ...userConfig, ...overrides };
|
|
15
33
|
}
|
|
16
34
|
return { ...DEFAULT_CONFIG, ...overrides };
|
|
17
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the path to the airyhooks.json configuration file if it exists,
|
|
38
|
+
* otherwise returns null.
|
|
39
|
+
*/
|
|
40
|
+
export function getConfigPath() {
|
|
41
|
+
const configPath = path.join(process.cwd(), "airyhooks.json");
|
|
42
|
+
if (!fs.existsSync(configPath)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return configPath;
|
|
46
|
+
}
|
|
18
47
|
//# sourceMappingURL=config.js.map
|
package/dist/utils/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,EAAE,WAAW,CAAC;IACxE,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC;IAC9C,eAAe,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC;IACrE,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC;IAC5C,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC;CAChE,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,cAAc,GAA8B;IACvD,MAAM,EAAE,WAAW;IACnB,SAAS,EAAE,WAAW;IACtB,eAAe,EAAE,MAAM;IACvB,YAAY,EAAE,KAAK;IACnB,SAAS,EAAE,QAAQ;CACpB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,SAAoC;IAEpC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CACnC,UAAU,CACX,CAA6B,CAAC;QAE/B,MAAM,gBAAgB,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC;QAE3E,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAC;YAC/D,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACxC,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,UAAU,EAAE,GAAG,SAAS,EAAE,CAAC;IAC5D,CAAC;IAED,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,SAAS,EAAE,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAE9D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
|