@openclaw/fs-safe 0.8.2 → 0.8.4

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 (200) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +1 -1
  3. package/dist/absolute-path.d.ts.map +1 -1
  4. package/dist/absolute-path.js +8 -7
  5. package/dist/advanced.d.ts +2 -2
  6. package/dist/advanced.d.ts.map +1 -1
  7. package/dist/advanced.js +2 -2
  8. package/dist/archive-kind.d.ts +1 -0
  9. package/dist/archive-kind.d.ts.map +1 -1
  10. package/dist/archive-kind.js +6 -0
  11. package/dist/archive-limits.d.ts +0 -1
  12. package/dist/archive-limits.d.ts.map +1 -1
  13. package/dist/archive-limits.js +0 -3
  14. package/dist/archive-native.d.ts +1 -0
  15. package/dist/archive-native.d.ts.map +1 -1
  16. package/dist/archive-native.js +20 -76
  17. package/dist/archive-parser-errors.d.ts +2 -0
  18. package/dist/archive-parser-errors.d.ts.map +1 -0
  19. package/dist/archive-parser-errors.js +12 -0
  20. package/dist/archive-plan.d.ts +20 -0
  21. package/dist/archive-plan.d.ts.map +1 -0
  22. package/dist/archive-plan.js +55 -0
  23. package/dist/archive-read.d.ts.map +1 -1
  24. package/dist/archive-read.js +7 -13
  25. package/dist/archive-tar-inspect.d.ts +7 -0
  26. package/dist/archive-tar-inspect.d.ts.map +1 -0
  27. package/dist/archive-tar-inspect.js +59 -0
  28. package/dist/archive-tar-wasm.d.ts +1 -1
  29. package/dist/archive-tar-wasm.d.ts.map +1 -1
  30. package/dist/archive-tar-wasm.js +5 -8
  31. package/dist/archive-tar.d.ts +3 -1
  32. package/dist/archive-tar.d.ts.map +1 -1
  33. package/dist/archive-tar.js +12 -49
  34. package/dist/archive.d.ts +1 -0
  35. package/dist/archive.d.ts.map +1 -1
  36. package/dist/archive.js +54 -33
  37. package/dist/atomic.d.ts +1 -1
  38. package/dist/atomic.d.ts.map +1 -1
  39. package/dist/atomic.js +1 -1
  40. package/dist/bounded-read-stream.d.ts +1 -5
  41. package/dist/bounded-read-stream.d.ts.map +1 -1
  42. package/dist/bounded-read-stream.js +5 -13
  43. package/dist/bounded-read.d.ts.map +1 -1
  44. package/dist/bounded-read.js +31 -4
  45. package/dist/byte-budget.d.ts +0 -1
  46. package/dist/byte-budget.d.ts.map +1 -1
  47. package/dist/byte-budget.js +1 -1
  48. package/dist/directory-durability.js +5 -5
  49. package/dist/directory-guard.d.ts.map +1 -1
  50. package/dist/directory-guard.js +5 -6
  51. package/dist/directory-mode-owner.d.ts.map +1 -1
  52. package/dist/directory-mode-owner.js +2 -0
  53. package/dist/error-detail.d.ts +1 -0
  54. package/dist/error-detail.d.ts.map +1 -1
  55. package/dist/error-detail.js +6 -0
  56. package/dist/file-store-boundary.d.ts +1 -1
  57. package/dist/file-store-boundary.d.ts.map +1 -1
  58. package/dist/file-store-boundary.js +3 -14
  59. package/dist/file-store-prune.js +17 -8
  60. package/dist/file-store.js +3 -3
  61. package/dist/file-sync.d.ts +5 -0
  62. package/dist/file-sync.d.ts.map +1 -0
  63. package/dist/file-sync.js +19 -0
  64. package/dist/guarded-mkdir.d.ts.map +1 -1
  65. package/dist/guarded-mkdir.js +5 -4
  66. package/dist/guarded-mutation.d.ts +3 -0
  67. package/dist/guarded-mutation.d.ts.map +1 -1
  68. package/dist/guarded-mutation.js +5 -1
  69. package/dist/home-dir.d.ts +0 -10
  70. package/dist/home-dir.d.ts.map +1 -1
  71. package/dist/home-dir.js +0 -28
  72. package/dist/json-durable-queue-ownership.d.ts +1 -0
  73. package/dist/json-durable-queue-ownership.d.ts.map +1 -1
  74. package/dist/json-durable-queue-ownership.js +139 -18
  75. package/dist/json-durable-queue.d.ts.map +1 -1
  76. package/dist/json-durable-queue.js +5 -10
  77. package/dist/json-store.d.ts.map +1 -1
  78. package/dist/json-store.js +1 -1
  79. package/dist/local-roots.d.ts.map +1 -1
  80. package/dist/local-roots.js +2 -3
  81. package/dist/move-path-cleanup.d.ts +1 -1
  82. package/dist/move-path-cleanup.d.ts.map +1 -1
  83. package/dist/move-path-cleanup.js +4 -2
  84. package/dist/move-path.d.ts +9 -0
  85. package/dist/move-path.d.ts.map +1 -1
  86. package/dist/move-path.js +53 -16
  87. package/dist/native-binding.d.ts +2 -1
  88. package/dist/native-binding.d.ts.map +1 -1
  89. package/dist/native-operations.d.ts +0 -1
  90. package/dist/native-operations.d.ts.map +1 -1
  91. package/dist/native-operations.js +0 -10
  92. package/dist/native-pinned-write-windows.d.ts.map +1 -1
  93. package/dist/native-pinned-write-windows.js +8 -4
  94. package/dist/native-pinned-write.js +3 -3
  95. package/dist/native-staged-file.d.ts +10 -3
  96. package/dist/native-staged-file.d.ts.map +1 -1
  97. package/dist/native-staged-file.js +38 -13
  98. package/dist/opened-realpath.d.ts +12 -1
  99. package/dist/opened-realpath.d.ts.map +1 -1
  100. package/dist/opened-realpath.js +16 -14
  101. package/dist/output.d.ts.map +1 -1
  102. package/dist/output.js +26 -2
  103. package/dist/path-policy.js +3 -3
  104. package/dist/permissions.d.ts +1 -0
  105. package/dist/permissions.d.ts.map +1 -1
  106. package/dist/permissions.js +3 -0
  107. package/dist/pinned-write.d.ts +2 -2
  108. package/dist/pinned-write.d.ts.map +1 -1
  109. package/dist/pinned-write.js +17 -22
  110. package/dist/private-temp-workspace.js +1 -1
  111. package/dist/publish-file.js +2 -2
  112. package/dist/regular-file.js +8 -8
  113. package/dist/replace-file-copy-source.d.ts.map +1 -1
  114. package/dist/replace-file-copy-source.js +2 -7
  115. package/dist/replace-file-descriptor.d.ts.map +1 -1
  116. package/dist/replace-file-descriptor.js +11 -20
  117. package/dist/replace-file-temp-owner.d.ts.map +1 -1
  118. package/dist/replace-file-temp-owner.js +15 -14
  119. package/dist/replace-file.d.ts.map +1 -1
  120. package/dist/replace-file.js +21 -8
  121. package/dist/root-context.js +5 -5
  122. package/dist/root-errors.d.ts +1 -0
  123. package/dist/root-errors.d.ts.map +1 -1
  124. package/dist/root-errors.js +9 -0
  125. package/dist/root-file.d.ts.map +1 -1
  126. package/dist/root-file.js +17 -28
  127. package/dist/root-impl.d.ts +2 -1
  128. package/dist/root-impl.d.ts.map +1 -1
  129. package/dist/root-impl.js +46 -58
  130. package/dist/root-path-existing.d.ts.map +1 -1
  131. package/dist/root-path-existing.js +2 -3
  132. package/dist/root-path-symlink.d.ts.map +1 -1
  133. package/dist/root-path-symlink.js +2 -3
  134. package/dist/root-path.d.ts.map +1 -1
  135. package/dist/root-path.js +51 -97
  136. package/dist/root-paths.d.ts.map +1 -1
  137. package/dist/root-paths.js +16 -15
  138. package/dist/root-write-mode.d.ts +6 -0
  139. package/dist/root-write-mode.d.ts.map +1 -0
  140. package/dist/root-write-mode.js +61 -0
  141. package/dist/root-write-verification.js +8 -8
  142. package/dist/safe-path-segment.d.ts +1 -0
  143. package/dist/safe-path-segment.d.ts.map +1 -1
  144. package/dist/safe-path-segment.js +1 -1
  145. package/dist/secret-file.d.ts.map +1 -1
  146. package/dist/secret-file.js +4 -11
  147. package/dist/secret-read-async.d.ts.map +1 -1
  148. package/dist/secret-read-async.js +2 -10
  149. package/dist/secret-read-policy.d.ts +4 -0
  150. package/dist/secret-read-policy.d.ts.map +1 -1
  151. package/dist/secret-read-policy.js +12 -0
  152. package/dist/sibling-staged-file.d.ts.map +1 -1
  153. package/dist/sibling-staged-file.js +2 -7
  154. package/dist/sidecar-lock-policy.d.ts +0 -1
  155. package/dist/sidecar-lock-policy.d.ts.map +1 -1
  156. package/dist/sidecar-lock-policy.js +0 -4
  157. package/dist/strict-file-identity.d.ts +1 -1
  158. package/dist/strict-file-identity.d.ts.map +1 -1
  159. package/dist/string-coerce.d.ts +0 -9
  160. package/dist/string-coerce.d.ts.map +1 -1
  161. package/dist/string-coerce.js +0 -56
  162. package/dist/symlink-parents.d.ts.map +1 -1
  163. package/dist/symlink-parents.js +1 -2
  164. package/dist/temp-target.d.ts.map +1 -1
  165. package/dist/temp-target.js +1 -12
  166. package/docs/archive.md +57 -0
  167. package/docs/atomic.md +53 -19
  168. package/docs/reading.md +2 -0
  169. package/docs/root.md +10 -1
  170. package/docs/staged-file.md +6 -2
  171. package/docs/types.md +2 -1
  172. package/docs/writing.md +30 -2
  173. package/package.json +8 -8
  174. package/dist/archive-tar-extract.d.ts +0 -11
  175. package/dist/archive-tar-extract.d.ts.map +0 -1
  176. package/dist/archive-tar-extract.js +0 -49
  177. package/dist/fsync.d.ts +0 -2
  178. package/dist/fsync.d.ts.map +0 -1
  179. package/dist/fsync.js +0 -1
  180. package/dist/json-durable-queue-retirement.d.ts +0 -9
  181. package/dist/json-durable-queue-retirement.d.ts.map +0 -1
  182. package/dist/json-durable-queue-retirement.js +0 -126
  183. package/dist/json-durable-queue-transfer-lock.d.ts +0 -2
  184. package/dist/json-durable-queue-transfer-lock.d.ts.map +0 -1
  185. package/dist/json-durable-queue-transfer-lock.js +0 -19
  186. package/dist/mode.d.ts +0 -2
  187. package/dist/mode.d.ts.map +0 -1
  188. package/dist/mode.js +0 -3
  189. package/dist/output-sibling.d.ts +0 -8
  190. package/dist/output-sibling.d.ts.map +0 -1
  191. package/dist/output-sibling.js +0 -30
  192. package/dist/read-error.d.ts +0 -2
  193. package/dist/read-error.d.ts.map +0 -1
  194. package/dist/read-error.js +0 -11
  195. package/dist/short-path.d.ts +0 -2
  196. package/dist/short-path.d.ts.map +0 -1
  197. package/dist/short-path.js +0 -7
  198. package/dist/staged-file.d.ts +0 -10
  199. package/dist/staged-file.d.ts.map +0 -1
  200. package/dist/staged-file.js +0 -15
@@ -111,7 +111,7 @@ async function observeOwnedAliasUnlink(sourcePath, group) {
111
111
  function mergeCleanupResults(a, b) {
112
112
  return a === "stale" || b === "stale" ? "stale" : "removed";
113
113
  }
114
- export async function cleanupCopiedEntry(sourcePath, manifest, state) {
114
+ export async function cleanupCopiedEntry(sourcePath, manifest, state, assertBeforeMutation) {
115
115
  const aliasGroup = manifest.kind === "leaf" ? state.aliasGroups.get(identityKey(manifest)) : undefined;
116
116
  if (aliasGroup?.stale) {
117
117
  return "stale";
@@ -134,8 +134,9 @@ export async function cleanupCopiedEntry(sourcePath, manifest, state) {
134
134
  // clean manifest children so the fallback does not duplicate copied files.
135
135
  let result = "removed";
136
136
  for (const child of manifest.children) {
137
- result = mergeCleanupResults(result, await cleanupCopiedEntry(path.join(sourcePath, child.name), child.manifest, state));
137
+ result = mergeCleanupResults(result, await cleanupCopiedEntry(path.join(sourcePath, child.name), child.manifest, state, assertBeforeMutation));
138
138
  }
139
+ assertBeforeMutation();
139
140
  try {
140
141
  await fs.rmdir(sourcePath);
141
142
  }
@@ -152,6 +153,7 @@ export async function cleanupCopiedEntry(sourcePath, manifest, state) {
152
153
  if (!sameIdentity(expected, entryIdentity(currentStat))) {
153
154
  return aliasGroup ? poisonAliasGroup(aliasGroup) : "stale";
154
155
  }
156
+ assertBeforeMutation();
155
157
  await fs.unlink(sourcePath);
156
158
  return aliasGroup
157
159
  ? await observeOwnedAliasUnlink(sourcePath, aliasGroup)
@@ -1,6 +1,15 @@
1
+ export type MovePathPublicationReceipt = Readonly<{
2
+ path: string;
3
+ dev: bigint;
4
+ ino: bigint;
5
+ }>;
1
6
  export type MovePathWithCopyFallbackOptions = {
7
+ /** Rechecks authority before each rename and copied-source unlink/rmdir dispatch. */
8
+ assertBeforeMutation?: () => void;
2
9
  /** Rechecks caller authority synchronously immediately before each rename dispatch. */
3
10
  assertBeforeRename?: () => void;
11
+ /** Reports the committed destination before post-rename checks or source cleanup. */
12
+ onDestinationPublished?: (receipt: MovePathPublicationReceipt) => void;
4
13
  from: string;
5
14
  sourceHardlinks?: "allow" | "reject";
6
15
  to: string;
@@ -1 +1 @@
1
- {"version":3,"file":"move-path.d.ts","sourceRoot":"","sources":["../src/move-path.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,+BAA+B,GAAG;IAC5C,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,KAAK,sBAAsB,GAAG,cAAc,GAAG,uBAAuB,CAAC;AAEvE,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,OAAO,EACd,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,sBAAsB,GAAG,SAAS,CASpC;AA8OD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,IAAI,CAAC,CAkFf"}
1
+ {"version":3,"file":"move-path.d.ts","sourceRoot":"","sources":["../src/move-path.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC,CAAC;AAEH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,qFAAqF;IACrF,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,qFAAqF;IACrF,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,IAAI,CAAC;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,KAAK,sBAAsB,GAAG,cAAc,GAAG,uBAAuB,CAAC;AAEvE,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,OAAO,EACd,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,sBAAsB,GAAG,SAAS,CASpC;AAsPD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,IAAI,CAAC,CAqHf"}
package/dist/move-path.js CHANGED
@@ -211,24 +211,49 @@ async function copyEntryWithManifest(from, to, options, expectedIdentity) {
211
211
  });
212
212
  return { ...identity, kind: "leaf" };
213
213
  }
214
+ function assertSynchronousResult(returned, name) {
215
+ if (returned !== undefined) {
216
+ // TypeScript permits async functions for () => void; consume their rejection.
217
+ void Promise.resolve(returned).catch(() => { });
218
+ throw new TypeError(`${name} must return undefined synchronously`);
219
+ }
220
+ }
214
221
  export async function movePathWithCopyFallback(options) {
215
- // Keep the initiating owner's callback across preparation and copy fallback.
216
- const callerAssert = options.assertBeforeRename;
222
+ // Keep the initiating owner's callbacks across preparation and copy fallback.
223
+ const callerRenameAssert = options.assertBeforeRename;
224
+ const callerMutationAssert = options.assertBeforeMutation;
225
+ const callerPublished = options.onDestinationPublished;
217
226
  let assertionRejected = false;
227
+ let destinationPublished = false;
228
+ const assertBeforeMutation = () => {
229
+ assertSynchronousResult(callerMutationAssert?.(), "assertBeforeMutation");
230
+ };
218
231
  const assertBeforeRename = () => {
219
232
  try {
220
- const returned = callerAssert?.();
221
- if (returned !== undefined) {
222
- // TypeScript permits async functions for () => void; they cannot authorize a rename.
223
- void Promise.resolve(returned).catch(() => { });
224
- throw new TypeError("assertBeforeRename must return undefined synchronously");
225
- }
233
+ assertSynchronousResult(callerRenameAssert?.(), "assertBeforeRename");
234
+ assertBeforeMutation();
226
235
  }
227
236
  catch (error) {
228
237
  assertionRejected = true;
229
238
  throw error;
230
239
  }
231
240
  };
241
+ let publicationReceipt;
242
+ const onSourceInspected = callerPublished
243
+ ? (identity) => {
244
+ publicationReceipt = Object.freeze({
245
+ path: targetPath,
246
+ dev: identity.dev,
247
+ ino: identity.ino,
248
+ });
249
+ }
250
+ : undefined;
251
+ const onRenamed = () => {
252
+ destinationPublished = true;
253
+ if (publicationReceipt) {
254
+ assertSynchronousResult(callerPublished?.(publicationReceipt), "onDestinationPublished");
255
+ }
256
+ };
232
257
  const sourcePath = path.resolve(options.from);
233
258
  const targetPath = path.resolve(options.to);
234
259
  const rejectHardlinks = options.sourceHardlinks === "reject";
@@ -237,12 +262,18 @@ export async function movePathWithCopyFallback(options) {
237
262
  }
238
263
  if (!rejectHardlinks) {
239
264
  try {
240
- await guardedRename({ from: sourcePath, to: targetPath, assertBeforeRename });
265
+ await guardedRename({
266
+ from: sourcePath,
267
+ to: targetPath,
268
+ assertBeforeRename,
269
+ onSourceInspected,
270
+ onRenamed,
271
+ });
241
272
  return;
242
273
  }
243
274
  catch (error) {
244
275
  // An owner's EXDEV/EPERM refusal is not permission to copy instead.
245
- if (assertionRejected || !moveCopyFallbackReasonForRenameError(error)) {
276
+ if (assertionRejected || destinationPublished || !moveCopyFallbackReasonForRenameError(error)) {
246
277
  throw error;
247
278
  }
248
279
  }
@@ -256,7 +287,6 @@ export async function movePathWithCopyFallback(options) {
256
287
  const targetDir = path.dirname(targetPath);
257
288
  const staged = path.join(targetDir, `.fs-safe-move-${process.pid}-${randomUUID()}.tmp`);
258
289
  const unregisterStaged = registerTempPathForExit(staged, { recursive: true });
259
- let stagedCommitted = false;
260
290
  try {
261
291
  const manifest = await copyEntryWithManifest(sourcePath, staged, {
262
292
  sourceHardlinks: options.sourceHardlinks ?? "allow",
@@ -265,16 +295,23 @@ export async function movePathWithCopyFallback(options) {
265
295
  const cleanupState = createCleanupCopiedEntryState(sourcePath, manifest);
266
296
  unregisterStaged.setIdentity(await fs.lstat(staged, { bigint: true }));
267
297
  await assertCopyDestinationOutsideSource(sourcePath, targetPath, manifest);
268
- await guardedRename({ from: staged, to: targetPath, assertBeforeRename });
269
- stagedCommitted = true;
270
- unregisterStaged();
271
- const cleanupResult = await cleanupCopiedEntry(sourcePath, manifest, cleanupState);
298
+ await guardedRename({
299
+ from: staged,
300
+ to: targetPath,
301
+ assertBeforeRename,
302
+ onSourceInspected,
303
+ onRenamed: () => {
304
+ unregisterStaged();
305
+ onRenamed();
306
+ },
307
+ });
308
+ const cleanupResult = await cleanupCopiedEntry(sourcePath, manifest, cleanupState, assertBeforeMutation);
272
309
  if (cleanupResult === "stale") {
273
310
  throw sourceChangedError(sourcePath);
274
311
  }
275
312
  }
276
313
  finally {
277
- if (!stagedCommitted) {
314
+ if (!destinationPublished) {
278
315
  try {
279
316
  const stagedIdentity = await fs.lstat(staged, { bigint: true });
280
317
  if (!stagedIdentity.isSymbolicLink())
@@ -1,4 +1,5 @@
1
1
  import type { TarMeterLimits } from "./archive-limits.js";
2
+ import type { ArchiveMemberKind } from "./archive-plan.js";
2
3
  export interface NativeFileHash {
3
4
  bytes: number;
4
5
  digest: string;
@@ -16,7 +17,7 @@ export interface NativeFileIdentity {
16
17
  export interface NativeArchiveEntry {
17
18
  index: number;
18
19
  path: string;
19
- kind: string;
20
+ kind: ArchiveMemberKind;
20
21
  size: number;
21
22
  mode: number;
22
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"native-binding.d.ts","sourceRoot":"","sources":["../src/native-binding.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"native-binding.d.ts","sourceRoot":"","sources":["../src/native-binding.ts"],"names":[],"mappings":"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"}
@@ -18,5 +18,4 @@ export declare function removeNativeCreatedFileIfStillPinned(params: {
18
18
  created?: BigIntStats;
19
19
  }): void;
20
20
  export declare function createNativeExclusiveFile(targetPath: string, mode: number): Promise<NativeFileHandle | undefined>;
21
- export declare function syncNativeFileBestEffort(fd: number): void;
22
21
  //# sourceMappingURL=native-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"native-operations.d.ts","sourceRoot":"","sources":["../src/native-operations.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAS5D;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,gBAAgB,EACvB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAsBD,wBAAgB,oCAAoC,CAAC,MAAM,EAAE;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB,GAAG,IAAI,CAqBP;AAED,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAwDvC;AAED,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAQzD"}
1
+ {"version":3,"file":"native-operations.d.ts","sourceRoot":"","sources":["../src/native-operations.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAS5D;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,gBAAgB,EACvB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAsBD,wBAAgB,oCAAoC,CAAC,MAAM,EAAE;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB,GAAG,IAAI,CAqBP;AAED,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAwDvC"}
@@ -130,13 +130,3 @@ export async function createNativeExclusiveFile(targetPath, mode) {
130
130
  await parent.close().catch(() => undefined);
131
131
  }
132
132
  }
133
- export function syncNativeFileBestEffort(fd) {
134
- try {
135
- fsSync.fsyncSync(fd);
136
- }
137
- catch (error) {
138
- if (error.code !== "EPERM") {
139
- throw error;
140
- }
141
- }
142
- }
@@ -1 +1 @@
1
- {"version":3,"file":"native-pinned-write-windows.d.ts","sourceRoot":"","sources":["../src/native-pinned-write-windows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAO3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,EAC3C,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,GAC3C,OAAO,CAET;AAWD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAiF3B"}
1
+ {"version":3,"file":"native-pinned-write-windows.d.ts","sourceRoot":"","sources":["../src/native-pinned-write-windows.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAM3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,EAC3C,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,GAC3C,OAAO,CAET;AAWD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAiF3B"}
@@ -1,7 +1,8 @@
1
+ import { syncFileBestEffortSync } from "./file-sync.js";
1
2
  import { randomUUID } from "node:crypto";
2
3
  import fsSync, {} from "node:fs";
3
4
  import { FsSafeError } from "./errors.js";
4
- import { nativeOpenFlags, removeNativeCreatedFileIfStillPinned, syncNativeFileBestEffort, writeNativeInput, } from "./native-operations.js";
5
+ import { nativeOpenFlags, removeNativeCreatedFileIfStillPinned, writeNativeInput, } from "./native-operations.js";
5
6
  import { inspectFileIdentitySync } from "./strict-file-identity.js";
6
7
  export function sameNativeIdentity(left, right) {
7
8
  return left.dev === right.dev && left.ino === right.ino;
@@ -34,7 +35,8 @@ export async function runPinnedWriteWindows(binding, params, root, parentFd, par
34
35
  // reopenable until the published name has been identity-fenced.
35
36
  fsSync.fchmodSync(tempFd, 0o600);
36
37
  await writeNativeInput(tempFd, params.input, params.maxBytes);
37
- syncNativeFileBestEffort(tempFd);
38
+ if (params.sync !== false)
39
+ syncFileBestEffortSync(tempFd);
38
40
  if (params.overwrite === false) {
39
41
  binding.renameNoReplace(parentFd, tempName, parentFd, params.basename);
40
42
  }
@@ -53,7 +55,8 @@ export async function runPinnedWriteWindows(binding, params, root, parentFd, par
53
55
  // verifiable and so broader modes are never exposed before that fence.
54
56
  try {
55
57
  fsSync.fchmodSync(targetFd, params.mode);
56
- syncNativeFileBestEffort(targetFd);
58
+ if (params.sync !== false)
59
+ syncFileBestEffortSync(targetFd);
57
60
  }
58
61
  catch (error) {
59
62
  closeWriteFd(targetFd);
@@ -66,7 +69,8 @@ export async function runPinnedWriteWindows(binding, params, root, parentFd, par
66
69
  });
67
70
  throw error;
68
71
  }
69
- syncNativeFileBestEffort(parentFd);
72
+ if (params.sync !== false)
73
+ syncFileBestEffortSync(parentFd);
70
74
  // Verification follows publication and final chmod, outside rollback handling.
71
75
  await params.verifyPublished?.(targetFd, verificationIdentity, parentGuard);
72
76
  completed = true;
@@ -103,13 +103,13 @@ export async function runPinnedWriteNative(binding, params) {
103
103
  binding.mkdirBeneath(root.fd, params.relativeParentPath, 0o777);
104
104
  }
105
105
  parentFd = binding.openBeneath(root.fd, params.relativeParentPath, directoryFlags).fd;
106
- const parentPath = await fs.realpath(params.relativeParentPath
106
+ const parentPath = fsSync.realpathSync.native(params.relativeParentPath
107
107
  ? path.join(params.rootPath, ...params.relativeParentPath.split("/"))
108
108
  : params.rootPath);
109
109
  const directory = windows ? undefined : describeStagedDirectory(parentFd, parentPath);
110
110
  const parentPathStat = exactRoot
111
111
  ? await inspectDirectoryIdentity(parentPath, inspectFileIdentitySync(() => fsSync.fstatSync(parentFd, { bigint: true })))
112
- : await fs.lstat(parentPath);
112
+ : fsSync.lstatSync(parentPath);
113
113
  if (windows && !exactRoot) {
114
114
  const parentIdentity = binding.fstatIdentity(parentFd);
115
115
  if (parentPathStat.isSymbolicLink() || !sameNativeIdentity(parentPathStat, parentIdentity)) {
@@ -122,7 +122,7 @@ export async function runPinnedWriteNative(binding, params) {
122
122
  const verificationGuard = { dir: parentPath, realPath: parentPath, stat: parentPathStat };
123
123
  if (params.overwrite === false) {
124
124
  try {
125
- await fs.lstat(path.join(parentPath, params.basename));
125
+ fsSync.lstatSync(path.join(parentPath, params.basename));
126
126
  throw Object.assign(new Error("destination already exists"), { code: "EEXIST" });
127
127
  }
128
128
  catch (error) {
@@ -1,3 +1,4 @@
1
+ import type { DirectoryReceipt } from "./directory-durability.js";
1
2
  import type { AnyAsyncDirectoryGuard } from "./directory-guard.js";
2
3
  import type { FileIdentityStat } from "./file-identity.js";
3
4
  import type { NativeBinding } from "./native-binding.js";
@@ -7,8 +8,8 @@ export type NativeStagingBinding = NativeBinding & Required<Pick<NativeBinding,
7
8
  export declare function assertNativeStaging(binding: NativeBinding): asserts binding is NativeStagingBinding;
8
9
  declare class NativeStagedFile implements StagedFile {
9
10
  #private;
10
- constructor(binding: NativeStagingBinding, parentFd: number, directory: StagedFileReceipt["directory"], portableNames: boolean, publishedMode: number);
11
- static create(binding: NativeStagingBinding, parentFd: number, directory: StagedFileReceipt["directory"], input: PinnedWriteInput, mode: number, maxBytes?: number, portableNames?: boolean): Promise<NativeStagedFile>;
11
+ constructor(binding: NativeStagingBinding, parentFd: number, directory: StagedFileReceipt["directory"], portableNames: boolean, publishedMode: number, sync: boolean);
12
+ static create(binding: NativeStagingBinding, parentFd: number, directory: StagedFileReceipt["directory"], input: PinnedWriteInput, mode: number, maxBytes?: number, portableNames?: boolean, sync?: boolean): Promise<NativeStagedFile>;
12
13
  static write(binding: NativeStagingBinding, parentFd: number, directory: StagedFileReceipt["directory"], params: PinnedWriteParams, parentGuard: AnyAsyncDirectoryGuard): Promise<FileIdentityStat>;
13
14
  get receipt(): StagedFileReceipt;
14
15
  assertCurrent(): Promise<void>;
@@ -20,5 +21,11 @@ declare class NativeStagedFile implements StagedFile {
20
21
  }
21
22
  export declare const createNativeStage: (...args: Parameters<typeof NativeStagedFile.create>) => Promise<StagedFile>;
22
23
  export declare const writeNativeStage: typeof NativeStagedFile.write;
23
- export {};
24
+ export type { PublishedFileReceipt, StagedFile, StagedFileCleanupReceipt, StagedFileFailureDetails, StagedFilePublication, StagedFileReceipt, } from "./staged-file-types.js";
25
+ export declare function stageFileInDirectory(options: {
26
+ directory: string | DirectoryReceipt;
27
+ content: string | Uint8Array;
28
+ /** Published mode; the unpublished stage stays at 0600. Defaults to 0600. */
29
+ mode?: number;
30
+ }): Promise<StagedFile>;
24
31
  //# sourceMappingURL=native-staged-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"native-staged-file.d.ts","sourceRoot":"","sources":["../src/native-staged-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,EACV,wBAAwB,EAGxB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,QAAQ,CAAC,IAAI,CAC9D,aAAa,EACb,kBAAkB,GAAG,mBAAmB,GAAG,kBAAkB,CAC9D,CAAC,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,IAAI,oBAAoB,CAUnG;AA6BD,cAAM,gBAAiB,YAAW,UAAU;;IAU1C,YACE,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC,EACzC,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,MAAM,EAOtB;IAGD,OAAa,MAAM,CACjB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC,EACzC,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EAEjB,aAAa,UAAO,GACnB,OAAO,CAAC,gBAAgB,CAAC,CAc3B;IAED,OAAa,KAAK,CAChB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC,EACzC,MAAM,EAAE,iBAAiB,EACzB,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAU3B;IAED,IAAI,OAAO,IAAI,iBAAiB,CAK/B;IAoFK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnC;IAEK,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgD9F;IA6CK,OAAO,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAMjD;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAO3C;CACF;AAED,eAAO,MAAM,iBAAiB,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,UAAU,CAClF,CAAC;AAC1B,eAAO,MAAM,gBAAgB,+BAAyB,CAAC"}
1
+ {"version":3,"file":"native-staged-file.d.ts","sourceRoot":"","sources":["../src/native-staged-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAKlE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,EACV,wBAAwB,EAGxB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,QAAQ,CAAC,IAAI,CAC9D,aAAa,EACb,kBAAkB,GAAG,mBAAmB,GAAG,kBAAkB,CAC9D,CAAC,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,IAAI,oBAAoB,CAUnG;AA6BD,cAAM,gBAAiB,YAAW,UAAU;;IAW1C,YACE,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC,EACzC,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,OAAO,EAQd;IAGD,OAAa,MAAM,CACjB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC,EACzC,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EAEjB,aAAa,UAAO,EACpB,IAAI,UAAO,GACV,OAAO,CAAC,gBAAgB,CAAC,CAc3B;IAED,OAAa,KAAK,CAChB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC,EACzC,MAAM,EAAE,iBAAiB,EACzB,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAU3B;IAED,IAAI,OAAO,IAAI,iBAAiB,CAK/B;IAoFK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnC;IAEK,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAqD9F;IA6CK,OAAO,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAMjD;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAO3C;CACF;AAED,eAAO,MAAM,iBAAiB,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,UAAU,CAClF,CAAC;AAC1B,eAAO,MAAM,gBAAgB,+BAAyB,CAAC;AAEvD,YAAY,EACV,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,wBAAwB,EACpF,qBAAqB,EAAE,iBAAiB,GACzC,MAAM,wBAAwB,CAAC;AAEhC,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACrC,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,UAAU,CAAC,CAUtB"}
@@ -50,11 +50,13 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
50
50
  var e = new Error(message);
51
51
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
52
  });
53
+ import { requireNativeBinding } from "./native.js";
54
+ import { syncFileBestEffortSync } from "./file-sync.js";
53
55
  import { randomUUID } from "node:crypto";
54
56
  import fs from "node:fs";
55
57
  import { FsSafeError } from "./errors.js";
56
- import { syncNativeFileBestEffort, writeNativeInput } from "./native-operations.js";
57
- import { assertStagedDirectoryCurrent } from "./staged-directory.js";
58
+ import { writeNativeInput } from "./native-operations.js";
59
+ import { assertStagedDirectoryCurrent, openStagedDirectory } from "./staged-directory.js";
58
60
  export function assertNativeStaging(binding) {
59
61
  if ([
60
62
  binding.createStagedFile,
@@ -90,23 +92,25 @@ class NativeStagedFile {
90
92
  #directory;
91
93
  #portableNames;
92
94
  #publishedMode;
95
+ #sync;
93
96
  #name = `.fs-safe-${randomUUID()}.tmp`;
94
97
  #state = { status: "open", publication: NOT_PUBLISHED };
95
98
  #receipt;
96
- constructor(binding, parentFd, directory, portableNames, publishedMode) {
99
+ constructor(binding, parentFd, directory, portableNames, publishedMode, sync) {
97
100
  this.#binding = binding;
98
101
  this.#parentFd = parentFd;
99
102
  this.#directory = directory;
100
103
  this.#portableNames = portableNames;
101
104
  this.#publishedMode = publishedMode;
105
+ this.#sync = sync;
102
106
  }
103
107
  // Takes ownership of parentFd, including all construction and preparation failures.
104
108
  static async create(binding, parentFd, directory, input, mode, maxBytes,
105
109
  // Public staging uses portable names; existing POSIX writes accept literal names.
106
- portableNames = true) {
110
+ portableNames = true, sync = true) {
107
111
  let staged;
108
112
  try {
109
- staged = new NativeStagedFile(binding, parentFd, directory, portableNames, mode);
113
+ staged = new NativeStagedFile(binding, parentFd, directory, portableNames, mode, sync);
110
114
  }
111
115
  catch (error) {
112
116
  try {
@@ -125,7 +129,7 @@ class NativeStagedFile {
125
129
  try {
126
130
  // This owner never escapes. Only the internal verifier borrows its fd;
127
131
  // public descriptor methods remain await-free and cannot race disposal.
128
- const staged = __addDisposableResource(env_1, await NativeStagedFile.create(binding, parentFd, directory, params.input, params.mode, params.maxBytes, false), true);
132
+ const staged = __addDisposableResource(env_1, await NativeStagedFile.create(binding, parentFd, directory, params.input, params.mode, params.maxBytes, false, params.sync), true);
129
133
  const published = await staged.publish(params.basename, { overwrite: params.overwrite !== false });
130
134
  const identity = published.staged.identity;
131
135
  await params.verifyPublished?.(staged.#file(), identity, parentGuard);
@@ -162,10 +166,12 @@ class NativeStagedFile {
162
166
  }
163
167
  #assertNamed(name) {
164
168
  const fd = this.#file();
165
- if (!this.#binding.stagedFileMatches(this.#parentFd, name, fd) ||
166
- fs.fstatSync(fd, { bigint: true }).nlink !== 1n) {
169
+ const stat = this.#binding.stagedFileMatches(this.#parentFd, name, fd)
170
+ ? fs.fstatSync(fd, { bigint: true }) : undefined;
171
+ if (!stat || stat.nlink !== 1n) {
167
172
  throw new FsSafeError("path-mismatch", "staged entry no longer names the exclusive created file");
168
173
  }
174
+ return Number(stat.mode & 4095n);
169
175
  }
170
176
  #assertCurrent() {
171
177
  if (this.#open().publication.status !== "not-published") {
@@ -188,7 +194,8 @@ class NativeStagedFile {
188
194
  const fd = state.fileFd;
189
195
  fs.fchmodSync(fd, 0o600);
190
196
  await writeNativeInput(fd, input, maxBytes);
191
- syncNativeFileBestEffort(fd);
197
+ if (this.#sync)
198
+ syncFileBestEffortSync(fd);
192
199
  const stat = fs.fstatSync(fd, { bigint: true });
193
200
  this.#receipt = Object.freeze({
194
201
  directory: this.#directory,
@@ -255,14 +262,21 @@ class NativeStagedFile {
255
262
  overwrite,
256
263
  });
257
264
  state.publication = receipt;
258
- this.#assertNamed(basename);
265
+ const stagedMode = this.#assertNamed(basename);
259
266
  assertStagedDirectoryCurrent(this.#directory);
260
267
  // Keep contents private until the published name passes its identity
261
268
  // fence. Mode changes use the owned fd, including for final mode 000.
262
269
  const fd = this.#file();
263
- fs.fchmodSync(fd, this.#publishedMode);
264
- syncNativeFileBestEffort(fd);
265
- syncNativeFileBestEffort(this.#parentFd);
270
+ if (this.#publishedMode !== 0o600 || stagedMode !== 0o600)
271
+ fs.fchmodSync(fd, this.#publishedMode);
272
+ // With sync enabled, content was synced before rename. A lost chmod leaves staged 0600,
273
+ // no wider than modes retaining owner rw. Restrictive modes and observed
274
+ // widening of the stage still need the permission correction made durable.
275
+ if (this.#sync && ((this.#publishedMode & 0o600) !== 0o600 || (stagedMode & ~this.#publishedMode) !== 0)) {
276
+ syncFileBestEffortSync(fd);
277
+ }
278
+ if (this.#sync)
279
+ syncFileBestEffortSync(this.#parentFd);
266
280
  this.#assertNamed(basename);
267
281
  assertStagedDirectoryCurrent(this.#directory);
268
282
  return receipt;
@@ -335,3 +349,14 @@ class NativeStagedFile {
335
349
  }
336
350
  export const createNativeStage = NativeStagedFile.create;
337
351
  export const writeNativeStage = NativeStagedFile.write;
352
+ export async function stageFileInDirectory(options) {
353
+ if (process.platform !== "linux" && process.platform !== "darwin") {
354
+ throw new FsSafeError("unsupported-platform", "retained-directory staging requires Linux or macOS");
355
+ }
356
+ const binding = requireNativeBinding();
357
+ assertNativeStaging(binding);
358
+ const input = { kind: "buffer", data: Buffer.from(options.content) };
359
+ const mode = options.mode ?? 0o600;
360
+ const parent = openStagedDirectory(options.directory);
361
+ return await createNativeStage(binding, parent.fd, parent.receipt, input, mode);
362
+ }
@@ -1,5 +1,16 @@
1
+ import type { BigIntStats, Stats } from "node:fs";
1
2
  import type { FileHandle } from "node:fs/promises";
2
3
  import { type FileIdentityStat } from "./file-identity.js";
3
4
  export declare function resolveOpenedFileRealPathForHandle(handle: FileHandle, ioPath: string): Promise<string>;
4
- export declare function resolveOpenedFileRealPathForFd(fd: number, handleStat: FileIdentityStat, ioPath: string): Promise<string>;
5
+ export declare function resolveOpenedFileRealPathForFd(fd: number, handleStat: {
6
+ dev: bigint;
7
+ ino: bigint;
8
+ }, ioPath: string): Promise<{
9
+ realPath: string;
10
+ stat: BigIntStats;
11
+ }>;
12
+ export declare function resolveOpenedFileRealPathForFd(fd: number, handleStat: FileIdentityStat, ioPath: string): Promise<{
13
+ realPath: string;
14
+ stat: Stats | BigIntStats;
15
+ }>;
5
16
  //# sourceMappingURL=opened-realpath.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opened-realpath.d.ts","sourceRoot":"","sources":["../src/opened-realpath.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG7E,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,gBAAgB,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CA2CjB"}
1
+ {"version":3,"file":"opened-realpath.d.ts","sourceRoot":"","sources":["../src/opened-realpath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG7E,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,MAAM,EACV,UAAU,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACxC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AACpD,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,gBAAgB,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,WAAW,CAAA;CAAE,CAAC,CAAC"}
@@ -1,26 +1,25 @@
1
+ import fsSync from "node:fs";
1
2
  import fs from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  import { openedPathResolutionError } from "./opened-file-failure.js";
4
5
  import { sameFileIdentity } from "./file-identity.js";
5
6
  import { isNotFoundPathError } from "./path.js";
6
7
  export async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
7
- const handleStat = await handle.stat();
8
- return await resolveOpenedFileRealPathForFd(handle.fd, handleStat, ioPath);
8
+ const handleStat = fsSync.fstatSync(handle.fd);
9
+ return (await resolveOpenedFileRealPathForFd(handle.fd, handleStat, ioPath)).realPath;
9
10
  }
10
11
  export async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
11
12
  const statOptions = typeof handleStat.dev === "bigint" || typeof handleStat.ino === "bigint"
12
13
  ? { bigint: true } : undefined;
13
14
  const fdCandidates = process.platform === "linux"
14
15
  ? [`/proc/self/fd/${fd}`, `/dev/fd/${fd}`]
15
- : process.platform === "win32"
16
- ? []
17
- : [`/dev/fd/${fd}`];
16
+ : [];
18
17
  for (const fdPath of fdCandidates) {
19
18
  try {
20
- const fdRealPath = await fs.realpath(fdPath);
21
- const fdRealStat = statOptions ? await fs.stat(fdRealPath, statOptions) : await fs.stat(fdRealPath);
19
+ const fdRealPath = fsSync.realpathSync.native(fdPath);
20
+ const fdRealStat = statOptions ? fsSync.statSync(fdRealPath, statOptions) : fsSync.statSync(fdRealPath);
22
21
  if (sameFileIdentity(handleStat, fdRealStat)) {
23
- return fdRealPath;
22
+ return { realPath: fdRealPath, stat: fdRealStat };
24
23
  }
25
24
  }
26
25
  catch {
@@ -28,10 +27,10 @@ export async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
28
27
  }
29
28
  }
30
29
  try {
31
- const ioRealPath = await fs.realpath(ioPath);
32
- const ioRealStat = statOptions ? await fs.stat(ioRealPath, statOptions) : await fs.stat(ioRealPath);
30
+ const ioRealPath = fsSync.realpathSync.native(ioPath);
31
+ const ioRealStat = statOptions ? fsSync.statSync(ioRealPath, statOptions) : fsSync.statSync(ioRealPath);
33
32
  if (sameFileIdentity(handleStat, ioRealStat)) {
34
- return ioRealPath;
33
+ return { realPath: ioRealPath, stat: ioRealStat };
35
34
  }
36
35
  }
37
36
  catch (err) {
@@ -54,7 +53,7 @@ export async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
54
53
  async function resolveOpenedFileRealPathFromParent(handleStat, ioPath, statOptions) {
55
54
  let parentReal;
56
55
  try {
57
- parentReal = await fs.realpath(path.dirname(ioPath));
56
+ parentReal = fsSync.realpathSync.native(path.dirname(ioPath));
58
57
  }
59
58
  catch (err) {
60
59
  if (isNotFoundPathError(err)) {
@@ -75,9 +74,12 @@ async function resolveOpenedFileRealPathFromParent(handleStat, ioPath, statOptio
75
74
  for (const entry of entries.toSorted()) {
76
75
  const candidatePath = path.join(parentReal, entry);
77
76
  try {
78
- const candidateStat = statOptions ? await fs.lstat(candidatePath, statOptions) : await fs.lstat(candidatePath);
77
+ const candidateStat = statOptions ? fsSync.lstatSync(candidatePath, statOptions) : fsSync.lstatSync(candidatePath);
79
78
  if (candidateStat.isFile() && sameFileIdentity(handleStat, candidateStat)) {
80
- return await fs.realpath(candidatePath);
79
+ const realPath = fsSync.realpathSync.native(candidatePath);
80
+ const stat = statOptions ? fsSync.statSync(realPath, statOptions) : fsSync.statSync(realPath);
81
+ if (sameFileIdentity(handleStat, stat))
82
+ return { realPath, stat };
81
83
  }
82
84
  }
83
85
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAyDF,wBAAsB,2BAA2B,CAAC,CAAC,GAAG,IAAI,EACxD,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC,GACnC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAgDrC"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAyDF,wBAAsB,2BAA2B,CAAC,CAAC,GAAG,IAAI,EACxD,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC,GACnC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAgDrC"}
package/dist/output.js CHANGED
@@ -1,9 +1,10 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { writeCallbackSibling } from "./sibling-staged-file.js";
1
3
  import path from "node:path";
2
4
  import { normalizeMaxBytes } from "./byte-budget.js";
3
5
  import { FsSafeError } from "./errors.js";
4
- import { sanitizeUntrustedFileName } from "./filename.js";
6
+ import { fitFileNameToPortableComponent, sanitizeUntrustedFileName } from "./filename.js";
5
7
  import { isPathInside } from "./path.js";
6
- import { writeExternalFileViaSibling } from "./output-sibling.js";
7
8
  import { root } from "./root.js";
8
9
  import { tempFile } from "./temp-target.js";
9
10
  const NON_PORTABLE_FILE_NAME_CHARACTERS = /[\u0000-\u001f\u007f-\u009f<>:"/\\|?*]/u;
@@ -97,3 +98,26 @@ export async function writeExternalFileWithinRoot(options) {
97
98
  await staged.cleanup();
98
99
  }
99
100
  }
101
+ function buildSiblingTempPath(targetPath, fallbackFileName) {
102
+ const prefix = `.fs-safe-output-${process.pid}-${randomUUID()}-`;
103
+ const suffix = ".part";
104
+ const safeTail = fitFileNameToPortableComponent({
105
+ prefix,
106
+ fileName: tempFileNameForTarget(targetPath, fallbackFileName),
107
+ suffix,
108
+ });
109
+ return path.join(path.dirname(targetPath), `${prefix}${safeTail}${suffix}`);
110
+ }
111
+ async function writeExternalFileViaSibling(params) {
112
+ const finalPath = path.resolve(params.finalPath);
113
+ const { result } = await writeCallbackSibling({
114
+ tempPath: buildSiblingTempPath(finalPath, params.fallbackFileName),
115
+ write: params.write,
116
+ resolveFinalPath: () => finalPath,
117
+ mode: params.mode,
118
+ maxBytes: params.maxBytes,
119
+ syncTempFile: true,
120
+ syncParentDir: true,
121
+ });
122
+ return result;
123
+ }
@@ -1,7 +1,7 @@
1
- import fs from "node:fs/promises";
1
+ import fs from "node:fs";
2
2
  import { ROOT_PATH_ALIAS_POLICIES, resolveRootPath, } from "./root-path.js";
3
3
  import { isNotFoundPathError } from "./path.js";
4
- import { shortPath } from "./short-path.js";
4
+ import { shortPath } from "./error-detail.js";
5
5
  export const PATH_ALIAS_POLICIES = ROOT_PATH_ALIAS_POLICIES;
6
6
  export async function assertNoPathAliasEscape(params) {
7
7
  const resolved = await resolveRootPath({
@@ -27,7 +27,7 @@ export async function assertNoHardlinkedFinalPath(params) {
27
27
  }
28
28
  let stat;
29
29
  try {
30
- stat = await fs.stat(params.filePath);
30
+ stat = fs.statSync(params.filePath);
31
31
  }
32
32
  catch (err) {
33
33
  if (isNotFoundPathError(err)) {
@@ -56,4 +56,5 @@ export declare function isWorldWritable(bits: number | null): boolean;
56
56
  export declare function isGroupWritable(bits: number | null): boolean;
57
57
  export declare function isWorldReadable(bits: number | null): boolean;
58
58
  export declare function isGroupReadable(bits: number | null): boolean;
59
+ export declare function formatPosixMode(mode: number): string;
59
60
  //# sourceMappingURL=permissions.d.ts.map