@neottia/repository-store 0.2.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/LICENSE +21 -0
- package/README.md +76 -0
- package/binding.gyp +9 -0
- package/dist/errors.d.ts +43 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +69 -0
- package/dist/errors.js.map +1 -0
- package/dist/files.d.ts +19 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +113 -0
- package/dist/files.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/fault-injection.d.ts +13 -0
- package/dist/internal/fault-injection.d.ts.map +1 -0
- package/dist/internal/fault-injection.js +68 -0
- package/dist/internal/fault-injection.js.map +1 -0
- package/dist/internal/filesystem.d.ts +25 -0
- package/dist/internal/filesystem.d.ts.map +1 -0
- package/dist/internal/filesystem.js +199 -0
- package/dist/internal/filesystem.js.map +1 -0
- package/dist/internal/model.d.ts +43 -0
- package/dist/internal/model.d.ts.map +1 -0
- package/dist/internal/model.js +49 -0
- package/dist/internal/model.js.map +1 -0
- package/dist/internal/native-publication.d.ts +9 -0
- package/dist/internal/native-publication.d.ts.map +1 -0
- package/dist/internal/native-publication.js +65 -0
- package/dist/internal/native-publication.js.map +1 -0
- package/dist/internal/publication.d.ts +10 -0
- package/dist/internal/publication.d.ts.map +1 -0
- package/dist/internal/publication.js +223 -0
- package/dist/internal/publication.js.map +1 -0
- package/dist/lease.d.ts +24 -0
- package/dist/lease.d.ts.map +1 -0
- package/dist/lease.js +932 -0
- package/dist/lease.js.map +1 -0
- package/dist/limits.d.ts +15 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +14 -0
- package/dist/limits.js.map +1 -0
- package/dist/paths.d.ts +15 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +58 -0
- package/dist/paths.js.map +1 -0
- package/dist/revision.d.ts +4 -0
- package/dist/revision.d.ts.map +1 -0
- package/dist/revision.js +8 -0
- package/dist/revision.js.map +1 -0
- package/dist/sqlite/adapter.d.ts +48 -0
- package/dist/sqlite/adapter.d.ts.map +1 -0
- package/dist/sqlite/adapter.js +183 -0
- package/dist/sqlite/adapter.js.map +1 -0
- package/dist/sqlite/bun.d.ts +2 -0
- package/dist/sqlite/bun.d.ts.map +1 -0
- package/dist/sqlite/bun.js +7 -0
- package/dist/sqlite/bun.js.map +1 -0
- package/dist/sqlite/cache-publication.d.ts +6 -0
- package/dist/sqlite/cache-publication.d.ts.map +1 -0
- package/dist/sqlite/cache-publication.js +191 -0
- package/dist/sqlite/cache-publication.js.map +1 -0
- package/dist/sqlite/cache.d.ts +26 -0
- package/dist/sqlite/cache.d.ts.map +1 -0
- package/dist/sqlite/cache.js +527 -0
- package/dist/sqlite/cache.js.map +1 -0
- package/dist/sqlite/node.d.ts +2 -0
- package/dist/sqlite/node.d.ts.map +1 -0
- package/dist/sqlite/node.js +6 -0
- package/dist/sqlite/node.js.map +1 -0
- package/dist/sqlite/runtime.d.ts +4 -0
- package/dist/sqlite/runtime.d.ts.map +1 -0
- package/dist/sqlite/runtime.js +34 -0
- package/dist/sqlite/runtime.js.map +1 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +2 -0
- package/dist/testing.js.map +1 -0
- package/dist/transaction/apply.d.ts +8 -0
- package/dist/transaction/apply.d.ts.map +1 -0
- package/dist/transaction/apply.js +273 -0
- package/dist/transaction/apply.js.map +1 -0
- package/dist/transaction/journal.d.ts +17 -0
- package/dist/transaction/journal.d.ts.map +1 -0
- package/dist/transaction/journal.js +207 -0
- package/dist/transaction/journal.js.map +1 -0
- package/dist/transaction/recovery.d.ts +6 -0
- package/dist/transaction/recovery.d.ts.map +1 -0
- package/dist/transaction/recovery.js +138 -0
- package/dist/transaction/recovery.js.map +1 -0
- package/dist/transaction/types.d.ts +45 -0
- package/dist/transaction/types.d.ts.map +1 -0
- package/dist/transaction/types.js +2 -0
- package/dist/transaction/types.js.map +1 -0
- package/native/rename_noreplace.cc +145 -0
- package/package.json +71 -0
- package/scripts/install-native.mjs +10 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { closeSync, constants as fsConstants, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readSync, } from 'node:fs';
|
|
2
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { DurabilityError, PathSafetyError, ResourceLimitError } from '../errors.js';
|
|
4
|
+
import { emitFilesystemFault } from './fault-injection.js';
|
|
5
|
+
export function noFollowFlag() {
|
|
6
|
+
return typeof fsConstants.O_NOFOLLOW === 'number' ? fsConstants.O_NOFOLLOW : 0;
|
|
7
|
+
}
|
|
8
|
+
export function hasCode(error, code) {
|
|
9
|
+
return error instanceof Error && 'code' in error && error.code === code;
|
|
10
|
+
}
|
|
11
|
+
export function sameIdentity(left, right) {
|
|
12
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
13
|
+
}
|
|
14
|
+
export function ensurePrivateDirectory(target) {
|
|
15
|
+
const missing = [];
|
|
16
|
+
let current = resolve(target);
|
|
17
|
+
while (true) {
|
|
18
|
+
try {
|
|
19
|
+
const stat = lstatSync(current);
|
|
20
|
+
if (stat.isSymbolicLink() || !stat.isDirectory())
|
|
21
|
+
throw unsafe(`Unsafe directory: ${current}`);
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (!hasCode(error, 'ENOENT'))
|
|
26
|
+
throw error;
|
|
27
|
+
const parent = dirname(current);
|
|
28
|
+
if (parent === current)
|
|
29
|
+
throw unsafe(`Cannot resolve directory ancestor: ${target}`);
|
|
30
|
+
missing.unshift(basename(current));
|
|
31
|
+
current = parent;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
for (const component of missing) {
|
|
35
|
+
current = join(current, component);
|
|
36
|
+
try {
|
|
37
|
+
mkdirSync(current, { mode: 0o700 });
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (!hasCode(error, 'EEXIST'))
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
const stat = lstatSync(current);
|
|
44
|
+
if (stat.isSymbolicLink() || !stat.isDirectory())
|
|
45
|
+
throw unsafe(`Unsafe directory: ${current}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function captureDirectories(directory) {
|
|
49
|
+
const paths = ancestorPaths(resolve(directory));
|
|
50
|
+
const identities = [];
|
|
51
|
+
for (const path of paths) {
|
|
52
|
+
const stat = lstatSync(path);
|
|
53
|
+
if (stat.isSymbolicLink() || !stat.isDirectory())
|
|
54
|
+
throw unsafe(`Unsafe directory ancestor: ${path}`);
|
|
55
|
+
identities.push({ path, stat });
|
|
56
|
+
}
|
|
57
|
+
return identities;
|
|
58
|
+
}
|
|
59
|
+
function ancestorPaths(path) {
|
|
60
|
+
const parent = dirname(path);
|
|
61
|
+
return parent === path ? [path] : [...ancestorPaths(parent), path];
|
|
62
|
+
}
|
|
63
|
+
export function revalidateDirectories(identities) {
|
|
64
|
+
for (const identity of identities) {
|
|
65
|
+
let current;
|
|
66
|
+
try {
|
|
67
|
+
current = lstatSync(identity.path);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
throw unsafe(`Directory changed during access: ${identity.path}`, 'IDENTITY_CHANGED', error);
|
|
71
|
+
}
|
|
72
|
+
if (current.isSymbolicLink() || !current.isDirectory() || !sameIdentity(identity.stat, current))
|
|
73
|
+
throw unsafe(`Directory changed during access: ${identity.path}`, 'IDENTITY_CHANGED');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function readRegularFile(path, maxBytes, options = {}) {
|
|
77
|
+
return readRegularFileWithIdentity(path, maxBytes, options).bytes;
|
|
78
|
+
}
|
|
79
|
+
export function readRegularFileWithIdentity(path, maxBytes, options = {}) {
|
|
80
|
+
const parents = captureDirectories(dirname(path));
|
|
81
|
+
const allowedLinkCounts = options.allowedLinkCounts ?? [1];
|
|
82
|
+
let descriptor;
|
|
83
|
+
try {
|
|
84
|
+
descriptor = openSync(path, fsConstants.O_RDONLY | noFollowFlag());
|
|
85
|
+
const before = fstatSync(descriptor);
|
|
86
|
+
assertRegularWithLinks(before, path, allowedLinkCounts);
|
|
87
|
+
if (before.size > maxBytes)
|
|
88
|
+
throw new ResourceLimitError(`Managed file exceeds configured byte limit: ${path}`);
|
|
89
|
+
const pathBefore = lstatSync(path);
|
|
90
|
+
if (pathBefore.isSymbolicLink() || !sameIdentity(before, pathBefore))
|
|
91
|
+
throw unsafe(`Managed file identity changed before read: ${path}`, 'IDENTITY_CHANGED');
|
|
92
|
+
emitFilesystemFault('bounded-read-opened', path);
|
|
93
|
+
const capacity = Math.min(maxBytes + 1, before.size + 1);
|
|
94
|
+
const buffer = Buffer.allocUnsafe(capacity);
|
|
95
|
+
let offset = 0;
|
|
96
|
+
while (offset < buffer.byteLength) {
|
|
97
|
+
const count = readSync(descriptor, buffer, offset, buffer.byteLength - offset, offset);
|
|
98
|
+
if (count === 0)
|
|
99
|
+
break;
|
|
100
|
+
offset += count;
|
|
101
|
+
}
|
|
102
|
+
if (offset > maxBytes)
|
|
103
|
+
throw new ResourceLimitError(`Managed file exceeds configured byte limit: ${path}`);
|
|
104
|
+
const after = fstatSync(descriptor);
|
|
105
|
+
assertRegularWithLinks(after, path, allowedLinkCounts);
|
|
106
|
+
if (!sameIdentity(before, after) ||
|
|
107
|
+
before.size !== after.size ||
|
|
108
|
+
before.mtimeMs !== after.mtimeMs ||
|
|
109
|
+
before.ctimeMs !== after.ctimeMs ||
|
|
110
|
+
before.nlink !== after.nlink ||
|
|
111
|
+
offset !== before.size)
|
|
112
|
+
throw unsafe(`Managed file changed during read: ${path}`, 'IDENTITY_CHANGED');
|
|
113
|
+
const pathAfter = lstatSync(path);
|
|
114
|
+
if (pathAfter.isSymbolicLink() || !sameIdentity(after, pathAfter))
|
|
115
|
+
throw unsafe(`Managed file identity changed after read: ${path}`, 'IDENTITY_CHANGED');
|
|
116
|
+
revalidateDirectories(parents);
|
|
117
|
+
return { bytes: buffer.subarray(0, offset), identity: after };
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (error instanceof PathSafetyError || error instanceof ResourceLimitError)
|
|
121
|
+
throw error;
|
|
122
|
+
if (hasCode(error, 'ELOOP'))
|
|
123
|
+
throw unsafe(`Symbolic link is not allowed: ${path}`, 'UNSAFE_LINK', error);
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
if (descriptor !== undefined)
|
|
128
|
+
closeSync(descriptor);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function assertSafeRegular(stat, path) {
|
|
132
|
+
assertRegularWithLinks(stat, path, [1]);
|
|
133
|
+
}
|
|
134
|
+
function assertRegularWithLinks(stat, path, allowedLinkCounts) {
|
|
135
|
+
if (stat.isSymbolicLink() || !stat.isFile())
|
|
136
|
+
throw unsafe(`Managed path is not a regular file: ${path}`, 'UNSAFE_LINK');
|
|
137
|
+
if (!allowedLinkCounts.includes(stat.nlink))
|
|
138
|
+
throw unsafe(`Managed file has an unsafe hard-link count: ${path}`, 'UNSAFE_HARD_LINK');
|
|
139
|
+
}
|
|
140
|
+
export function syncFileDescriptor(descriptor, path) {
|
|
141
|
+
try {
|
|
142
|
+
emitFilesystemFault('file-fsync', path);
|
|
143
|
+
fsyncSync(descriptor);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
throw new DurabilityError(`Failed to synchronize file: ${path}`, {
|
|
147
|
+
cause: error,
|
|
148
|
+
evidence: { operation: 'file-fsync', path },
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
export function syncRegularFile(path) {
|
|
153
|
+
let descriptor;
|
|
154
|
+
try {
|
|
155
|
+
descriptor = openSync(path, fsConstants.O_RDONLY | noFollowFlag());
|
|
156
|
+
const opened = fstatSync(descriptor);
|
|
157
|
+
assertSafeRegular(opened, path);
|
|
158
|
+
syncFileDescriptor(descriptor, path);
|
|
159
|
+
const current = lstatSync(path);
|
|
160
|
+
if (!sameIdentity(opened, current))
|
|
161
|
+
throw unsafe(`File changed during synchronization: ${path}`, 'IDENTITY_CHANGED');
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
if (descriptor !== undefined)
|
|
165
|
+
closeSync(descriptor);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export function syncDirectory(path) {
|
|
169
|
+
if (process.platform === 'win32')
|
|
170
|
+
return;
|
|
171
|
+
let descriptor;
|
|
172
|
+
try {
|
|
173
|
+
descriptor = openSync(path, fsConstants.O_RDONLY | fsConstants.O_DIRECTORY | noFollowFlag());
|
|
174
|
+
const stat = fstatSync(descriptor);
|
|
175
|
+
if (!stat.isDirectory())
|
|
176
|
+
throw unsafe(`Unsafe directory: ${path}`);
|
|
177
|
+
try {
|
|
178
|
+
emitFilesystemFault('directory-fsync', path);
|
|
179
|
+
fsyncSync(descriptor);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
throw new DurabilityError(`Failed to synchronize directory: ${path}`, {
|
|
183
|
+
cause: error,
|
|
184
|
+
evidence: { operation: 'directory-fsync', path },
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
if (descriptor !== undefined)
|
|
190
|
+
closeSync(descriptor);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function unsafe(message, code = 'UNSAFE_LINK', cause) {
|
|
194
|
+
const error = new PathSafetyError(message, code);
|
|
195
|
+
if (cause !== undefined)
|
|
196
|
+
Object.defineProperty(error, 'cause', { value: cause, enumerable: false });
|
|
197
|
+
return error;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/internal/filesystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Stats } from 'node:fs';
|
|
2
|
+
import type { StoreLimits } from '../limits.js';
|
|
3
|
+
export interface RootState {
|
|
4
|
+
readonly authorityRoot: string;
|
|
5
|
+
readonly managedRoot: string;
|
|
6
|
+
readonly authorityId: string;
|
|
7
|
+
readonly managedRootId: string;
|
|
8
|
+
readonly limits: StoreLimits;
|
|
9
|
+
}
|
|
10
|
+
export interface PathState {
|
|
11
|
+
readonly authorityId: string;
|
|
12
|
+
readonly managedRootId: string;
|
|
13
|
+
readonly absolutePath: string;
|
|
14
|
+
}
|
|
15
|
+
export interface LeaseState {
|
|
16
|
+
readonly authorityId: string;
|
|
17
|
+
readonly token: string;
|
|
18
|
+
readonly lockPath: string;
|
|
19
|
+
readonly lockIdentity: Stats;
|
|
20
|
+
readonly ownerIdentity: Stats;
|
|
21
|
+
readonly pendingOperations: Set<Promise<unknown>>;
|
|
22
|
+
active: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface ManagedRoot {
|
|
25
|
+
readonly authorityRoot: string;
|
|
26
|
+
readonly managedRoot: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ManagedPath {
|
|
29
|
+
readonly relativePath: string;
|
|
30
|
+
}
|
|
31
|
+
export interface RepositoryLease {
|
|
32
|
+
readonly authorityRoot: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function createManagedRoot(state: RootState): ManagedRoot;
|
|
35
|
+
export declare function createManagedPath(relativePath: string, state: PathState): ManagedPath;
|
|
36
|
+
export declare function createRepositoryLease(authorityRoot: string, state: LeaseState): RepositoryLease;
|
|
37
|
+
export declare function getRootState(root: ManagedRoot): RootState | undefined;
|
|
38
|
+
export declare function getPathState(path: ManagedPath): PathState | undefined;
|
|
39
|
+
export declare function requireRootState(root: ManagedRoot): RootState;
|
|
40
|
+
export declare function requirePathState(path: ManagedPath): PathState;
|
|
41
|
+
export declare function getLeaseState(lease: RepositoryLease): LeaseState | undefined;
|
|
42
|
+
export declare function managedPathBelongsToRoot(root: ManagedRoot, path: ManagedPath): boolean;
|
|
43
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/internal/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAGD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAGD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,MAAM,EAAE,OAAO,CAAC;CACjB;AAGD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAGD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAGD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AASD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAI/D;AAGD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW,CAIrF;AAGD,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,eAAe,CAI/F;AAGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAErE;AAGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAErE;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,CAI7D;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,CAI7D;AAGD,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,GAAG,SAAS,CAE5E;AAGD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAStF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PathSafetyError } from '../errors.js';
|
|
2
|
+
const rootStates = new WeakMap();
|
|
3
|
+
const pathStates = new WeakMap();
|
|
4
|
+
const leaseStates = new WeakMap();
|
|
5
|
+
export function createManagedRoot(state) {
|
|
6
|
+
const root = Object.freeze({ authorityRoot: state.authorityRoot, managedRoot: state.managedRoot });
|
|
7
|
+
rootStates.set(root, state);
|
|
8
|
+
return root;
|
|
9
|
+
}
|
|
10
|
+
export function createManagedPath(relativePath, state) {
|
|
11
|
+
const path = Object.freeze({ relativePath });
|
|
12
|
+
pathStates.set(path, state);
|
|
13
|
+
return path;
|
|
14
|
+
}
|
|
15
|
+
export function createRepositoryLease(authorityRoot, state) {
|
|
16
|
+
const lease = Object.freeze({ authorityRoot });
|
|
17
|
+
leaseStates.set(lease, state);
|
|
18
|
+
return lease;
|
|
19
|
+
}
|
|
20
|
+
export function getRootState(root) {
|
|
21
|
+
return rootStates.get(root);
|
|
22
|
+
}
|
|
23
|
+
export function getPathState(path) {
|
|
24
|
+
return pathStates.get(path);
|
|
25
|
+
}
|
|
26
|
+
export function requireRootState(root) {
|
|
27
|
+
const state = getRootState(root);
|
|
28
|
+
if (state === undefined)
|
|
29
|
+
throw new PathSafetyError('Managed root is not a repository-store handle.');
|
|
30
|
+
return state;
|
|
31
|
+
}
|
|
32
|
+
export function requirePathState(path) {
|
|
33
|
+
const state = getPathState(path);
|
|
34
|
+
if (state === undefined)
|
|
35
|
+
throw new PathSafetyError('Managed path is not a repository-store handle.');
|
|
36
|
+
return state;
|
|
37
|
+
}
|
|
38
|
+
export function getLeaseState(lease) {
|
|
39
|
+
return leaseStates.get(lease);
|
|
40
|
+
}
|
|
41
|
+
export function managedPathBelongsToRoot(root, path) {
|
|
42
|
+
const rootState = getRootState(root);
|
|
43
|
+
const pathState = getPathState(path);
|
|
44
|
+
return (pathState !== undefined &&
|
|
45
|
+
rootState !== undefined &&
|
|
46
|
+
pathState.authorityId === rootState.authorityId &&
|
|
47
|
+
pathState.managedRootId === rootState.managedRootId);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/internal/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAiD/C,MAAM,UAAU,GAAG,IAAI,OAAO,EAA0B,CAAC;AACzD,MAAM,UAAU,GAAG,IAAI,OAAO,EAA0B,CAAC;AACzD,MAAM,WAAW,GAAG,IAAI,OAAO,EAA+B,CAAC;AAG/D,MAAM,UAAU,iBAAiB,CAAC,KAAgB;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACnG,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,MAAM,UAAU,iBAAiB,CAAC,YAAoB,EAAE,KAAgB;IACtE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;IAC7C,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,MAAM,UAAU,qBAAqB,CAAC,aAAqB,EAAE,KAAiB;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;IAC/C,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC;AACf,CAAC;AAGD,MAAM,UAAU,YAAY,CAAC,IAAiB;IAC5C,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAGD,MAAM,UAAU,YAAY,CAAC,IAAiB;IAC5C,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAGD,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,eAAe,CAAC,gDAAgD,CAAC,CAAC;IACrG,OAAO,KAAK,CAAC;AACf,CAAC;AAGD,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,eAAe,CAAC,gDAAgD,CAAC,CAAC;IACrG,OAAO,KAAK,CAAC;AACf,CAAC;AAGD,MAAM,UAAU,aAAa,CAAC,KAAsB;IAClD,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAGD,MAAM,UAAU,wBAAwB,CAAC,IAAiB,EAAE,IAAiB;IAC3E,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CACL,SAAS,KAAK,SAAS;QACvB,SAAS,KAAK,SAAS;QACvB,SAAS,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW;QAC/C,SAAS,CAAC,aAAa,KAAK,SAAS,CAAC,aAAa,CACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface NativePublicationBackend {
|
|
2
|
+
renameNoReplace(source: string, destination: string): void;
|
|
3
|
+
supportsLocalPath(path: string): boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function requireNativePublicationBackend(): NativePublicationBackend;
|
|
6
|
+
export declare function nativeRenameNoReplace(backend: NativePublicationBackend, source: string, destination: string): void;
|
|
7
|
+
export declare function assertNativePublicationPath(backend: NativePublicationBackend, path: string): void;
|
|
8
|
+
export declare function setNativePublicationBackendForTests(backend: NativePublicationBackend | null | undefined): void;
|
|
9
|
+
//# sourceMappingURL=native-publication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-publication.d.ts","sourceRoot":"","sources":["../../src/internal/native-publication.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,wBAAwB;IACvC,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1C;AAOD,wBAAgB,+BAA+B,IAAI,wBAAwB,CAuB1E;AAGD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAQlH;AAGD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,wBAAwB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAOjG;AAGD,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAE9G"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { UnsupportedRuntimeError } from '../errors.js';
|
|
4
|
+
let injectedBackend;
|
|
5
|
+
let loadedBackend;
|
|
6
|
+
let loadFailure;
|
|
7
|
+
export function requireNativePublicationBackend() {
|
|
8
|
+
if (injectedBackend !== undefined) {
|
|
9
|
+
if (injectedBackend !== null)
|
|
10
|
+
return injectedBackend;
|
|
11
|
+
throw unsupported('Native publication backend is disabled for this operation.');
|
|
12
|
+
}
|
|
13
|
+
if (process.platform !== 'linux')
|
|
14
|
+
throw unsupported(`Exact destructive publication is unsupported on ${process.platform}.`);
|
|
15
|
+
if (loadedBackend !== undefined)
|
|
16
|
+
return loadedBackend;
|
|
17
|
+
if (loadFailure !== undefined)
|
|
18
|
+
throw unsupported('Native publication backend could not be loaded.', loadFailure);
|
|
19
|
+
try {
|
|
20
|
+
const require = createRequire(import.meta.url);
|
|
21
|
+
const packageRoot = fileURLToPath(new URL('../../', import.meta.url));
|
|
22
|
+
const candidate = require(`${packageRoot}build/Release/repository_store_native.node`);
|
|
23
|
+
if (typeof candidate.renameNoReplace !== 'function' || typeof candidate.supportsLocalPath !== 'function')
|
|
24
|
+
throw new Error('Native addon does not expose the complete publication contract.');
|
|
25
|
+
loadedBackend = candidate;
|
|
26
|
+
return loadedBackend;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
loadFailure = error;
|
|
30
|
+
throw unsupported('Native publication backend could not be loaded.', error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function nativeRenameNoReplace(backend, source, destination) {
|
|
34
|
+
try {
|
|
35
|
+
backend.renameNoReplace(source, destination);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (['EINVAL', 'EXDEV', 'ENOSYS', 'ENOTSUP', 'EOPNOTSUPP'].some((code) => hasCode(error, code)))
|
|
39
|
+
throw unsupported(`Native no-replace move is unsupported for ${source}.`, error);
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function assertNativePublicationPath(backend, path) {
|
|
44
|
+
try {
|
|
45
|
+
if (backend.supportsLocalPath(path))
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw unsupported(`Native filesystem capability check failed for ${path}.`, error);
|
|
50
|
+
}
|
|
51
|
+
throw unsupported(`Exact destructive publication requires a supported Linux local filesystem: ${path}.`);
|
|
52
|
+
}
|
|
53
|
+
export function setNativePublicationBackendForTests(backend) {
|
|
54
|
+
injectedBackend = backend;
|
|
55
|
+
}
|
|
56
|
+
function hasCode(error, code) {
|
|
57
|
+
return typeof error === 'object' && error !== null && 'code' in error && error.code === code;
|
|
58
|
+
}
|
|
59
|
+
function unsupported(message, cause) {
|
|
60
|
+
const error = new UnsupportedRuntimeError(message);
|
|
61
|
+
if (cause !== undefined)
|
|
62
|
+
Object.defineProperty(error, 'cause', { value: cause });
|
|
63
|
+
return error;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=native-publication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-publication.js","sourceRoot":"","sources":["../../src/internal/native-publication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Stats } from 'node:fs';
|
|
2
|
+
import { type ByteRevision } from '../revision.js';
|
|
3
|
+
export interface ExpectedRegularFile {
|
|
4
|
+
readonly identity: Stats;
|
|
5
|
+
readonly revision: ByteRevision;
|
|
6
|
+
readonly maxBytes: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function publishExactRegularFile(path: string, bytes: Uint8Array | null, expected: ExpectedRegularFile | undefined, token: string): void;
|
|
9
|
+
export declare function recoverExactPublication(path: string, token: string, allowedRevisions: readonly (ByteRevision | null)[], maxBytes: number): void;
|
|
10
|
+
//# sourceMappingURL=publication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication.d.ts","sourceRoot":"","sources":["../../src/internal/publication.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,KAAK,EACX,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAsBxE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAOD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,QAAQ,EAAE,mBAAmB,GAAG,SAAS,EACzC,KAAK,EAAE,MAAM,GACZ,IAAI,CAwGN;AAID,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,gBAAgB,EAAE,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,EAClD,QAAQ,EAAE,MAAM,GACf,IAAI,CA2CN"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { closeSync, constants as fsConstants, fstatSync, linkSync, lstatSync, openSync, rmSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { basename, dirname, join } from 'node:path';
|
|
3
|
+
import { PathSafetyError, RecoveryError, UnsupportedRuntimeError } from '../errors.js';
|
|
4
|
+
import { computeByteRevision } from '../revision.js';
|
|
5
|
+
import { emitFilesystemFault } from './fault-injection.js';
|
|
6
|
+
import { assertSafeRegular, captureDirectories, ensurePrivateDirectory, hasCode, noFollowFlag, readRegularFile, revalidateDirectories, sameIdentity, syncDirectory, syncFileDescriptor, } from './filesystem.js';
|
|
7
|
+
import { assertNativePublicationPath, nativeRenameNoReplace, requireNativePublicationBackend, } from './native-publication.js';
|
|
8
|
+
export function publishExactRegularFile(path, bytes, expected, token) {
|
|
9
|
+
const parent = dirname(path);
|
|
10
|
+
ensurePrivateDirectory(parent);
|
|
11
|
+
const parents = captureDirectories(parent);
|
|
12
|
+
const temporary = join(parent, `.${basename(path)}.${token}.repository-store.tmp`);
|
|
13
|
+
const evacuated = join(parent, `.${basename(path)}.${token}.repository-store.evacuated`);
|
|
14
|
+
const nativeBackend = expected === undefined ? undefined : requireNativePublicationBackend();
|
|
15
|
+
if (nativeBackend !== undefined)
|
|
16
|
+
assertNativePublicationPath(nativeBackend, parent);
|
|
17
|
+
let descriptor;
|
|
18
|
+
let temporaryIdentity;
|
|
19
|
+
let evacuatedIdentity;
|
|
20
|
+
try {
|
|
21
|
+
if (artifactExists(evacuated))
|
|
22
|
+
throw new RecoveryError('A prior exact-publication evacuation requires recovery.', 'RECOVERY_AMBIGUOUS', {
|
|
23
|
+
path,
|
|
24
|
+
evacuated,
|
|
25
|
+
});
|
|
26
|
+
if (bytes !== null) {
|
|
27
|
+
descriptor = openSync(temporary, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | noFollowFlag(), 0o600);
|
|
28
|
+
writeFileSync(descriptor, bytes);
|
|
29
|
+
syncFileDescriptor(descriptor, temporary);
|
|
30
|
+
temporaryIdentity = fstatSync(descriptor);
|
|
31
|
+
assertSafeRegular(temporaryIdentity, temporary);
|
|
32
|
+
closeSync(descriptor);
|
|
33
|
+
descriptor = undefined;
|
|
34
|
+
}
|
|
35
|
+
if (expected !== undefined) {
|
|
36
|
+
emitFilesystemFault(bytes === null ? 'before-exact-removal' : 'before-exact-publication', path);
|
|
37
|
+
emitFilesystemFault('before-exact-evacuation', evacuated);
|
|
38
|
+
moveNoReplace(nativeBackend, path, evacuated, 'evacuate destination');
|
|
39
|
+
emitFilesystemFault('destination-evacuated', path);
|
|
40
|
+
evacuatedIdentity = lstatSync(evacuated);
|
|
41
|
+
assertSafeRegular(evacuatedIdentity, evacuated);
|
|
42
|
+
const evacuatedBytes = readRegularFile(evacuated, expected.maxBytes);
|
|
43
|
+
if (!sameIdentity(expected.identity, evacuatedIdentity) ||
|
|
44
|
+
computeByteRevision(evacuatedBytes) !== expected.revision) {
|
|
45
|
+
restoreEvacuated(nativeBackend, evacuated, path, parent);
|
|
46
|
+
evacuatedIdentity = undefined;
|
|
47
|
+
throw new PathSafetyError(`Destination changed during publication: ${path}`, 'IDENTITY_CHANGED', {
|
|
48
|
+
path,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
revalidateDirectories(parents);
|
|
52
|
+
syncDirectory(parent);
|
|
53
|
+
}
|
|
54
|
+
else if (bytes !== null) {
|
|
55
|
+
emitFilesystemFault('before-exact-publication', path);
|
|
56
|
+
}
|
|
57
|
+
if (bytes !== null) {
|
|
58
|
+
try {
|
|
59
|
+
linkSync(temporary, path);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (hasCode(error, 'EEXIST')) {
|
|
63
|
+
if (evacuatedIdentity !== undefined)
|
|
64
|
+
restoreEvacuated(nativeBackend, evacuated, path, parent);
|
|
65
|
+
evacuatedIdentity = undefined;
|
|
66
|
+
throw new PathSafetyError(`Destination appeared during publication: ${path}`, 'IDENTITY_CHANGED');
|
|
67
|
+
}
|
|
68
|
+
throw unsupportedLink(error, path);
|
|
69
|
+
}
|
|
70
|
+
emitFilesystemFault('exclusive-destination-published', path);
|
|
71
|
+
const destination = lstatSync(path);
|
|
72
|
+
if (temporaryIdentity === undefined || !sameIdentity(temporaryIdentity, destination))
|
|
73
|
+
throw new PathSafetyError(`Destination changed during publication: ${path}`, 'IDENTITY_CHANGED');
|
|
74
|
+
rmSync(temporary);
|
|
75
|
+
temporaryIdentity = undefined;
|
|
76
|
+
revalidateDirectories(parents);
|
|
77
|
+
syncDirectory(parent);
|
|
78
|
+
}
|
|
79
|
+
if (evacuatedIdentity !== undefined) {
|
|
80
|
+
const current = lstatSync(evacuated);
|
|
81
|
+
if (!sameIdentity(evacuatedIdentity, current))
|
|
82
|
+
throw new RecoveryError('Evacuated publication evidence changed before cleanup.', 'RECOVERY_AMBIGUOUS', {
|
|
83
|
+
path,
|
|
84
|
+
evacuated,
|
|
85
|
+
});
|
|
86
|
+
rmSync(evacuated);
|
|
87
|
+
evacuatedIdentity = undefined;
|
|
88
|
+
syncDirectory(parent);
|
|
89
|
+
}
|
|
90
|
+
else if (bytes === null) {
|
|
91
|
+
revalidateDirectories(parents);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
if (descriptor !== undefined)
|
|
96
|
+
closeSync(descriptor);
|
|
97
|
+
try {
|
|
98
|
+
revalidateDirectories(parents);
|
|
99
|
+
if (temporaryIdentity !== undefined && artifactExists(temporary)) {
|
|
100
|
+
const current = lstatSync(temporary);
|
|
101
|
+
if (sameIdentity(temporaryIdentity, current))
|
|
102
|
+
rmSync(temporary);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function recoverExactPublication(path, token, allowedRevisions, maxBytes) {
|
|
110
|
+
const parent = dirname(path);
|
|
111
|
+
const evacuated = join(parent, `.${basename(path)}.${token}.repository-store.evacuated`);
|
|
112
|
+
const temporary = join(parent, `.${basename(path)}.${token}.repository-store.tmp`);
|
|
113
|
+
recoverTemporaryPublication(path, temporary, token, allowedRevisions, maxBytes);
|
|
114
|
+
if (!artifactExists(evacuated))
|
|
115
|
+
return;
|
|
116
|
+
const evidence = lstatSync(evacuated);
|
|
117
|
+
if (evidence.isSymbolicLink() || !evidence.isFile())
|
|
118
|
+
throw new RecoveryError('Evacuated publication evidence is unsafe.', 'RECOVERY_AMBIGUOUS', { path, evacuated });
|
|
119
|
+
let current;
|
|
120
|
+
try {
|
|
121
|
+
current = lstatSync(path);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
if (!hasCode(error, 'ENOENT'))
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
if (current === undefined) {
|
|
128
|
+
restoreEvacuated(requireNativePublicationBackend(), evacuated, path, parent);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (sameIdentity(evidence, current)) {
|
|
132
|
+
rmSync(evacuated);
|
|
133
|
+
syncDirectory(parent);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
assertSafeRegular(evidence, evacuated);
|
|
137
|
+
assertSafeRegular(current, path);
|
|
138
|
+
const evidenceRevision = computeByteRevision(readRegularFile(evacuated, maxBytes));
|
|
139
|
+
const currentRevision = computeByteRevision(readRegularFile(path, maxBytes));
|
|
140
|
+
if (!allowedRevisions.includes(evidenceRevision) || !allowedRevisions.includes(currentRevision))
|
|
141
|
+
throw new RecoveryError('Canonical and evacuated states contain unauthenticated revisions.', 'RECOVERY_AMBIGUOUS', {
|
|
142
|
+
path,
|
|
143
|
+
evacuated,
|
|
144
|
+
evidenceRevision,
|
|
145
|
+
currentRevision,
|
|
146
|
+
});
|
|
147
|
+
publishExactRegularFile(evacuated, null, { identity: evidence, revision: evidenceRevision, maxBytes }, `${token}-evidence`);
|
|
148
|
+
}
|
|
149
|
+
function recoverTemporaryPublication(path, temporary, token, allowedRevisions, maxBytes) {
|
|
150
|
+
if (!artifactExists(temporary))
|
|
151
|
+
return;
|
|
152
|
+
const temporaryIdentity = lstatSync(temporary);
|
|
153
|
+
let destination;
|
|
154
|
+
try {
|
|
155
|
+
destination = lstatSync(path);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
if (!hasCode(error, 'ENOENT'))
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
if (destination !== undefined && sameIdentity(temporaryIdentity, destination)) {
|
|
162
|
+
rmSync(temporary);
|
|
163
|
+
syncDirectory(dirname(path));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
assertSafeRegular(temporaryIdentity, temporary);
|
|
167
|
+
const revision = computeByteRevision(readRegularFile(temporary, maxBytes));
|
|
168
|
+
if (!allowedRevisions.includes(revision))
|
|
169
|
+
throw new RecoveryError('Temporary publication artifact has an unauthenticated revision.', 'RECOVERY_AMBIGUOUS', {
|
|
170
|
+
path,
|
|
171
|
+
temporary,
|
|
172
|
+
revision,
|
|
173
|
+
});
|
|
174
|
+
publishExactRegularFile(temporary, null, { identity: temporaryIdentity, revision, maxBytes }, `${token}-temporary`);
|
|
175
|
+
}
|
|
176
|
+
function restoreEvacuated(backend, evacuated, path, parent) {
|
|
177
|
+
try {
|
|
178
|
+
nativeRenameNoReplace(backend, evacuated, path);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
if (hasCode(error, 'EEXIST'))
|
|
182
|
+
throw new RecoveryError('Cannot restore raced destination because another entry appeared.', 'RECOVERY_AMBIGUOUS', { path, evacuated });
|
|
183
|
+
throw nativeMoveError(error, path, 'restore destination');
|
|
184
|
+
}
|
|
185
|
+
syncDirectory(parent);
|
|
186
|
+
}
|
|
187
|
+
function moveNoReplace(backend, source, destination, operation) {
|
|
188
|
+
try {
|
|
189
|
+
nativeRenameNoReplace(backend, source, destination);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
if (hasCode(error, 'EEXIST'))
|
|
193
|
+
throw new RecoveryError(`Cannot ${operation}; private destination already exists.`, 'RECOVERY_AMBIGUOUS', {
|
|
194
|
+
source,
|
|
195
|
+
destination,
|
|
196
|
+
});
|
|
197
|
+
if (hasCode(error, 'ENOENT'))
|
|
198
|
+
throw new PathSafetyError(`Source disappeared while attempting to ${operation}: ${source}`, 'IDENTITY_CHANGED');
|
|
199
|
+
throw nativeMoveError(error, source, operation);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function nativeMoveError(error, path, operation) {
|
|
203
|
+
if (['EINVAL', 'EXDEV', 'ENOSYS', 'ENOTSUP', 'EOPNOTSUPP'].some((code) => hasCode(error, code)))
|
|
204
|
+
return new UnsupportedRuntimeError(`Filesystem cannot ${operation} without replacement: ${path}`);
|
|
205
|
+
return error;
|
|
206
|
+
}
|
|
207
|
+
function unsupportedLink(error, path) {
|
|
208
|
+
if (['EPERM', 'EXDEV', 'ENOTSUP', 'EOPNOTSUPP', 'ENOSYS'].some((code) => hasCode(error, code)))
|
|
209
|
+
return new UnsupportedRuntimeError(`Filesystem does not support exclusive regular-file publication: ${path}`);
|
|
210
|
+
return error;
|
|
211
|
+
}
|
|
212
|
+
function artifactExists(path) {
|
|
213
|
+
try {
|
|
214
|
+
lstatSync(path);
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (hasCode(error, 'ENOENT'))
|
|
219
|
+
return false;
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=publication.js.map
|