nibs-cli 4.0.0 → 4.1.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 CHANGED
@@ -48,11 +48,22 @@ my-novelai-script/
48
48
  └── package.json # Optional (for your own development dependencies such as prettier formatter)
49
49
  ```
50
50
 
51
- ## Creating a New Project
51
+ ## Usage
52
52
 
53
- ### Quick Start (No Configuration)
53
+ ### Importing an existing project
54
54
 
55
- 1. Use the new command:
55
+ 1. Use the `import` command:
56
+
57
+ ```bash
58
+ nibs import my-script.naiscript
59
+ ```
60
+
61
+ This will create a `my-script/` directory, importing the `project.yaml` and `src/index.ts` from the `.naiscript` file. You can immediately `cd` into that directory and `nibs build`.
62
+
63
+
64
+ ### Creating a New Project
65
+
66
+ 1. Use the `new` command:
56
67
 
57
68
  ```bash
58
69
  nibs new my-script
@@ -113,6 +124,7 @@ config:
113
124
  | `nibs new <directory>` | Create a new project |
114
125
  | `nibs build [directory]` | Build project (default command) |
115
126
  | `nibs watch [directory]` | Watch project and rebuild on changes |
127
+ | `nibs import <file> | Import an existing .naiscript and create a project directory |
116
128
  | `nibs help` | Show help information |
117
129
 
118
130
  ## Writing Scripts with Imports
package/dist/cli.js CHANGED
@@ -9,7 +9,8 @@ const build_1 = require("./commands/build");
9
9
  const new_1 = require("./commands/new");
10
10
  const project_1 = require("./commands/project");
11
11
  const watch_1 = require("./commands/watch");
12
- const fetch_1 = require("./utils/fetch");
12
+ const utils_1 = require("./utils");
13
+ const import_1 = require("./commands/import");
13
14
  // Helpers
14
15
  async function ensureTypesFile(projectPath) {
15
16
  try {
@@ -20,14 +21,14 @@ async function ensureTypesFile(projectPath) {
20
21
  console.log("✓ Using cached NovelAI type definitions");
21
22
  }
22
23
  else {
23
- await (0, fetch_1.fetchExternalTypes)(projectPath);
24
+ await (0, utils_1.fetchExternalTypes)(projectPath);
24
25
  }
25
26
  }
26
27
  catch (err) {
27
- await (0, fetch_1.fetchExternalTypes)(projectPath);
28
+ await (0, utils_1.fetchExternalTypes)(projectPath);
28
29
  }
29
30
  }
30
- commander_1.program.description("NovelAI Script Build System").version("4.0.0");
31
+ commander_1.program.description("NovelAI Script Build System").version("4.1.0");
31
32
  commander_1.program.command("new [directory]").action((directory = ".") => {
32
33
  const projectPath = (0, path_1.resolve)((0, process_1.cwd)(), directory);
33
34
  (0, new_1.createNewProject)(projectPath);
@@ -73,4 +74,22 @@ commander_1.program
73
74
  console.log(`Watch error: ${err.message}`);
74
75
  }
75
76
  });
77
+ commander_1.program
78
+ .command("import <naiscript>")
79
+ .description("Import a naiscript file and initialize a new directory with the decompiled script.")
80
+ .action(async (naiscript) => {
81
+ const filePath = (0, path_1.resolve)((0, process_1.cwd)(), naiscript);
82
+ await (0, promises_1.access)(filePath, promises_1.constants.R_OK).catch(() => {
83
+ console.log(`File ${naiscript} is either not readable or doesn't exist.`);
84
+ (0, process_1.exit)(1);
85
+ });
86
+ if (!naiscript.endsWith(".naiscript")) {
87
+ console.log(`File ${naiscript} is not a '.naiscript' file.`);
88
+ (0, process_1.exit)(1);
89
+ }
90
+ await (0, import_1.importNaiscript)(filePath).catch((err) => {
91
+ console.log(`Error importing ${naiscript}: ${err.message}`);
92
+ (0, process_1.exit)(2);
93
+ });
94
+ });
76
95
  commander_1.program.parse();
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.importNaiscript = importNaiscript;
4
+ const promises_1 = require("fs/promises");
5
+ const posix_1 = require("path/posix");
6
+ const yaml_1 = require("yaml");
7
+ const prettier_1 = require("prettier");
8
+ const utils_1 = require("../utils");
9
+ const FRONTMATTER = /\/\*---\n([\s\S]+)---\*\/([\s\S]+)/;
10
+ async function importNaiscript(filePath) {
11
+ const naiScriptBuf = await (0, promises_1.readFile)(filePath);
12
+ const naiScript = naiScriptBuf.toString();
13
+ const matches = FRONTMATTER.exec(naiScript);
14
+ if (!matches)
15
+ throw new Error("Unable to parse naiscript.");
16
+ const frontMatter = (0, yaml_1.parseDocument)(matches[1]);
17
+ const script = matches[2];
18
+ const formattedScript = await (0, prettier_1.format)(script, { parser: "typescript" });
19
+ const name = frontMatter.get("name");
20
+ const projectDir = (0, posix_1.join)((0, posix_1.dirname)(filePath), kebab(name));
21
+ await (0, promises_1.mkdir)((0, posix_1.join)(projectDir, "src"), { recursive: true });
22
+ await (0, promises_1.writeFile)((0, posix_1.join)(projectDir, "project.yaml"), frontMatter.toString());
23
+ await (0, promises_1.writeFile)((0, posix_1.join)(projectDir, "src", "index.ts"), formattedScript);
24
+ await (0, utils_1.writeTsConfig)(projectDir);
25
+ }
26
+ // Helpers
27
+ function kebab(a) {
28
+ return a.toLocaleLowerCase().replaceAll(/\W/g, "-").replaceAll(/-+/g, "-");
29
+ }
@@ -43,32 +43,11 @@ const inquirer_1 = __importDefault(require("inquirer"));
43
43
  const path_1 = require("path");
44
44
  const yaml_1 = __importStar(require("yaml"));
45
45
  const project_1 = require("./project");
46
+ const utils_1 = require("../utils");
46
47
  // Constants
47
48
  const INDEX_TS_TEMPLATE = `(async () => {
48
49
  api.v1.log("Hello World!");
49
50
  })();`;
50
- const TSCONFIG = {
51
- compilerOptions: {
52
- target: "ES2023",
53
- module: "ESNext",
54
- lib: ["ES2023"],
55
- moduleResolution: "bundler",
56
- strict: true,
57
- esModuleInterop: true,
58
- skipLibCheck: true,
59
- forceConsistentCasingInFileNames: true,
60
- allowSyntheticDefaultImports: true,
61
- noUnusedLocals: true,
62
- noUnusedParameters: true,
63
- noImplicitReturns: true,
64
- noFallthroughCasesInSwitch: true,
65
- noEmit: true,
66
- typeRoots: ["./external", "./node_modules/@types"],
67
- rewriteRelativeImportExtensions: true,
68
- },
69
- include: ["src/**/*", "external/**/*"],
70
- exclude: ["node_modules", "dist", "**/*.test.ts"],
71
- };
72
51
  const COMPAT_VERSION = "naiscript-1.0";
73
52
  // Helpers
74
53
  async function checkExistingProject(projectPath) {
@@ -130,7 +109,7 @@ async function createNewProject(projectPath) {
130
109
  await Promise.all([
131
110
  (0, promises_1.writeFile)((0, path_1.join)(projectPath, "project.yaml"), yaml_1.default.stringify(project.meta), "utf-8"),
132
111
  (0, promises_1.writeFile)((0, path_1.join)(projectPath, "src", "index.ts"), INDEX_TS_TEMPLATE, "utf-8"),
133
- (0, promises_1.writeFile)((0, path_1.join)(projectPath, "tsconfig.json"), JSON.stringify(TSCONFIG), "utf-8"),
112
+ (0, utils_1.writeTsConfig)(projectPath),
134
113
  ]);
135
114
  console.log(`Project initialized at ${projectPath}`);
136
115
  }
package/dist/utils.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchExternalTypes = fetchExternalTypes;
4
+ exports.writeTsConfig = writeTsConfig;
5
+ const fs_1 = require("fs");
6
+ const promises_1 = require("fs/promises");
7
+ const path_1 = require("path");
8
+ const posix_1 = require("path/posix");
9
+ const promises_2 = require("stream/promises");
10
+ const NAI_TYPES_URL = "https://novelai.net/scripting/types/script-types.d.ts";
11
+ async function fetchExternalTypes(projectPath) {
12
+ const outputPath = (0, path_1.join)(projectPath, "external", "script-types.d.ts");
13
+ await (0, promises_1.mkdir)((0, posix_1.dirname)(outputPath), { recursive: true });
14
+ console.log("📥 Fetching NovelAI type definitions...");
15
+ const res = await fetch(NAI_TYPES_URL);
16
+ if (!res.ok) {
17
+ throw new Error(`Failed to fetch types: HTTP ${res.status}, ${res.statusText}`);
18
+ }
19
+ else if (!res.body) {
20
+ throw new Error("Got result, but body is empty");
21
+ }
22
+ try {
23
+ await (0, promises_2.pipeline)(res.body, (0, fs_1.createWriteStream)(outputPath));
24
+ }
25
+ catch (err) {
26
+ console.error(err);
27
+ throw err;
28
+ }
29
+ }
30
+ const TSCONFIG = {
31
+ compilerOptions: {
32
+ target: "ES2023",
33
+ module: "ESNext",
34
+ lib: ["ES2023"],
35
+ moduleResolution: "bundler",
36
+ strict: true,
37
+ esModuleInterop: true,
38
+ skipLibCheck: true,
39
+ forceConsistentCasingInFileNames: true,
40
+ allowSyntheticDefaultImports: true,
41
+ noUnusedLocals: true,
42
+ noUnusedParameters: true,
43
+ noImplicitReturns: true,
44
+ noFallthroughCasesInSwitch: true,
45
+ noEmit: true,
46
+ typeRoots: ["./external", "./node_modules/@types"],
47
+ rewriteRelativeImportExtensions: true,
48
+ },
49
+ include: ["src/**/*", "external/**/*"],
50
+ exclude: ["node_modules", "dist", "**/*.test.ts"],
51
+ };
52
+ function writeTsConfig(projectPath) {
53
+ return (0, promises_1.writeFile)((0, path_1.join)(projectPath, "tsconfig.json"), JSON.stringify(TSCONFIG, undefined, 2), "utf-8");
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nibs-cli",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "Project build tool for NovelAI scripts - bundles TypeScript files into single scripts",
5
5
  "bin": {
6
6
  "nibs": "dist/cli.js"
@@ -21,7 +21,6 @@
21
21
  "node": ">= 18"
22
22
  },
23
23
  "devDependencies": {
24
- "prettier": "^3.7.4",
25
24
  "@types/node": "^25.0.0",
26
25
  "@types/rollup": "^0.51.4",
27
26
  "typescript": "^5.3.0"
@@ -30,6 +29,7 @@
30
29
  "@rollup/plugin-typescript": "^12.3.0",
31
30
  "commander": "^14.0.2",
32
31
  "inquirer": "^13.0.2",
32
+ "prettier": "^3.7.4",
33
33
  "rollup": "^4.53.3",
34
34
  "yaml": "^2.8.2"
35
35
  }