-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
Copy pathcreate-file-node.js
106 lines (100 loc) · 3.16 KB
/
create-file-node.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const path = require(`path`)
const fs = require(`fs-extra`)
const mime = require(`mime`)
const prettyBytes = require(`pretty-bytes`)
const { createContentDigest, slash, md5File } = require(`gatsby-core-utils`)
exports.createFileNode = async (
pathToFile,
createNodeId,
pluginOptions = {},
cache = null
) => {
const slashed = slash(pathToFile)
const parsedSlashed = path.parse(slashed)
const slashedFile = {
...parsedSlashed,
absolutePath: slashed,
// Useful for limiting graphql query with certain parent directory
relativeDirectory: slash(
path.relative(pluginOptions.path || process.cwd(), parsedSlashed.dir)
),
}
const stats = await fs.stat(slashedFile.absolutePath)
let internal
if (stats.isDirectory()) {
const contentDigest = createContentDigest({
stats: stats,
absolutePath: slashedFile.absolutePath,
})
internal = {
contentDigest,
type: `Directory`,
description: `Directory "${path.relative(process.cwd(), slashed)}"`,
}
} else {
const key = stats.mtimeMs.toString() + stats.ino.toString()
let contentDigest
if (pluginOptions.fastHash) {
// Skip hashing.
contentDigest = key
} else {
// Generate a hash, but only if the file has changed.
contentDigest = cache && (await cache.get(key))
if (!contentDigest) {
contentDigest = await md5File(slashedFile.absolutePath)
if (cache) await cache.set(key, contentDigest)
}
}
const mediaType = mime.getType(slashedFile.ext)
internal = {
contentDigest,
type: `File`,
mediaType: mediaType ? mediaType : `application/octet-stream`,
description: `File "${path.relative(process.cwd(), slashed)}"`,
}
}
return {
// Don't actually make the File id the absolute path as otherwise
// people will use the id for that and ids shouldn't be treated as
// useful information.
id: createNodeId(pathToFile),
children: [],
parent: null,
internal,
sourceInstanceName: pluginOptions.name || `__PROGRAMMATIC__`,
relativePath: slash(
path.relative(
pluginOptions.path || process.cwd(),
slashedFile.absolutePath
)
),
extension: slashedFile.ext.slice(1).toLowerCase(),
prettySize: prettyBytes(stats.size),
modifiedTime: stats.mtime.toJSON(),
accessTime: stats.atime.toJSON(),
changeTime: stats.ctime.toJSON(),
birthTime: stats.birthtime.toJSON(),
// Note: deprecate splatting the slashedFile object
// Note: the object may contain different properties depending on File or Dir
...slashedFile,
// TODO: deprecate copying the entire object
// Note: not splatting for perf reasons (make sure Date objects are serialized)
dev: stats.dev,
mode: stats.mode,
nlink: stats.nlink,
uid: stats.uid,
rdev: stats.rdev,
blksize: stats.blksize,
ino: stats.ino,
size: stats.size,
blocks: stats.blocks,
atimeMs: stats.atimeMs,
mtimeMs: stats.mtimeMs,
ctimeMs: stats.ctimeMs,
birthtimeMs: stats.birthtimeMs,
atime: stats.atime.toJSON(),
mtime: stats.mtime.toJSON(),
ctime: stats.ctime.toJSON(),
birthtime: stats.birthtime.toJSON(),
}
}