@fireberry/cli 0.0.5-beta.9 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md ADDED
@@ -0,0 +1,156 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Overview
6
+
7
+ `@fireberry/cli` is a command-line tool for managing Fireberry applications. It allows developers to initialize credentials, create new apps from templates, push components to the Fireberry platform, and install apps on Fireberry accounts.
8
+
9
+ ## Development Commands
10
+
11
+ ### Build and Development
12
+
13
+ ```bash
14
+ npm run build # Compile TypeScript to dist/
15
+ npm run build:dev # Clean, build, link globally, and make executable
16
+ npm run dev # Watch mode compilation
17
+ npm run clean # Remove dist/ directory
18
+ ```
19
+
20
+ ### Testing
21
+
22
+ ```bash
23
+ npm test # Run smoke test (verifies CLI --help works)
24
+ ```
25
+
26
+ ### Local Development
27
+
28
+ ```bash
29
+ npm run build:dev # Build and link CLI locally
30
+ fireberry --help # Test the linked CLI
31
+ ```
32
+
33
+ ### Publishing
34
+
35
+ ```bash
36
+ npm run publish:beta # Version bump (beta) and publish to npm with beta tag
37
+ npm run publish:prod # Publish to npm with latest tag
38
+ ```
39
+
40
+ ## Architecture
41
+
42
+ ### Module System
43
+
44
+ - **Type**: ESM (ES Modules) with `"type": "module"` in package.json
45
+ - **Module Resolution**: NodeNext
46
+ - **Import Extensions**: All local imports must use `.js` extension (e.g., `import { foo } from "./bar.js"`)
47
+ - **JSON Imports**: Use `with { type: "json" }` syntax (e.g., `import packageJson from "../../package.json" with { type: "json" }`)
48
+
49
+ ### CLI Entry Point
50
+
51
+ - **Binary**: [dist/bin/fireberry.js](dist/bin/fireberry.js) (generated from [src/bin/fireberry.ts](src/bin/fireberry.ts))
52
+ - **Framework**: Commander.js for command parsing and routing
53
+ - **Error Handling**: Global error handler in [src/bin/fireberry.ts](src/bin/fireberry.ts) catches and formats errors
54
+
55
+ ### Command Structure
56
+
57
+ Each CLI command is in [src/commands/](src/commands/):
58
+
59
+ - **init**: Stores Fireberry API token in local config using `env-paths`
60
+ - **create**: Creates new Fireberry app from templates with generated UUIDs
61
+ - **push**: Validates manifest, zips components, uploads to Fireberry API
62
+ - **install**: Installs app on user's Fireberry account
63
+ - **delete**: Deletes app from Fireberry platform (requires confirmation)
64
+
65
+ ### Configuration System
66
+
67
+ - **User Config**: Stored via `env-paths` ("Fireberry CLI") in OS-specific config directory
68
+ - **Config File**: `config.json` with `{ apiToken, createdAt }`
69
+ - **Environment**: [src/config/env.ts](src/config/env.ts) loads `.env` file from project root using dotenv
70
+
71
+ ### API Layer ([src/api/](src/api/))
72
+
73
+ - **axios.ts**: Axios instance with automatic token injection via interceptors
74
+ - **API URL Logic**:
75
+ - Beta versions (version contains "beta") → Uses `FIREBERRY_STAGING_URL` environment variable
76
+ - Production versions → `FIREBERRY_API_URL` or `https://api.fireberry.com/api/v3`
77
+ - **Authentication**: Token passed via `tokenId` header (read from config in interceptor)
78
+ - **requests.ts**: API endpoints (`createApp`, `pushComponents`, `installApp`, `deleteApp`)
79
+ - **types.ts**: TypeScript interfaces for API requests/responses
80
+
81
+ ### Component System
82
+
83
+ Component utilities in [src/utils/components.utils.ts](src/utils/components.utils.ts):
84
+
85
+ - **Manifest Parsing**: YAML manifest loaded from `manifest.yml` in current directory
86
+ - **Component Validation**: Checks paths exist, components are unique, validates required settings per component type
87
+ - **Component Zipping**: Creates tar.gz archives of component builds (directories or single files)
88
+ - **Component Types** ([src/constants/component-types.ts](src/constants/component-types.ts)):
89
+ - **record**: Record page component with required settings: `iconName` (string), `iconColor` (string), `objectType` (number)
90
+ - **global-menu**: Global menu component with required setting: `displayName` (string)
91
+ - **side-menu**: Side menu component with required settings: `icon` (string), `width` (string: "S" | "M" | "L")
92
+ - **Manifest Structure**:
93
+ ```yaml
94
+ app:
95
+ id: "uuid"
96
+ name: "App Name"
97
+ components:
98
+ - type: record | global-menu | side-menu
99
+ title: component-name
100
+ id: "uuid"
101
+ path: relative/path/to/build
102
+ settings:
103
+ # For record type:
104
+ iconName: "icon-name"
105
+ iconColor: "#hexcolor"
106
+ objectType: 1
107
+ # For global-menu type:
108
+ displayName: "Menu Name"
109
+ # For side-menu type:
110
+ icon: "icon-name"
111
+ width: "S" | "M" | "L"
112
+ ```
113
+
114
+ ### Templates ([src/templates/](src/templates/))
115
+
116
+ Templates use mustache-style placeholders (`{{appName}}`, `{{appId}}`, `{{componentId}}`):
117
+
118
+ - **manifest.yml**: Default manifest with single component
119
+ - **index.html**: Basic HTML template
120
+
121
+ ## Key Patterns
122
+
123
+ ### Error Handling
124
+
125
+ - Commands throw errors which are caught by the global handler in [src/bin/fireberry.ts:47](src/bin/fireberry.ts#L47)
126
+ - Errors are formatted with chalk.red and prefixed with "Error:" if not already present
127
+ - API errors map HTTP status codes to user-friendly messages
128
+
129
+ ### User Feedback
130
+
131
+ - Use `ora` spinners for long-running operations (start → succeed/fail)
132
+ - Use `chalk` for colored output (cyan for highlights, gray for details, yellow for warnings)
133
+ - Use `inquirer` for interactive prompts when arguments are missing
134
+
135
+ ### File Operations
136
+
137
+ - Use `fs-extra` for all file operations (promisified, ensures directories exist)
138
+ - Check `fs.pathExists()` before operations
139
+ - Use `process.cwd()` as base for relative paths in user projects
140
+
141
+ ### Component Path Resolution
142
+
143
+ Component paths in manifest.yml are relative to the current working directory, not the CLI installation directory. Example: `path: static/comp/build` resolves to `process.cwd() + "/static/comp/build"`.
144
+
145
+ ## Important Notes
146
+
147
+ - **Manifest Required**: `push`, `install`, and `delete` commands must be run from a directory containing `manifest.yml`
148
+ - **Token Required**: Most commands require prior `init` to store API token
149
+ - **Component IDs**: Must be unique UUIDs within a manifest
150
+ - **Component Settings Validation**: Each component type has required settings that are validated during `push`:
151
+ - `record`: Must have `iconName`, `iconColor`, and `objectType`
152
+ - `global-menu`: Must have `displayName`
153
+ - `side-menu`: Must have `icon` and `width` (S/M/L)
154
+ - **Build Zipping**: Single files are wrapped in a directory before tar.gz creation
155
+ - **Template Location**: Templates are resolved from `src/templates/` at compile time, copied to `dist/templates/`
156
+ - **Delete Safety**: Delete command requires user confirmation before executing (cannot be undone)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Fireberry LTD
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/api/axios.js CHANGED
@@ -46,7 +46,7 @@ export async function sendApiRequest(config) {
46
46
  let errorMessage;
47
47
  switch (status) {
48
48
  case 401:
49
- console.log(error.response?.data?.message || error.message);
49
+ console.log(error.response?.data?.message || error.message); // TODO: remove this
50
50
  errorMessage = "Unauthorized user.";
51
51
  break;
52
52
  case 500:
@@ -1,4 +1,8 @@
1
1
  import "../config/env.js";
2
- import type { CreateAppRequest, ZippedComponent } from "./types.js";
3
- export declare const createApp: (data: CreateAppRequest) => Promise<void>;
4
- export declare const pushComponents: (appId: string, components: ZippedComponent[]) => Promise<void>;
2
+ import type { Manifest, ZippedComponent } from "./types.js";
3
+ export declare const createApp: (manifest: Manifest) => Promise<void>;
4
+ export declare const pushComponents: (appId: string, components: ZippedComponent[], manifest: Manifest) => Promise<void>;
5
+ export declare const installApp: (manifest: Manifest) => Promise<void>;
6
+ export declare const deleteApp: (manifest: Manifest) => Promise<void>;
7
+ export declare const startDebug: (appId: string, componentId: string, debugUrl: string, manifest: Manifest) => Promise<void>;
8
+ export declare const stopDebug: (appId: string, componentId: string, manifest: Manifest) => Promise<void>;
@@ -1,18 +1,55 @@
1
1
  import "../config/env.js";
2
+ import { BASE_SERVICE_URL } from "../constants/component-types.js";
2
3
  import { api } from "./axios.js";
3
- export const createApp = async (data) => {
4
- const url = "/services/developer/create";
4
+ export const createApp = async (manifest) => {
5
+ const url = `${BASE_SERVICE_URL}/create`;
5
6
  try {
6
- await api.post(url, data);
7
+ await api.post(url, { manifest });
7
8
  }
8
9
  catch (error) {
9
10
  throw new Error(error instanceof Error ? error.message : "Unknown error");
10
11
  }
11
12
  };
12
- export const pushComponents = async (appId, components) => {
13
- const url = `/services/developer/push`;
13
+ export const pushComponents = async (appId, components, manifest) => {
14
+ const url = `${BASE_SERVICE_URL}/push`;
14
15
  try {
15
- await api.post(url, { appId, components });
16
+ await api.post(url, { appId, components, manifest });
17
+ }
18
+ catch (error) {
19
+ throw new Error(error instanceof Error ? error.message : "Unknown error");
20
+ }
21
+ };
22
+ export const installApp = async (manifest) => {
23
+ const url = `${BASE_SERVICE_URL}/install`;
24
+ try {
25
+ await api.post(url, { manifest }, { timeout: 300000 }); // 5 minutes
26
+ }
27
+ catch (error) {
28
+ throw new Error(error instanceof Error ? error.message : "Unknown error");
29
+ }
30
+ };
31
+ export const deleteApp = async (manifest) => {
32
+ const url = `${BASE_SERVICE_URL}/delete`;
33
+ try {
34
+ await api.delete(url, { manifest });
35
+ }
36
+ catch (error) {
37
+ throw new Error(error instanceof Error ? error.message : "Unknown error");
38
+ }
39
+ };
40
+ export const startDebug = async (appId, componentId, debugUrl, manifest) => {
41
+ const url = `${BASE_SERVICE_URL}/debug`;
42
+ try {
43
+ await api.post(url, { appId, componentId, debugUrl, manifest });
44
+ }
45
+ catch (error) {
46
+ throw new Error(error instanceof Error ? error.message : "Unknown error");
47
+ }
48
+ };
49
+ export const stopDebug = async (appId, componentId, manifest) => {
50
+ const url = `${BASE_SERVICE_URL}/debug`;
51
+ try {
52
+ await api.delete(url, { appId, componentId, manifest });
16
53
  }
17
54
  catch (error) {
18
55
  throw new Error(error instanceof Error ? error.message : "Unknown error");
@@ -1,5 +1,8 @@
1
+ import { COMPONENT_TYPE } from "../constants/component-types.js";
2
+ import { HeightOption } from "../constants/height-options.js";
1
3
  export interface CreateAppRequest {
2
4
  appId: string;
5
+ componentId: string;
3
6
  }
4
7
  export interface ApiError {
5
8
  message: string;
@@ -16,10 +19,38 @@ interface ManifestApp {
16
19
  name: string;
17
20
  description?: string;
18
21
  }
19
- export interface ManifestComponent {
22
+ export interface RecordComponentSettings {
23
+ iconName: string;
24
+ iconColor: string;
25
+ objectType: number;
26
+ height: HeightOption;
27
+ }
28
+ export interface GlobalMenuComponentSettings {
29
+ displayName: string;
30
+ }
31
+ export interface SideMenuComponentSettings {
32
+ icon: string;
33
+ width: "S" | "M" | "L";
34
+ }
35
+ export type ComponentSettings = RecordComponentSettings | GlobalMenuComponentSettings | SideMenuComponentSettings;
36
+ export interface BaseManifestComponent {
37
+ title: string;
38
+ id: string;
39
+ path: string;
40
+ }
41
+ export interface RecordComponent extends BaseManifestComponent {
42
+ type: typeof COMPONENT_TYPE.RECORD;
43
+ settings: RecordComponentSettings;
44
+ }
45
+ export interface GlobalMenuComponent extends BaseManifestComponent {
46
+ type: typeof COMPONENT_TYPE.GLOBAL_MENU;
47
+ settings: GlobalMenuComponentSettings;
48
+ }
49
+ export type ManifestComponent = RecordComponent | GlobalMenuComponent;
50
+ export interface UntypedManifestComponent {
20
51
  type: string;
21
52
  title: string;
22
- key: string;
53
+ id: string;
23
54
  path: string;
24
55
  settings?: Record<string, unknown>;
25
56
  }
@@ -29,7 +60,7 @@ export interface Manifest {
29
60
  }
30
61
  export interface ZippedComponent {
31
62
  title: string;
32
- key: string;
63
+ id: string;
33
64
  build: Buffer;
34
65
  }
35
66
  export {};
@@ -5,6 +5,9 @@ import { runInit } from "../commands/init.js";
5
5
  import { runCreate } from "../commands/create.js";
6
6
  import packageJson from "../../package.json" with { type: "json" };
7
7
  import { runPush } from "../commands/push.js";
8
+ import { runInstall } from "../commands/install.js";
9
+ import { runDelete } from "../commands/delete.js";
10
+ import { runDebug } from "../commands/debug.js";
8
11
  const program = new Command();
9
12
  program
10
13
  .name("fireberry")
@@ -31,6 +34,26 @@ program
31
34
  .action(async () => {
32
35
  await runPush();
33
36
  });
37
+ program.command("install")
38
+ .description("Install app on your Fireberry account")
39
+ .action(async () => {
40
+ await runInstall();
41
+ });
42
+ program
43
+ .command("delete")
44
+ .description("Delete a Fireberry app")
45
+ .action(async () => {
46
+ await runDelete();
47
+ });
48
+ program
49
+ .command("debug")
50
+ .argument("<component-id>", "Component ID to debug")
51
+ .argument("[url]", "Debug URL in format localhost:[port]")
52
+ .option("--stop", "Stop debugging the component")
53
+ .description("Start or stop debugging a component")
54
+ .action(async (componentId, url, options) => {
55
+ await runDebug(componentId, url, options);
56
+ });
34
57
  program.parseAsync(process.argv).catch((err) => {
35
58
  const errorMessage = err instanceof Error
36
59
  ? err.message
@@ -6,6 +6,7 @@ import { fileURLToPath } from "node:url";
6
6
  import ora from "ora";
7
7
  import chalk from "chalk";
8
8
  import { createApp } from "../api/requests.js";
9
+ import { getManifest } from "../utils/components.utils.js";
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
  const __dirname = path.dirname(__filename);
11
12
  function slugifyName(name) {
@@ -28,23 +29,26 @@ export async function runCreate({ name }) {
28
29
  }
29
30
  const slug = slugifyName(appName);
30
31
  const appId = uuidv4();
32
+ const componentId = uuidv4();
31
33
  const appDir = path.resolve(process.cwd(), slug);
32
34
  if (await fs.pathExists(appDir)) {
33
35
  throw new Error(`Already exists. ${chalk.yellow(slug)}`);
34
36
  }
35
37
  const spinner = ora(`Creating app "${chalk.cyan(appName)}"...`).start();
36
38
  try {
37
- await createApp({ appId });
38
39
  await fs.ensureDir(appDir);
39
40
  const templatesDir = path.join(__dirname, "..", "..", "src", "templates");
40
41
  const manifestTemplate = await fs.readFile(path.join(templatesDir, "manifest.yml"), "utf-8");
41
42
  const htmlTemplate = await fs.readFile(path.join(templatesDir, "index.html"), "utf-8");
42
43
  const manifestContent = manifestTemplate
43
44
  .replace(/{{appName}}/g, appName)
44
- .replace(/{{appId}}/g, appId);
45
+ .replace(/{{appId}}/g, appId)
46
+ .replace(/{{componentId}}/g, componentId);
45
47
  const htmlContent = htmlTemplate.replace(/{{appName}}/g, appName);
46
48
  await fs.writeFile(path.join(appDir, "manifest.yml"), manifestContent);
47
49
  await fs.writeFile(path.join(appDir, "index.html"), htmlContent);
50
+ const manifest = await getManifest(appDir);
51
+ await createApp(manifest);
48
52
  spinner.succeed(`Successfully created "${chalk.cyan(appName)}" app!`);
49
53
  console.log(chalk.gray(`📁 Location: ${appDir}`));
50
54
  console.log(chalk.gray(`App ID: ${appId}`));
@@ -0,0 +1,3 @@
1
+ export declare function runDebug(componentId: string, url?: string, options?: {
2
+ stop?: boolean;
3
+ }): Promise<void>;
@@ -0,0 +1,54 @@
1
+ import ora from "ora";
2
+ import chalk from "chalk";
3
+ import { startDebug, stopDebug } from "../api/requests.js";
4
+ import { getManifest } from "../utils/components.utils.js";
5
+ function validateDebugUrl(url) {
6
+ const localhostPattern = /^localhost:\d+$/;
7
+ if (!localhostPattern.test(url)) {
8
+ throw new Error("Invalid URL format. URL must be in format: localhost:[port] (e.g., localhost:3000)\n" +
9
+ "Do not include http:// or https://");
10
+ }
11
+ }
12
+ function validateComponentExists(manifest, componentId) {
13
+ const component = manifest.components?.find((comp) => comp.id === componentId);
14
+ if (!component) {
15
+ throw new Error(`Component with ID "${componentId}" not found in manifest.\n` +
16
+ `Available components:\n` +
17
+ manifest.components
18
+ ?.map((comp) => ` - ${comp.title} (${comp.id})`)
19
+ .join("\n"));
20
+ }
21
+ }
22
+ export async function runDebug(componentId, url, options) {
23
+ const spinner = ora("Loading manifest...").start();
24
+ try {
25
+ const manifest = await getManifest();
26
+ spinner.succeed("Manifest loaded");
27
+ // Validate component exists
28
+ validateComponentExists(manifest, componentId);
29
+ if (options?.stop) {
30
+ // Stop debugging
31
+ spinner.start("Stopping debug mode...");
32
+ await stopDebug(manifest.app.id, componentId, manifest);
33
+ spinner.succeed(chalk.green(`Debug mode stopped for component: ${componentId}`));
34
+ }
35
+ else {
36
+ // Start debugging
37
+ if (!url) {
38
+ throw new Error("URL is required when starting debug mode.\n" +
39
+ `Usage: fireberry debug ${componentId} localhost:[port]`);
40
+ }
41
+ validateDebugUrl(url);
42
+ spinner.start(`Starting debug mode for component ${componentId}...`);
43
+ await startDebug(manifest.app.id, componentId, url, manifest);
44
+ spinner.succeed(chalk.green(`Debug mode started!\n` +
45
+ ` Component: ${componentId}\n` +
46
+ ` URL: ${url}\n\n` +
47
+ `To stop debugging, run: ${chalk.cyan(`fireberry debug ${componentId} --stop`)}`));
48
+ }
49
+ }
50
+ catch (error) {
51
+ spinner.fail(options?.stop ? "Failed to stop debug mode" : "Failed to start debug mode");
52
+ throw error;
53
+ }
54
+ }
@@ -0,0 +1 @@
1
+ export declare function runDelete(): Promise<void>;
@@ -0,0 +1,31 @@
1
+ import ora from "ora";
2
+ import chalk from "chalk";
3
+ import inquirer from "inquirer";
4
+ import { deleteApp } from "../api/requests.js";
5
+ import { getManifest } from "../utils/components.utils.js";
6
+ export async function runDelete() {
7
+ const spinner = ora("Loading manifest...").start();
8
+ try {
9
+ const manifest = await getManifest();
10
+ spinner.stop();
11
+ const confirmAnswer = await inquirer.prompt([
12
+ {
13
+ type: "confirm",
14
+ name: "confirm",
15
+ message: `Are you sure you want to delete app ${chalk.yellow(manifest.app.name)} (${chalk.gray(manifest.app.id)})? This action cannot be undone.`,
16
+ default: false,
17
+ },
18
+ ]);
19
+ if (!confirmAnswer.confirm) {
20
+ console.log(chalk.gray("Delete operation cancelled."));
21
+ return;
22
+ }
23
+ spinner.start(`Deleting app "${chalk.cyan(manifest.app.name)}"...`);
24
+ await deleteApp(manifest);
25
+ spinner.succeed(`Successfully deleted app "${chalk.cyan(manifest.app.name)}"`);
26
+ }
27
+ catch (error) {
28
+ spinner.fail("Failed to delete app");
29
+ throw error;
30
+ }
31
+ }
@@ -0,0 +1 @@
1
+ export declare function runInstall(): Promise<void>;
@@ -0,0 +1,17 @@
1
+ import ora from "ora";
2
+ import { installApp } from "../api/requests.js";
3
+ import { getManifest, validateManifestComponents, } from "../utils/components.utils.js";
4
+ export async function runInstall() {
5
+ const spinner = ora("Loading manifest...").start();
6
+ try {
7
+ const manifest = await getManifest();
8
+ await validateManifestComponents(manifest);
9
+ spinner.start("Installing app on Fireberry...");
10
+ await installApp(manifest);
11
+ spinner.succeed("App installed successfully");
12
+ }
13
+ catch (error) {
14
+ spinner.fail("Installation failed");
15
+ throw error;
16
+ }
17
+ }
@@ -15,10 +15,10 @@ export async function runPush() {
15
15
  console.log(chalk.cyan("\nComponents ready to push:"));
16
16
  zippedComponents.forEach((comp, idx) => {
17
17
  const sizeKB = (comp.build.length / 1024).toFixed(2);
18
- console.log(chalk.gray(` ${idx + 1}. ${comp.title} (${comp.key}) - ${sizeKB} KB`));
18
+ console.log(chalk.gray(` ${idx + 1}. ${comp.title} (${comp.id}) - ${sizeKB} KB`));
19
19
  });
20
20
  spinner.start("Uploading to Fireberry...");
21
- await pushComponents(manifest.app.id, zippedComponents);
21
+ await pushComponents(manifest.app.id, zippedComponents, manifest);
22
22
  spinner.succeed("Components pushed successfully");
23
23
  }
24
24
  else {
@@ -0,0 +1,7 @@
1
+ export declare const COMPONENT_TYPE: {
2
+ readonly RECORD: "record";
3
+ readonly GLOBAL_MENU: "global-menu";
4
+ readonly SIDE_MENU: "side-menu";
5
+ };
6
+ export type ComponentType = (typeof COMPONENT_TYPE)[keyof typeof COMPONENT_TYPE];
7
+ export declare const BASE_SERVICE_URL = "/services/developer/app";
@@ -0,0 +1,6 @@
1
+ export const COMPONENT_TYPE = {
2
+ RECORD: "record",
3
+ GLOBAL_MENU: "global-menu",
4
+ SIDE_MENU: "side-menu",
5
+ };
6
+ export const BASE_SERVICE_URL = "/services/developer/app";
@@ -0,0 +1,2 @@
1
+ export declare const HEIGHT_OPTIONS: readonly ["S", "M", "L", "XL"];
2
+ export type HeightOption = (typeof HEIGHT_OPTIONS)[number];
@@ -0,0 +1 @@
1
+ export const HEIGHT_OPTIONS = ["S", "M", "L", "XL"];
@@ -1,5 +1,6 @@
1
- import { Manifest, ManifestComponent, ZippedComponent } from "../api/types.js";
2
- export declare const getManifest: () => Promise<Manifest>;
3
- export declare const validateComponentBuild: (componentPath: string, comp: ManifestComponent) => Promise<void>;
1
+ import { Manifest, ZippedComponent, UntypedManifestComponent } from "../api/types.js";
2
+ export declare const getManifest: (basePath?: string) => Promise<Manifest>;
3
+ export declare const validateComponentBuild: (componentPath: string, comp: UntypedManifestComponent) => Promise<void>;
4
4
  export declare const zipComponentBuild: (componentPath: string, title: string) => Promise<Buffer>;
5
+ export declare const validateManifestComponents: (manifest: Manifest) => Promise<void>;
5
6
  export declare const handleComponents: (manifest: Manifest) => Promise<ZippedComponent[]>;