Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/targets/browser-edge/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { defineTarget, exec, manualSetup } from '@profullstack/sh1pt-core';
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { isAbsolute, join } from 'node:path';

function safeFileStem(value: string): string {
return value.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || 'edge-ext';
}

interface Config {
productId: string; // Edge Partner Center product ID
sourceDir?: string; // defaults to "dist/"
Expand All @@ -14,7 +18,7 @@ function sourceDir(ctx: { projectDir: string }, config: Config): string {
}

function packageArtifact(ctx: { outDir: string; version: string }, config: Config): string {
return join(ctx.outDir, `${config.productId}-${ctx.version}.zip`);
return join(ctx.outDir, `${safeFileStem(config.productId)}-${ctx.version}.zip`);
}

function packagePlan(ctx: { projectDir: string; outDir: string; version: string }, config: Config) {
Expand Down
6 changes: 5 additions & 1 deletion packages/targets/chat-telegram/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default defineTarget<Config>({
label: 'Telegram Bot',
async build(ctx, config) {
ctx.log(`telegram · prepare bot manifest for @${config.botUsername}`);
return { artifact: `${ctx.outDir}/telegram-${config.botUsername}.json` };
return { artifact: `${ctx.outDir}/telegram-${safeFileStem(config.botUsername)}.json` };
},
async ship(ctx, config) {
const username = normalizeUsername(config.botUsername);
Expand Down Expand Up @@ -98,6 +98,10 @@ async function callTelegram<T>(
return data.result;
}

function safeFileStem(value: string): string {
return value.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || 'telegram-bot';
}

function normalizeUsername(username: string): string {
const clean = username.replace(/^@/, '').trim();
if (!clean) throw new Error('botUsername is required');
Expand Down
6 changes: 5 additions & 1 deletion packages/targets/mobile-android/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ interface Config {
track?: 'internal' | 'alpha' | 'beta' | 'production';
}

function safeFileStem(value: string): string {
return value.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || 'android-app';
}

export default defineTarget<Config>({
id: 'mobile-android',
kind: 'mobile',
label: 'Google Play Store',
async build(ctx, config) {
ctx.log(`build Android AAB for ${config.packageName} v${ctx.version}`);
// TODO: run Gradle bundleRelease to produce signed .aab
return { artifact: `${ctx.outDir}/${config.packageName}-${ctx.version}.aab` };
return { artifact: `${ctx.outDir}/${safeFileStem(config.packageName)}-${ctx.version}.aab` };
},
async ship(ctx, config) {
const track = config.track ?? 'internal';
Expand Down
6 changes: 0 additions & 6 deletions packages/targets/pkg-flatpak/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ function renderList(values: string[], indent: string): string[] {
* each non-empty and containing only alphanumeric characters or hyphens/underscores.
* Must not contain path traversal characters.
*/
function validateAppId(appId: string): void {
if (!appId || typeof appId !== 'string') {
throw new Error('pkg-flatpak: appId is required');
}
// Block path traversal
if (appId.includes('/') || appId.includes('\\') || appId.includes('..')) {
throw new Error(`pkg-flatpak: invalid appId "${appId}" — must not contain path separators or ".." sequences`);
}
const segments = appId.split('.');
Expand Down
7 changes: 0 additions & 7 deletions packages/targets/pkg-snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ function renderDescription(description: string): string[] {
* Rules: lowercase letters, digits, and hyphens only; at least one letter;
* no leading or trailing hyphen; max 40 characters.
*/
function validateSnapName(snapName: string): void {
if (!snapName || typeof snapName !== 'string') {
throw new Error('pkg-snap: snapName is required');
}
if (snapName.length > 40) {
throw new Error(`pkg-snap: snapName "${snapName}" exceeds 40 characters`);
}
if (snapName.startsWith('-') || snapName.endsWith('-')) {
throw new Error(`pkg-snap: snapName "${snapName}" must not start or end with a hyphen`);
}
Expand Down
7 changes: 0 additions & 7 deletions packages/targets/pkg-winget/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ function yamlString(value: string): string {
* Must follow "Publisher.PackageName" format — at least one dot, no leading/trailing dot,
* each segment non-empty and containing only alphanumeric characters, hyphens, or underscores.
*/
function validatePackageId(packageId: string): void {
if (!packageId || typeof packageId !== 'string') {
throw new Error('winget: packageId is required');
}
if (packageId.startsWith('.') || packageId.endsWith('.')) {
throw new Error(`winget: invalid packageId "${packageId}" — must not start or end with a dot`);
}
const segments = packageId.split('.');
if (segments.length < 2) {
throw new Error(`winget: invalid packageId "${packageId}" — must use Publisher.Package format (e.g. "Microsoft.VSCode")`);
Expand Down
Loading