Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@forge/util

Package Overview
Dependencies
Maintainers
2
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@forge/util

  • 1.4.2-next.0
  • npm
  • Socket score

Version published
Weekly downloads
14K
decreased by-20.59%
Maintainers
2
Weekly downloads
 
Created
Source

@atlassian/ari

The official TypeScript library for creating, parsing and working with ARIs 🚀

The classes in this repository are auto-generated based upon the ARI Registry. We plan to release a new version of this library at the start of every business week, AEST.

Installation

To install this library, run:

yarn add @atlassian/ari

or

npm i @atlassian/ari

Usage

This library aims to give you the primitives you need to get working with ARIs. To the extent we can, we aim to provide a lightweight API for our consumers.

Importing

You can import a specific ARI class from a few places, depending on your bundle size requirements:

// Import from an entry point specific to a resource owner (Confluence).
import { ConfluencePageAri } from '@atlassian/ari/confluence';

// Import from an entry point specific to a resource owner (Confluence) and a resource type (page).
import { ConfluencePageAri } from '@atlassian/ari/confluence/page';

// Import core classes from root entry point.
import { Ari, AnyAri, Ati } from '@atlassian/ari';

Quick start

Most of the methods and classes you can interact with are shown below. For a more detailed reference, keep scrolling until the API reference section.

// Import core classes from root entrypoint.
import { AnyAri, Ati, ResourceOwner, ResourceType } from '@atlassian/ari';
// Import from an entry-point specific to a resource owner (Confluence) and a resource type (page).
import { ConfluenceSiteAri } from '@atlassian/ari/confluence/site';

// ===========================================================================
// Option 1️⃣: work with ARI classes representing definitions from the registry.
// ===========================================================================
// - Create an ARI, using segments defined in the registry definition.
const pageAri = ConfluencePageAri.create({
  siteId: '123',
  pageId: '456',
});

// - Access specific segments for this ARI.
console.log(pageAri.siteId); // yields '123'
console.log(pageAri.pageId); // yields '456'

// - Access generic segments conforming to the ARI specification.
console.log(pageAri.cloudId); // yields '123'
console.log(pageAri.resourceOwner); // yields 'confluence'
console.log(pageAri.resourceType); // yields 'page'
console.log(pageAri.resourceId); // yields '456'

// - Access the ATI for this segment.
console.log(pageAri.ati); // yields Ati { resourceOwner: 'confluence', resourceType: 'page' }

// - Check if an ARI string (or class) can be interepted as this type.
console.log(ConfluenceSiteAri.check('ari:cloud:jira::site/ee95456c-a203-42dc-b284-7bbb3854457f')); // yields 'false'
console.log(ConfluenceSiteAri.check('ari:cloud:confluence::site/ee95456c-a203-42dc-b284-7bbb3854457f')); // yields 'true'

// ===========================================================================
// Option 2️⃣: work with generic ARI classes, conforming to the ARI specification.
// ===========================================================================
// - Create an ARI based on the specification (no convenience methods)
const pageAriTheSecond = AnyAri.create({
  resourceOwner: ResourceOwner.Confluence,
  cloudId: '123',
  resourceType: ResourceType.Page,
  resourceId: '456',
});

// - Access generic segments conforming to the ARI specification
console.log(pageAri.cloudId); // yields '123'
console.log(pageAri.resourceOwner); // yields 'confluence'
console.log(pageAri.resourceType); // yields 'page'
console.log(pageAri.resourceId); // yields '456'

// - Access the ATI for this segment
console.log(pageAri.ati); // yields Ati { resourceOwner: 'confluence', resourceType: 'page' }

Lastly, here is an example of parsing into a specific ARI type:

import { ConfluencePageAri, JiraIssueAri, TrelloCardAri } from '@atlassian/ari';

const invokeApi = (ari: string): Promise<Ari> => {
  if (TrelloCardAri.check(ari)) {
    return this.http.client.post(`/trello/api/${ari}`);
  }

  if (JiraIssueAri.check(ari)) {
    return this.http.client.post(`/jira/api/${ari}`);
  }

  if (ConfluencePageAri.check(ari)) {
    return this.http.client.post(`/confluence/api/${ari}`);
  }
};

const ari = await invokeApi('ari:cloud:confluence:123:page/456'); // demonstrative of a valid Confluence Page ARI
console.log(ari.resourceId); // yields the resource ID returned from the upstream API

API reference

Working with ARIs
Parsing an ARI

If you are parsing an ARI from the registry, you can use a specific Ari class to parse from string to that instance (e.g. ConfluencePageAri), or the generic Ari for unregistered ARIs.

// Import from an entry-point specific to a resource owner (Confluence) and a resource type (page).
import { ConfluencePageAri } from '@atlassian/ari/confluence/page';

const ari = ConfluencePageAri.parse('ari:cloud:confluence:123:page/456'); // yields a ConfluencePageAri class instance
console.log(ari.siteId); // yields 123
console.log(ari.pageId); // yields 456

If you are parsing an ARI which does not exist in the registry (:paddlin:) you can use the core ARI class.

// Import core classes from root entrypoint.
import { AnyAri } from '@atlassian/ari';

const ari = AnyAri.parse('ari:cloud:confluence:123:page/456'); // yields a generic ARI class instance
console.log(ari.cloudId); // yields 123
console.log(ari.resourceId); // yields 456

Note: if the invocation of .parse() fails, a ValidationError will be thrown.

// Import core classes from root entrypoint.
import { AnyAri } from '@atlassian/ari';

try {
  const ari = AnyAri.parse('ari:cloud:confluence:123:unregistered-ari/456'); // yields a generic ARI class instance
} catch (err) {
  if (err.constructor.name === 'ValidationError') {
    // handle error
  }
}
Creating an ARI

If you are creating an ARI from the registry, you can use a specific Ari class to create from a set of options for that instance in conformance with its definition in the ARI registry (e.g. ConfluencePageAri), or the generic Ari for unregistered ARIs.

// Import from an entry-point specific to a resource owner (Confluence) and a resource type (page).
import { ConfluencePageAri } from '@atlassian/ari/confluence/page';

const ari = ConfluencePageAri.create({
  // yields a ConfluencePageAri class instance
  siteId: '123',
  pageId: '456',
});

console.log(ari.siteId); // yields 123
console.log(ari.pageId); // yields 456

If you are creating an ARI which does not exist in the registry (double :paddlin:) you can use the core ARI class.

// Import core classes from root entrypoint.
import { AnyAri } from '@atlassian/ari';

const ari = AnyAri.create({
  // yields a generic ARI class instance
  resourceOwner: 'confluence',
  cloudId: '123',
  resourceType: 'page',
  resourceId: '456',
});

console.log(ari.cloudId); // yields 123
console.log(ari.resourceId); // yields 456

Note: if the invocation of .create() or parse() fails, a ValidationError will be thrown.

// Import core classes from root entrypoint.
import { AnyAri } from '@atlassian/ari';

try {
  const ari = AnyAri.parse('ari:cloud:confluence:123:unregistered-ari/456'); // yields a generic ARI class instance
} catch (err) {
  if (err.constructor.name === 'ValidationError') {
    // handle error
  }
}
Checking ARIs

You can use the check() function to determine if an ARI string or class fits the requirements of a certain ARI.

import { AnyAri, ConfluenceSiteAri, JiraSiteAri } from '@atlassian/ari';

const result1 = AnyAri.check(ConfluenceSiteAri.create({ siteId: 'ee95456c-a203-42dc-b284-7bbb3854457f' }));
const result2 = JiraSiteAri.check('ari:cloud:confluence::site/ee95456c-a203-42dc-b284-7bbb3854457f');

console.log(result1); // yields true
console.log(result2); // yields false
Working with ATIs
Parsing an ATI

For ATIs, the use of more specific instance is not required. The core Ati class should be used:

// Import core classes from root entrypoint.
import { Ati, ResourceOwner, ResourceType } from '@atlassian/ari';

const ati = Ati.parse('ati:cloud:confluence:page');
console.log(ati.resourceOwner); // yields `confluence`
console.log(ati.resourceType); // yields `page`
Creating an ATI

For ATIs, the use of more specific instance is not required. The core Ati class should be used:

// Import core classes from root entrypoint.
import { Ati, ResourceOwner, ResourceType } from '@atlassian/ari';

const ati = Ati.create({
  resourceOwner: ResourceOwner.Confluence,
  resourceType: ResourceType.Page,
});

console.log(ati.toString()); // yields `ati:cloud:confluence:page`
Working with ARMs
Parsing an ARM

ARMs are exposed through the top-level Arm class. To parse an ARM string do the following:

// Import `Arm` class from root entrypoint.
import { Arm } from '@atlassian/ari';

const arm = Arm.parse('arm:cloud:jira.*::board/.+');
console.log(arm.resourceOwnerMatcher); // yields `jira.*`
console.log(arm.resourceTypeMatcher); // yields `board`
Creating an ARM

You can create an ARM using the same Arm class mentioned above!

// Import `Arm` from root entrypoint.
import { Arm } from '@atlassian/ari';

const arm = Arm.create({
  resourceOwnerMatcher: 'jira.*',
  cloudIdMatcher: '',
  resourceTypeMatcher: 'board',
  resourceIdMatcher: '.+',
});

console.log(arm.toString()); // yields `arm:cloud:jira.*::board/.+`
Matching an ARI against an ARM

You can match ARIs against ARMs using the .match method on ARM instances:

// Import `Arm` from root entrypoint.
import { Arm } from '@atlassian/ari';
import { ConfluencePageAri } from '@atlassian/ari/confluence/page';

const ari = ConfluencePageAri.create({
  siteId: '123',
  pageId: '456',
});
const arm = Arm.create({
  resourceOwnerMatcher: 'confluence',
  cloudIdMatcher: '[0-9]+',
  resourceTypeMatcher: 'page',
  resourceIdMatcher: '.+',
});

console.log(arm.match(ari)); // yields `true`

FAQ

I have a feature request - where should I raise it?

Please create a ticket on this Trello board. We will try to get back to you ASAP!

I cannot see an ARI which should exist in this repository. What do I do?

Try to figure out who the resource owner of the ARI is, and kindly ask them to add their ARI to the ARI Registry YAML 😄

We auto-generate classes based on what exists in the registry. Teams should be reflecting their ARI back into it, using the process defined here.

If your ARI has recently been added to the registry, you will have to wait until the start of the next business week (AEST) for the changes to be reflected in this library.

I need a change to go through urgently. Who do I speak to?

Come and chat to us in the #ari-working-group channel!

Contributing

If you're keen on helping us build out this library, reach out to us in #ari-working-group 😄

As a Working Group, we meet every fortnight. Library developers and maintainers will be present - we'd love to meet you and collaborate with you on this!

FAQs

Package last updated on 15 Mar 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc