2022-11-10 20:52:45 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const {
|
|
|
|
DateNow,
|
2024-09-26 08:24:39 +00:00
|
|
|
FunctionPrototypeApply,
|
2022-11-10 20:52:45 +00:00
|
|
|
NumberIsNaN,
|
|
|
|
ObjectDefineProperties,
|
2024-09-26 08:24:39 +00:00
|
|
|
ObjectSetPrototypeOf,
|
2023-11-29 16:00:57 +00:00
|
|
|
StringPrototypeToWellFormed,
|
2024-09-26 08:24:39 +00:00
|
|
|
Symbol,
|
2022-11-10 20:52:45 +00:00
|
|
|
SymbolToStringTag,
|
|
|
|
} = primordials;
|
|
|
|
|
|
|
|
const {
|
|
|
|
Blob,
|
2024-09-26 08:24:39 +00:00
|
|
|
TransferableBlob,
|
2022-11-10 20:52:45 +00:00
|
|
|
} = require('internal/blob');
|
|
|
|
|
|
|
|
const {
|
|
|
|
customInspectSymbol: kInspect,
|
|
|
|
kEnumerableProperty,
|
|
|
|
kEmptyObject,
|
|
|
|
} = require('internal/util');
|
|
|
|
|
|
|
|
const {
|
|
|
|
codes: {
|
2024-09-26 08:24:39 +00:00
|
|
|
ERR_INVALID_THIS,
|
2022-11-10 20:52:45 +00:00
|
|
|
ERR_MISSING_ARGS,
|
|
|
|
},
|
|
|
|
} = require('internal/errors');
|
|
|
|
|
|
|
|
const {
|
|
|
|
inspect,
|
|
|
|
} = require('internal/util/inspect');
|
|
|
|
|
2024-09-26 08:24:39 +00:00
|
|
|
const {
|
|
|
|
kClone,
|
|
|
|
kDeserialize,
|
|
|
|
} = require('internal/worker/js_transferable');
|
|
|
|
|
|
|
|
const kState = Symbol('state');
|
|
|
|
|
|
|
|
function isFile(object) {
|
|
|
|
return object?.[kState] !== undefined;
|
|
|
|
}
|
2022-11-10 20:52:45 +00:00
|
|
|
|
2024-09-26 08:24:39 +00:00
|
|
|
class FileState {
|
|
|
|
name;
|
|
|
|
lastModified;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} name
|
|
|
|
* @param {number} lastModified
|
|
|
|
*/
|
|
|
|
constructor(name, lastModified) {
|
|
|
|
this.name = name;
|
|
|
|
this.lastModified = lastModified;
|
|
|
|
}
|
|
|
|
}
|
2022-11-10 20:52:45 +00:00
|
|
|
|
2024-09-26 08:24:39 +00:00
|
|
|
class File extends Blob {
|
2022-11-10 20:52:45 +00:00
|
|
|
constructor(fileBits, fileName, options = kEmptyObject) {
|
|
|
|
if (arguments.length < 2) {
|
|
|
|
throw new ERR_MISSING_ARGS('fileBits', 'fileName');
|
|
|
|
}
|
|
|
|
|
|
|
|
super(fileBits, options);
|
|
|
|
|
|
|
|
let { lastModified } = options ?? kEmptyObject;
|
|
|
|
|
|
|
|
if (lastModified !== undefined) {
|
|
|
|
// Using Number(...) will not throw an error for bigints.
|
|
|
|
lastModified = +lastModified;
|
|
|
|
|
|
|
|
if (NumberIsNaN(lastModified)) {
|
|
|
|
lastModified = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
lastModified = DateNow();
|
|
|
|
}
|
|
|
|
|
2024-09-26 08:24:39 +00:00
|
|
|
this[kState] = new FileState(StringPrototypeToWellFormed(`${fileName}`), lastModified);
|
2022-11-10 20:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get name() {
|
2024-09-26 08:24:39 +00:00
|
|
|
if (!isFile(this))
|
|
|
|
throw new ERR_INVALID_THIS('File');
|
|
|
|
|
|
|
|
return this[kState].name;
|
2022-11-10 20:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get lastModified() {
|
2024-09-26 08:24:39 +00:00
|
|
|
if (!isFile(this))
|
|
|
|
throw new ERR_INVALID_THIS('File');
|
|
|
|
|
|
|
|
return this[kState].lastModified;
|
2022-11-10 20:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[kInspect](depth, options) {
|
|
|
|
if (depth < 0) {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const opts = {
|
|
|
|
...options,
|
|
|
|
depth: options.depth == null ? null : options.depth - 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
return `File ${inspect({
|
|
|
|
size: this.size,
|
|
|
|
type: this.type,
|
2024-09-26 08:24:39 +00:00
|
|
|
name: this[kState].name,
|
|
|
|
lastModified: this[kState].lastModified,
|
2022-11-10 20:52:45 +00:00
|
|
|
}, opts)}`;
|
|
|
|
}
|
2024-09-26 08:24:39 +00:00
|
|
|
|
|
|
|
[kClone]() {
|
|
|
|
return {
|
|
|
|
data: { ...super[kClone]().data, ...this[kState] },
|
|
|
|
deserializeInfo: 'internal/file:TransferableFile',
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
[kDeserialize](data) {
|
|
|
|
super[kDeserialize](data);
|
|
|
|
|
|
|
|
this[kState] = new FileState(data.name, data.lastModified);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function TransferableFile(handle, length, type = '') {
|
|
|
|
FunctionPrototypeApply(TransferableBlob, this, [handle, length, type]);
|
2024-09-28 22:05:58 +00:00
|
|
|
ObjectSetPrototypeOf(this, File.prototype);
|
2022-11-10 20:52:45 +00:00
|
|
|
}
|
|
|
|
|
2024-09-26 08:24:39 +00:00
|
|
|
ObjectSetPrototypeOf(TransferableFile.prototype, File.prototype);
|
|
|
|
ObjectSetPrototypeOf(TransferableFile, File);
|
|
|
|
|
2022-11-10 20:52:45 +00:00
|
|
|
ObjectDefineProperties(File.prototype, {
|
|
|
|
name: kEnumerableProperty,
|
|
|
|
lastModified: kEnumerableProperty,
|
|
|
|
[SymbolToStringTag]: {
|
|
|
|
__proto__: null,
|
|
|
|
configurable: true,
|
|
|
|
value: 'File',
|
2023-02-26 10:34:02 +00:00
|
|
|
},
|
2022-11-10 20:52:45 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
File,
|
2024-09-26 08:24:39 +00:00
|
|
|
TransferableFile,
|
2022-11-10 20:52:45 +00:00
|
|
|
};
|