Skip to content
This repository was archived by the owner on Jun 7, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
e16647c
Update index.js
jpalo Mar 17, 2021
e941e89
Upgrade to v12 SDK for Node.js
jpalo Apr 5, 2021
d6ba74e
Add await
jpalo Apr 5, 2021
162bb2c
Revert "Upgrade to v12 SDK for Node.js"
jpalo Apr 6, 2021
b00689f
Update gatsby-node.js
jpalo Apr 6, 2021
05c86d6
Improvements
jpalo Apr 6, 2021
d42c0dd
Upgrade versions
jpalo Nov 14, 2022
c3306ec
downgrade package
jpalo Nov 14, 2022
ad54452
update
jpalo Nov 14, 2022
66a3fd9
Fix gatsby to 4.19
jpalo Nov 15, 2022
a4cf343
Gatsby5 update
jpalo Apr 23, 2024
8cf445f
Remove azure-storage
jpalo Apr 23, 2024
eecee5d
Revert to support Gatsby4
jpalo Apr 23, 2024
70e1226
WIP
jpalo Apr 23, 2024
9600aee
WIP
jpalo Apr 23, 2024
0d5f121
Merge branch 'dev' of https://github.com/jpalo/gatsby-source-azure-st…
jpalo Apr 23, 2024
bffd7c4
WIP
jpalo Apr 23, 2024
667b7d1
WIP
jpalo Apr 23, 2024
fc1bbd6
WIP
jpalo Apr 23, 2024
766e83f
WIP
jpalo Apr 24, 2024
52ccb1f
WIP
jpalo Apr 24, 2024
24fb49f
WIP
jpalo Apr 24, 2024
b3c8a90
WIP
jpalo Apr 24, 2024
f3fd5cd
WIP
jpalo Apr 24, 2024
4b2386a
update gatsby-source-filesystem dependency and refactor sourceNodes f…
jpalo Oct 31, 2024
ed5cb51
Merge pull request #2 from jpalo/features/async_update
jpalo Oct 31, 2024
3646bbf
update gatsby-source-filesystem version to 4.24.0 and adjust dependen…
jpalo Nov 1, 2024
6972d6f
update gatsby-source-filesystem to version 4.25.0 and adjust related …
jpalo Nov 1, 2024
d573efb
downgrade gatsby-source-filesystem to version 4.24.0 and comment out …
jpalo Nov 1, 2024
22bccc6
Merge branch 'master' into dev
jpalo Nov 1, 2024
fe862d0
Merge pull request #3 from jpalo/dev
jpalo Nov 1, 2024
d893110
Update gatsby-node.js
jpalo Nov 1, 2024
5de3d61
refactor: remove azure-storage dependency and update downloadBlobFile…
jpalo Nov 1, 2024
e7cc2fe
Merge branch 'master' into dev
jpalo Nov 1, 2024
4998653
Merge pull request #4 from jpalo/dev
jpalo Nov 1, 2024
6cc8075
Update gatsby-node.js
jpalo Nov 16, 2024
27480e8
Update gatsby-node.js
jpalo Nov 16, 2024
38df545
Update gatsby-node.js
jpalo Nov 16, 2024
46d91ec
Update gatsby-node.js
jpalo Nov 16, 2024
b27b32e
Update package.json
jpalo Nov 16, 2024
2f9cc9c
wip
jpalo Nov 16, 2024
e1e063d
Update gatsby-node.js and package.json for improved error handling an…
jpalo Nov 17, 2024
12eb05e
WIP
jpalo Nov 17, 2024
b7b4097
Merge branch 'master' of https://github.com/jpalo/gatsby-source-azure…
jpalo Nov 17, 2024
3f597f0
Merge pull request #5 from jpalo/features/old_azure_storage
jpalo Nov 17, 2024
7bfe83f
Refactor gatsby-node.js to use azure-storage SDK and enhance blob/con…
jpalo Nov 17, 2024
0a87392
Merge pull request #6 from jpalo/features/old_azure_storage
jpalo Nov 17, 2024
a478be4
Remove unnecessary tablePromises from sourceNodes function in gatsby-…
jpalo Nov 17, 2024
47155ef
Merge pull request #7 from jpalo/features/old_azure_storage
jpalo Nov 17, 2024
01163f3
Replace @azure/storage-blob with azure-storage in package.json
jpalo Nov 17, 2024
16835cb
Merge pull request #8 from jpalo/features/old_azure_storage
jpalo Nov 17, 2024
35fd92c
chore: replace azure-storage with @azure/storage-blob in dependencies
jpalo Jul 28, 2025
611172b
Merge pull request #9 from jpalo/features/azure_storage-blob
jpalo Jul 28, 2025
4d10fb9
chore: update gatsby-source-filesystem to version 5.15.0
jpalo Oct 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed example_table_screenshot.png
Binary file not shown.
240 changes: 65 additions & 175 deletions gatsby-node.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,8 @@
const crypto = require("crypto");
var azure = require('azure-storage');
var path = require('path');
var mkdirp = require('mkdirp');
var { createFileNode } = require('gatsby-source-filesystem/create-file-node');

const getValueWithDefault = (valueItem, defaultValue) => { return ((valueItem || { _: defaultValue })._ || defaultValue) }
const getValue = valueItem => getValueWithDefault(valueItem, null)


function makeTableNode(createNode, createNodeId, tableName, tableType) {
const item = {
name: tableName,
type: tableType
}
const nodeId = createNodeId('azureTable/' + tableName)
const nodeContent = JSON.stringify(item)
const nodeContentDigest = crypto
.createHash('md5')
.update(nodeContent)
.digest('hex')
const nodeData = Object.assign(item, {
id: nodeId,
parent: null,
children: [],
internal: {
type: 'azureTable',
content: nodeContent,
contentDigest: nodeContentDigest,
},
})
createNode(nodeData)
}
const { BlobServiceClient } = require("@azure/storage-blob");

function makeContainerNode(createNode, createNodeId, containerName, localFolder) {
const item = {
Expand All @@ -56,142 +28,68 @@ function makeContainerNode(createNode, createNodeId, containerName, localFolder)
createNode(nodeData)
}

function downloadBlobFile(createNode, createNodeId, blobService, { container, name, localPath }) {
mkdirp.sync(path.dirname(localPath, createNodeId));
return new Promise(function (resolve, reject) {
try {
blobService.getBlobToLocalFile(container, name, localPath, function (error, result, response) {
if (!error) {
createFileNode(localPath, createNodeId, pluginOptions = {
name: "gatsby-source-azure-storage"
}).then(function (node) {

let publicUrl = blobService.getUrl(container, name)
let nodeWithUrl = Object.assign({ url: publicUrl}, node)
createNode(nodeWithUrl)

resolve()
}, function (failure) {
console.error(` Failed creating node from blob "${name}" from container "${container}"`)
reject(failure)
})
} else {
console.error(` Failed downloading blob "${name}" from container "${container}"`)
reject(error)
}
})
} catch (err) {
console.error(` Failed to download blob "${name}" from container "${container}"`)
reject(err)
}
})
}

function makeNodesFromQuery(createNode, createNodeId, tableService, tableName, typeName) {
return new Promise(function (resolve, reject) {
try {
const query = new azure.TableQuery()

function queryWithToken(token) {
tableService.queryEntities(tableName, query, token, function (error, result, response) {
if (!error) {
result.entries.forEach(value => {
const item = Object.entries(value).reduce((o, prop) => ({ ...o, [prop[0]]: getValue(prop[1]) }), {})
const nodeId = createNodeId(`${item.PartitionKey}/${item.RowKey}`)
const nodeContent = JSON.stringify(item)
const nodeContentDigest = crypto
.createHash('md5')
.update(nodeContent)
.digest('hex')
const nodeData = Object.assign(item, {
id: nodeId,
parent: null,
children: [],
internal: {
type: typeName,
content: nodeContent,
contentDigest: nodeContentDigest,
},
})
createNode(nodeData)
})

if (result.continuationToken == null) {
resolve()
} else {
queryWithToken(result.continuationToken)
}
} else {
console.error(` Unable to query table "${tableName}"`)
reject(error)
}
})
}

queryWithToken(null)
} catch (err) {
console.error(` Error on table "${tableName}"`)
reject(err)
}
})
async function downloadBlobFile(createNode, createNodeId, blobService, { container, name, localPath }) {
mkdirp.sync(path.dirname(localPath));
try {
const containerClient = blobService.getContainerClient(container);
const blockBlobClient = containerClient.getBlockBlobClient(name);
await blockBlobClient.downloadToFile(localPath);

const node = await createFileNode(localPath, createNodeId, {
name: "gatsby-source-azure-storage"
});

const publicUrl = blockBlobClient.url;
const nodeWithUrl = Object.assign({ url: publicUrl }, node);
createNode(nodeWithUrl);

return;
} catch (err) {
console.error(` Failed to download blob "${name}" from container "${container}"`);
throw err;
}
}

function makeNodesFromContainer(createNode, createNodeId, blobService, containerName, downloadFolder) {
return new Promise(function (resolve, reject) {
try {
function queryWithToken(token = null, nodes = []) {
blobService.listBlobsSegmented(containerName, token, function (error, result, response) {
if (!error) {
result.entries.forEach(value => {
const item = {
name: value.name,
container: value.container || containerName,
contentMD5: value.contentSettings.contentMD5,
creationTime: value.creationTime,
lastModified: value.lastModified,
blobType: value.blobType,
serverEncrypted: value.serverEncrypted,
localPath: (downloadFolder == null ? null : path.join(process.cwd(), downloadFolder, value.name))
}
const nodeId = createNodeId(`${value.name}/${value.contentSettings.contentMD5}`)
const nodeContent = JSON.stringify(item)
const nodeContentDigest = crypto
.createHash('md5')
.update(nodeContent)
.digest('hex')
const nodeData = Object.assign(item, {
id: nodeId,
parent: null,
children: [],
internal: {
type: 'azureBlob',
content: nodeContent,
contentDigest: nodeContentDigest,
},
})
createNode(nodeData)

nodes.push(nodeData)
})

if (result.continuationToken == null) {
resolve(nodes)
} else {
queryWithToken(result.continuationToken, nodes)
}
} else {
console.error(` Unable to query container "${tableName}"`)
reject(error)
}
})
}

queryWithToken()
} catch (err) {
console.error(` Error on container "${containerName}"`)
reject(err)
async function makeNodesFromContainer(createNode, createNodeId, containerClient, containerName, downloadFolder) {
try {
let nodes = [];
for await (const blob of containerClient.listBlobsFlat()) {
const item = {
name: blob.name,
container: containerName,
contentMD5: blob.properties.contentMD5,
creationTime: blob.properties.createdOn,
lastModified: blob.properties.lastModified,
blobType: blob.properties.blobType,
serverEncrypted: blob.properties.serverEncrypted,
localPath: downloadFolder ? path.join(process.cwd(), downloadFolder, blob.name) : null
};

const nodeId = createNodeId(`${item.name}/${blob.properties.contentMD5 || ''}`);
const nodeContent = JSON.stringify(item);
const nodeContentDigest = crypto
.createHash('md5')
.update(nodeContent)
.digest('hex');
const nodeData = Object.assign(item, {
id: nodeId,
parent: null,
children: [],
internal: {
type: 'azureBlob',
content: nodeContent,
contentDigest: nodeContentDigest,
},
});
createNode(nodeData);

nodes.push(nodeData);
}
})
return nodes;
} catch (err) {
console.error(` Error on container "${containerName}"`);
throw err;
}
}

exports.sourceNodes = (
Expand All @@ -203,23 +101,15 @@ exports.sourceNodes = (
// Gatsby adds a configOption that's not needed for this plugin, delete it
delete configOptions.plugins

let tableService = azure.createTableService()
let blobService = azure.createBlobService()

let hasTables = configOptions.tables != null && configOptions.tables.length > 0
let tablePromises = hasTables
? configOptions.tables.map(x => {
let typeName = (x.type || x.name)
makeTableNode(createNode, createNodeId, x.name, typeName)
return makeNodesFromQuery(createNode, createNodeId, tableService, x.name, typeName)
})
: []
const blobService = BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING);

let blobPromises = (configOptions.containers != null && configOptions.containers.length > 0)
? configOptions.containers.map(x => {
let localFolder = (x.localFolder || configOptions.containerLocalFolder)
makeContainerNode(createNode, createNodeId, x.name, localFolder)
let promiseNode = makeNodesFromContainer(createNode, createNodeId, blobService, x.name, localFolder)

let containerClient = blobService.getContainerClient(x.name);
let promiseNode = makeNodesFromContainer(createNode, createNodeId, containerClient, x.name, localFolder)

if (localFolder == null) {
return promiseNode
Expand All @@ -234,5 +124,5 @@ exports.sourceNodes = (
})
: []

return Promise.all(tablePromises.concat(blobPromises))
return Promise.all(blobPromises)
}
10 changes: 9 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
// no-op-lo-op
"use strict";

const fs = require(`fs-extra`);

function loadNodeContent(fileNode) {
return fs.readFile(fileNode.absolutePath, `utf-8`);
}

exports.loadNodeContent = loadNodeContent;
Loading