Skip to content

Commit 22ec37e

Browse files
committed
Initial commit
0 parents  commit 22ec37e

File tree

9 files changed

+4093
-0
lines changed

9 files changed

+4093
-0
lines changed

.github/workflows/build.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Brief: Builds current database from upstream at https://github.com/jshttp/mime-db
2+
# Note: Must be run on default branch
3+
4+
name: Build
5+
6+
on:
7+
workflow_dispatch: # Enables manual triggering
8+
schedule: # Enables scheduled triggerring. Max frequency allowed by GitHub is, trigger every 5 mins
9+
- cron: '30 * * * *' # Trigger at 30th min of every hour
10+
# Not starting at the start of every hour, as recommended by GitHub, to avoid delay
11+
# Ref: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule
12+
13+
concurrency:
14+
group: ${{ github.repository }}
15+
cancel-in-progress: false
16+
17+
jobs:
18+
19+
build:
20+
21+
permissions:
22+
contents: write
23+
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- uses: actions/checkout@v4
28+
- uses: actions/setup-node@v4
29+
with:
30+
node-version: '20.x'
31+
check-latest: false
32+
- name: Add current directory to system path
33+
run: echo "${PWD}" >> "${GITHUB_PATH}"
34+
- name: Fetch latest upstream release
35+
id: release
36+
run: echo "UPSTREAM_LATEST_RELEASE=$(latest.js)" >> "${GITHUB_OUTPUT}"
37+
- name: Fail if latest upstream release is not in our tags
38+
id: up-to-date
39+
continue-on-error: true
40+
run: git ls-remote --tags --exit-code origin ${{ steps.release.outputs.UPSTREAM_LATEST_RELEASE }}
41+
- name: Fetch and build DB
42+
id: fetch-build
43+
if: steps.up-to-date.outcome == 'failure'
44+
run: build.js ${{ steps.release.outputs.UPSTREAM_LATEST_RELEASE }}
45+
- name: Commit the build
46+
if: steps.fetch-build.outcome == 'success'
47+
env:
48+
RELEASE: ${{ steps.release.outputs.UPSTREAM_LATEST_RELEASE }}
49+
run: |
50+
git config --global user.name ${{ github.triggering_actor }}
51+
git config --global user.email '73181168+SomajitDey@users.noreply.github.com'
52+
git checkout --orphan=database
53+
git add .
54+
git commit -m "Equivalent to jshttp/mime-db@${RELEASE}"
55+
git tag "${RELEASE}"
56+
git push --force --tags origin database
57+

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Somajit
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# 💁 mime-db-cdn
2+
CDN-compatible version of [mime-db](https://github.com/jshttp/mime-db).
3+
4+
## Why this project?
5+
[mime-db](https://github.com/jshttp/mime-db) managed to stay un-opinionated about an API by packing the entire MIME-type database into a [JSON file](https://github.com/jshttp/mime-db/blob/master/db.json). Using `mime-db` directly, therefore, entails downloading the entire database at once, albeit from a CDN. If you just need to query a handful of MIME-types or file-extensions, downloading the entire database followed by loading and retaining it in memory would be an overkill. This problem persists with popular opinionated APIs based on `mime-db`, such as [mime](https://www.npmjs.com/package/mime) or [mime-types](https://www.npmjs.com/package/mime-types), which must first store the entire database locally on the user's machine in order to function.
6+
7+
The current project solves this problem by fragmenting `mime-db` into tiny files, each storing data only for one of the available MIME-types or file-extensions. To understand the file-structure, explore the directories in the [database branch](https://github.com/SomajitDey/mime-db-cdn/tree/database). Each of these files is readily downloadable using any of the free CDNs that serve GitHub contents, e.g.
8+
- [jsdelivr](https://www.jsdelivr.com/?docs=gh)
9+
- [statically](https://github.com/staticallyio/statically)
10+
- [raw.githack](https://raw.githack.com/)
11+
12+
or even using
13+
- `https://raw.githubusercontents.com/somajitdey/mime-db-cdn/database/<path>`
14+
15+
## Usage
16+
17+
### MIME-type to file-extension(s)
18+
Download from CDN as JSON:
19+
```
20+
https://cdn.jsdelivr.net/gh/somajitdey/mime-db-cdn@database/mime-types/<mime-type>/data.json
21+
```
22+
replace `<mime-type>` with your chosen MIME-type e.g. `image/jpeg`.
23+
24+
### File-extension to MIME-type(s)
25+
Download from CDN:
26+
```
27+
https://cdn.jsdelivr.net/gh/somajitdey/mime-db-cdn@database/extensions/type.<extension>
28+
```
29+
replace `<extension>` with your chosen extension e.g. `jpg`.
30+
31+
👉 The `Content-Type` header from the CDN's http-response might contain the desired MIME-type, as provided by the CDN provider.
32+
33+
👉 However, we recommend using the textual data contained within the response's body, formatted as one MIME-type per line, as it is taken from the [mime-db](https://github.com/jshttp/mime-db).
34+
35+
👉 To download the data with `Content-Type: text/plain` http-response-header use:
36+
37+
```
38+
https://raw.githubusercontents.com/somajitdey/mime-db-cdn/database/extensions/type.<extension>
39+
```
40+
41+
### Examples
42+
The database may be found at branch [database](https://github.com/SomajitDey/mime-db-cdn/tree/database) or any of the [tags](https://github.com/SomajitDey/mime-db-cdn/tags) that has a [release with the same name in mime-db](https://github.com/jshttp/mime-db/tags).
43+
44+
👉 In production, it is recommended to use a specific [tag](https://github.com/SomajitDey/mime-db-cdn/tags) instead of the `database` string in the CDN URLs provided above.
45+
46+
For example, to download the MIME-type for `image/jpeg` from [mime-db release v1.54.0](https://github.com/jshttp/mime-db/releases/tag/v1.54.0), use CDN:
47+
48+
https://cdn.jsdelivr.net/gh/somajitdey/mime-db-cdn@v1.54.0/mime-types/image/jpeg/data.json
49+
50+
To get the MIME-type corresponding to `.mjs`, use CDN:
51+
52+
https://cdn.jsdelivr.net/gh/somajitdey/mime-db-cdn@v1.54.0/extensions/type.mjs
53+
54+
## Reliability of this database
55+
The upstream [mime-db](https://github.com/jshttp/mime-db) is [checked hourly for updates](https://github.com/SomajitDey/mime-db-cdn/actions). If a new release is available upstream, [this database](https://github.com/SomajitDey/mime-db-cdn/tree/database) is built afresh from that release and a new [git-tag](https://github.com/SomajitDey/mime-db-cdn/tags) is released with the same name as the [latest mime-db release](https://github.com/jshttp/mime-db/releases).
56+
57+
# Contribute
58+
To register new media types in the database [contribute directly to mime-db](https://github.com/jshttp/mime-db#contributing).
59+
60+
If you like this project, you can show your appreciation by
61+
- [giving it a star](https://github.com/SomajitDey/mime-db-cdn/stargazers)
62+
- sponsoring me through 👇
63+
64+
[![Sponsor](https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://buymeacoffee.com/SomajitDey)
65+
66+
Thank you 💚.

build.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env node
2+
// Brief: Builds current DataBase from the MIME-type DB at https://github.com/jshttp/mime-db
3+
// Argument: [<ref>], optionally provide a reference (branch/tag/commitSHA) to download from, default: latest
4+
5+
import { mkdir, writeFile, link } from 'node:fs/promises';
6+
7+
const ref = process.argv[2] ?? 'latest';
8+
9+
// Fetch the DataBase from https://github.com/jshttp/mime-db
10+
const cdnLink = `https://cdn.jsdelivr.net/gh/jshttp/mime-db@${ref}/db.json`;
11+
const db = await fetch(cdnLink).then((response) => response.json());
12+
13+
// Data for Extensions => MIME-type are stored in './extensions'
14+
await mkdir('./extensions', { recursive: true });
15+
16+
async function saveMimeData (mimeType) {
17+
const dir = `./mime-types/${mimeType}`;
18+
const data = db[mimeType];
19+
mkdir(dir, { recursive: true })
20+
.then(() => {
21+
writeFile(`${dir}/data.json`, JSON.stringify(data));
22+
});
23+
}
24+
25+
async function saveExtToMime (mimeType) {
26+
const extensions = db[mimeType].extensions ?? [];
27+
if (extensions.length === 0) return;
28+
29+
const [first, ...rest] = extensions;
30+
31+
// Write the MIME type to a prototype file, with the first extension, ignore 'EEXIST' errors
32+
const protoFile = `./extensions/type.${first}`;
33+
await writeFile(protoFile, mimeType);
34+
35+
// Hard link rest of the extensions to the prototype file, ignore 'EEXIST' errors
36+
const pending = []; // To hold all pending promises
37+
for (const extension of rest) {
38+
pending.push(
39+
link(protoFile, `./extensions/type.${extension}`)
40+
.catch((err) => {
41+
if (err.code !== 'EEXIST') throw err;
42+
})
43+
);
44+
}
45+
return Promise.all(pending);
46+
}
47+
48+
const pending = []; // To hold all pending promises
49+
// Loop over all MIME types in the DataBase
50+
for (const mimeType in db) {
51+
pending.push(
52+
saveMimeData(mimeType),
53+
saveExtToMime(mimeType)
54+
);
55+
}
56+
57+
await Promise.all(pending);
58+
console.log(`Built Database from http://github.com/jshttp/mime-db@${ref}`);

clean.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env sh
2+
rm -rfv './mime-types' './extensions'

latest.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env node
2+
// Brief: Returns the latest release for https://github.com/jshttp/mime-db
3+
4+
const url = `https://api.github.com/repos/jshttp/mime-db/releases/latest`;
5+
const latest = await fetch(url)
6+
.then((response) => {
7+
if (response.ok) return response.json();
8+
throw new Error(`Failed to fetch latest release for https://github.com/${ownerRepo}`);
9+
})
10+
.then((obj) => obj.tag_name);
11+
console.log(latest);

0 commit comments

Comments
 (0)