Links

Getting started

Getting started with the Specify SDK in your Javascript / Typescript code base.
Try out Specify with your team and put us to the test! Do you have an ideal workflow in mind, or are you curious if your output can be generated? Challenge us on GitHub or send us a message! We welcome all your feedback.

Prerequisites

  • Javascript ESM compatible runtime (browser or NodeJS)
  • [Optional] Typescript >= 4.9

Installation

npm install @specifyapp/sdk

Create a client

import { createSpecifyClient } from '@specifyapp/sdk';
const specifyClient = createSpecifyClient();

Authenticate

In order to consume the private data from a Specify repository, you must authenticate using a personal access token.
You can generate a new PAT in your Specify user settings.
await specifyClient.authenticate('your-personal-access-token');
console.log(specifyClient.isAuthenticated); // true
console.log(specifyClient.whoAmI()); // current user

List your organization repositories

Get a list of repositories belonging to your organization.
const repositories = await specifyClient.getRepositories();
console.log(repositories); // [{ id: '...', name: '...' }, ...]

Get a repositoryTokenTree client

The RepositoryTokenTree is an object providing numerous methods to work with the design data stored using the Specify Design Token Format (SDTF).
const repositoryTokenTree = specifyClient.getRepositoryTokenTreeByName('repository-name');
console.log(repositoryTokenTree); // instance of RepositoryTokenTree
console.log(repositoryTokenTree.information) // { id: string; name: string... }

Get the SDTF JSON token tree

You would want to grab the SDTF JSON token tree of a repository anytime you want to: send the token tree over the network or debug an intermediate manipulation.
const jsonTokenTree = repositoryTokenTree.getJSONTokenTree();
console.log(jsonTokenTree) // the object literal representation of the Specify Design Token data

Manipulating the token tree

Imagine we have the following tokenTree:
const tokenTree: SpecifyDesignTokenFormat = {
color: {
Red: { $type: 'color', $value: { default: { model: 'hex', hex: '#ff0000', alpha: 1 } } },
Blue: { $type: 'color', $value: { default: { model: 'hex', hex: '#0000ff', alpha: 1 } } },
},
spacing: {
Base: { $type: 'dimension', $value: { default: { unit: 'px', value: 8 } } },
},
};
And we want to only grab the Red color, in its group, and change its name to be lowercase. We would do:
const mutatedRepositoryTokenTree = repositoryTokenTree
.pick(['color'])
.remove({ where: { token: '^Blue$', select: true } })
.mapQueryResult(
{ where: { token: '^Red$', select: true } },
(treeNodeState, engine, queryResult) => {
if (treeNodeState.isToken) {
engine.mutation.renameToken({
atPath: treeNodeState.path,
name: treeNodeState.name.toLowerCase(),
});
}
},
);
Then we transform the repositoryTokenTree into a code output (CSS custom properties variables in this case):
const pipeEngineOutput = await mutatedRepositoryTokenTree.transformWithRemoteParsers([
{
name: 'to-css-custom-properties',
output: { type: 'file', filePath: 'filtered-colors.css' },
},
]);
With this example, we expect the following CSS output:
:root {
--color-red: #ff0000;
}

Write files to file system

The Specify SDK is a universal package that does not provide file system utilities.
However, you can use the @specifyapp/node-utils package to write the files generated by the Specify to file system.
import {createSpecifyFileSystemHelper} from '@specifyapp/node-utils';
const pipeEngineRuleResponseBody = await repositoryTokenTree.transformWithRemoteParsers([
{
name: 'to-css-custom-properties',
output: {type: 'file', filePath: 'tokens.css'},
},
]);
const fileSystemHelper = createSpecifyFileSystemHelper({
pipeEngineRuleResponseBody
});
const writtenFiles = await fileSystemHelper.writeToDisk('./public');
console.log(writtenFiles); // ['public/tokens.css']