@hailer/app-sdk 2.4.2 → 2.5.0

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.
@@ -4,6 +4,8 @@ export interface FileResponse {
4
4
  /** Base64-encoded file data */
5
5
  data: string;
6
6
  mimeType: string;
7
+ /** Free-form string tags attached to the file */
8
+ tags: string[];
7
9
  }
8
10
  export interface UploadOptions {
9
11
  /** Whether the file should be publicly accessible */
@@ -34,5 +36,29 @@ export declare class FileApi {
34
36
  * @throws {HailerError} if upload fails
35
37
  */
36
38
  upload(file: File, filename: string, options?: UploadOptions): Promise<string>;
39
+ /**
40
+ * Appends tags to a file, deduping against the existing list.
41
+ *
42
+ * Tags are case-sensitive free-form strings (trimmed, 1-64 characters, max 50 per file).
43
+ *
44
+ * @param fileId The ID of the file to tag
45
+ * @param tags Tags to add
46
+ *
47
+ * @returns The file's resulting tag list
48
+ *
49
+ * @throws {HailerError} if validation fails or the file cannot be edited
50
+ */
51
+ addTags(fileId: string, tags: string[]): Promise<string[]>;
52
+ /**
53
+ * Removes tags from a file by case-sensitive exact match. Tags not present are silently ignored.
54
+ *
55
+ * @param fileId The ID of the file to untag
56
+ * @param tags Tags to remove
57
+ *
58
+ * @returns The file's resulting tag list
59
+ *
60
+ * @throws {HailerError} if validation fails or the file cannot be edited
61
+ */
62
+ removeTags(fileId: string, tags: string[]): Promise<string[]>;
37
63
  private toBase64;
38
64
  }
@@ -1,4 +1,4 @@
1
- import { Client } from "@wishcore/wish-rpc";
1
+ import { Client } from '@wishcore/wish-rpc';
2
2
  export interface HTTPFetchOptions {
3
3
  method?: string;
4
4
  headers?: Record<string, string>;
@@ -46,19 +46,19 @@ export declare class HttpApi {
46
46
  private client;
47
47
  constructor(client: Client);
48
48
  /**
49
- * Make an HTTP request through the parent frame.
50
- * The parent's browser context sends the hlrkey cookie automatically.
51
- */
49
+ * Make an HTTP request through the parent frame.
50
+ * The parent's browser context sends the hlrkey cookie automatically.
51
+ */
52
52
  fetch(url: string, options?: HTTPFetchOptions): Promise<HTTPFetchResponse>;
53
53
  /**
54
- * Upload files through the parent frame as multipart/form-data.
55
- * Files are sent as base64 strings and reconstructed into FormData by the parent.
56
- * The parent's browser context sends the hlrkey cookie automatically.
57
- */
54
+ * Upload files through the parent frame as multipart/form-data.
55
+ * Files are sent as base64 strings and reconstructed into FormData by the parent.
56
+ * The parent's browser context sends the hlrkey cookie automatically.
57
+ */
58
58
  upload(url: string, entries: HTTPUploadEntry[]): Promise<HTTPFetchResponse>;
59
59
  /**
60
- * Open a WebSocket connection through the parent frame.
61
- * Returns a HTTPWebSocket that mimics the native WebSocket API.
62
- */
60
+ * Open a WebSocket connection through the parent frame.
61
+ * Returns a HTTPWebSocket that mimics the native WebSocket API.
62
+ */
63
63
  openWebSocket(url: string): HTTPWebSocket;
64
64
  }
@@ -73,35 +73,35 @@ export declare class MetricsApi {
73
73
  private client;
74
74
  constructor(client: Client);
75
75
  /**
76
- * Get list of available metrics for current user based on permissions
77
- * @param options Optional filtering options
78
- * @returns Array of metric IDs or detailed metric definitions
79
- */
76
+ * Get list of available metrics for current user based on permissions
77
+ * @param options Optional filtering options
78
+ * @returns Array of metric IDs or detailed metric definitions
79
+ */
80
80
  list(options?: MetricListOptions): Promise<string[] | MetricDefinition[]>;
81
81
  /**
82
- * Get metrics data with optional Query Builder
83
- * @param metricTypes Single metric or array of metrics to fetch
84
- * @param options Optional filtering, time range, and Query Builder options
85
- * @returns Metric data with values and optional time series
86
- *
87
- * @example
88
- * // Simple query
89
- * await api.metrics.get('hailer.activity.create', { workspaceId: 'abc123' });
90
- *
91
- * @example
92
- * // Query Builder: Top 10 users by activity
93
- * await api.metrics.get('hailer.activity.create', {
94
- * workspaceId: 'abc123',
95
- * timeRange: { start: Date.now() - 86400000, end: Date.now() },
96
- * aggregation: 'sum',
97
- * groupBy: ['user'],
98
- * topk: 10
99
- * });
100
- */
82
+ * Get metrics data with optional Query Builder
83
+ * @param metricTypes Single metric or array of metrics to fetch
84
+ * @param options Optional filtering, time range, and Query Builder options
85
+ * @returns Metric data with values and optional time series
86
+ *
87
+ * @example
88
+ * // Simple query
89
+ * await api.metrics.get('hailer.activity.create', { workspaceId: 'abc123' });
90
+ *
91
+ * @example
92
+ * // Query Builder: Top 10 users by activity
93
+ * await api.metrics.get('hailer.activity.create', {
94
+ * workspaceId: 'abc123',
95
+ * timeRange: { start: Date.now() - 86400000, end: Date.now() },
96
+ * aggregation: 'sum',
97
+ * groupBy: ['user'],
98
+ * topk: 10
99
+ * });
100
+ */
101
101
  get(metricTypes: string | string[], options?: MetricOptions): Promise<MetricData>;
102
102
  /**
103
- * Admin endpoints for metrics management
104
- */
103
+ * Admin endpoints for metrics management
104
+ */
105
105
  admin: {
106
106
  /**
107
107
  * Get list of workspaces for admin metrics filtering
@@ -118,14 +118,14 @@ export declare class MetricsApi {
118
118
  */
119
119
  workspacesList: (options: WorkspaceMetricsListOptions) => Promise<WorkspaceMetricsListResult>;
120
120
  /**
121
- * Get list of users for admin metrics filtering
122
- * @param options Lookup by userIds array
123
- * @returns List of users with _id, name, email
124
- *
125
- * @example
126
- * // Look up by user IDs
127
- * await api.metrics.admin.usersList({ userIds: ['id1', 'id2'] });
128
- */
121
+ * Get list of users for admin metrics filtering
122
+ * @param options Lookup by userIds array
123
+ * @returns List of users with _id, name, email
124
+ *
125
+ * @example
126
+ * // Look up by user IDs
127
+ * await api.metrics.admin.usersList({ userIds: ['id1', 'id2'] });
128
+ */
129
129
  usersList: (options: UserMetricsListOptions) => Promise<UserMetricsListResult>;
130
130
  };
131
131
  }
@@ -1,10 +1,10 @@
1
- import { Client } from "@wishcore/wish-rpc";
1
+ import { Client } from '@wishcore/wish-rpc';
2
2
  /**
3
3
  * Valid tab types for opening discussions.
4
4
  * - Private discussions: "discussions" | "files" | "info" | "location"
5
5
  * - Group discussions: "discussion" | "overview" | "files"
6
6
  */
7
- export type DiscussionTabTypes = "discussions" | "files" | "location" | "info" | "discussion" | "overview" | "detail" | "participants" | "linkedFrom" | "options";
7
+ export type DiscussionTabTypes = 'discussions' | 'files' | 'location' | 'info' | 'discussion' | 'overview' | 'detail' | 'participants' | 'linkedFrom' | 'options';
8
8
  export declare class Discussion {
9
9
  private client;
10
10
  constructor(client: Client);
@@ -68,7 +68,9 @@ var import_path = require("path");
68
68
  (0, import_dotenv.config)({ path: (0, import_path.join)((0, import_os.homedir)(), ".env") });
69
69
  function getArgValue(flag) {
70
70
  const index = process.argv.indexOf(flag);
71
- if (index === -1 || index + 1 >= process.argv.length) return void 0;
71
+ if (index === -1 || index + 1 >= process.argv.length) {
72
+ return void 0;
73
+ }
72
74
  return process.argv[index + 1];
73
75
  }
74
76
  function hasFlag(flag) {
@@ -139,7 +141,7 @@ if (!userApiKey && !email && !process.env.LOCAL) {
139
141
  );
140
142
  } else {
141
143
  if (!password) {
142
- password = await prompt("enter password for " + email + ": ");
144
+ password = await prompt(`enter password for ${email}: `);
143
145
  }
144
146
  cli = await import_cli.Client.create({ host, username: email, password, rejectUnauthorized: !isLocal }).catch(
145
147
  (error) => {
@@ -228,7 +230,7 @@ if (!userApiKey && !email && !process.env.LOCAL) {
228
230
  if (personalApp) {
229
231
  console.log(" Workspace: any (personal app)");
230
232
  } else {
231
- console.log(" Workspace:", info.networks[app.cid]?.name, "(" + app.cid + ")");
233
+ console.log(" Workspace:", info.networks[app.cid]?.name, `(${app.cid})`);
232
234
  }
233
235
  console.log(" Environment:", host);
234
236
  console.log();
@@ -270,7 +272,7 @@ if (!userApiKey && !email && !process.env.LOCAL) {
270
272
  } else if (cli.userApiKey) {
271
273
  headers.hlrkey = cli.userApiKey;
272
274
  }
273
- const resp = await fetch(host + "/app/publish", {
275
+ const resp = await fetch(`${host}/app/publish`, {
274
276
  method: "POST",
275
277
  headers,
276
278
  body: formData
@@ -303,7 +305,7 @@ if (!userApiKey && !email && !process.env.LOCAL) {
303
305
  manifestUpdated = true;
304
306
  console.log("Updated", manifestPath, "with appId:", appId);
305
307
  }
306
- if (response.manifest && response.manifest.targetId) {
308
+ if (response.manifest?.targetId) {
307
309
  publicManifest.targetId = response.manifest.targetId;
308
310
  manifestUpdated = true;
309
311
  infoMarket = "Note! Use targetId in public/manifest.json file when creating the product in market!";
@@ -314,8 +316,9 @@ if (!userApiKey && !email && !process.env.LOCAL) {
314
316
  }
315
317
  console.log("App info:", (0, import_util.inspect)(response, { depth: 10, colors: true }));
316
318
  console.log();
317
- if (infoMarket)
319
+ if (infoMarket) {
318
320
  console.log(infoMarket);
321
+ }
319
322
  console.log("Published successfully!");
320
323
  cli.disconnect();
321
324
  })();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../tools/publish.ts", "../../tools/minimal-password-prompt.ts"],
4
- "sourcesContent": ["import { Client } from '@hailer/cli';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\nimport { prompt } from './minimal-password-prompt';\nimport { inspect } from 'util';\nimport { createInterface } from 'readline';\nimport { config as loadEnv } from 'dotenv';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\n// Load ~/.env as fallback (doesn't overwrite existing env vars)\nloadEnv({ path: join(homedir(), '.env') });\n\n/** Get the value following a named flag, e.g. getArgValue('--user-api-key') */\nfunction getArgValue(flag: string): string | undefined {\n const index = process.argv.indexOf(flag);\n if (index === -1 || index + 1 >= process.argv.length) return undefined;\n return process.argv[index + 1];\n}\n\nfunction hasFlag(flag: string): boolean {\n return process.argv.includes(flag);\n}\n\nconst userApiKey = getArgValue('--user-api-key') || process.env.USER_API_KEY || process.env.HAILER_USER_API_KEY;\n\nlet email = getArgValue('--email') || process.env.EMAIL;\n\nif (!userApiKey && !email && !process.env.LOCAL) {\n console.log('Please provide authentication: --email, --user-api-key, or EMAIL env var.');\n console.log('');\n console.log('Usage:');\n console.log(' npm run publish-production -- --email user@mail.com (will prompt for password)');\n console.log(' npm run publish-production -- --user-api-key <key>');\n console.log(' EMAIL=user@mail.com npm run publish-production (going to be deprecated, use --email instead)');\n console.log(' USER_API_KEY=<key> npm run publish-production (going to be deprecated, use --user-api-key instead)');\n console.log('');\n console.log('Create and publish new app:');\n console.log(' npm run publish-production -- --create --app-name \"My App\" --workspace <id> --user-api-key <key> --yes');\n console.log('');\n console.log('Options:');\n console.log(' --email <email> User email for authentication');\n console.log(' --user-api-key <key> API key for authentication');\n console.log(' --create Create a new app before publishing');\n console.log(' --app-name <name> App name (with --create)');\n console.log(' --workspace <id> Workspace ID (with --create)');\n console.log(' --market Also publish to Hailer marketplace');\n console.log(' --yes Skip confirmation prompt (going to be deprecated, use --force instead)');\n console.log(' --force Skip confirmation prompt');\n console.log(' --host <host> Specify the host URL');\n process.exit(10);\n}\n\n(async () => {\n\n let password: string | undefined;\n\n const market = hasFlag('--market') || process.env.MARKET === 'true';\n\n const appPackageFile = process.argv[2];\n\n /** Detect mode from any position in argv */\n const mode = ['--development', '--staging', '--production', '--local']\n .find(m => process.argv.includes(m));\n\n let host = getArgValue(\"--host\") || process.env.HOST || 'https://localhost:9443';\n\n switch (mode) {\n case '--development':\n host = getArgValue(\"--host\") || process.env.HOST || 'https://testapi.hailer.biz';\n break;\n case '--staging':\n host = getArgValue(\"--host\") || process.env.HOST || 'https://api.hailer.biz';\n break;\n case '--production':\n host = getArgValue(\"--host\") || process.env.HOST || 'https://api.hailer.com';\n break;\n }\n\n if (process.env.LOCAL || mode === '--local') {\n host = getArgValue(\"--host\") || process.env.HOST || 'https://api.hailer.local.gd';\n if (!userApiKey) {\n console.log('Overriding credentials with local settings!');\n email = 'el@hailero.es';\n password = 'el@hailero.es';\n }\n }\n\n const isLocal = !!(process.env.LOCAL || mode === '--local');\n\n if (isLocal) {\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';\n }\n\n // Authenticate\n let cli: Client;\n\n if (userApiKey) {\n cli = await Client.create({ host, userApiKey, rejectUnauthorized: !isLocal }).catch(\n (error) => {\n console.log('Hailer Cli Error (API key auth):', error);\n process.exit(8);\n }\n );\n } else {\n if (!password) {\n password = await prompt('enter password for ' + email + ': ');\n }\n\n cli = await Client.create({ host, username: email, password, rejectUnauthorized: !isLocal }).catch(\n (error) => {\n if (error.msg === 'Invalid Login Data') {\n console.log('Invalid username or password when logging into Hailer.');\n } else {\n console.log('Hailer Cli Error:', error);\n }\n\n process.exit(8);\n }\n );\n }\n\n // Validate .tgz file\n if (!appPackageFile?.endsWith('.tgz')) {\n console.log('Failed getting .tgz file, found:', appPackageFile);\n process.exit(7);\n }\n\n const content = readFileSync(appPackageFile);\n let appId: string;\n\n // --create: Create a new app, then publish it\n if (hasFlag('--create')) {\n let appName = getArgValue('--app-name');\n let workspaceId = getArgValue('--workspace');\n\n if (!appName) {\n appName = await prompt('App name: ', { hidden: false });\n }\n\n if (!workspaceId) {\n workspaceId = await prompt('Workspace ID: ', { hidden: false });\n }\n\n if (!appName) {\n console.log('Error: --create requires --app-name <name>');\n process.exit(11);\n }\n if (!workspaceId) {\n console.log('Error: --create requires --workspace <id>');\n process.exit(12);\n }\n\n console.log('Creating new app...');\n console.log(' Name:', appName);\n console.log(' Workspace:', workspaceId);\n console.log(' Environment:', host);\n console.log();\n\n const appDoc = await cli.request('v3.app.create', [{\n name: appName,\n cid: workspaceId,\n }]).catch((error: any) => {\n console.log('Failed to create app:', error);\n process.exit(13);\n });\n\n appId = appDoc._id;\n console.log('App created with id:', appId);\n console.log();\n\n } else {\n // Normal publish: read appId from manifest\n const manifest = JSON.parse(readFileSync('./dist/manifest.json').toString());\n\n // Market code\n if (market) {\n if (!manifest.version) {\n manifest.version = '';\n manifest.versionDescription = '';\n\n const updatedManifestContent = JSON.stringify(manifest, null, 2);\n writeFileSync('./public/manifest.json', updatedManifestContent, 'utf-8');\n\n console.log('');\n console.log('Please set version in format (x.y.z) & versionDescription in file public/manifest.json! You have added MARKET=true or --market in your publish string.');\n console.log('');\n process.exit(10);\n }\n }\n\n const info = await cli.request('v2.core.init', [['network', 'networks', 'apps']]);\n\n const getAppById = (manifestAppId: string): { _id: string, name: string, cid: string } | null => {\n for (const appMap of Object.values(info.apps)) {\n for (const [id, app] of Object.entries(appMap as any)) {\n if (id === manifestAppId) {\n return app as any;\n }\n }\n }\n return null;\n }\n\n const app = getAppById(manifest.appId);\n\n if (!app) {\n const authInfo = userApiKey ? 'the provided API key' : email;\n console.log('The app was not found using:', authInfo);\n process.exit(2);\n }\n\n const personalApp = !app.cid;\n\n console.log('Publishing App');\n console.log(' Id:', manifest.appId);\n console.log(' Name:', app.name);\n if (personalApp) {\n console.log(' Workspace: any (personal app)');\n } else {\n console.log(' Workspace:', info.networks[app.cid]?.name, '(' + app.cid + ')');\n }\n console.log(' Environment:', host);\n console.log();\n\n // Market code\n if (market) {\n console.log(' Note: Also publishing app to Hailer market');\n }\n\n /** Default to publish (yes) */\n const promptOverwriteQuestion = async () => {\n if (hasFlag('--yes') || hasFlag('--force')) {\n return true;\n }\n\n return new Promise<boolean>(resolve => {\n const rl = createInterface(process.stdin, process.stdout);\n\n rl.setPrompt('Overwrite the app? (Y/n): ');\n rl.prompt();\n rl.on('line', (line) => {\n if (line.trim().toLocaleLowerCase().startsWith('n')) {\n resolve(false);\n } else {\n resolve(true);\n }\n rl.close();\n });\n });\n }\n\n const shouldOverwrite = await promptOverwriteQuestion();\n\n if (!shouldOverwrite) {\n console.log('Aborted publishing app.');\n process.exit(0);\n }\n\n appId = manifest.appId;\n }\n\n // Upload\n const formData = new FormData();\n formData.append('file', new Blob([content]), appPackageFile);\n formData.append('appId', appId);\n // Market code\n formData.append('publishMarket', market.toString());\n\n const headers: Record<string, string> = {};\n \n if (cli.sessionKey) {\n headers.hlrkey = cli.sessionKey;\n } else if (cli.userApiKey) {\n headers.hlrkey = cli.userApiKey;\n }\n\n const resp = await fetch(host + '/app/publish', {\n method: 'POST',\n headers,\n body: formData,\n }).catch((error) => {\n console.log('Publish error uploading file:', error);\n process.exit(9);\n });\n\n if (!resp.ok) {\n console.log('Publish failed with status:', resp.status, resp.statusText);\n const body = await resp.text();\n console.log('Response:', body);\n process.exit(9);\n }\n\n const body = await resp.text();\n let response;\n let infoMarket = '';\n\n try {\n response = JSON.parse(body);\n } catch (error) {\n console.log('Failed to parse publish response:', error);\n console.log('Response body:', body);\n process.exit(6);\n }\n\n // Update manifest.json with appId (--create) and/or targetId (--market)\n const manifestPath = './public/manifest.json';\n if (existsSync(manifestPath)) {\n const publicManifest = JSON.parse(readFileSync(manifestPath).toString());\n let manifestUpdated = false;\n\n if (hasFlag('--create')) {\n publicManifest.appId = appId;\n manifestUpdated = true;\n console.log('Updated', manifestPath, 'with appId:', appId);\n }\n\n if (response.manifest && response.manifest.targetId) {\n publicManifest.targetId = response.manifest.targetId;\n manifestUpdated = true;\n infoMarket = 'Note! Use targetId in public/manifest.json file when creating the product in market!';\n }\n\n if (manifestUpdated) {\n writeFileSync(manifestPath, JSON.stringify(publicManifest, null, 2), 'utf-8');\n }\n }\n\n console.log('App info:', inspect(response, { depth: 10, colors: true }));\n console.log();\n if (infoMarket)\n console.log(infoMarket);\n console.log('Published successfully!');\n\n cli.disconnect();\n})();\n", "// Re-written to TypeScript to fix typing issue, see: https://www.npmjs.com/package/minimal-password-prompt/v/1.1.0\n\nconst stdin = process.stdin;\nconst stdout = process.stdout;\n\nconst captureStdin = (onData: (data: string) => void) => {\n stdin.setEncoding('utf-8');\n stdin.setRawMode(true);\n stdin.on('data', onData);\n stdin.resume();\n};\n\nconst releaseStdin = (onData: (data: string) => void) => {\n stdin.pause();\n stdin.removeListener('data', onData);\n stdin.setRawMode(false);\n stdout.write('\\n');\n};\n\nexport const prompt = (question: string, { hidden = true, ctrlcExits = true } = {}): Promise<string> => (\n new Promise((resolve, reject) => {\n let input = '';\n const onData = (data: string) => {\n switch (data) {\n case '\\u000A': // \\n\n case '\\u000D': // \\r\n case '\\u0004': // Ctrl+D\n releaseStdin(onData);\n resolve(input);\n break;\n case '\\u0003': // Ctrl+C\n releaseStdin(onData);\n if (ctrlcExits) { // exit or raise error\n process.exit();\n } else {\n reject(new Error('Ctrl+C'));\n }\n break;\n case '\\u0008': // Backspace\n case '\\u007F': // Delete\n input = input.slice(0, -1);\n if (!hidden) {\n stdout.write('\\b \\b');\n }\n break;\n default: // any other\n input += data;\n if (!hidden) {\n stdout.write(data);\n }\n };\n };\n captureStdin(onData);\n stdout.write(question);\n })\n);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Client } from '@hailer/cli';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\nimport { prompt } from './minimal-password-prompt';\nimport { inspect } from 'util';\nimport { createInterface } from 'readline';\nimport { config as loadEnv } from 'dotenv';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\n// Load ~/.env as fallback (doesn't overwrite existing env vars)\nloadEnv({ path: join(homedir(), '.env') });\n\n/** Get the value following a named flag, e.g. getArgValue('--user-api-key') */\nfunction getArgValue(flag: string): string | undefined {\n const index = process.argv.indexOf(flag);\n if (index === -1 || index + 1 >= process.argv.length) {\n return undefined;\n }\n return process.argv[index + 1];\n}\n\nfunction hasFlag(flag: string): boolean {\n return process.argv.includes(flag);\n}\n\nconst userApiKey = getArgValue('--user-api-key') || process.env.USER_API_KEY || process.env.HAILER_USER_API_KEY;\n\nlet email = getArgValue('--email') || process.env.EMAIL;\n\nif (!userApiKey && !email && !process.env.LOCAL) {\n console.log('Please provide authentication: --email, --user-api-key, or EMAIL env var.');\n console.log('');\n console.log('Usage:');\n console.log(' npm run publish-production -- --email user@mail.com (will prompt for password)');\n console.log(' npm run publish-production -- --user-api-key <key>');\n console.log(' EMAIL=user@mail.com npm run publish-production (going to be deprecated, use --email instead)');\n console.log(' USER_API_KEY=<key> npm run publish-production (going to be deprecated, use --user-api-key instead)');\n console.log('');\n console.log('Create and publish new app:');\n console.log(' npm run publish-production -- --create --app-name \"My App\" --workspace <id> --user-api-key <key> --yes');\n console.log('');\n console.log('Options:');\n console.log(' --email <email> User email for authentication');\n console.log(' --user-api-key <key> API key for authentication');\n console.log(' --create Create a new app before publishing');\n console.log(' --app-name <name> App name (with --create)');\n console.log(' --workspace <id> Workspace ID (with --create)');\n console.log(' --market Also publish to Hailer marketplace');\n console.log(' --yes Skip confirmation prompt (going to be deprecated, use --force instead)');\n console.log(' --force Skip confirmation prompt');\n console.log(' --host <host> Specify the host URL');\n process.exit(10);\n}\n\n(async () => {\n\n let password: string | undefined;\n\n const market = hasFlag('--market') || process.env.MARKET === 'true';\n\n const appPackageFile = process.argv[2];\n\n /** Detect mode from any position in argv */\n const mode = ['--development', '--staging', '--production', '--local']\n .find(m => process.argv.includes(m));\n\n let host = getArgValue('--host') || process.env.HOST || 'https://localhost:9443';\n\n switch (mode) {\n case '--development':\n host = getArgValue('--host') || process.env.HOST || 'https://testapi.hailer.biz';\n break;\n case '--staging':\n host = getArgValue('--host') || process.env.HOST || 'https://api.hailer.biz';\n break;\n case '--production':\n host = getArgValue('--host') || process.env.HOST || 'https://api.hailer.com';\n break;\n }\n\n if (process.env.LOCAL || mode === '--local') {\n host = getArgValue('--host') || process.env.HOST || 'https://api.hailer.local.gd';\n if (!userApiKey) {\n console.log('Overriding credentials with local settings!');\n email = 'el@hailero.es';\n password = 'el@hailero.es';\n }\n }\n\n const isLocal = !!(process.env.LOCAL || mode === '--local');\n\n if (isLocal) {\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';\n }\n\n // Authenticate\n let cli: Client;\n\n if (userApiKey) {\n cli = await Client.create({ host, userApiKey, rejectUnauthorized: !isLocal }).catch(\n (error) => {\n console.log('Hailer Cli Error (API key auth):', error);\n process.exit(8);\n }\n );\n } else {\n if (!password) {\n password = await prompt(`enter password for ${ email }: `);\n }\n\n cli = await Client.create({ host, username: email, password, rejectUnauthorized: !isLocal }).catch(\n (error) => {\n if (error.msg === 'Invalid Login Data') {\n console.log('Invalid username or password when logging into Hailer.');\n } else {\n console.log('Hailer Cli Error:', error);\n }\n\n process.exit(8);\n }\n );\n }\n\n // Validate .tgz file\n if (!appPackageFile?.endsWith('.tgz')) {\n console.log('Failed getting .tgz file, found:', appPackageFile);\n process.exit(7);\n }\n\n const content = readFileSync(appPackageFile);\n let appId: string;\n\n // --create: Create a new app, then publish it\n if (hasFlag('--create')) {\n let appName = getArgValue('--app-name');\n let workspaceId = getArgValue('--workspace');\n\n if (!appName) {\n appName = await prompt('App name: ', { hidden: false });\n }\n\n if (!workspaceId) {\n workspaceId = await prompt('Workspace ID: ', { hidden: false });\n }\n\n if (!appName) {\n console.log('Error: --create requires --app-name <name>');\n process.exit(11);\n }\n if (!workspaceId) {\n console.log('Error: --create requires --workspace <id>');\n process.exit(12);\n }\n\n console.log('Creating new app...');\n console.log(' Name:', appName);\n console.log(' Workspace:', workspaceId);\n console.log(' Environment:', host);\n console.log();\n\n const appDoc = await cli.request('v3.app.create', [{\n name: appName,\n cid: workspaceId,\n }]).catch((error: any) => {\n console.log('Failed to create app:', error);\n process.exit(13);\n });\n\n appId = appDoc._id;\n console.log('App created with id:', appId);\n console.log();\n\n } else {\n // Normal publish: read appId from manifest\n const manifest = JSON.parse(readFileSync('./dist/manifest.json').toString());\n\n // Market code\n if (market) {\n if (!manifest.version) {\n manifest.version = '';\n manifest.versionDescription = '';\n\n const updatedManifestContent = JSON.stringify(manifest, null, 2);\n writeFileSync('./public/manifest.json', updatedManifestContent, 'utf-8');\n\n console.log('');\n console.log('Please set version in format (x.y.z) & versionDescription in file public/manifest.json! You have added MARKET=true or --market in your publish string.');\n console.log('');\n process.exit(10);\n }\n }\n\n const info = await cli.request('v2.core.init', [['network', 'networks', 'apps']]);\n\n const getAppById = (manifestAppId: string): { _id: string, name: string, cid: string } | null => {\n for (const appMap of Object.values(info.apps)) {\n for (const [id, app] of Object.entries(appMap as any)) {\n if (id === manifestAppId) {\n return app as any;\n }\n }\n }\n return null;\n };\n\n const app = getAppById(manifest.appId);\n\n if (!app) {\n const authInfo = userApiKey ? 'the provided API key' : email;\n console.log('The app was not found using:', authInfo);\n process.exit(2);\n }\n\n const personalApp = !app.cid;\n\n console.log('Publishing App');\n console.log(' Id:', manifest.appId);\n console.log(' Name:', app.name);\n if (personalApp) {\n console.log(' Workspace: any (personal app)');\n } else {\n console.log(' Workspace:', info.networks[app.cid]?.name, `(${ app.cid })`);\n }\n console.log(' Environment:', host);\n console.log();\n\n // Market code\n if (market) {\n console.log(' Note: Also publishing app to Hailer market');\n }\n\n /** Default to publish (yes) */\n const promptOverwriteQuestion = async () => {\n if (hasFlag('--yes') || hasFlag('--force')) {\n return true;\n }\n\n return new Promise<boolean>(resolve => {\n const rl = createInterface(process.stdin, process.stdout);\n\n rl.setPrompt('Overwrite the app? (Y/n): ');\n rl.prompt();\n rl.on('line', (line) => {\n if (line.trim().toLocaleLowerCase().startsWith('n')) {\n resolve(false);\n } else {\n resolve(true);\n }\n rl.close();\n });\n });\n };\n\n const shouldOverwrite = await promptOverwriteQuestion();\n\n if (!shouldOverwrite) {\n console.log('Aborted publishing app.');\n process.exit(0);\n }\n\n appId = manifest.appId;\n }\n\n // Upload\n const formData = new FormData();\n formData.append('file', new Blob([content]), appPackageFile);\n formData.append('appId', appId);\n // Market code\n formData.append('publishMarket', market.toString());\n\n const headers: Record<string, string> = {};\n\n if (cli.sessionKey) {\n headers.hlrkey = cli.sessionKey;\n } else if (cli.userApiKey) {\n headers.hlrkey = cli.userApiKey;\n }\n\n const resp = await fetch(`${host }/app/publish`, {\n method: 'POST',\n headers,\n body: formData,\n }).catch((error) => {\n console.log('Publish error uploading file:', error);\n process.exit(9);\n });\n\n if (!resp.ok) {\n console.log('Publish failed with status:', resp.status, resp.statusText);\n const body = await resp.text();\n console.log('Response:', body);\n process.exit(9);\n }\n\n const body = await resp.text();\n let response;\n let infoMarket = '';\n\n try {\n response = JSON.parse(body);\n } catch (error) {\n console.log('Failed to parse publish response:', error);\n console.log('Response body:', body);\n process.exit(6);\n }\n\n // Update manifest.json with appId (--create) and/or targetId (--market)\n const manifestPath = './public/manifest.json';\n if (existsSync(manifestPath)) {\n const publicManifest = JSON.parse(readFileSync(manifestPath).toString());\n let manifestUpdated = false;\n\n if (hasFlag('--create')) {\n publicManifest.appId = appId;\n manifestUpdated = true;\n console.log('Updated', manifestPath, 'with appId:', appId);\n }\n\n if (response.manifest?.targetId) {\n publicManifest.targetId = response.manifest.targetId;\n manifestUpdated = true;\n infoMarket = 'Note! Use targetId in public/manifest.json file when creating the product in market!';\n }\n\n if (manifestUpdated) {\n writeFileSync(manifestPath, JSON.stringify(publicManifest, null, 2), 'utf-8');\n }\n }\n\n console.log('App info:', inspect(response, { depth: 10, colors: true }));\n console.log();\n if (infoMarket) {\n console.log(infoMarket);\n }\n console.log('Published successfully!');\n\n cli.disconnect();\n})();\n", "// Re-written to TypeScript to fix typing issue, see: https://www.npmjs.com/package/minimal-password-prompt/v/1.1.0\n\nconst stdin = process.stdin;\nconst stdout = process.stdout;\n\nconst captureStdin = (onData: (data: string) => void) => {\n stdin.setEncoding('utf-8');\n stdin.setRawMode(true);\n stdin.on('data', onData);\n stdin.resume();\n};\n\nconst releaseStdin = (onData: (data: string) => void) => {\n stdin.pause();\n stdin.removeListener('data', onData);\n stdin.setRawMode(false);\n stdout.write('\\n');\n};\n\nexport const prompt = (question: string, { hidden = true, ctrlcExits = true } = {}): Promise<string> => (\n new Promise((resolve, reject) => {\n let input = '';\n const onData = (data: string) => {\n switch (data) {\n case '\\u000A': // \\n\n case '\\u000D': // \\r\n case '\\u0004': // Ctrl+D\n releaseStdin(onData);\n resolve(input);\n break;\n case '\\u0003': // Ctrl+C\n releaseStdin(onData);\n if (ctrlcExits) { // exit or raise error\n process.exit();\n } else {\n reject(new Error('Ctrl+C'));\n }\n break;\n case '\\u0008': // Backspace\n case '\\u007F': // Delete\n input = input.slice(0, -1);\n if (!hidden) {\n stdout.write('\\b \\b');\n }\n break;\n default: // any other\n input += data;\n if (!hidden) {\n stdout.write(data);\n }\n };\n };\n captureStdin(onData);\n stdout.write(question);\n })\n);\n"],
5
+ "mappings": "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",
6
6
  "names": ["loadEnv", "app", "body"]
7
7
  }
package/package.json CHANGED
@@ -1,46 +1,63 @@
1
1
  {
2
- "name": "@hailer/app-sdk",
3
- "version": "2.4.2",
4
- "description": "SDK for building Hailer Apps",
5
- "author": "",
6
- "license": "ISC",
7
- "main": "./lib/app-sdk.js",
8
- "type": "module",
9
- "types": "./lib/index.d.ts",
10
- "files": [
11
- "./lib/**/*"
2
+ "name": "@hailer/app-sdk",
3
+ "version": "2.5.0",
4
+ "description": "SDK for building Hailer Apps",
5
+ "author": "",
6
+ "license": "ISC",
7
+ "main": "./lib/app-sdk.js",
8
+ "type": "module",
9
+ "types": "./lib/index.d.ts",
10
+ "files": [
11
+ "./lib/**/*"
12
+ ],
13
+ "scripts": {
14
+ "build": "esbuild tools/publish.ts --platform=node --packages=external --bundle --format=cjs --sourcemap --outfile=lib/tools/publish.cjs && tsc && esbuild src/index.ts --bundle --format=esm --minify --sourcemap --outfile=lib/app-sdk.js",
15
+ "prepublishOnly": "npm run build",
16
+ "watch": "concurrently --kill-others \"npm run watch-tsc\" \"npm run watch-esbuild\"",
17
+ "watch-tsc": "tsc --watch",
18
+ "watch-esbuild": "esbuild src/index.ts --bundle --format=esm --sourcemap --outfile=lib/app-sdk.js --watch",
19
+ "docs": "typedoc --entryPointStrategy expand ./src && open-cli ./docs/index.html",
20
+ "test": "vitest run",
21
+ "test:watch": "vitest",
22
+ "lint": "eslint .",
23
+ "lint:fix": "eslint . --fix",
24
+ "format": "eslint . --fix",
25
+ "release:patch": "npm version patch -m 'chore: release v%s' && git push && git push --tags",
26
+ "release:minor": "npm version minor -m 'chore: release v%s' && git push && git push --tags",
27
+ "release:major": "npm version major -m 'chore: release v%s' && git push && git push --tags",
28
+ "release:beta-patch": "npm version prerelease --preid=beta -m 'chore: release v%s' && git push && git push --tags",
29
+ "release:beta-minor": "npm version preminor --preid=beta -m 'chore: release v%s' && git push && git push --tags",
30
+ "release:beta-major": "npm version premajor --preid=beta -m 'chore: release v%s' && git push && git push --tags",
31
+ "prepare": "husky"
32
+ },
33
+ "dependencies": {
34
+ "@hailer/cli": "1.2.0",
35
+ "@wishcore/wish-rpc": "0.6.11",
36
+ "dotenv": "^17.4.1"
37
+ },
38
+ "devDependencies": {
39
+ "@eslint/js": "10.0.1",
40
+ "@hailer-repos/eslint-config": "1.14.0",
41
+ "@types/node": "^22.19.17",
42
+ "@typescript-eslint/eslint-plugin": "^8.59.4",
43
+ "@typescript-eslint/parser": "^8.59.4",
44
+ "concurrently": "8.2.1",
45
+ "esbuild": "^0.28.0",
46
+ "eslint": "^10.4.0",
47
+ "eslint-plugin-diff": "2.1.7",
48
+ "husky": "9.1.7",
49
+ "lint-staged": "17.0.5",
50
+ "open-cli": "^9.0.0",
51
+ "typedoc": "^0.24.8",
52
+ "typescript": "^5.1.3",
53
+ "vitest": "^4.1.4"
54
+ },
55
+ "lint-staged": {
56
+ "*.{ts,js}": [
57
+ "eslint --config eslint.config.staged.mjs --fix"
12
58
  ],
13
- "scripts": {
14
- "build": "esbuild tools/publish.ts --platform=node --packages=external --bundle --format=cjs --sourcemap --outfile=lib/tools/publish.cjs && tsc && esbuild src/index.ts --bundle --format=esm --minify --sourcemap --outfile=lib/app-sdk.js",
15
- "prepublishOnly": "npm run build",
16
- "watch": "concurrently --kill-others \"npm run watch-tsc\" \"npm run watch-esbuild\"",
17
- "watch-tsc": "tsc --watch",
18
- "watch-esbuild": "esbuild src/index.ts --bundle --format=esm --sourcemap --outfile=lib/app-sdk.js --watch",
19
- "docs": "typedoc --entryPointStrategy expand ./src && open-cli ./docs/index.html",
20
- "test": "vitest run",
21
- "test:watch": "vitest",
22
- "release:patch": "npm version patch -m 'chore: release v%s' && git push && git push --tags",
23
- "release:minor": "npm version minor -m 'chore: release v%s' && git push && git push --tags",
24
- "release:major": "npm version major -m 'chore: release v%s' && git push && git push --tags",
25
- "release:beta-patch": "npm version prerelease --preid=beta -m 'chore: release v%s' && git push && git push --tags",
26
- "release:beta-minor": "npm version preminor --preid=beta -m 'chore: release v%s' && git push && git push --tags",
27
- "release:beta-major": "npm version premajor --preid=beta -m 'chore: release v%s' && git push && git push --tags"
28
- },
29
- "dependencies": {
30
- "@hailer/cli": "1.2.0",
31
- "@wishcore/wish-rpc": "0.6.11",
32
- "dotenv": "^17.4.1"
33
- },
34
- "devDependencies": {
35
- "@types/node": "^22.19.17",
36
- "@typescript-eslint/eslint-plugin": "^5.60.0",
37
- "@typescript-eslint/parser": "^5.60.0",
38
- "concurrently": "8.2.1",
39
- "esbuild": "^0.28.0",
40
- "eslint": "^8.43.0",
41
- "open-cli": "^9.0.0",
42
- "typedoc": "^0.24.8",
43
- "typescript": "^5.1.3",
44
- "vitest": "^4.1.4"
45
- }
59
+ "*.json": [
60
+ "eslint --config eslint.config.staged.mjs --fix"
61
+ ]
62
+ }
46
63
  }