Skip to content

Commit

Permalink
Introduce integration metadata file to improve config handling
Browse files Browse the repository at this point in the history
  • Loading branch information
xentobias committed Sep 28, 2024
1 parent b36e233 commit d07b2fb
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 222 deletions.
Binary file modified bun.lockb
Binary file not shown.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@xentom/cli",
"version": "0.0.14",
"version": "0.0.15",
"type": "module",
"scripts": {
"format": "prettier --check .",
"format:fix": "bun format --continue -- --write --cache --cache-location .cache/.prettiercache",
"format:fix": "bun format --write --cache --cache-location .cache/.prettiercache",
"typecheck": "tsc --noEmit --emitDeclarationOnly false",
"lint": "eslint",
"dev": "bun ./src/index.ts",
Expand All @@ -15,7 +15,7 @@
"@t3-oss/env-core": "^0.11.0",
"@trpc/client": "next",
"@trpc/server": "next",
"@xentom/integration": "^0.0.19",
"@xentom/integration": "^0.0.21",
"archiver": "^7.0.1",
"commander": "^12.1.0",
"detect-package-manager": "^3.0.2",
Expand Down
1 change: 0 additions & 1 deletion playground/assets/index-BrWalHZA.css

This file was deleted.

1 change: 1 addition & 0 deletions playground/assets/index-CK8UHEQ7.css

Large diffs are not rendered by default.

68 changes: 34 additions & 34 deletions playground/index.html
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link
rel="icon"
media="(prefers-color-scheme: light)"
type="image/svg+xml"
href="/favicons/light.svg"
/>

<link
rel="icon"
media="(prefers-color-scheme: dark)"
type="image/svg+xml"
href="/favicons/dark.svg"
/>

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800&display=swap"
rel="stylesheet"
/>

<title>Xentom: Integration Playground</title>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link
rel="icon"
media="(prefers-color-scheme: light)"
type="image/svg+xml"
href="/favicons/light.svg"
/>

<link
rel="icon"
media="(prefers-color-scheme: dark)"
type="image/svg+xml"
href="/favicons/dark.svg"
/>

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800&display=swap"
rel="stylesheet"
/>

<title>Xentom: Integration Playground</title>
<script type="module" crossorigin src="/index.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BrWalHZA.css">
</head>
<body class="antialiased">
<div id="root"></div>
</body>
</html>
<link rel="stylesheet" crossorigin href="/assets/index-CK8UHEQ7.css">
</head>
<body class="antialiased">
<div id="root"></div>
</body>
</html>
270 changes: 135 additions & 135 deletions playground/index.js

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions src/commands/dev/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createCommand } from '@/commands/utils';
import { ActionError, actionErrorHandler } from '@/utils/action';
import { getPackageJson } from '@/utils/pm';
import { getIntegrationMetadata } from '@/utils/metadata';
import { type WebSocketHandler } from 'bun';
import mime from 'mime/lite';
import { cyan } from 'yoctocolors';
import { type IntegrationPackageJson } from '@xentom/integration';
import { type IntegrationMetadata } from '@xentom/integration/schema';
import { createIntegrationBuilder } from '../build';
import { getPlaygroundFiles } from './embed' with { type: 'macro' };

Expand Down Expand Up @@ -48,11 +48,11 @@ export async function dev(options: DevOptions) {
throw new ActionError('Integration builder failed');
});

const pkg = await getPackageJson();
const router = createPlaygroundRouter(pkg);
const metadata = await getIntegrationMetadata();
const router = createPlaygroundRouter(metadata);
const server = Bun.serve({
port: options.port,
websocket: createWebSocketHandler(pkg.name, listeners),
websocket: createWebSocketHandler(metadata.name, listeners),
async fetch(req, server) {
if (server.upgrade(req)) return;
return router.handle(req);
Expand All @@ -64,7 +64,7 @@ export async function dev(options: DevOptions) {
);
}

function createPlaygroundRouter(pkg: IntegrationPackageJson) {
function createPlaygroundRouter(metadata: IntegrationMetadata) {
const files = Object.fromEntries(getPlaygroundFiles());
return {
async handle(req: Request) {
Expand All @@ -79,14 +79,14 @@ function createPlaygroundRouter(pkg: IntegrationPackageJson) {
}

case '/integration/logo': {
if (!pkg.logo) {
if (!metadata.logo) {
return new Response(null, { status: 404 });
}

return new Response(await Bun.file(pkg.logo).arrayBuffer(), {
return new Response(await Bun.file(metadata.logo).arrayBuffer(), {
headers: {
'Content-Type':
mime.getType(pkg.logo) ?? 'application/octet-stream',
mime.getType(metadata.logo) ?? 'application/octet-stream',
'Access-Control-Allow-Origin': '*',
},
});
Expand Down
8 changes: 8 additions & 0 deletions src/commands/init/templates/typescript/integration.json.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://cdn.xentom.com/schemas/integration.json",
"name": "{{ name }}",
"version": "0.0.1",
"organization": "{{ organization }}",
"source": "./src/index.ts",
"logo": "./assets/logo.png"
}
12 changes: 3 additions & 9 deletions src/commands/init/templates/typescript/package.json.tpl
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
{
"$schema": "https://cdn.xentom.com/schemas/package.json",
"name": "{{ name }}",
"version": "0.0.1",
"organization": "{{ organization }}",
"source": "./src/index.ts",
"logo": "./assets/logo.png",
"scripts": {
"dev": "xentom dev",
"build": "xentom build",
"publish": "xentom publish"
},
"dependencies": {
"@tabler/icons-react": "^3.17.0"
"@xentom/integration": "^0.0.21",
"@tabler/icons-react": "^3.19.0"
},
"devDependencies": {
"@types/bun": "^1.1.9",
"@types/bun": "^1.1.10",
"typescript": "^5.6.2"
},
"peerDependencies": {
"@xentom/integration": "^0.0.16"
}
}
52 changes: 26 additions & 26 deletions src/commands/publish/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { env } from '@/env';
import { createRequestHeaders } from '@/lib/trpc';
import { createZipInMemory } from '@/lib/zip';
import { ActionError, actionErrorHandler } from '@/utils/action';
import { getIntegrationMetadata } from '@/utils/metadata';
import { cmd } from '@/utils/output';
import { getPackageJson } from '@/utils/pm';
import ora from 'ora';
import { cyan, red } from 'yoctocolors';
import { ZodError } from 'zod';
import { IntegrationPackageJson } from '@xentom/integration/schema';
import { IntegrationMetadata } from '@xentom/integration/schema';

export function createPublishCommand() {
return createCommand()
Expand All @@ -33,36 +33,36 @@ export interface PublishOptions {
export async function publish(options: PublishOptions) {
const spinner = ora('Publishing integration...').start();

let pkg;
let metadata;
try {
pkg = await getPackageJson();
metadata = await getIntegrationMetadata();
} catch (error) {
spinner.clear();
throw new ActionError(
`The ${cmd('package.json')} file is missing or invalid. Please make sure the file exists and is valid JSON.`,
`The ${cmd('integration.json')} file is missing or invalid. Please make sure the file exists and is valid JSON.`,
);
}

try {
IntegrationPackageJson.parse(pkg);
IntegrationMetadata.parse(metadata);
} catch (error) {
spinner.clear();

if (!(error instanceof ZodError)) {
throw new ActionError(`The ${cmd('package.json')} file is invalid.`);
throw new ActionError(`The ${cmd('integration.json')} file is invalid.`);
}

throw new ActionError(
`The ${cmd('package.json')} file is invalid. Please fix the following fields:\n${error.errors
`The ${cmd('integration.json')} file is invalid. Please fix the following fields:\n${error.errors
.map((e) => ` - ${red(e.path[0].toString())} (${e.message})`)
.join('\n')}`,
);
}

if (pkg.logo?.endsWith('.svg')) {
if (metadata.logo?.endsWith('.svg')) {
spinner.clear();
throw new ActionError(
`SVG logos are not allowed due to security reasons. Please use a different format for the ${cmd('logo')} in ${cmd('package.json')}.`,
`SVG logos are not allowed due to security reasons. Please use a different format for the ${cmd('logo')} in ${cmd('integration.json')}.`,
);
}

Expand All @@ -78,17 +78,17 @@ export async function publish(options: PublishOptions) {
);
}

const previousVersion = pkg.version;
const previousVersion = metadata.version;
if (options.increment) {
pkg = await incrementVersion(pkg);
metadata = await incrementVersion(metadata);
}

try {
await upload(await pack(pkg), options.tag);
await upload(await pack(metadata), options.tag);
} catch (error) {
// Revert the version back to the previous one if the upload fails
if (options.increment) {
pkg = await setVersion(pkg, previousVersion);
metadata = await setVersion(metadata, previousVersion);
}

if (options.ignoreDuplicates) {
Expand All @@ -100,7 +100,7 @@ export async function publish(options: PublishOptions) {
) {
spinner.succeed(
`The integration version ${cyan(
`${pkg.name}@${pkg.version}`,
`${metadata.name}@${metadata.version}`,
)} has already been published under the ${cyan(options.tag)} tag.`,
);

Expand All @@ -113,26 +113,26 @@ export async function publish(options: PublishOptions) {
}

spinner.succeed(
`Integration ${cyan(`${pkg.name}@${pkg.version}`)} has been successfully published under the ${cyan(options.tag)} tag.`,
`Integration ${cyan(`${metadata.name}@${metadata.version}`)} has been successfully published under the ${cyan(options.tag)} tag.`,
);
}

async function incrementVersion(pkg: IntegrationPackageJson) {
const version = pkg.version.split('.');
async function incrementVersion(metadata: IntegrationMetadata) {
const version = metadata.version.split('.');
version[version.length - 1] = String(Number(version[version.length - 1]) + 1);
return await setVersion(pkg, version.join('.'));
return await setVersion(metadata, version.join('.'));
}

async function setVersion(pkg: IntegrationPackageJson, version: string) {
const copy = { ...pkg };
async function setVersion(metadata: IntegrationMetadata, version: string) {
const copy = { ...metadata };
copy.version = version;
await Bun.write('./package.json', JSON.stringify(copy, null, 2));
await Bun.write('./integration.json', JSON.stringify(copy, null, 2));
return copy;
}

async function pack(pkg: IntegrationPackageJson) {
async function pack(metadata: IntegrationMetadata) {
const files = [
'./package.json',
'./integration.json',
'./CHANGELOG.md',
'./LICENSE.txt',
'./README.md',
Expand All @@ -144,8 +144,8 @@ async function pack(pkg: IntegrationPackageJson) {
'./dist/index.d.ts',
];

if (pkg.logo) {
files.push(pkg.logo);
if (metadata.logo) {
files.push(metadata.logo);
}

return await createZipInMemory(files);
Expand Down
5 changes: 5 additions & 0 deletions src/utils/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { type IntegrationMetadata } from '@xentom/integration';

export async function getIntegrationMetadata(path = './integration.json') {
return (await Bun.file(path).json()) as IntegrationMetadata;
}
5 changes: 0 additions & 5 deletions src/utils/pm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { detect, type PM } from 'detect-package-manager';
import { type IntegrationPackageJson } from '@xentom/integration';

export async function getPackageManager() {
return await detect({
Expand All @@ -22,7 +21,3 @@ export function getPackageManagerInstallCommand(pm: PM) {
return 'npm install';
}
}

export async function getPackageJson(path = './package.json') {
return (await Bun.file(path).json()) as IntegrationPackageJson;
}

0 comments on commit d07b2fb

Please sign in to comment.