New:Socket for Asana Is Now Available.Learn more
Get Started

@flashcatcloud/hvigor-plugin

Package Overview
Dependencies
Maintainers
3
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@flashcatcloud/hvigor-plugin - npm Package Compare versions

Comparing version
0.1.2
to
0.1.3
+14
-0
CHANGELOG.md
# Changelog
## 0.1.3
- Default symbol-upload host is now `https://ci.flashcat.cloud` (was
`https://browser.flashcat.cloud`, which 404s — that host is RUM ingest only).
- Honour `FLASHCAT_SOURCEMAP_INTAKE_URL` first (same variable as Android /
flashcat-cli); `FLASHCAT_ENDPOINT` remains a legacy alias and emits a warning.
- Explicit empty `endpoint` / empty env vars **skip** upload instead of falling
back to SaaS. Values are validated with `new URL()` (http(s), no query/hash).
- Warn when the resolved host is a known RUM-ingest-only host
(`browser.flashcat.cloud` / `jira.flashcat.cloud`).
- If the configured endpoint already ends with `/sourcemap/upload`, do not
append the path again.
- `pluginVersion` fallback reads `package.json` (no hand-copied literal).
## 0.1.2

@@ -4,0 +18,0 @@

+4
-3

@@ -15,5 +15,6 @@ export interface HvigorNode {

export interface FlashcatPluginOptions {
/** RUM ingest base URL. Optional — defaults to $FLASHCAT_ENDPOINT, else the SaaS
* ingest (https://browser.flashcat.cloud). Set it (or the env var) for staging /
* self-hosted. */
/** Symbol-upload base URL. Optional — when omitted, uses $FLASHCAT_SOURCEMAP_INTAKE_URL,
* then legacy $FLASHCAT_ENDPOINT, then SaaS `https://ci.flashcat.cloud`.
* When set (including empty string), that value is used alone: empty/invalid skips
* upload instead of falling back to SaaS. Private deploys: scheme + host, no path. */
endpoint?: string;

@@ -20,0 +21,0 @@ apiKey: string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.flashcatSymbolUploadPlugin = flashcatSymbolUploadPlugin;
const node_module_1 = require("node:module");
const index_ts_1 = require("./index.js");
const upload_ts_1 = require("./upload.js");
// Keep the reported plugin version in sync with package.json (no hand-copied literal).
const requirePackageJson = (0, node_module_1.createRequire)(__filename);
const PACKAGE_VERSION = requirePackageJson('../package.json').version;
/**

@@ -44,10 +49,18 @@ * Registers an `uploadFlashcatSymbols` task on the module. Runs AFTER the module

}
// endpoint may be omitted in config; fall back to env then the SaaS ingest.
const endpoint = options.endpoint ?? process.env.FLASHCAT_ENDPOINT ?? 'https://browser.flashcat.cloud';
const resolved = (0, upload_ts_1.resolveUploadEndpoint)(options.endpoint);
for (const w of resolved.warnings) {
// eslint-disable-next-line no-console
console.warn(`flashcat: ${w}`);
}
if (!resolved.ok) {
// eslint-disable-next-line no-console
console.warn(`flashcat: ${resolved.reason}`);
return;
}
const cfg = {
endpoint,
endpoint: resolved.endpoint,
apiKey: options.apiKey,
service: options.service,
version: options.version,
pluginVersion: options.pluginVersion ?? '0.1.2' // keep in sync with package.json version
pluginVersion: options.pluginVersion ?? PACKAGE_VERSION
};

@@ -54,0 +67,0 @@ const buildDir = `${node.getNodePath()}/${options.buildDir ?? 'build/default'}`;

@@ -8,4 +8,29 @@ import type { ArktsSourcemap, NativeSymbol } from './collect.ts';

export declare const TYPE_SYMBOL_FILE = "harmony_symbol_file";
export type EndpointResolution = {
ok: true;
endpoint: string;
warnings: string[];
} | {
ok: false;
reason: string;
warnings: string[];
};
/**
* Resolve the symbol-upload base URL.
*
* Priority when `explicit` is **omitted** (`undefined`):
* `FLASHCAT_SOURCEMAP_INTAKE_URL` → legacy `FLASHCAT_ENDPOINT` → SaaS default.
*
* When `explicit` is provided (`''` included; `null` counts as omitted — plain-JS
* hvigorfiles pass it from config lookups), it is the only source — an empty
* or invalid value skips the upload instead of falling back to SaaS.
*/
export declare function resolveUploadEndpoint(explicit?: string | null, env?: NodeJS.ProcessEnv): EndpointResolution;
/**
* Build the upload URL. Accepts either a base host or a full
* `.../sourcemap/upload` path so private-deploy pastes don't double the suffix.
*/
export declare function resolveSourcemapUploadUrl(endpoint: string): string;
export interface UploadConfig {
/** Ingest host, e.g. https://browser.flashcat.cloud (prod) or https://jira.flashcat.cloud (staging). */
/** Symbol-upload base URL, e.g. https://ci.flashcat.cloud (SaaS) or a private ingest host. */
endpoint: string;

@@ -12,0 +37,0 @@ apiKey: string;

@@ -37,2 +37,4 @@ "use strict";

exports.TYPE_SYMBOL_FILE = exports.TYPE_SOURCEMAP = exports.ORIGIN = void 0;
exports.resolveUploadEndpoint = resolveUploadEndpoint;
exports.resolveSourcemapUploadUrl = resolveSourcemapUploadUrl;
exports.sourcemapEvent = sourcemapEvent;

@@ -50,2 +52,92 @@ exports.symbolFileEvent = symbolFileEvent;

exports.TYPE_SYMBOL_FILE = 'harmony_symbol_file';
/** SaaS sourcemap/symbol upload host. Distinct from RUM ingest (`browser.flashcat.cloud`). */
const DEFAULT_UPLOAD_ENDPOINT = 'https://ci.flashcat.cloud';
/** Known RUM-ingest-only hosts that 404 on `/sourcemap/upload`. */
const RUM_INGEST_ONLY_HOSTS = new Set(['browser.flashcat.cloud', 'jira.flashcat.cloud']);
/**
* Resolve the symbol-upload base URL.
*
* Priority when `explicit` is **omitted** (`undefined`):
* `FLASHCAT_SOURCEMAP_INTAKE_URL` → legacy `FLASHCAT_ENDPOINT` → SaaS default.
*
* When `explicit` is provided (`''` included; `null` counts as omitted — plain-JS
* hvigorfiles pass it from config lookups), it is the only source — an empty
* or invalid value skips the upload instead of falling back to SaaS.
*/
function resolveUploadEndpoint(explicit, env = process.env) {
const warnings = [];
let raw;
let source;
if (explicit != null) {
raw = explicit.trim();
source = 'option';
if (!raw) {
return { ok: false, reason: 'endpoint is empty — skipping symbol upload (will not fall back to SaaS)', warnings };
}
}
else if (env.FLASHCAT_SOURCEMAP_INTAKE_URL !== undefined) {
raw = env.FLASHCAT_SOURCEMAP_INTAKE_URL.trim();
source = 'FLASHCAT_SOURCEMAP_INTAKE_URL';
if (!raw) {
return {
ok: false,
reason: 'FLASHCAT_SOURCEMAP_INTAKE_URL is empty — skipping symbol upload (will not fall back to SaaS)',
warnings
};
}
}
else if (env.FLASHCAT_ENDPOINT !== undefined) {
raw = env.FLASHCAT_ENDPOINT.trim();
source = 'FLASHCAT_ENDPOINT';
if (!raw) {
return {
ok: false,
reason: 'FLASHCAT_ENDPOINT is empty — skipping symbol upload (will not fall back to SaaS)',
warnings
};
}
warnings.push('FLASHCAT_ENDPOINT is deprecated for symbol upload; prefer FLASHCAT_SOURCEMAP_INTAKE_URL (or omit for SaaS)');
}
else {
raw = DEFAULT_UPLOAD_ENDPOINT;
source = 'default';
}
let url;
try {
url = new URL(raw);
}
catch {
return { ok: false, reason: `invalid symbol-upload endpoint from ${source}: ${JSON.stringify(raw)}`, warnings };
}
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
return {
ok: false,
reason: `symbol-upload endpoint from ${source} must be http(s), got ${url.protocol}`,
warnings
};
}
if (url.search || url.hash) {
return {
ok: false,
reason: `symbol-upload endpoint from ${source} must not include query or hash`,
warnings
};
}
if (RUM_INGEST_ONLY_HOSTS.has(url.hostname)) {
warnings.push(`${url.hostname} is a RUM ingest host and returns 404 on /sourcemap/upload — use https://ci.flashcat.cloud (SaaS) or your private symbol-upload base URL`);
}
const endpoint = raw.replace(/\/+$/, '');
return { ok: true, endpoint, warnings };
}
/**
* Build the upload URL. Accepts either a base host or a full
* `.../sourcemap/upload` path so private-deploy pastes don't double the suffix.
*/
function resolveSourcemapUploadUrl(endpoint) {
const normalized = endpoint.trim().replace(/\/+$/, '');
if (normalized.endsWith('/sourcemap/upload')) {
return normalized;
}
return `${normalized}/sourcemap/upload`;
}
/** event metadata for an ArkTS sourcemap upload. */

@@ -83,3 +175,3 @@ function sourcemapEvent(cfg) {

function uploadUrl(cfg) {
return `${cfg.endpoint.replace(/\/+$/, '')}/sourcemap/upload`;
return resolveSourcemapUploadUrl(cfg.endpoint);
}

@@ -86,0 +178,0 @@ function fileBlob(filePath) {

{
"name": "@flashcatcloud/hvigor-plugin",
"version": "0.1.2",
"version": "0.1.3",
"description": "FlashCat hvigor plugin: upload HarmonyOS ArkTS sourcemaps + native .so debug symbols to fc-rum for crash symbolication.",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",

@@ -15,6 +15,12 @@ # @flashcatcloud/hvigor-plugin

hvigor plugins are declared in the project's `hvigor/hvigor-config.json5`
`dependencies` (this is the hvigor mechanism — **not** `ohpm install`, which is for
ArkTS/ohpm packages). hvigor installs it from npm and resolves the import below.
The plugin is published on **npm**, not ohpm. Install it as a devDependency in
the project root `package.json` (not `oh-package.json5`):
```sh
npm install -D @flashcatcloud/hvigor-plugin
```
Alternatively, declare it in `hvigor/hvigor-config.json5` `dependencies` —
hvigor still fetches it from npm:
```json5

@@ -24,3 +30,3 @@ {

"dependencies": {
"@flashcatcloud/hvigor-plugin": "^0.1.0"
"@flashcatcloud/hvigor-plugin": "^0.1.3"
}

@@ -42,3 +48,5 @@ }

flashcatSymbolUploadPlugin({
endpoint: 'https://browser.flashcat.cloud', // staging: https://jira.flashcat.cloud
// Omit endpoint for SaaS (defaults to https://ci.flashcat.cloud).
// Private deploy: set FLASHCAT_SOURCEMAP_INTAKE_URL=https://rum.example.com
// (scheme + host, no path), or pass endpoint: 'https://rum.example.com'.
apiKey: process.env.FLASHCAT_API_KEY ?? '',

@@ -60,2 +68,11 @@ service: 'my-app',

Endpoint resolution (first match wins):
1. `endpoint` option — if provided (even as `''`), it is the only source; empty/invalid **skips** upload (no SaaS fallback)
2. `FLASHCAT_SOURCEMAP_INTAKE_URL` (preferred for private deploys; same name as Android / flashcat-cli)
3. Legacy `FLASHCAT_ENDPOINT` (deprecated; emits a warning — historically often set to the RUM host `browser.flashcat.cloud`, which 404s on symbol upload)
4. SaaS default `https://ci.flashcat.cloud`
Do **not** use `browser.flashcat.cloud` / `jira.flashcat.cloud` for symbol upload — those are RUM ingest hosts only.
The task is registered with `dependencies: ['assembleHap','assembleHar']` (it runs

@@ -70,3 +87,4 @@ after the assemble tasks), so the sourcemap + native libs exist when it runs. A missing artifact or upload

const result = await uploadAll('entry/build/default', {
endpoint, apiKey, service, version, pluginVersion: '0.1.0'
endpoint: process.env.FLASHCAT_SOURCEMAP_INTAKE_URL || 'https://ci.flashcat.cloud',
apiKey, service, version, pluginVersion: '0.1.3'
}, console.log);

@@ -73,0 +91,0 @@ ```