Comparing version 6.21.0 to 6.22.0-next.1627422969.3bf63e5da2dd32ff496115c84271f2addc3d4730
export interface FormatOptions { | ||
/** Whether or not to display the fellow's email */ | ||
displayEmail?: true | ||
/** Whether or not to display the copright icon */ | ||
displayCopyright?: boolean | ||
/** Whether or not to display the copyright years */ | ||
displayYears?: boolean | ||
/** Whether or not to display a link to the user's contributions, if used along with {@link .githubRepoSlug} */ | ||
displayContributions?: boolean | ||
/** The repository for when using with {@link .displayContributions} */ | ||
githubRepoSlug?: string | ||
/** An array of fields to prefer for the URL */ | ||
urlFields?: ['githubUrl', 'url'] | ||
/** Whether or not to display the fellow's email */ | ||
displayEmail?: true; | ||
/** Whether or not to display the copright icon */ | ||
displayCopyright?: boolean; | ||
/** Whether or not to display the copyright years */ | ||
displayYears?: boolean; | ||
/** Whether or not to display a link to the user's contributions, if used along with {@link .githubRepoSlug} */ | ||
displayContributions?: boolean; | ||
/** The repository for when using with {@link .displayContributions} */ | ||
githubRepoSlug?: string; | ||
/** An array of fields to prefer for the URL */ | ||
urlFields?: ['githubUrl', 'url']; | ||
} | ||
/** Comparator for sorting fellows in an array */ | ||
export declare function comparator(a: Fellow, b: Fellow): 0 | 1 | -1 | ||
export declare function comparator(a: Fellow, b: Fellow): 0 | 1 | -1; | ||
/** A fellow with similarties to other people */ | ||
export default class Fellow { | ||
/** Note that any property can be assigned directly to fellow */ | ||
[key: string]: any | ||
/** Actual name that is stored, otherwise falls back to username from the url fields */ | ||
private _name? | ||
/** Years active for the current repository, extracted from the name */ | ||
years?: string | ||
/** URLs used */ | ||
readonly urls: Set<string> | ||
/** Emails used */ | ||
readonly emails: Set<string> | ||
/** Map of repository slugs with the contributions from the user */ | ||
readonly contributions: Map<string, number> | ||
/** Set of repository slugs that the fellow administers to */ | ||
readonly administeredRepositories: Set<string> | ||
/** Set of repository slugs that the fellow contributes to */ | ||
readonly contributedRepositories: Set<string> | ||
/** Set of repository slugs that the fellow maintains */ | ||
readonly maintainedRepositories: Set<string> | ||
/** Set of repository slugs that the fellow authors */ | ||
readonly authoredRepositories: Set<string> | ||
/** | ||
* An array of field names that are used to determine if two fellow's are the same. | ||
* Don't need to add usernames for github, twitter, and facebook, as they will be compared via `urls`. | ||
* Can't compare just username, as that is not unique unless comparison's are on the same service, hence why `urls` are used and not `usernames`. | ||
*/ | ||
protected readonly idFields: string[] | ||
/** An array of field names that are used to determine the fellow's URL */ | ||
protected readonly urlFields: string[] | ||
/** A singleton attached to the class that stores it's instances to enable convergence of data */ | ||
static readonly fellows: Array<Fellow> | ||
/** | ||
* Sort a list of fellows. | ||
* Uses {@link Fellow::sort} for the comparison. | ||
*/ | ||
static sort(list: Array<Fellow>): Fellow[] | ||
/** Flatten lists of fellows into one set of fellows */ | ||
static flatten(lists: Array<Array<Fellow> | Set<Fellow>>): Set<Fellow> | ||
/** Compare to another fellow for sorting. */ | ||
compare(other: Fellow): -1 | 0 | 1 | ||
/** | ||
* Compare to another fellow for equivalancy. | ||
* Uses {@link Fellow::idFields} for the comparison. | ||
* @param other The other fellow to compare ourselves with | ||
* @returns Returns `true` if they appear to be the same person, or `false` if not. | ||
*/ | ||
same(other: Fellow): boolean | ||
/** | ||
* With the value, see if an existing fellow exists in our singleton list property with the value, otherwise create a new fellow instance with the value and add them to our singleton list. | ||
* Uses {@link Fellow::same} for the comparison. | ||
* @param value The value to create a new fellow instance or find the existing fellow instance with | ||
* @param add Whether to add the created person to the list | ||
* @returns The new or existing fellow instance | ||
*/ | ||
static ensure(value: any, add?: boolean): Fellow | ||
/** | ||
* Get a fellow from the singleton list | ||
* @param value The value to fetch the value with | ||
* @returns The fetched fellow, if they exist with that value | ||
*/ | ||
static get(value: any): Fellow | ||
/** | ||
* Add a fellow or a series of people, denoted by the value, to the singleton list | ||
* @param values The fellow or people to add | ||
* @returns An array of the fellow objects for the passed people | ||
*/ | ||
static add(...values: any[]): Array<Fellow> | ||
/** Create a new Fellow instance with the value, however if the value is already a fellow instance, then just return it */ | ||
static create(value: any): Fellow | ||
/** | ||
* Construct our fellow instance with the value | ||
* @param value The value used to set the properties of the fellow, forwarded to {@link Fellow::set} | ||
*/ | ||
constructor(value: any) | ||
/** | ||
* Update our fellow with the passed value | ||
* @param fellow A string or object representation of the user | ||
*/ | ||
set(fellow: string | Fellow | any): this | ||
/** | ||
* If the name is empty, we will try to fallback to githubUsername then twitterUsername | ||
* If the name is prefixed with a series of numbers, that is considered the year | ||
* E.g. In `2015+ Bevry Pty Ltd` then `2015+` is the years | ||
* E.g. In `2013-2015 Bevry Pty Ltd` then `2013-2015` is the years | ||
*/ | ||
set name(value: string) | ||
/** | ||
* Fetch the user's name, otherwise their usernames | ||
*/ | ||
get name(): string | ||
/** Add the email to the set instead of replacing it */ | ||
set email(value: string) | ||
/** Fetch the first email that was applied, otherwise an empty string */ | ||
get email(): string | ||
/** | ||
* Will determine if the passed URL is a github, facebook, or twitter URL. | ||
* If it is, then it will extract the username and url from it. | ||
* If it was not, then it will set the homepage variable. | ||
*/ | ||
set url(input: string) | ||
/** Fetch the homepage with fallback to one of the service URLs if available */ | ||
get url(): string | ||
/** Get the field field from the list that isn't empty */ | ||
getFirstField(fields: string[]): any | ||
/** Get all fellows who administrate a particular repository */ | ||
static administersRepository(repoSlug: string): Array<Fellow> | ||
/** Get all fellows who contribute to a particular repository */ | ||
static contributesRepository(repoSlug: string): Array<Fellow> | ||
/** Get all fellows who maintain a particular repository */ | ||
static maintainsRepository(repoSlug: string): Array<Fellow> | ||
/** Get all fellows who author a particular repository */ | ||
static authorsRepository(repoSlug: string): Array<Fellow> | ||
/** | ||
* Convert the fellow into the usual string format | ||
* @example `NAME <EMAIL> (URL)` | ||
*/ | ||
toString(format?: FormatOptions): string | ||
/** | ||
* Convert the fellow into the usual markdown format | ||
* @example `[NAME](URL) <EMAIL>` | ||
*/ | ||
toMarkdown(format?: FormatOptions): string | ||
/** | ||
* Convert the fellow into the usual HTML format | ||
*/ | ||
toHTML(format?: FormatOptions): string | ||
/** Note that any property can be assigned directly to fellow */ | ||
[key: string]: any; | ||
/** Actual name that is stored, otherwise falls back to username from the url fields */ | ||
private _name?; | ||
/** Years active for the current repository, extracted from the name */ | ||
years?: string; | ||
/** URLs used */ | ||
readonly urls: Set<string>; | ||
/** Emails used */ | ||
readonly emails: Set<string>; | ||
/** Map of repository slugs with the contributions from the user */ | ||
readonly contributions: Map<string, number>; | ||
/** Set of repository slugs that the fellow administers to */ | ||
readonly administeredRepositories: Set<string>; | ||
/** Set of repository slugs that the fellow contributes to */ | ||
readonly contributedRepositories: Set<string>; | ||
/** Set of repository slugs that the fellow maintains */ | ||
readonly maintainedRepositories: Set<string>; | ||
/** Set of repository slugs that the fellow authors */ | ||
readonly authoredRepositories: Set<string>; | ||
/** | ||
* An array of field names that are used to determine if two fellow's are the same. | ||
* Don't need to add usernames for github, twitter, and facebook, as they will be compared via `urls`. | ||
* Can't compare just username, as that is not unique unless comparison's are on the same service, hence why `urls` are used and not `usernames`. | ||
*/ | ||
protected readonly idFields: string[]; | ||
/** An array of field names that are used to determine the fellow's URL */ | ||
protected readonly urlFields: string[]; | ||
/** A singleton attached to the class that stores it's instances to enable convergence of data */ | ||
static readonly fellows: Array<Fellow>; | ||
/** | ||
* Sort a list of fellows. | ||
* Uses {@link Fellow::sort} for the comparison. | ||
*/ | ||
static sort(list: Array<Fellow>): Fellow[]; | ||
/** Flatten lists of fellows into one set of fellows */ | ||
static flatten(lists: Array<Array<Fellow> | Set<Fellow>>): Set<Fellow>; | ||
/** Compare to another fellow for sorting. */ | ||
compare(other: Fellow): -1 | 0 | 1; | ||
/** | ||
* Compare to another fellow for equivalancy. | ||
* Uses {@link Fellow::idFields} for the comparison. | ||
* @param other The other fellow to compare ourselves with | ||
* @returns Returns `true` if they appear to be the same person, or `false` if not. | ||
*/ | ||
same(other: Fellow): boolean; | ||
/** | ||
* With the value, see if an existing fellow exists in our singleton list property with the value, otherwise create a new fellow instance with the value and add them to our singleton list. | ||
* Uses {@link Fellow::same} for the comparison. | ||
* @param value The value to create a new fellow instance or find the existing fellow instance with | ||
* @param add Whether to add the created person to the list | ||
* @returns The new or existing fellow instance | ||
*/ | ||
static ensure(value: any, add?: boolean): Fellow; | ||
/** | ||
* Get a fellow from the singleton list | ||
* @param value The value to fetch the value with | ||
* @returns The fetched fellow, if they exist with that value | ||
*/ | ||
static get(value: any): Fellow; | ||
/** | ||
* Add a fellow or a series of people, denoted by the value, to the singleton list | ||
* @param values The fellow or people to add | ||
* @returns An array of the fellow objects for the passed people | ||
*/ | ||
static add(...values: any[]): Array<Fellow>; | ||
/** Create a new Fellow instance with the value, however if the value is already a fellow instance, then just return it */ | ||
static create(value: any): Fellow; | ||
/** | ||
* Construct our fellow instance with the value | ||
* @param value The value used to set the properties of the fellow, forwarded to {@link Fellow::set} | ||
*/ | ||
constructor(value: any); | ||
/** | ||
* Update our fellow with the passed value | ||
* @param fellow A string or object representation of the user | ||
*/ | ||
set(fellow: string | Fellow | any): this; | ||
/** | ||
* If the name is empty, we will try to fallback to githubUsername then twitterUsername | ||
* If the name is prefixed with a series of numbers, that is considered the year | ||
* E.g. In `2015+ Bevry Pty Ltd` then `2015+` is the years | ||
* E.g. In `2013-2015 Bevry Pty Ltd` then `2013-2015` is the years | ||
*/ | ||
set name(value: string); | ||
/** | ||
* Fetch the user's name, otherwise their usernames | ||
*/ | ||
get name(): string; | ||
/** Add the email to the set instead of replacing it */ | ||
set email(value: string); | ||
/** Fetch the first email that was applied, otherwise an empty string */ | ||
get email(): string; | ||
/** | ||
* Will determine if the passed URL is a github, facebook, or twitter URL. | ||
* If it is, then it will extract the username and url from it. | ||
* If it was not, then it will set the homepage variable. | ||
*/ | ||
set url(input: string); | ||
/** Fetch the homepage with fallback to one of the service URLs if available */ | ||
get url(): string; | ||
/** Get the field field from the list that isn't empty */ | ||
getFirstField(fields: string[]): any; | ||
/** Get all fellows who administrate a particular repository */ | ||
static administersRepository(repoSlug: string): Array<Fellow>; | ||
/** Get all fellows who contribute to a particular repository */ | ||
static contributesRepository(repoSlug: string): Array<Fellow>; | ||
/** Get all fellows who maintain a particular repository */ | ||
static maintainsRepository(repoSlug: string): Array<Fellow>; | ||
/** Get all fellows who author a particular repository */ | ||
static authorsRepository(repoSlug: string): Array<Fellow>; | ||
/** | ||
* Convert the fellow into the usual string format | ||
* @example `NAME <EMAIL> (URL)` | ||
*/ | ||
toString(format?: FormatOptions): string; | ||
/** | ||
* Convert the fellow into the usual markdown format | ||
* @example `[NAME](URL) <EMAIL>` | ||
*/ | ||
toMarkdown(format?: FormatOptions): string; | ||
/** | ||
* Convert the fellow into the usual HTML format | ||
*/ | ||
toHTML(format?: FormatOptions): string; | ||
} | ||
//# sourceMappingURL=index.d.ts.map | ||
//# sourceMappingURL=index.d.ts.map |
/** Comparator for sorting fellows in an array */ | ||
export function comparator(a, b) { | ||
return a.compare(b) | ||
return a.compare(b); | ||
} | ||
/** A fellow with similarties to other people */ | ||
export default class Fellow { | ||
/** | ||
* Construct our fellow instance with the value | ||
* @param value The value used to set the properties of the fellow, forwarded to {@link Fellow::set} | ||
*/ | ||
constructor(value) { | ||
/** URLs used */ | ||
this.urls = new Set() | ||
/** Emails used */ | ||
this.emails = new Set() | ||
/** Map of repository slugs with the contributions from the user */ | ||
this.contributions = new Map() | ||
/** Set of repository slugs that the fellow administers to */ | ||
this.administeredRepositories = new Set() | ||
/** Set of repository slugs that the fellow contributes to */ | ||
this.contributedRepositories = new Set() | ||
/** Set of repository slugs that the fellow maintains */ | ||
this.maintainedRepositories = new Set() | ||
/** Set of repository slugs that the fellow authors */ | ||
this.authoredRepositories = new Set() | ||
/** | ||
* An array of field names that are used to determine if two fellow's are the same. | ||
* Don't need to add usernames for github, twitter, and facebook, as they will be compared via `urls`. | ||
* Can't compare just username, as that is not unique unless comparison's are on the same service, hence why `urls` are used and not `usernames`. | ||
*/ | ||
this.idFields = ['urls', 'emails'] | ||
/** An array of field names that are used to determine the fellow's URL */ | ||
this.urlFields = [ | ||
'url', | ||
'homepage', | ||
'web', | ||
'githubUrl', | ||
'twitterUrl', | ||
'facebookUrl', | ||
] | ||
this.set(value) | ||
} | ||
// ----------------------------------- | ||
// Methods | ||
/** | ||
* Sort a list of fellows. | ||
* Uses {@link Fellow::sort} for the comparison. | ||
*/ | ||
static sort(list) { | ||
return list.sort(comparator) | ||
} | ||
/** Flatten lists of fellows into one set of fellows */ | ||
static flatten(lists) { | ||
const fellows = new Set() | ||
for (const list of lists) { | ||
for (const fellow of list) { | ||
fellows.add(fellow) | ||
} | ||
} | ||
return fellows | ||
} | ||
/** Compare to another fellow for sorting. */ | ||
compare(other) { | ||
const A = this.name.toLowerCase() | ||
const B = other.name.toLowerCase() | ||
if (A === B) { | ||
return 0 | ||
} else if (A < B) { | ||
return -1 | ||
} else { | ||
return 1 | ||
} | ||
} | ||
/** | ||
* Compare to another fellow for equivalancy. | ||
* Uses {@link Fellow::idFields} for the comparison. | ||
* @param other The other fellow to compare ourselves with | ||
* @returns Returns `true` if they appear to be the same person, or `false` if not. | ||
*/ | ||
same(other) { | ||
for (const field of this.idFields) { | ||
const value = this[field] | ||
const otherValue = other[field] | ||
if (value && otherValue) { | ||
if (value instanceof Set && otherValue instanceof Set) { | ||
for (const item of value) { | ||
if (otherValue.has(item)) { | ||
return true | ||
} | ||
} | ||
} else if (Array.isArray(value) && Array.isArray(otherValue)) { | ||
for (const item of value) { | ||
if (otherValue.includes(item)) { | ||
return true | ||
} | ||
} | ||
} else if (value === otherValue) { | ||
return true | ||
} | ||
} | ||
} | ||
return false | ||
} | ||
/** | ||
* With the value, see if an existing fellow exists in our singleton list property with the value, otherwise create a new fellow instance with the value and add them to our singleton list. | ||
* Uses {@link Fellow::same} for the comparison. | ||
* @param value The value to create a new fellow instance or find the existing fellow instance with | ||
* @param add Whether to add the created person to the list | ||
* @returns The new or existing fellow instance | ||
*/ | ||
static ensure(value, add = true) { | ||
const newFellow = this.create(value) | ||
for (const existingFellow of this.fellows) { | ||
if (newFellow.same(existingFellow)) { | ||
return existingFellow.set(value) | ||
} | ||
} | ||
if (add) { | ||
this.fellows.push(newFellow) | ||
return newFellow | ||
} else { | ||
throw new Error(`Fellow by ${value} does not exist`) | ||
} | ||
} | ||
/** | ||
* Get a fellow from the singleton list | ||
* @param value The value to fetch the value with | ||
* @returns The fetched fellow, if they exist with that value | ||
*/ | ||
static get(value) { | ||
return this.ensure(value, false) | ||
} | ||
/** | ||
* Add a fellow or a series of people, denoted by the value, to the singleton list | ||
* @param values The fellow or people to add | ||
* @returns An array of the fellow objects for the passed people | ||
*/ | ||
static add(...values) { | ||
const result = [] | ||
for (const value of values) { | ||
if (value instanceof this) { | ||
result.push(this.ensure(value)) | ||
} else if (typeof value === 'string') { | ||
result.push(...value.split(/, +/).map((fellow) => this.ensure(fellow))) | ||
} else if (Array.isArray(value)) { | ||
result.push(...value.map((value) => this.ensure(value))) | ||
} else if (value) { | ||
result.push(this.ensure(value)) | ||
} | ||
} | ||
return result | ||
} | ||
/** Create a new Fellow instance with the value, however if the value is already a fellow instance, then just return it */ | ||
static create(value) { | ||
return value instanceof this ? value : new this(value) | ||
} | ||
/** | ||
* Update our fellow with the passed value | ||
* @param fellow A string or object representation of the user | ||
*/ | ||
set(fellow) { | ||
// String format, e.g. | ||
// Benjamin Lupton <b@lupton.cc> (https://balupton.com) | ||
if (typeof fellow === 'string') { | ||
const match = /^([^<(]+)\s*(?:<(.*?)>)?\s*(?:\((.*?)\))?$/.exec(fellow) | ||
if (!match) { | ||
throw new Error('Invalid fellow string') | ||
} | ||
const name = (match[1] || '').trim() | ||
const email = (match[2] || '').trim() | ||
const url = (match[3] || '').trim() | ||
if (name) this.name = name | ||
if (email) this.email = email | ||
if (url) this.url = url | ||
} | ||
// Data|Fellow Format | ||
else if (typeof fellow === 'object') { | ||
Object.keys(fellow).forEach((key) => { | ||
if (key[0] === '_') return // skip if private | ||
const value = fellow[key] || null | ||
if (value) { | ||
// if any of the url fields, redirect to url setter | ||
if (this.urlFields.includes(key)) { | ||
this.url = value | ||
} | ||
// if not a url field, e.g. name or email | ||
else { | ||
this[key] = value | ||
} | ||
} | ||
}) | ||
} else { | ||
throw new Error('Invalid fellow input') | ||
} | ||
return this | ||
} | ||
// ----------------------------------- | ||
// Accessors | ||
/** | ||
* If the name is empty, we will try to fallback to githubUsername then twitterUsername | ||
* If the name is prefixed with a series of numbers, that is considered the year | ||
* E.g. In `2015+ Bevry Pty Ltd` then `2015+` is the years | ||
* E.g. In `2013-2015 Bevry Pty Ltd` then `2013-2015` is the years | ||
*/ | ||
set name(value /* :string */) { | ||
const match = /^((?:[0-9]+[-+]?)+)?(.+)$/.exec(value) | ||
if (match) { | ||
// fetch the years, but for now, discard it | ||
const years = String(match[1] || '').trim() | ||
if (years) this.years = years | ||
// fetch the name, and apply it | ||
const name = match[2].trim() | ||
if (name) this._name = name | ||
} | ||
} | ||
/** | ||
* Fetch the user's name, otherwise their usernames | ||
*/ | ||
get name() { | ||
return ( | ||
this._name || | ||
this.githubUsername || | ||
this.twitterUsername || | ||
this.facebookUsername || | ||
'' | ||
) | ||
} | ||
/** Add the email to the set instead of replacing it */ | ||
set email(value) { | ||
if (value) { | ||
this.emails.add(value) | ||
} | ||
} | ||
/** Fetch the first email that was applied, otherwise an empty string */ | ||
get email() { | ||
for (const email of this.emails) { | ||
return email | ||
} | ||
return '' | ||
} | ||
/** | ||
* Will determine if the passed URL is a github, facebook, or twitter URL. | ||
* If it is, then it will extract the username and url from it. | ||
* If it was not, then it will set the homepage variable. | ||
*/ | ||
set url(input) { | ||
if (input) { | ||
let url | ||
// github | ||
const githubMatch = /^.+github.com\/([^/]+)\/?$/.exec(input) | ||
if (githubMatch) { | ||
this.githubUsername = githubMatch[1] | ||
url = this.githubUrl = 'https://github.com/' + this.githubUsername | ||
} else { | ||
const facebookMatch = /^.+facebook.com\/([^/]+)\/?$/.exec(input) | ||
if (facebookMatch) { | ||
this.facebookUsername = facebookMatch[1] | ||
url = this.facebookUrl = | ||
'https://facebook.com/' + this.facebookUsername | ||
} else { | ||
const twitterMatch = /^.+twitter.com\/([^/]+)\/?$/.exec(input) | ||
if (twitterMatch) { | ||
this.twitterUsername = twitterMatch[1] | ||
url = this.twitterUrl = | ||
'https://twitter.com/' + this.twitterUsername | ||
} else { | ||
url = this.homepage = input | ||
} | ||
} | ||
} | ||
// add url in encrypted and unecrypted forms to urls | ||
this.urls.add(url.replace(/^http:/, 'https:')) | ||
this.urls.add(url.replace(/^https:/, 'http:')) | ||
} | ||
} | ||
/** Fetch the homepage with fallback to one of the service URLs if available */ | ||
get url() { | ||
return ( | ||
this.homepage || | ||
this.githubUrl || | ||
this.facebookUrl || | ||
this.twitterUrl || | ||
'' | ||
) | ||
} | ||
/** Get the field field from the list that isn't empty */ | ||
getFirstField(fields) { | ||
for (const field of fields) { | ||
const value = this[field] | ||
if (value) return value | ||
} | ||
return null | ||
} | ||
// ----------------------------------- | ||
// Repositories | ||
/** Get all fellows who administrate a particular repository */ | ||
static administersRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.administeredRepositories.has(repoSlug) | ||
}) | ||
} | ||
/** Get all fellows who contribute to a particular repository */ | ||
static contributesRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.contributedRepositories.has(repoSlug) | ||
}) | ||
} | ||
/** Get all fellows who maintain a particular repository */ | ||
static maintainsRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.maintainedRepositories.has(repoSlug) | ||
}) | ||
} | ||
/** Get all fellows who author a particular repository */ | ||
static authorsRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.authoredRepositories.has(repoSlug) | ||
}) | ||
} | ||
// ----------------------------------- | ||
// Formats | ||
/** | ||
* Convert the fellow into the usual string format | ||
* @example `NAME <EMAIL> (URL)` | ||
*/ | ||
toString(format = {}) { | ||
const parts = [] | ||
if (!this.name) return '' | ||
// copyright | ||
if (format.displayCopyright) parts.push('Copyright ©') | ||
if (format.displayYears && this.years) parts.push(this.years) | ||
// name | ||
parts.push(this.name) | ||
if (format.displayEmail && this.email) { | ||
parts.push(`<${this.email}>`) | ||
} | ||
// url | ||
const url = format.urlFields | ||
? this.getFirstField(format.urlFields) | ||
: this.url | ||
if (url) { | ||
parts.push(`(${url})`) | ||
} | ||
// return | ||
return parts.join(' ') | ||
} | ||
/** | ||
* Convert the fellow into the usual markdown format | ||
* @example `[NAME](URL) <EMAIL>` | ||
*/ | ||
toMarkdown(format = {}) { | ||
if (!this.name) return '' | ||
const parts = [] | ||
// copyright | ||
if (format.displayCopyright) parts.push('Copyright ©') | ||
if (format.displayYears && this.years) parts.push(this.years) | ||
// name + url | ||
const url = format.urlFields | ||
? this.getFirstField(format.urlFields) | ||
: this.url | ||
if (url) parts.push(`[${this.name}](${url})`) | ||
else parts.push(this.name) | ||
if (format.displayEmail && this.email) { | ||
parts.push(`<${this.email}>`) | ||
} | ||
// contributions | ||
if ( | ||
format.displayContributions && | ||
format.githubRepoSlug && | ||
this.githubUsername | ||
) { | ||
const contributionsURL = `https://github.com/${format.githubRepoSlug}/commits?author=${this.githubUsername}` | ||
parts.push( | ||
`— [view contributions](${contributionsURL} "View the GitHub contributions of ${this.name} on repository ${format.githubRepoSlug}")` | ||
) | ||
} | ||
// return | ||
return parts.join(' ') | ||
} | ||
/** | ||
* Convert the fellow into the usual HTML format | ||
*/ | ||
toHTML(format = {}) { | ||
if (!this.name) return '' | ||
const parts = [] | ||
// copyright | ||
if (format.displayCopyright) parts.push('Copyright ©') | ||
if (format.displayYears && this.years) parts.push(this.years) | ||
// name + url | ||
const url = format.urlFields | ||
? this.getFirstField(format.urlFields) | ||
: this.url | ||
if (url) parts.push(`<a href="${url}">${this.name}</a>`) | ||
else parts.push(this.name) | ||
if (format.displayEmail && this.email) { | ||
parts.push( | ||
`<a href="mailto:${this.email}" title="Email ${this.name}"><${this.email}></a>` | ||
) | ||
} | ||
// contributions | ||
if ( | ||
format.displayContributions && | ||
format.githubRepoSlug && | ||
this.githubUsername | ||
) { | ||
const contributionsURL = `https://github.com/${format.githubRepoSlug}/commits?author=${this.githubUsername}` | ||
parts.push( | ||
`— <a href="${contributionsURL}" title="View the GitHub contributions of ${this.name} on repository ${format.githubRepoSlug}">view contributions</a>` | ||
) | ||
} | ||
// return | ||
return parts.join(' ') | ||
} | ||
/** | ||
* Construct our fellow instance with the value | ||
* @param value The value used to set the properties of the fellow, forwarded to {@link Fellow::set} | ||
*/ | ||
constructor(value) { | ||
/** URLs used */ | ||
this.urls = new Set(); | ||
/** Emails used */ | ||
this.emails = new Set(); | ||
/** Map of repository slugs with the contributions from the user */ | ||
this.contributions = new Map(); | ||
/** Set of repository slugs that the fellow administers to */ | ||
this.administeredRepositories = new Set(); | ||
/** Set of repository slugs that the fellow contributes to */ | ||
this.contributedRepositories = new Set(); | ||
/** Set of repository slugs that the fellow maintains */ | ||
this.maintainedRepositories = new Set(); | ||
/** Set of repository slugs that the fellow authors */ | ||
this.authoredRepositories = new Set(); | ||
/** | ||
* An array of field names that are used to determine if two fellow's are the same. | ||
* Don't need to add usernames for github, twitter, and facebook, as they will be compared via `urls`. | ||
* Can't compare just username, as that is not unique unless comparison's are on the same service, hence why `urls` are used and not `usernames`. | ||
*/ | ||
this.idFields = ['urls', 'emails']; | ||
/** An array of field names that are used to determine the fellow's URL */ | ||
this.urlFields = [ | ||
'url', | ||
'homepage', | ||
'web', | ||
'githubUrl', | ||
'twitterUrl', | ||
'facebookUrl', | ||
]; | ||
this.set(value); | ||
} | ||
// ----------------------------------- | ||
// Methods | ||
/** | ||
* Sort a list of fellows. | ||
* Uses {@link Fellow::sort} for the comparison. | ||
*/ | ||
static sort(list) { | ||
return list.sort(comparator); | ||
} | ||
/** Flatten lists of fellows into one set of fellows */ | ||
static flatten(lists) { | ||
const fellows = new Set(); | ||
for (const list of lists) { | ||
for (const fellow of list) { | ||
fellows.add(fellow); | ||
} | ||
} | ||
return fellows; | ||
} | ||
/** Compare to another fellow for sorting. */ | ||
compare(other) { | ||
const A = this.name.toLowerCase(); | ||
const B = other.name.toLowerCase(); | ||
if (A === B) { | ||
return 0; | ||
} | ||
else if (A < B) { | ||
return -1; | ||
} | ||
else { | ||
return 1; | ||
} | ||
} | ||
/** | ||
* Compare to another fellow for equivalancy. | ||
* Uses {@link Fellow::idFields} for the comparison. | ||
* @param other The other fellow to compare ourselves with | ||
* @returns Returns `true` if they appear to be the same person, or `false` if not. | ||
*/ | ||
same(other) { | ||
for (const field of this.idFields) { | ||
const value = this[field]; | ||
const otherValue = other[field]; | ||
if (value && otherValue) { | ||
if (value instanceof Set && otherValue instanceof Set) { | ||
for (const item of value) { | ||
if (otherValue.has(item)) { | ||
return true; | ||
} | ||
} | ||
} | ||
else if (Array.isArray(value) && Array.isArray(otherValue)) { | ||
for (const item of value) { | ||
if (otherValue.includes(item)) { | ||
return true; | ||
} | ||
} | ||
} | ||
else if (value === otherValue) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* With the value, see if an existing fellow exists in our singleton list property with the value, otherwise create a new fellow instance with the value and add them to our singleton list. | ||
* Uses {@link Fellow::same} for the comparison. | ||
* @param value The value to create a new fellow instance or find the existing fellow instance with | ||
* @param add Whether to add the created person to the list | ||
* @returns The new or existing fellow instance | ||
*/ | ||
static ensure(value, add = true) { | ||
const newFellow = this.create(value); | ||
for (const existingFellow of this.fellows) { | ||
if (newFellow.same(existingFellow)) { | ||
return existingFellow.set(value); | ||
} | ||
} | ||
if (add) { | ||
this.fellows.push(newFellow); | ||
return newFellow; | ||
} | ||
else { | ||
throw new Error(`Fellow by ${value} does not exist`); | ||
} | ||
} | ||
/** | ||
* Get a fellow from the singleton list | ||
* @param value The value to fetch the value with | ||
* @returns The fetched fellow, if they exist with that value | ||
*/ | ||
static get(value) { | ||
return this.ensure(value, false); | ||
} | ||
/** | ||
* Add a fellow or a series of people, denoted by the value, to the singleton list | ||
* @param values The fellow or people to add | ||
* @returns An array of the fellow objects for the passed people | ||
*/ | ||
static add(...values) { | ||
const result = []; | ||
for (const value of values) { | ||
if (value instanceof this) { | ||
result.push(this.ensure(value)); | ||
} | ||
else if (typeof value === 'string') { | ||
result.push(...value.split(/, +/).map((fellow) => this.ensure(fellow))); | ||
} | ||
else if (Array.isArray(value)) { | ||
result.push(...value.map((value) => this.ensure(value))); | ||
} | ||
else if (value) { | ||
result.push(this.ensure(value)); | ||
} | ||
} | ||
return result; | ||
} | ||
/** Create a new Fellow instance with the value, however if the value is already a fellow instance, then just return it */ | ||
static create(value) { | ||
return value instanceof this ? value : new this(value); | ||
} | ||
/** | ||
* Update our fellow with the passed value | ||
* @param fellow A string or object representation of the user | ||
*/ | ||
set(fellow) { | ||
// String format, e.g. | ||
// Benjamin Lupton <b@lupton.cc> (https://balupton.com) | ||
if (typeof fellow === 'string') { | ||
const match = /^([^<(]+)\s*(?:<(.*?)>)?\s*(?:\((.*?)\))?$/.exec(fellow); | ||
if (!match) { | ||
throw new Error('Invalid fellow string'); | ||
} | ||
const name = (match[1] || '').trim(); | ||
const email = (match[2] || '').trim(); | ||
const url = (match[3] || '').trim(); | ||
if (name) | ||
this.name = name; | ||
if (email) | ||
this.email = email; | ||
if (url) | ||
this.url = url; | ||
} | ||
// Data|Fellow Format | ||
else if (typeof fellow === 'object') { | ||
Object.keys(fellow).forEach((key) => { | ||
if (key[0] === '_') | ||
return; // skip if private | ||
const value = fellow[key] || null; | ||
if (value) { | ||
// if any of the url fields, redirect to url setter | ||
if (this.urlFields.includes(key)) { | ||
this.url = value; | ||
} | ||
// if not a url field, e.g. name or email | ||
else { | ||
this[key] = value; | ||
} | ||
} | ||
}); | ||
} | ||
else { | ||
throw new Error('Invalid fellow input'); | ||
} | ||
return this; | ||
} | ||
// ----------------------------------- | ||
// Accessors | ||
/** | ||
* If the name is empty, we will try to fallback to githubUsername then twitterUsername | ||
* If the name is prefixed with a series of numbers, that is considered the year | ||
* E.g. In `2015+ Bevry Pty Ltd` then `2015+` is the years | ||
* E.g. In `2013-2015 Bevry Pty Ltd` then `2013-2015` is the years | ||
*/ | ||
set name(value /* :string */) { | ||
const match = /^((?:[0-9]+[-+]?)+)?(.+)$/.exec(value); | ||
if (match) { | ||
// fetch the years, but for now, discard it | ||
const years = String(match[1] || '').trim(); | ||
if (years) | ||
this.years = years; | ||
// fetch the name, and apply it | ||
const name = match[2].trim(); | ||
if (name) | ||
this._name = name; | ||
} | ||
} | ||
/** | ||
* Fetch the user's name, otherwise their usernames | ||
*/ | ||
get name() { | ||
return (this._name || | ||
this.githubUsername || | ||
this.twitterUsername || | ||
this.facebookUsername || | ||
''); | ||
} | ||
/** Add the email to the set instead of replacing it */ | ||
set email(value) { | ||
if (value) { | ||
this.emails.add(value); | ||
} | ||
} | ||
/** Fetch the first email that was applied, otherwise an empty string */ | ||
get email() { | ||
for (const email of this.emails) { | ||
return email; | ||
} | ||
return ''; | ||
} | ||
/** | ||
* Will determine if the passed URL is a github, facebook, or twitter URL. | ||
* If it is, then it will extract the username and url from it. | ||
* If it was not, then it will set the homepage variable. | ||
*/ | ||
set url(input) { | ||
if (input) { | ||
let url; | ||
// github | ||
const githubMatch = /^.+github.com\/([^/]+)\/?$/.exec(input); | ||
if (githubMatch) { | ||
this.githubUsername = githubMatch[1]; | ||
url = this.githubUrl = 'https://github.com/' + this.githubUsername; | ||
} | ||
else { | ||
const facebookMatch = /^.+facebook.com\/([^/]+)\/?$/.exec(input); | ||
if (facebookMatch) { | ||
this.facebookUsername = facebookMatch[1]; | ||
url = this.facebookUrl = | ||
'https://facebook.com/' + this.facebookUsername; | ||
} | ||
else { | ||
const twitterMatch = /^.+twitter.com\/([^/]+)\/?$/.exec(input); | ||
if (twitterMatch) { | ||
this.twitterUsername = twitterMatch[1]; | ||
url = this.twitterUrl = | ||
'https://twitter.com/' + this.twitterUsername; | ||
} | ||
else { | ||
url = this.homepage = input; | ||
} | ||
} | ||
} | ||
// add url in encrypted and unecrypted forms to urls | ||
this.urls.add(url.replace(/^http:/, 'https:')); | ||
this.urls.add(url.replace(/^https:/, 'http:')); | ||
} | ||
} | ||
/** Fetch the homepage with fallback to one of the service URLs if available */ | ||
get url() { | ||
return (this.homepage || | ||
this.githubUrl || | ||
this.facebookUrl || | ||
this.twitterUrl || | ||
''); | ||
} | ||
/** Get the field field from the list that isn't empty */ | ||
getFirstField(fields) { | ||
for (const field of fields) { | ||
const value = this[field]; | ||
if (value) | ||
return value; | ||
} | ||
return null; | ||
} | ||
// ----------------------------------- | ||
// Repositories | ||
/** Get all fellows who administrate a particular repository */ | ||
static administersRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.administeredRepositories.has(repoSlug); | ||
}); | ||
} | ||
/** Get all fellows who contribute to a particular repository */ | ||
static contributesRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.contributedRepositories.has(repoSlug); | ||
}); | ||
} | ||
/** Get all fellows who maintain a particular repository */ | ||
static maintainsRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.maintainedRepositories.has(repoSlug); | ||
}); | ||
} | ||
/** Get all fellows who author a particular repository */ | ||
static authorsRepository(repoSlug) { | ||
return this.fellows.filter(function (fellow) { | ||
return fellow.authoredRepositories.has(repoSlug); | ||
}); | ||
} | ||
// ----------------------------------- | ||
// Formats | ||
/** | ||
* Convert the fellow into the usual string format | ||
* @example `NAME <EMAIL> (URL)` | ||
*/ | ||
toString(format = {}) { | ||
const parts = []; | ||
if (!this.name) | ||
return ''; | ||
// copyright | ||
if (format.displayCopyright) | ||
parts.push('Copyright ©'); | ||
if (format.displayYears && this.years) | ||
parts.push(this.years); | ||
// name | ||
parts.push(this.name); | ||
if (format.displayEmail && this.email) { | ||
parts.push(`<${this.email}>`); | ||
} | ||
// url | ||
const url = format.urlFields | ||
? this.getFirstField(format.urlFields) | ||
: this.url; | ||
if (url) { | ||
parts.push(`(${url})`); | ||
} | ||
// return | ||
return parts.join(' '); | ||
} | ||
/** | ||
* Convert the fellow into the usual markdown format | ||
* @example `[NAME](URL) <EMAIL>` | ||
*/ | ||
toMarkdown(format = {}) { | ||
if (!this.name) | ||
return ''; | ||
const parts = []; | ||
// copyright | ||
if (format.displayCopyright) | ||
parts.push('Copyright ©'); | ||
if (format.displayYears && this.years) | ||
parts.push(this.years); | ||
// name + url | ||
const url = format.urlFields | ||
? this.getFirstField(format.urlFields) | ||
: this.url; | ||
if (url) | ||
parts.push(`[${this.name}](${url})`); | ||
else | ||
parts.push(this.name); | ||
if (format.displayEmail && this.email) { | ||
parts.push(`<${this.email}>`); | ||
} | ||
// contributions | ||
if (format.displayContributions && | ||
format.githubRepoSlug && | ||
this.githubUsername) { | ||
const contributionsURL = `https://github.com/${format.githubRepoSlug}/commits?author=${this.githubUsername}`; | ||
parts.push(`— [view contributions](${contributionsURL} "View the GitHub contributions of ${this.name} on repository ${format.githubRepoSlug}")`); | ||
} | ||
// return | ||
return parts.join(' '); | ||
} | ||
/** | ||
* Convert the fellow into the usual HTML format | ||
*/ | ||
toHTML(format = {}) { | ||
if (!this.name) | ||
return ''; | ||
const parts = []; | ||
// copyright | ||
if (format.displayCopyright) | ||
parts.push('Copyright ©'); | ||
if (format.displayYears && this.years) | ||
parts.push(this.years); | ||
// name + url | ||
const url = format.urlFields | ||
? this.getFirstField(format.urlFields) | ||
: this.url; | ||
if (url) | ||
parts.push(`<a href="${url}">${this.name}</a>`); | ||
else | ||
parts.push(this.name); | ||
if (format.displayEmail && this.email) { | ||
parts.push(`<a href="mailto:${this.email}" title="Email ${this.name}"><${this.email}></a>`); | ||
} | ||
// contributions | ||
if (format.displayContributions && | ||
format.githubRepoSlug && | ||
this.githubUsername) { | ||
const contributionsURL = `https://github.com/${format.githubRepoSlug}/commits?author=${this.githubUsername}`; | ||
parts.push(`— <a href="${contributionsURL}" title="View the GitHub contributions of ${this.name} on repository ${format.githubRepoSlug}">view contributions</a>`); | ||
} | ||
// return | ||
return parts.join(' '); | ||
} | ||
} | ||
/** A singleton attached to the class that stores it's instances to enable convergence of data */ | ||
Fellow.fellows = [] | ||
Fellow.fellows = []; |
# History | ||
## v6.22.0 2021 July 28 | ||
- Updated dependencies, [base files](https://github.com/bevry/base), and [editions](https://editions.bevry.me) using [boundation](https://github.com/bevry/boundation) | ||
## v6.21.0 2020 October 29 | ||
@@ -4,0 +8,0 @@ |
@@ -18,3 +18,3 @@ <!-- LICENSEFILE/ --> | ||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. | ||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
@@ -21,0 +21,0 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
{ | ||
"name": "fellow", | ||
"version": "6.21.0", | ||
"version": "6.22.0-next.1627422969.3bf63e5da2dd32ff496115c84271f2addc3d4730", | ||
"description": "Fellow is a package for creating people that can be unified by their shared values via a singleton list on the class", | ||
@@ -13,7 +13,3 @@ "homepage": "https://github.com/bevry/fellow", | ||
"contributors", | ||
"deno", | ||
"deno-edition", | ||
"deno-entry", | ||
"denoland", | ||
"esnext", | ||
"es2019", | ||
"export-default", | ||
@@ -35,3 +31,3 @@ "fellow", | ||
"list": [ | ||
"travisci", | ||
"githubworkflow", | ||
"npmversion", | ||
@@ -53,2 +49,3 @@ "npmdownloads", | ||
"config": { | ||
"githubWorkflow": "bevry", | ||
"githubSponsorsUsername": "balupton", | ||
@@ -63,3 +60,2 @@ "buymeacoffeeUsername": "balupton", | ||
"wishlistURL": "https://bevry.me/wishlist", | ||
"travisTLD": "com", | ||
"githubUsername": "bevry", | ||
@@ -102,3 +98,3 @@ "githubRepository": "fellow", | ||
{ | ||
"description": "TypeScript compiled against ES2019 for web browsers with Import for modules", | ||
"description": "TypeScript compiled against ES2020 for web browsers with Import for modules", | ||
"directory": "edition-browsers", | ||
@@ -117,4 +113,4 @@ "entry": "index.js", | ||
{ | ||
"description": "TypeScript compiled against ESNext for Node.js 10 || 12 || 14 || 15 with Require for modules", | ||
"directory": "edition-esnext", | ||
"description": "TypeScript compiled against ES2019 for Node.js 10 || 12 || 14 with Require for modules", | ||
"directory": "edition-es2019", | ||
"entry": "index.js", | ||
@@ -124,7 +120,7 @@ "tags": [ | ||
"javascript", | ||
"esnext", | ||
"es2019", | ||
"require" | ||
], | ||
"engines": { | ||
"node": "10 || 12 || 14 || 15", | ||
"node": "10 || 12 || 14", | ||
"browsers": false | ||
@@ -134,4 +130,4 @@ } | ||
{ | ||
"description": "TypeScript compiled against ESNext for Node.js 12 || 14 || 15 with Import for modules", | ||
"directory": "edition-esnext-esm", | ||
"description": "TypeScript compiled against ES2019 for Node.js 12 || 14 with Import for modules", | ||
"directory": "edition-es2019-esm", | ||
"entry": "index.js", | ||
@@ -141,23 +137,9 @@ "tags": [ | ||
"javascript", | ||
"esnext", | ||
"es2019", | ||
"import" | ||
], | ||
"engines": { | ||
"node": "12 || 14 || 15", | ||
"node": "12 || 14", | ||
"browsers": false | ||
} | ||
}, | ||
{ | ||
"description": "TypeScript source code made to be compatible with Deno", | ||
"directory": "edition-deno", | ||
"entry": "index.ts", | ||
"tags": [ | ||
"typescript", | ||
"import", | ||
"deno" | ||
], | ||
"engines": { | ||
"deno": true, | ||
"browsers": true | ||
} | ||
} | ||
@@ -167,7 +149,7 @@ ], | ||
"type": "module", | ||
"main": "edition-esnext/index.js", | ||
"main": "edition-es2019/index.js", | ||
"exports": { | ||
"node": { | ||
"import": "./edition-esnext-esm/index.js", | ||
"require": "./edition-esnext/index.js" | ||
"import": "./edition-es2019-esm/index.js", | ||
"require": "./edition-es2019/index.js" | ||
}, | ||
@@ -178,32 +160,31 @@ "browser": { | ||
}, | ||
"deno": "edition-deno/index.ts", | ||
"browser": "edition-browsers/index.js", | ||
"module": "edition-browsers/index.js", | ||
"devDependencies": { | ||
"@bevry/update-contributors": "^1.17.0", | ||
"@typescript-eslint/eslint-plugin": "^4.6.0", | ||
"@typescript-eslint/parser": "^4.6.0", | ||
"assert-helpers": "^8.1.0", | ||
"eslint": "^7.12.1", | ||
"@bevry/update-contributors": "^1.18.0", | ||
"@typescript-eslint/eslint-plugin": "^4.28.5", | ||
"@typescript-eslint/parser": "^4.28.5", | ||
"assert-helpers": "^8.2.0", | ||
"eslint": "^7.31.0", | ||
"eslint-config-bevry": "^3.23.0", | ||
"eslint-config-prettier": "^6.15.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-plugin-babel": "^5.3.1", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"kava": "^5.12.0", | ||
"make-deno-edition": "^1.2.0", | ||
"prettier": "^2.1.2", | ||
"projectz": "^2.16.0", | ||
"surge": "^0.21.6", | ||
"typedoc": "^0.19.2", | ||
"typescript": "^4.0.5", | ||
"valid-directory": "^3.4.0", | ||
"valid-module": "^1.14.0" | ||
"eslint-plugin-prettier": "^3.4.0", | ||
"kava": "^5.13.0", | ||
"make-deno-edition": "^1.3.0", | ||
"prettier": "^2.3.2", | ||
"projectz": "^2.18.0", | ||
"surge": "^0.23.0", | ||
"typedoc": "^0.21.4", | ||
"typescript": "4.3.5", | ||
"valid-directory": "^3.7.0", | ||
"valid-module": "^1.15.0" | ||
}, | ||
"scripts": { | ||
"our:clean": "rm -Rf ./docs ./edition* ./es2015 ./es5 ./out ./.next", | ||
"our:compile": "npm run our:compile:deno && npm run our:compile:edition-browsers && npm run our:compile:edition-esnext && npm run our:compile:edition-esnext-esm && npm run our:compile:types", | ||
"our:compile": "npm run our:compile:deno && npm run our:compile:edition-browsers && npm run our:compile:edition-es2019 && npm run our:compile:edition-es2019-esm && npm run our:compile:types", | ||
"our:compile:deno": "make-deno-edition --attempt", | ||
"our:compile:edition-browsers": "tsc --module ESNext --target ES2019 --outDir ./edition-browsers --project tsconfig.json && ( test ! -d edition-browsers/source || ( mv edition-browsers/source edition-temp && rm -Rf edition-browsers && mv edition-temp edition-browsers ) )", | ||
"our:compile:edition-esnext": "tsc --module commonjs --target ESNext --outDir ./edition-esnext --project tsconfig.json && ( test ! -d edition-esnext/source || ( mv edition-esnext/source edition-temp && rm -Rf edition-esnext && mv edition-temp edition-esnext ) ) && echo '{\"type\": \"commonjs\"}' > edition-esnext/package.json", | ||
"our:compile:edition-esnext-esm": "tsc --module ESNext --target ESNext --outDir ./edition-esnext-esm --project tsconfig.json && ( test ! -d edition-esnext-esm/source || ( mv edition-esnext-esm/source edition-temp && rm -Rf edition-esnext-esm && mv edition-temp edition-esnext-esm ) ) && echo '{\"type\": \"module\"}' > edition-esnext-esm/package.json", | ||
"our:compile:edition-browsers": "tsc --module ESNext --target ES2020 --outDir ./edition-browsers --project tsconfig.json && ( test ! -d edition-browsers/source || ( mv edition-browsers/source edition-temp && rm -Rf edition-browsers && mv edition-temp edition-browsers ) )", | ||
"our:compile:edition-es2019": "tsc --module commonjs --target ES2019 --outDir ./edition-es2019 --project tsconfig.json && ( test ! -d edition-es2019/source || ( mv edition-es2019/source edition-temp && rm -Rf edition-es2019 && mv edition-temp edition-es2019 ) ) && echo '{\"type\": \"commonjs\"}' > edition-es2019/package.json", | ||
"our:compile:edition-es2019-esm": "tsc --module ESNext --target ES2019 --outDir ./edition-es2019-esm --project tsconfig.json && ( test ! -d edition-es2019-esm/source || ( mv edition-es2019-esm/source edition-temp && rm -Rf edition-es2019-esm && mv edition-temp edition-es2019-esm ) ) && echo '{\"type\": \"module\"}' > edition-es2019-esm/package.json", | ||
"our:compile:types": "tsc --project tsconfig.json --emitDeclarationOnly --declaration --declarationMap --declarationDir ./compiled-types && ( test ! -d compiled-types/source || ( mv compiled-types/source edition-temp && rm -Rf compiled-types && mv edition-temp compiled-types ) )", | ||
@@ -214,3 +195,3 @@ "our:deploy": "echo no need for this project", | ||
"our:meta:docs": "npm run our:meta:docs:typedoc", | ||
"our:meta:docs:typedoc": "rm -Rf ./docs && typedoc --mode file --exclude '**/+(*test*|node_modules)' --excludeExternals --name \"$npm_package_name\" --readme ./README.md --out ./docs ./source", | ||
"our:meta:docs:typedoc": "rm -Rf ./docs && typedoc --exclude '**/+(*test*|node_modules)' --excludeExternals --out ./docs ./source", | ||
"our:meta:projectz": "projectz compile", | ||
@@ -221,3 +202,3 @@ "our:release": "npm run our:release:prepare && npm run our:release:check-changelog && npm run our:release:check-dirty && npm run our:release:tag && npm run our:release:push", | ||
"our:release:prepare": "npm run our:clean && npm run our:compile && npm run our:test && npm run our:meta", | ||
"our:release:push": "git push origin master && git push origin --tags", | ||
"our:release:push": "git push origin && git push origin --tags", | ||
"our:release:tag": "export MESSAGE=$(cat ./HISTORY.md | sed -n \"/## v$npm_package_version/,/##/p\" | sed 's/## //' | awk 'NR>1{print buf}{buf = $0}') && test \"$MESSAGE\" || (echo 'proper changelog entry not found' && exit -1) && git tag v$npm_package_version -am \"$MESSAGE\"", | ||
@@ -232,3 +213,3 @@ "our:setup": "npm run our:setup:install", | ||
"our:verify:prettier": "prettier --write .", | ||
"test": "node ./edition-esnext/test.js" | ||
"test": "node ./edition-es2019/test.js" | ||
}, | ||
@@ -235,0 +216,0 @@ "eslintConfig": { |
@@ -10,3 +10,3 @@ <!-- TITLE/ --> | ||
<span class="badge-travisci"><a href="http://travis-ci.com/bevry/fellow" title="Check this project's build status on TravisCI"><img src="https://img.shields.io/travis/com/bevry/fellow/master.svg" alt="Travis CI Build Status" /></a></span> | ||
<span class="badge-githubworkflow"><a href="https://github.com/bevry/fellow/actions?query=workflow%3Abevry" title="View the status of this project's GitHub Workflow: bevry"><img src="https://github.com/bevry/fellow/workflows/bevry/badge.svg" alt="Status of the GitHub Workflow: bevry" /></a></span> | ||
<span class="badge-npmversion"><a href="https://npmjs.org/package/fellow" title="View this project on NPM"><img src="https://img.shields.io/npm/v/fellow.svg" alt="NPM version" /></a></span> | ||
@@ -52,8 +52,2 @@ <span class="badge-npmdownloads"><a href="https://npmjs.org/package/fellow" title="View this project on NPM"><img src="https://img.shields.io/npm/dm/fellow.svg" alt="NPM downloads" /></a></span> | ||
<a href="https://deno.land" title="Deno is a secure runtime for JavaScript and TypeScript, it is an alternative for Node.js"><h3>Deno</h3></a> | ||
``` typescript | ||
import pkg from 'https://unpkg.com/fellow@^6.21.0/edition-deno/index.ts' | ||
``` | ||
<a href="https://www.skypack.dev" title="Skypack is a JavaScript Delivery Network for modern web apps"><h3>Skypack</h3></a> | ||
@@ -63,3 +57,3 @@ | ||
<script type="module"> | ||
import pkg from '//cdn.skypack.dev/fellow@^6.21.0' | ||
import pkg from '//cdn.skypack.dev/fellow@^6.22.0' | ||
</script> | ||
@@ -72,3 +66,3 @@ ``` | ||
<script type="module"> | ||
import pkg from '//unpkg.com/fellow@^6.21.0' | ||
import pkg from '//unpkg.com/fellow@^6.22.0' | ||
</script> | ||
@@ -81,3 +75,3 @@ ``` | ||
<script type="module"> | ||
import pkg from '//dev.jspm.io/fellow@6.21.0' | ||
import pkg from '//dev.jspm.io/fellow@6.22.0' | ||
</script> | ||
@@ -91,7 +85,6 @@ ``` | ||
<ul><li><code>fellow/source/index.ts</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> source code with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li> | ||
<li><code>fellow/edition-browsers/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#10th_Edition_-_ECMAScript_2019" title="ECMAScript ES2019">ES2019</a> for web browsers with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li> | ||
<li><code>fellow</code> aliases <code>fellow/edition-esnext/index.js</code></li> | ||
<li><code>fellow/edition-esnext/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#ES.Next" title="ECMAScript Next">ESNext</a> for <a href="https://nodejs.org" title="Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine">Node.js</a> 10 || 12 || 14 || 15 with <a href="https://nodejs.org/dist/latest-v5.x/docs/api/modules.html" title="Node/CJS Modules">Require</a> for modules</li> | ||
<li><code>fellow/edition-esnext-esm/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#ES.Next" title="ECMAScript Next">ESNext</a> for <a href="https://nodejs.org" title="Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine">Node.js</a> 12 || 14 || 15 with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li> | ||
<li><code>fellow/edition-deno/index.ts</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> source code made to be compatible with <a href="https://deno.land" title="Deno is a secure runtime for JavaScript and TypeScript, it is an alternative to Node.js">Deno</a></li></ul> | ||
<li><code>fellow/edition-browsers/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#11th_Edition_–_ECMAScript_2020" title="ECMAScript ES2020">ES2020</a> for web browsers with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li> | ||
<li><code>fellow</code> aliases <code>fellow/edition-es2019/index.js</code></li> | ||
<li><code>fellow/edition-es2019/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#10th_Edition_-_ECMAScript_2019" title="ECMAScript ES2019">ES2019</a> for <a href="https://nodejs.org" title="Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine">Node.js</a> 10 || 12 || 14 with <a href="https://nodejs.org/dist/latest-v5.x/docs/api/modules.html" title="Node/CJS Modules">Require</a> for modules</li> | ||
<li><code>fellow/edition-es2019-esm/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#10th_Edition_-_ECMAScript_2019" title="ECMAScript ES2019">ES2019</a> for <a href="https://nodejs.org" title="Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine">Node.js</a> 12 || 14 with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li></ul> | ||
@@ -98,0 +91,0 @@ <!-- /INSTALL --> |
@@ -9,4 +9,3 @@ { | ||
"strict": true, | ||
"target": "ESNext", | ||
"lib": ["ESNext"], | ||
"target": "ES2019", | ||
"module": "ESNext" | ||
@@ -13,0 +12,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112778
2355
14
1
154