Skip to content

Commit

Permalink
test(mime): more mime tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jwerle committed Nov 10, 2023
1 parent dc75e03 commit 6b6dee3
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 34 deletions.
105 changes: 95 additions & 10 deletions api/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4914,12 +4914,32 @@ declare module "socket:i18n" {
declare module "socket:mime/index" {
/**
* Look up a MIME type in various MIME databases.
* @return {Promise<Array<{ name: string, mime: string }>>}
* @param {string} query
* @return {Promise<DatabaseQueryResult[]>}
*/
export function lookup(query: string): Promise<DatabaseQueryResult[]>;
/**
* A container for a database lookup query.
*/
export function lookup(query: any): Promise<Array<{
export class DatabaseQueryResult {
/**
* `DatabaseQueryResult` class constructor.
* @ignore
* @param {Database} database
* @param {string} name
* @param {string} mime
*/
constructor(database: Database, name: string, mime: string);
/**
* @type {string}
*/
name: string;
/**
* @type {string}
*/
mime: string;
}>>;
database: Database;
}
/**
* A container for MIME types by class (audio, video, text, etc)
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml}
Expand All @@ -4931,43 +4951,108 @@ declare module "socket:mime/index" {
*/
constructor(name: string);
/**
* The name of the MIME database.
* @type {string}
*/
name: string;
/**
* The URL of the MIME database.
* @type {URL}
*/
url: URL;
/**
* The mapping of MIME name to the MIME "content type"
* @type {Map}
*/
map: Map<any, any>;
/**
* An index of MIME "content type" to the MIME name.
* @type {Map}
*/
index: Map<any, any>;
/**
* An enumeration of all database entries.
* @return {Array<Array<string>>}
*/
entries(): Array<Array<string>>;
/**
* Loads database MIME entries into internal map.
* @return {Promise}
*/
load(): Promise<any>;
/**
* Lookup MIME type by name.
* Lookup MIME type by name or content type
* @param {string} query
* @return {Promise<{ name: string, mime: string}>}
* @return {Promise<DatabaseQueryResult>}
*/
lookup(query: string): Promise<{
name: string;
mime: string;
}>;
lookup(query: string): Promise<DatabaseQueryResult>;
}
/**
* A database of MIME types for 'application/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#application}
*/
export const application: Database;
/**
* A database of MIME types for 'audio/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#audio}
*/
export const audio: Database;
/**
* A database of MIME types for 'font/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#font}
*/
export const font: Database;
/**
* A database of MIME types for 'image/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#image}
*/
export const image: Database;
/**
* A database of MIME types for 'model/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#model}
*/
export const model: Database;
/**
* A database of MIME types for 'multipart/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#multipart}
*/
export const multipart: Database;
/**
* A database of MIME types for 'text/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#text}
*/
export const text: Database;
/**
* A database of MIME types for 'video/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#video}
*/
export const video: Database;
/**
* An array of known MIME databases. Custom databases can be added to this
* array in userspace for lookup with `mime.lookup()`
* @type {Database[]}
*/
export const databases: Database[];
namespace _default {
export { application };
export { Database };
export { databases };
export { lookup };
export { application };
export { audio };
export { font };
export { image };
export { model };
export { multipart };
export { text };
export { video };
}
export default _default;
}
Expand Down
1 change: 1 addition & 0 deletions api/mime/audio.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"mp3": "audio/mpeg",
"mpeg": "audio/mpeg",
"mpeg4-generic": "audio/mpeg4-generic",
"oga": "audio/ogg",
"ogg": "audio/ogg",
"opus": "audio/opus",
"parityfec": "audio/parityfec",
Expand Down
154 changes: 135 additions & 19 deletions api/mime/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,59 @@
/**
* A container for a database lookup query.
*/
export class DatabaseQueryResult {
/**
* @type {string}
*/
name = ''

/**
* @type {string}
*/
mime = ''

/**
* `DatabaseQueryResult` class constructor.
* @ignore
* @param {Database} database
* @param {string} name
* @param {string} mime
*/
constructor (database, name, mime) {
this.database = database
this.name = name
this.mime = mime
}
}

/**
* A container for MIME types by class (audio, video, text, etc)
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml}
*/
export class Database {
/**
* The name of the MIME database.
* @type {string}
*/
name = ''

/**
* The URL of the MIME database.
* @type {URL}
*/
url = null

/**
* The mapping of MIME name to the MIME "content type"
* @type {Map}
*/
map = new Map()

/**
* An index of MIME "content type" to the MIME name.
* @type {Map}
*/
map = null
index = new Map()

/**
* `Database` class constructor.
Expand All @@ -25,10 +62,17 @@ export class Database {
constructor (name) {
// @ts-ignore
this.url = new URL(`${name}.json`, import.meta.url)
this.map = new Map()
this.name = name
}

/**
* An enumeration of all database entries.
* @return {Array<Array<string>>}
*/
entries () {
return this.map.entries()
}

/**
* Loads database MIME entries into internal map.
* @return {Promise}
Expand All @@ -40,14 +84,15 @@ export class Database {

for (const [key, value] of Object.entries(json)) {
this.map.set(key, value)
this.index.set(value.toLowerCase(), key.toLowerCase())
}
}
}

/**
* Lookup MIME type by name.
* Lookup MIME type by name or content type
* @param {string} query
* @return {Promise<{ name: string, mime: string}>}
* @return {Promise<DatabaseQueryResult>}
*/
async lookup (query) {
query = query.toLowerCase()
Expand All @@ -62,7 +107,9 @@ export class Database {
const mime = value.toLowerCase()

if (query === name) {
results.push({ name, mime })
results.push(new DatabaseQueryResult(this, name, mime))
} else if (query === mime) { // reverse lookup
results.push(new DatabaseQueryResult(this, name, mime))
} else if (name.startsWith(query)) {
const nameParts = key.toLowerCase().split('+')
if (queryParts.length <= nameParts.length) {
Expand All @@ -78,7 +125,7 @@ export class Database {
}

if (match) {
results.push({ name, mime })
results.push(new DatabaseQueryResult(this, name, mime))
}
}
}
Expand All @@ -88,32 +135,89 @@ export class Database {
}
}

/**
* A database of MIME types for 'application/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#application}
*/
export const application = new Database('application')

/**
* A database of MIME types for 'audio/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#audio}
*/
export const audio = new Database('audio')

/**
* A database of MIME types for 'font/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#font}
*/
export const font = new Database('font')

/**
* A database of MIME types for 'image/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#image}
*/
export const image = new Database('image')

/**
* A database of MIME types for 'model/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#model}
*/
export const model = new Database('model')

/**
* A database of MIME types for 'multipart/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#multipart}
*/
export const multipart = new Database('multipart')

/**
* A database of MIME types for 'text/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#text}
*/
export const text = new Database('text')

/**
* A database of MIME types for 'video/' content types
* @type {Database}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml#video}
*/
export const video = new Database('video')

/**
* An array of known MIME databases. Custom databases can be added to this
* array in userspace for lookup with `mime.lookup()`
* @type {Database[]}
*/
export const databases = [
application,
audio,
font,
image,
model,
multipart,
text,
video
]

/**
* Look up a MIME type in various MIME databases.
* @return {Promise<Array<{ name: string, mime: string }>>}
* @param {string} query
* @return {Promise<DatabaseQueryResult[]>}
*/
export async function lookup (query) {
const databases = [
application,
audio,
font,
image,
model,
multipart,
text,
video
]

const results = []

// preload all databasees
await Promise.all(databases.map((db) => db.load()))

for (const database of databases) {
const result = await database.lookup(query)
results.push(...result)
Expand All @@ -123,6 +227,18 @@ export async function lookup (query) {
}

export default {
// API
Database,
databases,
lookup,

// databases
application,
Database
audio,
font,
image,
model,
multipart,
text,
video
}
Loading

0 comments on commit 6b6dee3

Please sign in to comment.