@eighty4/c2 0.0.4 → 0.0.5

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/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@
4
4
 
5
5
  - ???
6
6
 
7
+ ## [v0.0.5] - 2026-02-21
8
+
9
+ ### Fixed
10
+
11
+ - Rewrite code using Bun APIs and npm packages to remove
12
+ package install size and dependency on specific runtime
13
+
7
14
  ## [v0.0.4] - 2025-06-30
8
15
 
9
16
  ### Fixed
@@ -28,7 +35,8 @@
28
35
  - Evaluate env() and file() expressions in user data
29
36
  - Merge multiple user data into a MIME multipart message
30
37
 
31
- [Unreleased]: https://github.com/eighty4/c2/compare/v0.0.4...HEAD
38
+ [Unreleased]: https://github.com/eighty4/c2/compare/v0.0.5...HEAD
39
+ [v0.0.5]: https://github.com/eighty4/c2/compare/v0.0.4...v0.0.5
32
40
  [v0.0.4]: https://github.com/eighty4/c2/compare/v0.0.3...v0.0.4
33
41
  [v0.0.3]: https://github.com/eighty4/c2/compare/v0.0.2...v0.0.3
34
42
  [v0.0.2]: https://github.com/eighty4/c2/releases/tag/v0.0.2
package/README.md CHANGED
@@ -12,9 +12,6 @@ npm i -g @eighty4/c2
12
12
  c2 -h
13
13
  ```
14
14
 
15
- (tests use `bun:test` so [install Bun](https://bun.sh/docs/installation)
16
- for contributing!)
17
-
18
15
  ## Using the CLI program
19
16
 
20
17
  ```
@@ -1,5 +1,5 @@
1
+ import { readdir, readFile } from 'node:fs/promises'
1
2
  import { evalTemplateExpressions } from './expression.ts'
2
- import { readDirListing, readToString } from './fs.ts'
3
3
 
4
4
  export type AttachmentType = 'cloud-config' | 'x-shellscript'
5
5
 
@@ -14,11 +14,11 @@ export interface Attachment {
14
14
  export async function collectAttachments(
15
15
  dir: string,
16
16
  ): Promise<Array<Attachment>> {
17
- const filenames = await readDirListing(dir)
17
+ const filenames = await readdir(dir)
18
18
  const attachments = await Promise.all(
19
19
  filenames.map(async filename => {
20
20
  const path = `${dir}/${filename}`
21
- const source = await readToString(path)
21
+ const source = await readFile(path, 'utf-8')
22
22
  const type = resolveAttachmentType(filename, source)
23
23
  const content = await evalTemplateExpressions(source)
24
24
  return { content, filename, path, type, source }
package/lib/bin.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { stat } from 'node:fs/promises'
3
4
  import { buildUserData } from './build.ts'
4
5
  import { parseArgs, type ParsedArgs } from './cli.ts'
5
- import { doesDirExist } from './fs.ts'
6
6
  import { startUserDataHttp } from './http.ts'
7
7
 
8
8
  let args: ParsedArgs | undefined
@@ -52,3 +52,11 @@ function errorExit(msg: string): never {
52
52
  function errorText(s: string): string {
53
53
  return `\u001b[1;31m${s}\u001b[0m`
54
54
  }
55
+
56
+ async function doesDirExist(p: string): Promise<boolean> {
57
+ try {
58
+ return (await stat(p)).isDirectory()
59
+ } catch (ignore) {
60
+ return false
61
+ }
62
+ }
package/lib/expression.ts CHANGED
@@ -1,5 +1,4 @@
1
- import MagicString from 'magic-string'
2
- import { readToString } from './fs.ts'
1
+ import { readFile } from 'node:fs/promises'
3
2
 
4
3
  type TemplateExpression = {
5
4
  index: number
@@ -23,15 +22,18 @@ export async function evalTemplateExpressions(
23
22
  if (!expressions.length) {
24
23
  return content
25
24
  }
26
- const ms = new MagicString(content)
25
+ let offset = 0
27
26
  for (const expression of expressions) {
28
- ms.update(
29
- expression.index,
30
- expression.index + expression.outie.length,
31
- await evaluate(expression.innie),
32
- )
27
+ const expressionResult = await evaluate(expression.innie)
28
+ content =
29
+ content.substring(0, expression.index + offset) +
30
+ expressionResult +
31
+ content.substring(
32
+ expression.index + expression.outie.length + offset,
33
+ )
34
+ offset += expressionResult.length - expression.outie.length
33
35
  }
34
- return ms.toString()
36
+ return content
35
37
  }
36
38
 
37
39
  async function evaluate(expression: string): Promise<string> {
@@ -56,7 +58,7 @@ async function evaluate(expression: string): Promise<string> {
56
58
  }
57
59
  path = `${process.env.HOME}${path.substring(1)}`
58
60
  }
59
- return readToString(path)
61
+ return await readFile(path, 'utf-8')
60
62
  }
61
63
 
62
64
  throw new Error(`unsupported expression: ${expression}`)
package/lib/fs.testing.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { mkdtemp, rm } from 'node:fs/promises'
1
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises'
2
2
  import { tmpdir } from 'node:os'
3
3
  import { join } from 'node:path'
4
4
 
@@ -8,7 +8,7 @@ export async function makeFile(
8
8
  pathPrefix?: string,
9
9
  ): Promise<string> {
10
10
  const p = !!pathPrefix ? join(pathPrefix, path) : path
11
- await Bun.file(p).write(content)
11
+ await writeFile(p, content)
12
12
  return p
13
13
  }
14
14
 
@@ -1,10 +1,10 @@
1
+ import { readdir, readFile } from 'node:fs/promises';
1
2
  import { evalTemplateExpressions } from "./expression.js";
2
- import { readDirListing, readToString } from "./fs.js";
3
3
  export async function collectAttachments(dir) {
4
- const filenames = await readDirListing(dir);
4
+ const filenames = await readdir(dir);
5
5
  const attachments = await Promise.all(filenames.map(async (filename) => {
6
6
  const path = `${dir}/${filename}`;
7
- const source = await readToString(path);
7
+ const source = await readFile(path, 'utf-8');
8
8
  const type = resolveAttachmentType(filename, source);
9
9
  const content = await evalTemplateExpressions(source);
10
10
  return { content, filename, path, type, source };
package/lib_js/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import { stat } from 'node:fs/promises';
2
3
  import { buildUserData } from "./build.js";
3
4
  import { parseArgs } from "./cli.js";
4
- import { doesDirExist } from "./fs.js";
5
5
  import { startUserDataHttp } from "./http.js";
6
6
  let args;
7
7
  try {
@@ -44,3 +44,11 @@ function errorExit(msg) {
44
44
  function errorText(s) {
45
45
  return `\u001b[1;31m${s}\u001b[0m`;
46
46
  }
47
+ async function doesDirExist(p) {
48
+ try {
49
+ return (await stat(p)).isDirectory();
50
+ }
51
+ catch (ignore) {
52
+ return false;
53
+ }
54
+ }
@@ -1,5 +1,4 @@
1
- import MagicString from 'magic-string';
2
- import { readToString } from "./fs.js";
1
+ import { readFile } from 'node:fs/promises';
3
2
  export async function evalTemplateExpressions(content) {
4
3
  const regex = new RegExp(/\${{\s*(.*)\s*}}/g);
5
4
  let match;
@@ -14,11 +13,16 @@ export async function evalTemplateExpressions(content) {
14
13
  if (!expressions.length) {
15
14
  return content;
16
15
  }
17
- const ms = new MagicString(content);
16
+ let offset = 0;
18
17
  for (const expression of expressions) {
19
- ms.update(expression.index, expression.index + expression.outie.length, await evaluate(expression.innie));
18
+ const expressionResult = await evaluate(expression.innie);
19
+ content =
20
+ content.substring(0, expression.index + offset) +
21
+ expressionResult +
22
+ content.substring(expression.index + expression.outie.length + offset);
23
+ offset += expressionResult.length - expression.outie.length;
20
24
  }
21
- return ms.toString();
25
+ return content;
22
26
  }
23
27
  async function evaluate(expression) {
24
28
  let match;
@@ -41,7 +45,7 @@ async function evaluate(expression) {
41
45
  }
42
46
  path = `${process.env.HOME}${path.substring(1)}`;
43
47
  }
44
- return readToString(path);
48
+ return await readFile(path, 'utf-8');
45
49
  }
46
50
  throw new Error(`unsupported expression: ${expression}`);
47
51
  }
@@ -1,9 +1,9 @@
1
- import { mkdtemp, rm } from 'node:fs/promises';
1
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
2
2
  import { tmpdir } from 'node:os';
3
3
  import { join } from 'node:path';
4
4
  export async function makeFile(path, content, pathPrefix) {
5
5
  const p = !!pathPrefix ? join(pathPrefix, path) : path;
6
- await Bun.file(p).write(content);
6
+ await writeFile(p, content);
7
7
  return p;
8
8
  }
9
9
  export async function makeTempDir() {
@@ -1 +1 @@
1
- {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../lib/expression.ts"],"names":[],"mappings":"AASA,wBAAsB,uBAAuB,CACzC,OAAO,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../lib/expression.ts"],"names":[],"mappings":"AAQA,wBAAsB,uBAAuB,CACzC,OAAO,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CA0BjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eighty4/c2",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "author": "Adam McKee <adam.be.g84d@gmail.com>",
5
5
  "repository": "https://github.com/eighty4/c2",
6
6
  "homepage": "https://github.com/eighty4/c2",
@@ -29,21 +29,10 @@
29
29
  "types": "./lib_types/api.d.ts"
30
30
  }
31
31
  },
32
- "scripts": {
33
- "build": "tsc",
34
- "fmt": "prettier --write .",
35
- "fmtcheck": "prettier --check .",
36
- "test": "bun test",
37
- "typecheck": "tsc --noEmit"
38
- },
39
- "dependencies": {
40
- "magic-string": "0.30.17"
41
- },
42
32
  "devDependencies": {
43
- "@types/bun": "1.2.5",
44
- "@types/node": "^22.14.1",
45
- "prettier": "^3.5.3",
46
- "typescript": "5.8.2"
33
+ "@types/node": "^25.3.0",
34
+ "prettier": "^3.8.1",
35
+ "typescript": "5.9.3"
47
36
  },
48
37
  "files": [
49
38
  "lib/*",
@@ -51,5 +40,12 @@
51
40
  "lib_js/*",
52
41
  "lib_types/*",
53
42
  "CHANGELOG.md"
54
- ]
55
- }
43
+ ],
44
+ "scripts": {
45
+ "build": "tsc",
46
+ "fmt": "prettier --write .",
47
+ "fmtcheck": "prettier --check .",
48
+ "test": "node --test \"lib/**/*.spec.ts\"",
49
+ "typecheck": "tsc --noEmit"
50
+ }
51
+ }
package/lib/fs.ts DELETED
@@ -1,17 +0,0 @@
1
- import { readdir, readFile, stat } from 'node:fs/promises'
2
-
3
- export async function doesDirExist(p: string): Promise<boolean> {
4
- try {
5
- return (await stat(p)).isDirectory()
6
- } catch (ignore) {
7
- return false
8
- }
9
- }
10
-
11
- export async function readDirListing(p: string): Promise<Array<string>> {
12
- return readdir(p)
13
- }
14
-
15
- export async function readToString(p: string): Promise<string> {
16
- return readFile(p, 'utf8')
17
- }
package/lib_js/fs.js DELETED
@@ -1,15 +0,0 @@
1
- import { readdir, readFile, stat } from 'node:fs/promises';
2
- export async function doesDirExist(p) {
3
- try {
4
- return (await stat(p)).isDirectory();
5
- }
6
- catch (ignore) {
7
- return false;
8
- }
9
- }
10
- export async function readDirListing(p) {
11
- return readdir(p);
12
- }
13
- export async function readToString(p) {
14
- return readFile(p, 'utf8');
15
- }
package/lib_types/fs.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export declare function doesDirExist(p: string): Promise<boolean>;
2
- export declare function readDirListing(p: string): Promise<Array<string>>;
3
- export declare function readToString(p: string): Promise<string>;
4
- //# sourceMappingURL=fs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../lib/fs.ts"],"names":[],"mappings":"AAEA,wBAAsB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM9D;AAED,wBAAsB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAEtE;AAED,wBAAsB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7D"}