Metadata Helpers
These utility functions are designed to fetch and process blocklet metadata (blocklet.json
) from various remote sources, such as HTTP endpoints or local file paths. They are essential for dynamically loading, validating, and composing blocklets within an application.
This collection of helpers simplifies the process of resolving a blocklet's source, validating its metadata, and ensuring its dependencies, like the distribution tarball, are accessible.
getBlockletMetaByUrl#
Fetches the raw blocklet metadata object from a specified URL. This function supports both http(s)://
and file://
protocols and incorporates a cache to improve performance for repeated requests.
async function getBlockletMetaByUrl(url: string): Promise<TBlockletMeta>
Parameters
Name | Type | Description |
---|---|---|
|
| The full URL pointing to the |
Returns
Promise<TBlockletMeta>
: A promise that resolves to the parsed blocklet metadata object.
Example
import { getBlockletMetaByUrl } from '@blocklet/meta';
async function fetchMeta() {
try {
const meta = await getBlockletMetaByUrl('https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/blocklet.json');
console.log('Fetched meta:', meta.name, meta.version);
} catch (error) {
console.error('Failed to fetch metadata:', error.message);
}
}
fetchMeta();
Example Response
{
"name": "z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq",
"version": "1.6.29",
"title": "Blocklet Registry",
"description": "A blocklet registry that allows you to publish and install blocklets.",
"did": "z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq",
"dist": {
"tarball": "https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/1.6.29/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq-1.6.29.tgz"
}
}
getBlockletMetaFromUrl#
A more comprehensive function that not only fetches metadata from a URL but also validates its structure and can perform additional checks, such as ensuring the dist.tarball
URL is accessible.
async function getBlockletMetaFromUrl(
url: string,
options?: {
validateFn?: Function;
returnUrl?: boolean;
ensureTarball?: boolean;
logger?: any;
}
): Promise<any>
Parameters
Name | Type | Description |
---|---|---|
|
| The URL of the |
|
| An optional configuration object. |
|
| A custom function to validate the metadata. Defaults to an internal validator. |
|
| If |
|
| If |
|
| An optional logger instance for debugging. |
Returns
Promise<any>
: A promise that resolves to the validated metadata. IfreturnUrl
is true, it resolves to an object containing both the metadata and the source URL.
Example
import { getBlockletMetaFromUrl } from '@blocklet/meta';
async function fetchAndValidateMeta() {
try {
const { meta, url } = await getBlockletMetaFromUrl(
'https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/blocklet.json',
{
returnUrl: true,
ensureTarball: true,
}
);
console.log(`Successfully validated meta for ${meta.name} from ${url}`);
console.log(`Tarball location: ${meta.dist.tarball}`);
} catch (error) {
console.error('Failed to fetch or validate metadata:', error.message);
}
}
fetchAndValidateMeta();
Example Response
{
"meta": {
"name": "z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq",
"version": "1.6.29",
"title": "Blocklet Registry",
"did": "z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq",
"dist": {
"tarball": "https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/1.6.29/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq-1.6.29.tgz"
}
},
"url": "https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/blocklet.json"
}
getBlockletMetaFromUrls#
Attempts to fetch and validate blocklet metadata from an array of URLs. It returns the result from the first URL that resolves successfully, providing a robust fallback mechanism for sourcing blocklets from multiple registries or locations.
async function getBlockletMetaFromUrls(
urls: string[],
options?: {
validateFn?: Function;
returnUrl?: boolean;
ensureTarball?: boolean;
logger?: any;
}
): Promise<any>
Parameters
Name | Type | Description |
---|---|---|
|
| An array of |
|
| The same options object as |
Returns
Promise<any>
: A promise that resolves with the metadata from the first successful URL fetch. If all URLs fail, the promise is rejected with an aggregate error.
Example Flow
Example Usage
import { getBlockletMetaFromUrls } from '@blocklet/meta';
async function fetchWithFallback() {
const urls = [
'https://invalid-store.example.com/api/blocklet/meta.json', // This will fail
'https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/blocklet.json' // This is the fallback
];
try {
const meta = await getBlockletMetaFromUrls(urls);
console.log(`Successfully fetched meta for ${meta.name} using fallback.`);
} catch (error) {
console.error('All URLs failed:', error.message);
}
}
fetchWithFallback();
getSourceUrlsFromConfig#
Constructs an array of potential blocklet.json
URLs from a blocklet's component configuration object (TBlockletMeta.components
). This helper is useful for resolving child blocklets within a composite application.
It can derive URLs from various source specifications:
- A direct
source.url
. - A combination of
source.store
,source.name
, andsource.version
. - A pre-resolved URL in
resolved
.
function getSourceUrlsFromConfig(config: TComponent & any): string[]
Parameters
Name | Type | Description |
---|---|---|
|
| The component configuration object from a parent blocklet's metadata. |
Returns
string[]
: An array of potential metadata URLs for the component.
Example
import { getSourceUrlsFromConfig } from '@blocklet/meta';
// Example 1: Source from a blocklet store
const componentConfig1 = {
source: {
name: 'z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq',
store: 'https://store.blocklet.dev/api',
version: '1.6.29'
}
};
// Example 2: Source from a direct URL
const componentConfig2 = {
source: {
name: 'my-component',
url: 'https://github.com/my-org/my-component/blocklet.json'
}
};
// Example 3: Source from a resolved URL
const componentConfig3 = {
name: 'another-component',
resolved: 'file:///path/to/local/blocklet.json'
};
const urls1 = getSourceUrlsFromConfig(componentConfig1);
const urls2 = getSourceUrlsFromConfig(componentConfig2);
const urls3 = getSourceUrlsFromConfig(componentConfig3);
console.log('From store:', urls1);
// Output: From store: [ 'https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/1.6.29/blocklet.json' ]
console.log('From direct URL:', urls2);
// Output: From direct URL: [ 'https://github.com/my-org/my-component/blocklet.json' ]
console.log('From resolved:', urls3);
// Output: From resolved: [ 'file:///path/to/local/blocklet.json' ]
validateUrl#
A utility to check if a URL is accessible and valid. It handles file://
protocols by checking for file existence and http(s)://
protocols by making a HEAD
request to check for a successful status and an expected Content-Type
header.
async function validateUrl(url: string, expectedHttpResTypes?: string[]): Promise<boolean>
Parameters
Name | Type | Description |
---|---|---|
|
| The URL to validate. |
|
| An optional array of allowed MIME types for HTTP responses. Defaults to |
Returns
Promise<boolean>
: A promise that resolves totrue
if the URL is valid. It throws an error on failure.
Example
import { validateUrl } from '@blocklet/meta';
async function checkTarballUrl() {
const tarballUrl = 'https://store.blocklet.dev/api/blocklets/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq/1.6.29/z8iZtw2f8XF7myz5WZFv1o9bLgsswVoaF7Psq-1.6.29.tgz';
try {
await validateUrl(tarballUrl, ['application/octet-stream', 'application/x-gzip']);
console.log('Tarball URL is valid and has the correct content type.');
} catch (error) {
console.error('URL validation failed:', error.message);
}
}
checkTarballUrl();
With these helpers, you can build sophisticated systems for managing blocklets. To learn about helpers for working with the internal state of a blocklet, proceed to the Component & State Utilities section.