@opencode-ai/util 0.0.0-next-16486 → 0.0.0-next-16490

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/dist/bom.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export * as Bom from "./bom.js";
2
+ import { Effect } from "effect";
3
+ import { FSUtil } from "./fs-util.js";
4
+ export declare function split(text: string): {
5
+ bom: boolean;
6
+ text: string;
7
+ };
8
+ export declare function join(text: string, bom: boolean): string;
9
+ export declare function has(content: Uint8Array): boolean;
10
+ export declare const readFile: (fs: FSUtil.Interface, filepath: string) => Effect.Effect<{
11
+ bom: boolean;
12
+ text: string;
13
+ }, import("effect/PlatformError").PlatformError, never>;
14
+ export declare const syncFile: (fs: FSUtil.Interface, filepath: string, bom: boolean) => Effect.Effect<string, FSUtil.Error, never>;
package/dist/bom.js ADDED
@@ -0,0 +1,31 @@
1
+ export * as Bom from "./bom.js";
2
+ import { Effect } from "effect";
3
+ import { FSUtil } from "./fs-util.js";
4
+ const code = 0xfeff;
5
+ const value = String.fromCharCode(code);
6
+ export function split(text) {
7
+ const stripped = text.replace(/^\uFEFF+/, "");
8
+ return { bom: stripped.length !== text.length, text: stripped };
9
+ }
10
+ export function join(text, bom) {
11
+ const stripped = split(text).text;
12
+ return bom ? value + stripped : stripped;
13
+ }
14
+ export function has(content) {
15
+ return content[0] === 0xef && content[1] === 0xbb && content[2] === 0xbf;
16
+ }
17
+ export const readFile = Effect.fn("Bom.readFile")(function* (fs, filepath) {
18
+ return split(decode(yield* fs.readFile(filepath)));
19
+ });
20
+ export const syncFile = Effect.fn("Bom.syncFile")(function* (fs, filepath, bom) {
21
+ const decoded = decode(yield* fs.readFile(filepath));
22
+ const current = split(decoded);
23
+ const canonical = join(current.text, bom);
24
+ if (decoded === canonical)
25
+ return current.text;
26
+ yield* fs.writeWithDirs(filepath, canonical);
27
+ return current.text;
28
+ });
29
+ function decode(content) {
30
+ return new TextDecoder("utf-8", { ignoreBOM: true }).decode(content);
31
+ }
package/dist/fs-util.d.ts CHANGED
@@ -86,7 +86,7 @@ export declare namespace FSUtil {
86
86
  readonly makeTempDirectoryScoped: (options?: {
87
87
  readonly directory?: string | undefined;
88
88
  readonly prefix?: string | undefined;
89
- } | undefined) => Effect.Effect<string, PlatformError, import("effect/Scope").Scope | Service>;
89
+ } | undefined) => Effect.Effect<string, PlatformError, Service | import("effect/Scope").Scope>;
90
90
  readonly makeTempFile: (options?: {
91
91
  readonly directory?: string | undefined;
92
92
  readonly prefix?: string | undefined;
@@ -96,11 +96,11 @@ export declare namespace FSUtil {
96
96
  readonly directory?: string | undefined;
97
97
  readonly prefix?: string | undefined;
98
98
  readonly suffix?: string | undefined;
99
- } | undefined) => Effect.Effect<string, PlatformError, import("effect/Scope").Scope | Service>;
99
+ } | undefined) => Effect.Effect<string, PlatformError, Service | import("effect/Scope").Scope>;
100
100
  readonly open: (path: string, options?: {
101
101
  readonly flag?: FileSystem.OpenFlag | undefined;
102
102
  readonly mode?: number | undefined;
103
- } | undefined) => Effect.Effect<FileSystem.File, PlatformError, import("effect/Scope").Scope | Service>;
103
+ } | undefined) => Effect.Effect<FileSystem.File, PlatformError, Service | import("effect/Scope").Scope>;
104
104
  readonly readDirectory: (path: string, options?: {
105
105
  readonly recursive?: boolean | undefined;
106
106
  } | undefined) => Effect.Effect<string[], PlatformError, Service>;
package/dist/patch.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * as Patch from "./patch.js";
2
2
  import { Result, Schema } from "effect";
3
+ import { Bom } from "./bom.js";
3
4
  export class BoundaryError extends Schema.TaggedErrorClass()("Patch.BoundaryError", {
4
5
  boundary: Schema.Literals(["first", "last"]),
5
6
  }) {
@@ -95,7 +96,7 @@ export function parse(patchText) {
95
96
  return Result.succeed(hunks);
96
97
  }
97
98
  export function derive(path, chunks, original) {
98
- const source = splitBom(original);
99
+ const source = Bom.split(original);
99
100
  const lines = source.text.split("\n");
100
101
  if (lines.at(-1) === "")
101
102
  lines.pop();
@@ -105,12 +106,11 @@ export function derive(path, chunks, original) {
105
106
  updated.splice(start, remove, ...insert);
106
107
  if (updated.at(-1) !== "")
107
108
  updated.push("");
108
- const next = splitBom(updated.join("\n"));
109
+ const next = Bom.split(updated.join("\n"));
109
110
  return { content: next.text, bom: source.bom || next.bom };
110
111
  }
111
112
  export function joinBom(text, bom) {
112
- const stripped = splitBom(text).text;
113
- return bom ? `\uFEFF${stripped}` : stripped;
113
+ return Bom.join(text, bom);
114
114
  }
115
115
  function parseAdd(lines, start, end, path) {
116
116
  const content = [];
@@ -329,5 +329,4 @@ const normalize = (value) => value
329
329
  .replace(/[“”„‟]/g, '"')
330
330
  .replace(/[‐‑‒–—―−]/g, "-")
331
331
  .replace(/[\u00A0\u2002-\u200A\u202F\u205F\u3000]/g, " ");
332
- const splitBom = (text) => text.startsWith("\uFEFF") ? { bom: true, text: text.slice(1) } : { bom: false, text };
333
332
  const stripHeredoc = (input) => input.match(/^(?:cat\s+)?<<(['"]?)(\w+)\1\s*\n([\s\S]*?)\n\2\s*$/)?.[3] ?? input;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode-ai/util",
4
- "version": "0.0.0-next-16486",
4
+ "version": "0.0.0-next-16490",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {