datasign is a file format to describe data contract signatures to be used as a single source of (specified) truth to generate files for various pipelines.
Supported specification targets:
GraphQLProtocol BuffersTypeScript
Text.datasign
|
_________________________________________________________________________
| | |
to TypeScript to GraphQL to Protocol Buffers/gRPC
Text.ts Text.graphql Text.proto
// Text.datasign
/*
* Text Documentation
*/
Text {
// type the `id` field to `ID` for GraphQL, and `string` for TypeScript/Protocol Buffers/gRPC
@graphql ID
id string
name string
value string
@graphql Int
characters number
public boolean
@graphql Date
@proto number
generatedAt Date // assumes Date is already defined somewhere else/globally
generatedBy User
}
User {
id string
name string
}
// Text.ts
/**
* Text Documentation
*/
export interface Text {
id: string;
name: string;
value: string;
characters: number;
public: boolean;
generatedAt: Date;
generatedBy: User;
}
export interface User {
id: string;
name: string;
}# Text.graphql
#
# Text Documentation
#
type Text {
id: ID!
name: String!
value: String!
characters: Int!
public: Boolean!
generatedAt: Date!
generatedBy: User!
}
type User {
id: String!
name: String!
}// Text.proto
/**
* Text Documentation
*/
message Text {
required string id = 1;
required string name = 2;
required string value = 3;
required number characters = 4;
required boolean public = 5;
required number generatedAt = 6;
required User generatedBy = 7;
}
message User {
required string id = 1;
required string name = 2;
}Usage: datasign <files | directories...>
Options:
-v, --version output the version number
-t, --target <type> comma-separated compilation targets: typescript, graphql, proto (default: "typescript,graphql,proto")
-o, --output <path> output directory path (default: "./")
-r, --resolve <type> resolve the output path relative to the "file" directory, "process" directory, or "flatten" into the output path (default: "file")
-m, --merge [name] merge the output into a single file (named or not) for each target
-c, --comments [value] insert the comments into the target files (default: true)
-s, --spacing <value> indentation spacing to be used in the compiled files (default: "4")
-p, --preserve [value] preserve newline spacing of the ".datasign" file (default: true)
-g, --generated [value] inject a header in each generated file mentioning the source (default: true)
-d, --debug display compiling errors (default: false)
-h, --help display help for command
For scripting usage, run in the package
npm install @plurid/datasignor
yarn add @plurid/datasignand add a script in package.json
// .json
{
"scripts": {
"datasign": "datasign /path/to/files"
}
}For a simple compilation, create the .datasign files, e.g. Message.datasign:
// .datasign
Message {
id string
value string
}
and run the command pointing to the files location
npx @plurid/datasign ./Message.datasignFor programmatic usage, install the @plurid/datasign package with npm or yarn and use in a similar manner
// .ts
import {
DatasignLoader,
} from '@plurid/datasign';
async function main() {
const datasignLoader = new DatasignLoader('/path/to/file');
const graphql = await datasignLoader.load('graphql');
// `graphql` contains the types string
const proto = await datasignLoader.load('proto');
// `proto` contains the messages string
const typescript = await datasignLoader.load('typescript');
// `typescript` contains the types namespace
}
main();A datasign file uses the .datasign extension, is conventionally named using PascalCase, and is composed of one or more Datasign Entities.
A Datasign Entity is constituted by a Name, and a pair of braces {, }, signifying the start, respectively, the end, of the Datasign Fields section.
A Datasign Field is a key type pair, incremented with 2 or 4 spaces.
Each Datasign Field should be on a new line.
// .datasign
Name {
namedKeyOne string
namedKeyTwo number
}
The Datasign Entities and the Data Fields can be annotated using the @ symbol.
The annotations allow for target-specific alterations of the compiled files.
Each Datasign Annotation should be on a new line.
Datasign Annotations 'stack' on top of each other and affect the next available Datasign Entity or Datasign Field.
A comment is specified using the double slash (//) and can be on it's own line or either inlined.
example:
// .datasign
// this is a valid comment
Message { // this is also valid
id string
// other fields
}
For documentation purposes the documentation comment symbols /* paired with */ can be used.
example:
// .datasign
/*
* Documentation for the Message Entity.
*/
// this is a valid comment
Message { // this is also valid
/*
* Documentation for the id field.
*/
id string
// other fields
}
A .datasign file can import data signatures from another .datasign file. The import can be namespaced or extracted. The .datasign filename extension is not required in the import statement.
// a.datasign
SomeData {
one string
}
// b.datasign
// namespaced import
import A from ./path/to/a
// extracted import
import {
SomeData
} from ./path/to/a
SomeOtherData {
two A.SomeData
three SomeData
}
Metas allow the insertion of specific data for each individual target.
// .datasign
!proto `
// this text will be inserted only in the compiled .proto file
`
!graphql `
# this text will be inserted only in the compiled .graphql file
`
!typescript `
// this text will be inserted only in the compiled .ts file
`
numberbooleanstring
-
numberwill default to:IntforGraphQLint32forProtocol BuffersnumberforTypescript
-
booleanwill default to:BooleanforGraphQLboolforProtocol BuffersbooleanforTypescript
-
stringwill default to:StringforGraphQLstringforProtocol BuffersstringforTypescript
A type can be composed with another using parantheses, ( and ), and, &, or, |, equal, =, operators.
// .datasign
A {
b string
}
B = A & {
c string
}
C = A | B
D = (A | B) & {
e string
}
Allowed Datasign Entity annotations:
graphqlprototypescript
Allowed Datasign Field annotations:
graphqlprototypescript
To export or no the compiled interface.
default: true
example:
// .datasign
@typescript export false
Message {
// fields
}
compiles to
// .ts
interface Message {
// fields
}The GraphQL kind of the compiled GraphQL data structure.
values: type | input | type-input
default: type
example:
// .datasign
@graphql kind input
Message {
// fields
}
which is equivalent to
// .datasign
@graphql input
Message {
// fields
}
compiles to
# .graphql
input Message {
# fields
}or multi-kind
// .datasign
@graphql type-input
Message {
// fields
}
compiles to
# .graphql
type Message {
# fields
}
input Message {
# fields
}The GraphQL type of the compiled GraphQL field.
example:
Message {
@graphql type ID
id string
}
which is equivalent to
Message {
@graphql ID
id string
}
compiles to
type Message {
id: ID!
}Adds the directive to the GraphQL field. The directive needs to be provided in the GraphQL schema.
example:
Message {
newField string
// the `deprecated` directive needs to be provided to the graphql schema
@graphql directive deprecated reason "Use `newField`."
oldField string
}
compiles to
type Message {
newField: String!
oldField: String! @deprecated(reason: "Use `newField`.")
}The Protocol Buffers type of the compiled Protocol Buffers field.
example:
Count {
@proto type int64
value number
}
which is equivalent to
Count {
@proto int64
value number
}
compiles to
message Count {
required int64 value = 1;
}@plurid/datasign-javascript • JavaScript/TypeScript implementation
@plurid/datasign-grammar • grammar for text editors (syntax highlighting, syntax verification)