1.1.1 • Published 1 year ago

@xman.io/xman-js-sdk v1.1.1

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
1 year ago

xman-js-sdk

Javascript SDK for accessing XMan I/O data

Prerequisite

  1. Sign-up and create a workspace at https://xman.io
  2. Create and publish some content
  3. Create an API Client Key in Xman I/O a. Make sure you add localhost to allowed hosts, if you are doing development on localhost b. Secret key is required for SSR and Static Generation (Nuxt, NextJS, Gatsby, etc.)
  4. Generate and copy Types for your API. Paste these types in xman.d.ts file in your project and add "xman.d.ts" entry to your tsconfig.json > "include" section. This will provide IntelliSense in the IDE/editor you are using.

With globally distributed Cloudflare CDN, we have sub-second response times for content queries. Static generation is not recommended.

Server side rendering (SSR) could be used for better SEO.

Examples coming soon...

Install SDK

# Add XMan SDK to your project
yarn add @xman.io/xman-js-sdk

Or

npm install --save @xman.io/xman-js-sdk

Then

import { getWorkspace } from '@xman.io/xman-js-sdk'

Get Workspace and Stage

In a web app

// Workspace can be a global variable
// Default stage is 'live'
const workspace = getWorkspace('api-client-id', 'workspace-id')

// You can pass a stage name to get a different stage
const workspace = getWorkspace('api-client-id', 'workspace-id', 'pre-production')

// or 

const workspace = getWorkspace('api-client-id', 'workspace-id')
  .stage('pre-production')

Server side access

For server side access pass the the secret key. Make sure the key does not leak to the client.

This step also applies to frameworks that do server side rendering or static page generation, such as: Nuxt, NextJS, Gatsby, etc.

let workspace = getWorkspace('api-client-id', 'workspace-id')
.secret('api-secret-key')

Get data from XMan I/O

Use XMan SDK to read collections and items

// Get a list of items
const itemsList = await workspace.list<T>('collection-id', optionalListParams)
// returns
interface XmanItemsList<T> {
  items: XmanItem<T>[],
  nextPageToken?: string
}
// Where
interface XmanItem<T> {
  id: string
  data: T,
  createTime: string,
  updateTime: string,
  version: number
}

// E.g.
const articleList = await workspace.list<Article>('xman-article')
// articleList.should.be.an('object')
// articleList.items.should.be.an('array')

// Get one item
const item = await workspace.read<T>('collection-id', 'item-id')
// item.should.have.keys('id', 'data', 'version', 'updateTime', 'createTime')

Single Item

const item = await workspace.read<PropertyDevelopment>('xman-property-development', '0123456789abcdefghIJ')
// item.should.be.an('object')
// item.should.have.keys('id', 'data', 'version', 'updateTime', 'createTime')

Would return an item or null:

  {
    "id": "0123456789abcdefghIJ",
    "data": {
      "coverImage": [{ 
        "collection": "xman-assets-image-set",
        "id": "image-id"
      }],
      "about": "Centrally located ...",
      "description": "Perfectly positioned ...",
      "imageGallery": [
        {
          "collection": "xman-assets-image-set",
          "id": "image-id"
        },
        {
          "collection": "xman-assets-image-set",
          "id": "image-id"
        }
      ],
      "communitiesAround": [{"collection": "xman-property-development", "id": "another-property-id"}]
    },
    "version": 2,
    "createTime": "2019-10-31T13:44:13.625Z",
    "updateTime": "2020-04-02T22:09:40.874Z"
  }
Result Fieldtypedescription
idstringXMan I/O item id
item.dataObjectProperties managed in XMan I/O. References to Items and Images get special types with helper methods
createTimestringTimestamp when the item was first published to this stage
updateTimestringTimestamp when the item was most recently published to this stage

List of Items

interface ListParams {
  /** in page size. Default 12. Max 24. */
  pageSize?: number,
  /** the `nextPageToken` returned by the previous `list()` call. */
  nextPage?: string,
  /** property path to order by, followed by direction. E.g. `name asc` */
  orderBy?: string
}

interface XmanItemsList<T> {
  items: XmanItem<T>[],
  nextPageToken?: string
}

list<T> (collection: string, listParams?: ListParams): Promise<XmanItemsList<T>>;

workspace.list function

Inputtyperequireddescription
collection nameStringYes
listParamsObjectNoSorting and Paging parameters
listParams.pageSizeNumberNoDefault: 12, Max: 24
listParams.orderByStringNoData property name, followed by blank space and desc or asc. Default: updateTime desc
listParams.pageTokenStringIf PagingToken returned by the previous list() call in nextPageToken field

Would return an array of items. Array can be empty, but never undefined or null | Result Field | type | Can be undefined | description | | ------|------|------|------| | nextPageToken | String | Yes | If there are more pages, This token can be passed to the next list() call | | items | Array<Item> | No | List of items |

{
  "items": [
    {
      "id": "0123456789abcdefghIJ",
      "data": {
        "coverImage": { "collection": "xman-assets-image-set", "id": "image-id" },
        "about": "Centrally located ...",
        "description": "Perfectly positioned ...",
        "imageGallery": { "collection": "xman-assets-image-set", "id": "image-id" },
        "communitiesAround": [{"collection": "xman-property-development", "id": "another-property-id"}]
      },
      "version": 2,
      "createTime": "2019-10-31T13:44:13.625Z",
      "updateTime": "2020-04-02T22:09:40.874Z"
    },
    {
      "id": "z9y8x7w6v5u4t3s2r1q0",
      "data": {
        "coverImage": { "collection": "xman-assets-image-set", "id": "image-id" },
        "about": "Centrally located ...",
        "description": "Perfectly positioned ...",
        "imageGallery": { "collection": "xman-assets-image-set", "id": "image-id" },
        "communitiesAround": []
      },
      "version": 1,
      "createTime": "2019-10-31T13:52:57.109Z",
      "updateTime": "2019-10-31T17:46:37.373Z"
    }
  ],
  "nextPageToken": "loooooooooo...ooonnnnng...string"
}

Item References

An item may reference other items. E.g. An Article may reference an Author. In the above example, property developments are referencing Images (coverImage, imageGallery) and other property developments (communitiesAround)

We can get referenced objects by calling getReferencedItem() for single (first) item or getReferencedItems() for all items

  const propertyDevelopment = await workspace.read<PropertyDevelopment>('xman-property-development', '0123456789abcdefghIJ')
  const nearbyCommunities = await workspace.getReferencedItems<PropertyDevelopment>(propertyDevelopment?.data.communitiesAround)
  // nearbyCommunities.should.be.an('array')

Images

XMan.io comes with an Image Delivery Service backed by globally distributed Content Delivery Network (CDN). You can use this service to dynamically render images in specific sizes.

We use the Sharp Library for image operations. In the future releases we will support more image manipulation options supported by the Sharp Library

You can get alt text and the CDN URLs for image variations with specific settings (width and height) by calling workspace.getImage for a single (first) image or workspace.getImages for a set of images. The results can be used in a <picture> tag or an <img> tag.

Example:

  const propertyDevelopment = await workspace.read('xman-property-development', '0123456789abcdefghIJ')
  
  // Single image; no cropping
  const coverImage = await workspace.getImage(propertyDevelopment.coverImage)
  // When no settings are passed, the default variation is named 'main'
  // Render <img src='${coverImage.variations.main?.src}' alt='${coverImage.alt}'>

  // Single image
  const coverImage = await workspace.getImage(propertyDevelopment.coverImage, [{key: 'default', width: 1266, height: 713}])
  // Render <img src='${coverImage.variations.default?.src}' alt='${coverImage.alt}'>

// Single image, many responsive variations
  const variations: ImageSettings[] = [
    { key: 'default', width: 500 },
    { key: 'medium', width: 750, fit: 'cover' },
    { key: 'full' }
  ]
  const coverImage = await workspace.getImage(propertyDevelopment.coverImage, variations)
  // Render:
  //  <picture>
  //    <source srcset="${coverImage.full.src}" media="(min-width: 800px)" />
  //    <source srcset="${coverImage.medium.src}" media="(min-width: 550px)" />
  //    <img src="${coverImage.default.src}" alt="${coverImage.alt}" />
  //  </picture>


  // Set of Images, with responsive variations
  const galleryImages = await workspace.getImages(propertyDevelopment.imageGallery, variations)

  galleryImages.forEach(img => {
  //  <picture>
  //    <source srcset="${img.full.src}" media="(min-width: 800px)" />
  //    <source srcset="${img.medium.src}" media="(min-width: 550px)" />
  //    <img src="${img.default.src}" alt="${img.alt}" />
  //  </picture>
  })

Image cropping

If you specify either width or height (but not both), the aspect ratio is maintained and the original image is scaled. The image is never scaled up beyond the original width and height. We may do this in later releases.

If you specify both width and height, the original image is focus cropped (if needed) and resized to fit in the box. Focus is set on the region with the highest Shannon Entropy (aka "art direction").

For example:

With only { height: 200 }

Wide image with 200px height and subject to the right side

With { width: 120, height: 200}

Narrow image with 120px width and 200px height and subject in focus

Credit: Photo by Eye for Ebony on Unsplash

You can also choose the focus point manually in XMan.io.

Demo of selecting focus in XMan.io

Image service always delivers images in progressive JPEG format (image/jpeg)

1.1.1

1 year ago

1.1.0

1 year ago

1.0.5

1 year ago

0.5.6

4 years ago

0.4.0

4 years ago

0.3.0

4 years ago

0.1.6

4 years ago

0.1.5

4 years ago

0.1.3

4 years ago

0.1.2

4 years ago