zcw-shared 1.15.0 → 1.16.2

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.
@@ -0,0 +1,6 @@
1
+ import type { File, Window } from '../../../references/browser.d';
2
+ export declare function compressToTargetSize(file: File, options: {
3
+ targetSize?: number;
4
+ maxIterations?: number;
5
+ mimeType?: string;
6
+ } | undefined, window: Window): Promise<File>;
@@ -0,0 +1,93 @@
1
+ import { getImageDimensions } from './getImageDimensions';
2
+ export async function compressToTargetSize(file, options = {}, window) {
3
+ const { targetSize = 30 * 1024, maxIterations = 30, mimeType = 'image/jpeg' } = options;
4
+ if (file.size <= targetSize) {
5
+ return file;
6
+ }
7
+ const dimensions = await getImageDimensions(file, window);
8
+ let currentWidth = dimensions.width;
9
+ let currentHeight = dimensions.height;
10
+ let currentQuality = 0.9;
11
+ let iteration = 0;
12
+ async function attemptCompress() {
13
+ iteration++;
14
+ if (iteration > maxIterations) {
15
+ throw new Error(`压缩失败:达到最大尝试次数(${maxIterations}),仍未达到目标大小`);
16
+ }
17
+ const result = await compressImage(file, {
18
+ quality: currentQuality,
19
+ maxWidth: currentWidth,
20
+ maxHeight: currentHeight,
21
+ mimeType
22
+ }, window);
23
+ if (result.size <= targetSize) {
24
+ return result;
25
+ }
26
+ const ratio = targetSize / result.size;
27
+ if (ratio < 0.05) {
28
+ currentWidth = Math.max(50, Math.floor(currentWidth * 0.5));
29
+ currentHeight = Math.max(50, Math.floor(currentHeight * 0.5));
30
+ currentQuality = Math.max(0.05, currentQuality * 0.5);
31
+ }
32
+ else if (ratio < 0.15) {
33
+ currentWidth = Math.max(80, Math.floor(currentWidth * 0.6));
34
+ currentHeight = Math.max(80, Math.floor(currentHeight * 0.6));
35
+ currentQuality = Math.max(0.08, currentQuality * 0.6);
36
+ }
37
+ else if (ratio < 0.3) {
38
+ currentWidth = Math.max(100, Math.floor(currentWidth * 0.7));
39
+ currentHeight = Math.max(100, Math.floor(currentHeight * 0.7));
40
+ currentQuality = Math.max(0.1, currentQuality * 0.8);
41
+ }
42
+ else if (ratio < 0.7) {
43
+ currentWidth = Math.max(100, Math.floor(currentWidth * 0.85));
44
+ currentHeight = Math.max(100, Math.floor(currentHeight * 0.85));
45
+ currentQuality = Math.max(0.1, currentQuality * 0.85);
46
+ }
47
+ else {
48
+ currentQuality = Math.max(0.1, currentQuality * 0.9);
49
+ }
50
+ return attemptCompress();
51
+ }
52
+ return attemptCompress();
53
+ }
54
+ async function compressImage(file, options, window) {
55
+ const { quality, maxWidth, maxHeight, mimeType } = options;
56
+ return new Promise((resolve, reject) => {
57
+ const img = new window.Image();
58
+ img.onload = () => {
59
+ const canvas = window.document.createElement('canvas');
60
+ let width = img.naturalWidth;
61
+ let height = img.naturalHeight;
62
+ if (width > maxWidth || height > maxHeight) {
63
+ const ratio = Math.min(maxWidth / width, maxHeight / height);
64
+ width = Math.floor(width * ratio);
65
+ height = Math.floor(height * ratio);
66
+ }
67
+ canvas.width = width;
68
+ canvas.height = height;
69
+ const ctx = canvas.getContext('2d');
70
+ if (!ctx) {
71
+ reject(new Error('无法创建canvas上下文'));
72
+ return;
73
+ }
74
+ ctx.drawImage(img, 0, 0, width, height);
75
+ canvas.toBlob((blob) => {
76
+ if (!blob) {
77
+ reject(new Error('图片压缩失败'));
78
+ return;
79
+ }
80
+ const newFile = new window.File([blob], file.name, {
81
+ type: mimeType,
82
+ lastModified: Date.now()
83
+ });
84
+ resolve(newFile);
85
+ }, mimeType, quality);
86
+ };
87
+ img.onerror = () => {
88
+ reject(new Error('图片加载失败'));
89
+ };
90
+ img.src = window.URL.createObjectURL(file);
91
+ });
92
+ }
93
+ //# sourceMappingURL=compressToTargetSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compressToTargetSize.js","sourceRoot":"","sources":["../../../src/functions/image/compressToTargetSize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { File, Window } from '../../../references/browser.d';
2
+ export declare function getImageDimensions(file: File, window: Window): Promise<{
3
+ width: number;
4
+ height: number;
5
+ }>;
@@ -0,0 +1,16 @@
1
+ export async function getImageDimensions(file, window) {
2
+ return new Promise((resolve, reject) => {
3
+ const img = new window.Image();
4
+ img.onload = () => {
5
+ resolve({
6
+ width: img.naturalWidth,
7
+ height: img.naturalHeight
8
+ });
9
+ };
10
+ img.onerror = () => {
11
+ reject(new Error('获取图片尺寸失败'));
12
+ };
13
+ img.src = window.URL.createObjectURL(file);
14
+ });
15
+ }
16
+ //# sourceMappingURL=getImageDimensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getImageDimensions.js","sourceRoot":"","sources":["../../../src/functions/image/getImageDimensions.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAU,EAAE,MAAc;IACjE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,CAAA;QAC9B,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;YAChB,OAAO,CAAC;gBACN,KAAK,EAAE,GAAG,CAAC,YAAY;gBACvB,MAAM,EAAE,GAAG,CAAC,aAAa;aAC1B,CAAC,CAAA;QACJ,CAAC,CAAA;QACD,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE;YACjB,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;QAC/B,CAAC,CAAA;QACD,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zcw-shared",
3
- "version": "1.15.0",
3
+ "version": "1.16.2",
4
4
  "files": [
5
5
  "references",
6
6
  "dist",
@@ -20,11 +20,15 @@
20
20
  "publish:patch": "npx tsx scripts/publish.ts patch",
21
21
  "publish:minor": "npx tsx scripts/publish.ts minor",
22
22
  "publish:major": "npx tsx scripts/publish.ts major",
23
- "publish:prerelease": "npx tsx scripts/publish.ts prerelease"
23
+ "publish:prerelease": "npx tsx scripts/publish.ts prerelease",
24
+ "docs:dev": "vitepress dev docs",
25
+ "docs:build": "vitepress build docs",
26
+ "docs:preview": "vitepress preview docs"
24
27
  },
25
28
  "devDependencies": {
26
29
  "tsx": "^4.20.3",
27
- "typescript": "^5.8.3"
30
+ "typescript": "^5.8.3",
31
+ "vitepress": "^1.6.4"
28
32
  },
29
33
  "exports": {
30
34
  "./constants/colorPatterns": "./dist/constants/colorPatterns.js",
@@ -47,11 +51,13 @@
47
51
  "./functions/dom/getElementRect": "./dist/functions/dom/getElementRect.js",
48
52
  "./functions/dom/getRelativePosition": "./dist/functions/dom/getRelativePosition.js",
49
53
  "./functions/dom/getViewportRect": "./dist/functions/dom/getViewportRect.js",
54
+ "./functions/image/compressToTargetSize": "./dist/functions/image/compressToTargetSize.js",
50
55
  "./functions/image/generateMacIcons": "./dist/functions/image/generateMacIcons.js",
51
56
  "./functions/image/generateMacTrayIcon": "./dist/functions/image/generateMacTrayIcon.js",
52
57
  "./functions/image/generatePaddedImage": "./dist/functions/image/generatePaddedImage.js",
53
58
  "./functions/image/generatePwaIcons": "./dist/functions/image/generatePwaIcons.js",
54
59
  "./functions/image/generateRoundedImage": "./dist/functions/image/generateRoundedImage.js",
60
+ "./functions/image/getImageDimensions": "./dist/functions/image/getImageDimensions.js",
55
61
  "./functions/ipc/dispatchIpcRequest": "./dist/functions/ipc/dispatchIpcRequest.js",
56
62
  "./functions/software/findSoftware": "./dist/functions/software/findSoftware.js",
57
63
  "./functions/string/base64": "./dist/functions/string/base64.js",
@@ -4,13 +4,25 @@ import type { AbortController, Response, FetchFunction } from './fetch.d'
4
4
  import type { URLSearchParams } from './url.d'
5
5
  import type { Storage } from './storage.d'
6
6
  import type { WorkerConstructor } from './worker.d'
7
- import type { Document, HTMLElement, Element } from './dom.d'
7
+ import type { Document, HTMLElement, Element, HTMLImageElement } from './dom.d'
8
8
  import type { IDBFactory } from './indexeddb.d'
9
9
  import type { Blob, BlobPart, BlobPropertyBag, MediaSource, ReadableStream } from './blob.d'
10
10
  import type { TextDecoderConstructor, TextEncoderConstructor } from './encoding.d'
11
11
  import type { Location } from './location.d'
12
12
  import type { ArrayBufferConstructor, Uint8ArrayConstructor, DataViewConstructor } from './arraybuffer.d'
13
13
 
14
+ // File 接口定义
15
+ export interface FilePropertyBag extends BlobPropertyBag {
16
+ lastModified?: number
17
+ }
18
+
19
+ export interface File extends Blob {
20
+ readonly name: string
21
+ readonly size: number
22
+ readonly type: string
23
+ readonly lastModified: number
24
+ }
25
+
14
26
 
15
27
 
16
28
  // 浏览器Window对象 - 包含所有浏览器API
@@ -58,6 +70,16 @@ export interface Window {
58
70
  new (blobParts?: BlobPart[], options?: BlobPropertyBag): Blob
59
71
  }
60
72
 
73
+ // File API
74
+ File: {
75
+ new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): File
76
+ }
77
+
78
+ // Image API
79
+ Image: {
80
+ new (width?: number, height?: number): HTMLImageElement
81
+ }
82
+
61
83
  // ArrayBuffer API
62
84
  ArrayBuffer: ArrayBufferConstructor
63
85
  Uint8Array: Uint8ArrayConstructor
@@ -18,7 +18,27 @@ export interface HTMLElement extends Element {
18
18
  }
19
19
  }
20
20
 
21
+ export interface HTMLImageElement extends HTMLElement {
22
+ src: string
23
+ naturalWidth: number
24
+ naturalHeight: number
25
+ onload: (() => void) | null
26
+ onerror: (() => void) | null
27
+ }
28
+
29
+ export interface CanvasRenderingContext2D {
30
+ drawImage(image: HTMLImageElement, dx: number, dy: number, dWidth: number, dHeight: number): void
31
+ }
32
+
33
+ export interface HTMLCanvasElement extends HTMLElement {
34
+ width: number
35
+ height: number
36
+ getContext(contextId: '2d'): CanvasRenderingContext2D | null
37
+ toBlob(callback: (blob: Blob | null) => void, type?: string, quality?: number): void
38
+ }
39
+
21
40
  export interface Document {
41
+ createElement(tagName: 'canvas'): HTMLCanvasElement
22
42
  createElement(tagName: string): HTMLElement
23
43
  documentElement: {
24
44
  clientWidth: number
@@ -1,30 +0,0 @@
1
- export interface CommandResult {
2
- exitCode: number;
3
- stdout: string;
4
- stderr: string;
5
- success: boolean;
6
- }
7
- export interface Executor {
8
- exec(command: string, options?: {
9
- cwd?: string;
10
- }): CommandResult;
11
- }
12
- export interface Logger {
13
- info(message: string): void;
14
- error(message: string): void;
15
- warn(message: string): void;
16
- debug(message: string): void;
17
- }
18
- export interface GitEnvironment {
19
- installed: boolean;
20
- version?: string;
21
- userConfigured: boolean;
22
- userName?: string;
23
- userEmail?: string;
24
- inRepository: boolean;
25
- }
26
- export declare function checkGitEnvironment(executor: Executor): GitEnvironment;
27
- export declare function checkBranch(executor: Executor, logger: Logger, options?: {
28
- allowedBranches?: string[];
29
- force?: boolean;
30
- }): boolean;
@@ -1,71 +0,0 @@
1
- export function checkGitEnvironment(executor) {
2
- const result = {
3
- installed: false,
4
- userConfigured: false,
5
- inRepository: false
6
- };
7
- const versionResult = executor.exec('git --version');
8
- if (versionResult.success) {
9
- result.installed = true;
10
- result.version = versionResult.stdout.trim().replace('git version ', '');
11
- }
12
- else {
13
- return result;
14
- }
15
- const userNameResult = executor.exec('git config user.name');
16
- const userEmailResult = executor.exec('git config user.email');
17
- if (userNameResult.success && userEmailResult.success) {
18
- result.userConfigured = true;
19
- result.userName = userNameResult.stdout.trim();
20
- result.userEmail = userEmailResult.stdout.trim();
21
- }
22
- const repoResult = executor.exec('git rev-parse --git-dir');
23
- result.inRepository = repoResult.success;
24
- return result;
25
- }
26
- function getCurrentBranch(executor) {
27
- const result = executor.exec('git branch --show-current');
28
- if (!result.success) {
29
- throw new Error(`获取当前分支失败: ${result.stderr}`);
30
- }
31
- return result.stdout.trim();
32
- }
33
- export function checkBranch(executor, logger, options = {}) {
34
- const { allowedBranches = ['main', 'master'], force = false } = options;
35
- try {
36
- const gitEnv = checkGitEnvironment(executor);
37
- if (!gitEnv.installed) {
38
- logger.error('Git 未安装,请先安装 Git');
39
- return false;
40
- }
41
- if (!gitEnv.userConfigured) {
42
- logger.error('Git 用户信息未配置,请先配置用户名和邮箱');
43
- return false;
44
- }
45
- if (!gitEnv.inRepository) {
46
- logger.error('当前目录不是 Git 仓库');
47
- return false;
48
- }
49
- logger.info('检查当前分支...');
50
- const currentBranch = getCurrentBranch(executor);
51
- if (!allowedBranches.includes(currentBranch)) {
52
- const message = `当前在分支 '${currentBranch}',建议在主分支发布`;
53
- if (force) {
54
- logger.warn(`${message}(已强制继续)`);
55
- return true;
56
- }
57
- else {
58
- logger.error(`${message},使用 --force 参数强制发布`);
59
- return false;
60
- }
61
- }
62
- logger.info(`当前分支: ${currentBranch}`);
63
- return true;
64
- }
65
- catch (error) {
66
- const errorMessage = error instanceof Error ? error.message : String(error);
67
- logger.error(`无法获取当前分支信息: ${errorMessage}`);
68
- return false;
69
- }
70
- }
71
- //# sourceMappingURL=checkBranch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"checkBranch.js","sourceRoot":"","sources":["../../../src/functions/git/checkBranch.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { Git } from '../../../references/git.d';
2
- import type { LogEntry } from '../../../types/publish.d';
3
- export declare function checkWorkingDirectory(git: Git, logger?: (entry: LogEntry) => void): boolean;
@@ -1,41 +0,0 @@
1
- export function checkWorkingDirectory(git, logger) {
2
- try {
3
- logger?.({
4
- level: 'info',
5
- message: '检查 Git 工作目录状态...',
6
- timestamp: new Date()
7
- });
8
- const status = git.status();
9
- if (!status.clean) {
10
- const message = '工作目录不干净,请先提交或暂存所有更改';
11
- logger?.({
12
- level: 'error',
13
- message,
14
- timestamp: new Date(),
15
- details: {
16
- staged: status.staged,
17
- modified: status.modified,
18
- untracked: status.untracked
19
- }
20
- });
21
- return false;
22
- }
23
- logger?.({
24
- level: 'success',
25
- message: '工作目录干净',
26
- timestamp: new Date()
27
- });
28
- return true;
29
- }
30
- catch (error) {
31
- const message = '无法检查 Git 状态,请确保在 Git 仓库中运行';
32
- logger?.({
33
- level: 'error',
34
- message,
35
- timestamp: new Date(),
36
- details: error
37
- });
38
- return false;
39
- }
40
- }
41
- //# sourceMappingURL=checkWorkingDirectory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"checkWorkingDirectory.js","sourceRoot":"","sources":["../../../src/functions/git/checkWorkingDirectory.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,qBAAqB,CACnC,GAAQ,EACR,MAAkC;IAElC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,kBAAkB;YAC3B,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;QAE3B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,qBAAqB,CAAA;YACrC,MAAM,EAAE,CAAC;gBACP,KAAK,EAAE,OAAO;gBACd,OAAO;gBACP,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,OAAO,EAAE;oBACP,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,SAAS,EAAE,MAAM,CAAC,SAAS;iBAC5B;aACF,CAAC,CAAA;YACF,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,QAAQ;YACjB,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAA;QAEF,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,4BAA4B,CAAA;QAC5C,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,OAAO;YACd,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,OAAO,EAAE,KAAK;SACf,CAAC,CAAA;QACF,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
@@ -1,7 +0,0 @@
1
- import type { Git } from '../../../references/git.d';
2
- import type { LogEntry } from '../../../types/publish.d';
3
- export declare function createGitTag(git: Git, version: string, options?: {
4
- files?: string[];
5
- commitMessage?: string;
6
- tagMessage?: string;
7
- }, logger?: (entry: LogEntry) => void): boolean;
@@ -1,36 +0,0 @@
1
- export function createGitTag(git, version, options = {}, logger) {
2
- const { files = ['package.json'], commitMessage = `chore: bump version to ${version}`, tagMessage = `Release v${version}` } = options;
3
- try {
4
- logger?.({
5
- level: 'info',
6
- message: '创建 Git 提交和标签...',
7
- timestamp: new Date()
8
- });
9
- git.add(files);
10
- git.commit(commitMessage);
11
- git.createTag(`v${version}`, tagMessage);
12
- logger?.({
13
- level: 'success',
14
- message: `已创建标签 v${version}`,
15
- timestamp: new Date(),
16
- details: {
17
- version,
18
- commitMessage,
19
- tagMessage,
20
- files
21
- }
22
- });
23
- return true;
24
- }
25
- catch (error) {
26
- const message = '创建 Git 标签失败';
27
- logger?.({
28
- level: 'error',
29
- message,
30
- timestamp: new Date(),
31
- details: error
32
- });
33
- return false;
34
- }
35
- }
36
- //# sourceMappingURL=createGitTag.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createGitTag.js","sourceRoot":"","sources":["../../../src/functions/git/createGitTag.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,YAAY,CAC1B,GAAQ,EACR,OAAe,EACf,UAII,EAAE,EACN,MAAkC;IAElC,MAAM,EACJ,KAAK,GAAG,CAAC,cAAc,CAAC,EACxB,aAAa,GAAG,0BAA0B,OAAO,EAAE,EACnD,UAAU,GAAG,YAAY,OAAO,EAAE,EACnC,GAAG,OAAO,CAAA;IAEX,IAAI,CAAC;QACH,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,iBAAiB;YAC1B,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAA;QAGF,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAGd,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QAGzB,GAAG,CAAC,SAAS,CAAC,IAAI,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;QAExC,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,UAAU,OAAO,EAAE;YAC5B,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,OAAO,EAAE;gBACP,OAAO;gBACP,aAAa;gBACb,UAAU;gBACV,KAAK;aACN;SACF,CAAC,CAAA;QAEF,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,aAAa,CAAA;QAC7B,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,OAAO;YACd,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,OAAO,EAAE,KAAK;SACf,CAAC,CAAA;QACF,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
@@ -1,34 +0,0 @@
1
- export interface CommandResult {
2
- exitCode: number;
3
- stdout: string;
4
- stderr: string;
5
- success: boolean;
6
- }
7
- export interface ExecOptions {
8
- cwd?: string;
9
- env?: Record<string, string>;
10
- timeout?: number;
11
- }
12
- export interface Executor {
13
- exec(command: string, options?: ExecOptions): CommandResult;
14
- }
15
- export interface Logger {
16
- info(message: string): void;
17
- error(message: string): void;
18
- warn(message: string): void;
19
- debug(message: string): void;
20
- }
21
- export interface PushOptions extends ExecOptions {
22
- remote?: string;
23
- branch?: string;
24
- pushTags?: boolean;
25
- force?: boolean;
26
- }
27
- export interface PushResult {
28
- success: boolean;
29
- branch: string;
30
- remote: string;
31
- tagsPushed: boolean;
32
- error?: string;
33
- }
34
- export declare function pushToRemote(executor: Executor, logger: Logger, options?: PushOptions): Promise<PushResult>;
@@ -1,51 +0,0 @@
1
- function getCurrentBranch(executor, options) {
2
- const result = executor.exec('git branch --show-current', options);
3
- if (!result.success) {
4
- throw new Error(`获取当前分支失败: ${result.stderr}`);
5
- }
6
- return result.stdout.trim();
7
- }
8
- export async function pushToRemote(executor, logger, options = {}) {
9
- const { remote = 'origin', branch, pushTags = false, force = false, ...execOptions } = options;
10
- try {
11
- const targetBranch = branch || getCurrentBranch(executor, execOptions);
12
- logger.info(`开始推送到远程仓库: ${remote}/${targetBranch}`);
13
- let pushCommand = `git push ${remote} ${targetBranch}`;
14
- if (force) {
15
- pushCommand = `git push --force ${remote} ${targetBranch}`;
16
- }
17
- const pushResult = executor.exec(pushCommand, execOptions);
18
- if (!pushResult.success) {
19
- throw new Error(`推送分支失败: ${pushResult.stderr}`);
20
- }
21
- logger.info(`成功推送分支: ${targetBranch}`);
22
- let tagsPushed = false;
23
- if (pushTags) {
24
- const tagCommand = `git push --tags ${remote}`;
25
- const tagResult = executor.exec(tagCommand, execOptions);
26
- if (!tagResult.success) {
27
- throw new Error(`推送标签失败: ${tagResult.stderr}`);
28
- }
29
- tagsPushed = true;
30
- logger.info(`成功推送标签到: ${remote}`);
31
- }
32
- return {
33
- success: true,
34
- branch: targetBranch,
35
- remote,
36
- tagsPushed
37
- };
38
- }
39
- catch (error) {
40
- const errorMessage = error instanceof Error ? error.message : String(error);
41
- logger.error(`推送失败: ${errorMessage}`);
42
- return {
43
- success: false,
44
- branch: branch || 'unknown',
45
- remote,
46
- tagsPushed: false,
47
- error: errorMessage
48
- };
49
- }
50
- }
51
- //# sourceMappingURL=pushToRemote.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pushToRemote.js","sourceRoot":"","sources":["../../../src/functions/git/pushToRemote.ts"],"names":[],"mappings":"AAqFA,SAAS,gBAAgB,CAAC,QAAkB,EAAE,OAAqB;IACjE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAA;IAClE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;AAC7B,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAkB,EAClB,MAAc,EACd,UAAuB,EAAE;IAEzB,MAAM,EACJ,MAAM,GAAG,QAAQ,EACjB,MAAM,EACN,QAAQ,GAAG,KAAK,EAChB,KAAK,GAAG,KAAK,EACb,GAAG,WAAW,EACf,GAAG,OAAO,CAAA;IAEX,IAAI,CAAC;QAEH,MAAM,YAAY,GAAG,MAAM,IAAI,gBAAgB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;QAEtE,MAAM,CAAC,IAAI,CAAC,cAAc,MAAM,IAAI,YAAY,EAAE,CAAC,CAAA;QAGnD,IAAI,WAAW,GAAG,YAAY,MAAM,IAAI,YAAY,EAAE,CAAA;QACtD,IAAI,KAAK,EAAE,CAAC;YACV,WAAW,GAAG,oBAAoB,MAAM,IAAI,YAAY,EAAE,CAAA;QAC5D,CAAC;QAGD,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QAC1D,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,WAAW,UAAU,CAAC,MAAM,EAAE,CAAC,CAAA;QACjD,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,WAAW,YAAY,EAAE,CAAC,CAAA;QAGtC,IAAI,UAAU,GAAG,KAAK,CAAA;QACtB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,UAAU,GAAG,mBAAmB,MAAM,EAAE,CAAA;YAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;YACxD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;YAChD,CAAC;YACD,UAAU,GAAG,IAAI,CAAA;YACjB,MAAM,CAAC,IAAI,CAAC,YAAY,MAAM,EAAE,CAAC,CAAA;QACnC,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,YAAY;YACpB,MAAM;YACN,UAAU;SACX,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3E,MAAM,CAAC,KAAK,CAAC,SAAS,YAAY,EAAE,CAAC,CAAA;QAErC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,MAAM,IAAI,SAAS;YAC3B,MAAM;YACN,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,YAAY;SACpB,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { FileSystem } from '../../../references/node.d';
2
- import type { PackageInfo, LogEntry } from '../../../types/publish.d';
3
- export declare function readPackageInfo(fs: FileSystem, packagePath?: string, logger?: (entry: LogEntry) => void): PackageInfo;
@@ -1,53 +0,0 @@
1
- export function readPackageInfo(fs, packagePath = 'package.json', logger) {
2
- try {
3
- logger?.({
4
- level: 'info',
5
- message: `读取包信息: ${packagePath}`,
6
- timestamp: new Date()
7
- });
8
- if (!fs.existsSync(packagePath)) {
9
- throw new Error(`package.json 文件不存在: ${packagePath}`);
10
- }
11
- const content = fs.readFileSync(packagePath, 'utf8');
12
- const packageJson = JSON.parse(content);
13
- const packageInfo = {
14
- name: packageJson.name || '',
15
- version: packageJson.version || '0.0.0',
16
- description: packageJson.description || '',
17
- main: packageJson.main,
18
- scripts: packageJson.scripts || {},
19
- dependencies: packageJson.dependencies || {},
20
- devDependencies: packageJson.devDependencies || {},
21
- peerDependencies: packageJson.peerDependencies || {},
22
- keywords: packageJson.keywords || [],
23
- author: packageJson.author,
24
- license: packageJson.license,
25
- repository: packageJson.repository,
26
- bugs: packageJson.bugs,
27
- homepage: packageJson.homepage,
28
- private: packageJson.private || false
29
- };
30
- logger?.({
31
- level: 'success',
32
- message: `已读取包信息: ${packageInfo.name}@${packageInfo.version}`,
33
- timestamp: new Date(),
34
- details: {
35
- name: packageInfo.name,
36
- version: packageInfo.version,
37
- private: packageInfo.private
38
- }
39
- });
40
- return packageInfo;
41
- }
42
- catch (error) {
43
- const message = `读取包信息失败: ${packagePath}`;
44
- logger?.({
45
- level: 'error',
46
- message,
47
- timestamp: new Date(),
48
- details: error
49
- });
50
- throw new Error(message);
51
- }
52
- }
53
- //# sourceMappingURL=readPackageInfo.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"readPackageInfo.js","sourceRoot":"","sources":["../../../src/functions/package/readPackageInfo.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,eAAe,CAC7B,EAAc,EACd,cAAsB,cAAc,EACpC,MAAkC;IAElC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,UAAU,WAAW,EAAE;YAChC,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAA;QAEF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,EAAE,CAAC,CAAA;QACvD,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QACpD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAEvC,MAAM,WAAW,GAAgB;YAC/B,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,EAAE;YAC5B,OAAO,EAAE,WAAW,CAAC,OAAO,IAAI,OAAO;YACvC,WAAW,EAAE,WAAW,CAAC,WAAW,IAAI,EAAE;YAC1C,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,OAAO,EAAE,WAAW,CAAC,OAAO,IAAI,EAAE;YAClC,YAAY,EAAE,WAAW,CAAC,YAAY,IAAI,EAAE;YAC5C,eAAe,EAAE,WAAW,CAAC,eAAe,IAAI,EAAE;YAClD,gBAAgB,EAAE,WAAW,CAAC,gBAAgB,IAAI,EAAE;YACpD,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI,EAAE;YACpC,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,UAAU,EAAE,WAAW,CAAC,UAAU;YAClC,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,OAAO,EAAE,WAAW,CAAC,OAAO,IAAI,KAAK;SACtC,CAAA;QAED,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,WAAW,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,EAAE;YAC7D,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,OAAO,EAAE;gBACP,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,OAAO,EAAE,WAAW,CAAC,OAAO;aAC7B;SACF,CAAC,CAAA;QAEF,OAAO,WAAW,CAAA;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,YAAY,WAAW,EAAE,CAAA;QACzC,MAAM,EAAE,CAAC;YACP,KAAK,EAAE,OAAO;YACd,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,OAAO,EAAE,KAAK;SACf,CAAC,CAAA;QACF,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC"}