Skip to content
Open
Changes from 2 commits
Commits
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
201 changes: 199 additions & 2 deletions typescript-types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,207 @@
* LICENSE: MIT
*/

export type Author = Record<string, unknown> & {};

export type URI = string; // in JSON schema this should be a validated string

/** =====================
* Common Primitive Aliases
* ===================== */
type URL = string;
type PositiveInteger = number;

/** =====================
* MediaObject
* ===================== */
export type MediaObject = Record<string, unknown> & {
/** The bitrate of the media object. */
bitrate?: number;

/** File size in (mega/kilo)bytes. */
contentSize: number;

/** Actual bytes of the media object, e.g., the image or video file. */
contentUrl?: URL;

/**
* Media type (MIME format, IANA/MDN ref). E.g., application/zip, audio/mpeg.
* Can also be a URL describing the format.
*/
encodingFormat?: Text | URL;

/** Height of the item. */
height?: number;

/** Width of the item. */
width?: number;

/** Upload date. */
uploadDate: string; // ISO date or date-time
}

/** =====================
* Identifier / OrganizationIdentifier
* ===================== */
export type Identifier = PropertyValue & {}

export type OrganizationIdentifier =
| ISO6523Code
| Ringgold
| ResearchOrganizationRegistry
| EIN
| CaliforniaCorporationNumber
| PropertyValue;

/** =====================
* Organization
* ===================== */
export type Organization = Record<string, unknown> & {
/** Physical address of the item. */
address?: PostalAddress;

/** The name of the organization. */
name: Text;
Comment thread
cscheid marked this conversation as resolved.
Outdated

/** Contact emails. */
emails?: Email[];
Comment thread
cscheid marked this conversation as resolved.
Outdated

/** Identifiers for the organization. */
identifiers: OrganizationIdentifier[];

/** Parent organizations (supersedes branchOf). */
parentOrganizations?: Organization[];

/** An Organization to which this Organization belongs. */
memberOf?: Organization[];

/** Members (Persons or Organizations). */
members?: Organization[];

/** Sub-organizations (inverse of parentOrganizations). */
subOrganization?: Organization[];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need subOrganizations here; if they were involved, then they should be the actual organization in the attribution. If not, then they shouldn't appear at all. I don't think this adds information that's necessary for a document to be completely described.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also includes departments for an institute which may have different identifiers and billing contracts. I was going off of how Stencila uses this portion.

}

/** =====================
* Author and AuthorCRediT
* ===================== */
export type Author = Record<string, unknown> & {
/** The creator of an item. */
author: Organization | Person;

/** Description of how a user contributed. */
contributorRoles: (PropertyValue | AuthorCRediT)[];

/** Order of appearance (tie-break by family name). */
order?: PositiveInteger;
}

export enum AuthorCRediT {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to avoid typescript enums; they have negative downstream consequences for building packages. See eg https://www.totaltypescript.com/why-i-dont-like-typescript-enums

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Good point. How should we handle this? They are supported in JSON-schema.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even want to support AuthCredit or should we just leave it as PropertyValue like other identifiers?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string[]?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PropertyValue makes you have to see what kind of identifier it is in case it changes what things people want to use for contributions. Makes it a longer lasting schema.

Conceptualization = "Conceptualization",
Methodology = "Methodology",
Software = "Software",
Validation = "Validation",
FormalAnalysis = "Formal analysis",
Investigation = "Investigation",
Resources = "Resources",
DataCuration = "Data Curation",
WritingOriginalDraft = "Writing - Original Draft",
WritingReviewEditing = "Writing - Review & Editing",
Visualization = "Visualization",
Supervision = "Supervision",
ProjectAdministration = "Project administration",
FundingAcquisition = "Funding acquisition",
}

/** =====================
* Person
* ===================== */
export type Person = Record<string, unknown> & {
/** Identifiers for a person. */
identifiers?: PersonIdentifier[];

/** Affiliations. */
affiliations?: Affiliation[];

/** Emails. */
emails?: string[];

/** Names the author is known by. */
names: PersonName[];

/** Physical address. */
address?: PostalAddress;

/** Known languages (IETF BCP 47 codes). */
knowsLanguage?: Language;
}
export type Affiliation = Record<string, unknown> & {
affiliate: Organization | Person;
dateStart: string; // in JSON-schema this should be format date or date-time
Comment thread
cscheid marked this conversation as resolved.
Outdated
dateEnd?: string; // in JSON-schema this should be format date or date-time
affiliationType: string; // in JSON-schema this should have the description, "Describe the relationship to the item."
}

export type PersonName = Record<string, unknown> & {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love that article! I was talking to Nokome about how I'm, myself, an edgecase with multiple legal names. So! I'm going off of schema.org and Stencila here as a compromise. I think this is the best and most common way of gathering this information.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made family name optional in latest push.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm, in this case, not letting "good" get in the way of "good enough". :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In schema.org they're all optional and a single string: https://schema.org/Person

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Stencila has multiple/array here which is where I based off of. I originally had it as a single value, but Nokome pointed out Stencila has needed to use multiple values for names so that seems fine to me.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nokome, tagging you here for comment: can you give a bit more context on how multiple names are used, in contrast to how CSL-JSON does it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

familyNames: string[];
givenNames?: string[];
honorificPrefixes?: string[];
honorificSuffixes?: string[];
order: number;
Comment thread
cscheid marked this conversation as resolved.
Outdated
}

/** =====================
* Grant
* ===================== */
export type Grant = Record<string, unknown> & {
/** Ways to identify the grant. */
identifiers: PropertyValue[];

/**
* Something funded or sponsored through a Grant.
* (inverse: funding)
*/
fundedItem: ScholarlyWork | Person | Organization | Event | Product;

/** The person or organization funding. */
funder: Person | Organization;

/** The monetary or non-monetary contribution. */
funding: MonetaryAmount | Product | Service;

/** Description of what the funding contributed towards. */
description?: string;
}

/** =====================
* MonetaryAmount
* ===================== */
export type MonetaryAmount = Record<string, unknown> & {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is too fine-grained.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it helps add some structure. We do need to enforce something. Schema.org has these mechanics and I think it's a good way of doing it. There are multiple options.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do need to enforce something.

Why?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having too much flexibility brings us back to JATS.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is about exchanging documents. We truly don't have to define a standard for exchanging monetary units.

/** Currency, e.g., USD, BTC, etc. */
currency: Text;

/** The value of the monetary amount. */
value: number | StructuredValue;
}

/** =====================
* Placeholder Types (referenced but not defined in YAML)
* ===================== */
export interface PropertyValue { [key: string]: any; }
export interface ISO6523Code { [key: string]: any; }
export interface Ringgold { [key: string]: any; }
export interface ResearchOrganizationRegistry { [key: string]: any; }
export interface EIN { [key: string]: any; }
export interface CaliforniaCorporationNumber { [key: string]: any; }
export interface PostalAddress { [key: string]: any; }
export interface Email { [key: string]: any; }
export interface PersonIdentifier { [key: string]: any; }
export interface Language { [key: string]: any; }
export interface ScholarlyWork { [key: string]: any; }
export interface Event { [key: string]: any; }
export interface Product { [key: string]: any; }
export interface Service { [key: string]: any; }
export interface StructuredValue { [key: string]: any; }


export type License = {
uri?: URI; // link to full version of license if short name provided
name?: string; // short name (eg "CC-BY-SA 3.0", "MIT")
Expand Down