fix ts
This commit is contained in:
@@ -2,13 +2,14 @@ import { KintoneRestAPIClient } from "@kintone/rest-api-client";
|
|||||||
import type { KintoneRestAPIError } from "@kintone/rest-api-client";
|
import type { KintoneRestAPIError } from "@kintone/rest-api-client";
|
||||||
import type { DomainWithPassword } from "@shared/types/domain";
|
import type { DomainWithPassword } from "@shared/types/domain";
|
||||||
import type {
|
import type {
|
||||||
KintoneApp,
|
AppResponse,
|
||||||
|
AppsResponse,
|
||||||
|
AppCustomizeResponse,
|
||||||
AppDetail,
|
AppDetail,
|
||||||
FileContent,
|
FileContent,
|
||||||
AppCustomizationConfig,
|
AppCustomizationConfig,
|
||||||
KintoneApiError,
|
KintoneApiError,
|
||||||
JSFileConfig,
|
FileConfig,
|
||||||
CSSFileConfig,
|
|
||||||
} from "@shared/types/kintone";
|
} from "@shared/types/kintone";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,12 +33,6 @@ export class KintoneError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use typeof to get SDK method return types
|
|
||||||
type KintoneClient = KintoneRestAPIClient;
|
|
||||||
type AppResponse = ReturnType<KintoneClient["app"]["getApp"]>;
|
|
||||||
type AppsResponse = ReturnType<KintoneClient["app"]["getApps"]>;
|
|
||||||
type AppCustomizeResponse = ReturnType<KintoneClient["app"]["getAppCustomize"]>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kintone REST API Client
|
* Kintone REST API Client
|
||||||
*/
|
*/
|
||||||
@@ -87,48 +82,24 @@ export class SelfKintoneClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private mapApp(app: Awaited<AppResponse>): KintoneApp {
|
|
||||||
return {
|
|
||||||
appId: app.appId,
|
|
||||||
name: app.name,
|
|
||||||
code: app.code,
|
|
||||||
spaceId: app.spaceId || undefined,
|
|
||||||
createdAt: app.createdAt,
|
|
||||||
creator: app.creator,
|
|
||||||
modifiedAt: app.modifiedAt,
|
|
||||||
modifier: app.modifier,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private mapResource(
|
private mapResource(
|
||||||
resource:
|
resource:
|
||||||
| Awaited<AppCustomizeResponse>["desktop"]["js"][number]
|
| Awaited<AppCustomizeResponse>["desktop"]["js"][number]
|
||||||
| Awaited<AppCustomizeResponse>["desktop"]["css"][number],
|
| Awaited<AppCustomizeResponse>["desktop"]["css"][number],
|
||||||
): JSFileConfig | CSSFileConfig {
|
): FileConfig {
|
||||||
if (resource.type === "FILE") {
|
// Return SDK type directly - no conversion needed
|
||||||
return {
|
return resource;
|
||||||
type: "FILE",
|
|
||||||
file: {
|
|
||||||
fileKey: resource.file.fileKey,
|
|
||||||
name: resource.file.name,
|
|
||||||
size: parseInt(resource.file.size, 10),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: "URL",
|
|
||||||
url: resource.url,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildCustomizeSection(
|
private buildCustomizeSection(
|
||||||
js?: JSFileConfig[],
|
js?: FileConfig[],
|
||||||
css?: CSSFileConfig[],
|
css?: FileConfig[],
|
||||||
): Parameters<KintoneClient["app"]["updateAppCustomize"]>[0]["desktop"] {
|
): Parameters<
|
||||||
|
KintoneRestAPIClient["app"]["updateAppCustomize"]
|
||||||
|
>[0]["desktop"] {
|
||||||
if (!js && !css) return undefined;
|
if (!js && !css) return undefined;
|
||||||
|
|
||||||
const mapItem = (item: JSFileConfig | CSSFileConfig) => {
|
const mapItem = (item: FileConfig) => {
|
||||||
if (item.type === "FILE" && item.file) {
|
if (item.type === "FILE" && item.file) {
|
||||||
return { type: "FILE" as const, file: { fileKey: item.file.fileKey } };
|
return { type: "FILE" as const, file: { fileKey: item.file.fileKey } };
|
||||||
}
|
}
|
||||||
@@ -150,7 +121,7 @@ export class SelfKintoneClient {
|
|||||||
async getApps(options?: {
|
async getApps(options?: {
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
}): Promise<KintoneApp[]> {
|
}): Promise<AppResponse[]> {
|
||||||
return this.withErrorHandling(async () => {
|
return this.withErrorHandling(async () => {
|
||||||
// If pagination options provided, use them directly
|
// If pagination options provided, use them directly
|
||||||
if (options?.limit !== undefined || options?.offset !== undefined) {
|
if (options?.limit !== undefined || options?.offset !== undefined) {
|
||||||
@@ -158,11 +129,11 @@ export class SelfKintoneClient {
|
|||||||
if (options.limit) params.limit = options.limit;
|
if (options.limit) params.limit = options.limit;
|
||||||
if (options.offset) params.offset = options.offset;
|
if (options.offset) params.offset = options.offset;
|
||||||
const response = await this.client.app.getApps(params);
|
const response = await this.client.app.getApps(params);
|
||||||
return response.apps.map((app) => this.mapApp(app));
|
return response.apps;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, fetch all apps (pagination handled internally)
|
// Otherwise, fetch all apps (pagination handled internally)
|
||||||
const allApps: Awaited<AppsResponse>["apps"] = [];
|
const allApps: AppResponse[] = [];
|
||||||
const limit = 100; // Max allowed by Kintone API
|
const limit = 100; // Max allowed by Kintone API
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
let hasMore = true;
|
let hasMore = true;
|
||||||
@@ -179,7 +150,7 @@ export class SelfKintoneClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return allApps.map((app) => this.mapApp(app));
|
return allApps;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +174,6 @@ export class SelfKintoneClient {
|
|||||||
mobile:
|
mobile:
|
||||||
customizeInfo.mobile.css?.map((css) => this.mapResource(css)) || [],
|
customizeInfo.mobile.css?.map((css) => this.mapResource(css)) || [],
|
||||||
},
|
},
|
||||||
plugins: [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
10
src/preload/index.d.ts
vendored
10
src/preload/index.d.ts
vendored
@@ -16,9 +16,10 @@ import type {
|
|||||||
} from "@shared/types/ipc";
|
} from "@shared/types/ipc";
|
||||||
import type { Domain, DomainWithStatus } from "@shared/types/domain";
|
import type { Domain, DomainWithStatus } from "@shared/types/domain";
|
||||||
import type {
|
import type {
|
||||||
KintoneApp,
|
AppResponse,
|
||||||
AppDetail,
|
AppDetail,
|
||||||
FileContent,
|
FileContent,
|
||||||
|
KintoneSpace,
|
||||||
} from "@shared/types/kintone";
|
} from "@shared/types/kintone";
|
||||||
import type { Version } from "@shared/types/version";
|
import type { Version } from "@shared/types/version";
|
||||||
|
|
||||||
@@ -39,10 +40,13 @@ export interface SelfAPI {
|
|||||||
updateDomain: (params: UpdateDomainParams) => Promise<Result<Domain>>;
|
updateDomain: (params: UpdateDomainParams) => Promise<Result<Domain>>;
|
||||||
deleteDomain: (id: string) => Promise<Result<void>>;
|
deleteDomain: (id: string) => Promise<Result<void>>;
|
||||||
testConnection: (id: string) => Promise<Result<DomainWithStatus>>;
|
testConnection: (id: string) => Promise<Result<DomainWithStatus>>;
|
||||||
testDomainConnection: (params: TestDomainConnectionParams) => Promise<Result<boolean>>;
|
testDomainConnection: (
|
||||||
|
params: TestDomainConnectionParams,
|
||||||
|
) => Promise<Result<boolean>>;
|
||||||
|
|
||||||
// ==================== Browse ====================
|
// ==================== Browse ====================
|
||||||
getApps: (params: GetAppsParams) => Promise<Result<KintoneApp[]>>;
|
getSpaces: (params: { domainId: string }) => Promise<Result<KintoneSpace[]>>;
|
||||||
|
getApps: (params: GetAppsParams) => Promise<Result<AppResponse[]>>;
|
||||||
getAppDetail: (params: GetAppDetailParams) => Promise<Result<AppDetail>>;
|
getAppDetail: (params: GetAppDetailParams) => Promise<Result<AppDetail>>;
|
||||||
getFileContent: (
|
getFileContent: (
|
||||||
params: GetFileContentParams,
|
params: GetFileContentParams,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { createStyles } from "antd-style";
|
|||||||
import { useAppStore } from "@renderer/stores";
|
import { useAppStore } from "@renderer/stores";
|
||||||
import { useDomainStore } from "@renderer/stores";
|
import { useDomainStore } from "@renderer/stores";
|
||||||
import { CodeViewer } from "../CodeViewer";
|
import { CodeViewer } from "../CodeViewer";
|
||||||
import { JSFileConfig, CSSFileConfig } from "@shared/types/kintone";
|
import { FileConfig } from "@shared/types/kintone";
|
||||||
|
|
||||||
const useStyles = createStyles(({ token, css }) => ({
|
const useStyles = createStyles(({ token, css }) => ({
|
||||||
container: css`
|
container: css`
|
||||||
@@ -168,7 +168,7 @@ const AppDetail: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const renderFileList = (
|
const renderFileList = (
|
||||||
files: (JSFileConfig | CSSFileConfig)[] | undefined,
|
files: (FileConfig)[] | undefined,
|
||||||
type: "js" | "css",
|
type: "js" | "css",
|
||||||
) => {
|
) => {
|
||||||
if (!files || files.length === 0) {
|
if (!files || files.length === 0) {
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { persist } from "zustand/middleware";
|
import { persist } from "zustand/middleware";
|
||||||
import type { KintoneApp, AppDetail } from "@shared/types/kintone";
|
import type { AppResponse, AppDetail } from "@shared/types/kintone";
|
||||||
|
|
||||||
interface AppState {
|
interface AppState {
|
||||||
// State
|
// State
|
||||||
apps: KintoneApp[];
|
apps: AppResponse[];
|
||||||
currentApp: AppDetail | null;
|
currentApp: AppDetail | null;
|
||||||
selectedAppId: string | null;
|
selectedAppId: string | null;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
@@ -27,7 +27,7 @@ interface AppState {
|
|||||||
loadedAt: string | null;
|
loadedAt: string | null;
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
setApps: (apps: KintoneApp[]) => void;
|
setApps: (apps: AppResponse[]) => void;
|
||||||
setCurrentApp: (app: AppDetail | null) => void;
|
setCurrentApp: (app: AppDetail | null) => void;
|
||||||
setSelectedAppId: (id: string | null) => void;
|
setSelectedAppId: (id: string | null) => void;
|
||||||
setLoading: (loading: boolean) => void;
|
setLoading: (loading: boolean) => void;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
import type { Domain, DomainWithPassword, DomainWithStatus } from "./domain";
|
import type { Domain, DomainWithPassword, DomainWithStatus } from "./domain";
|
||||||
import type {
|
import type {
|
||||||
|
AppResponse,
|
||||||
KintoneSpace,
|
KintoneSpace,
|
||||||
KintoneApp,
|
|
||||||
AppDetail,
|
AppDetail,
|
||||||
FileContent,
|
FileContent,
|
||||||
} from "./kintone";
|
} from "./kintone";
|
||||||
@@ -136,11 +136,13 @@ export interface ElectronAPI {
|
|||||||
updateDomain: (params: UpdateDomainParams) => Promise<Result<Domain>>;
|
updateDomain: (params: UpdateDomainParams) => Promise<Result<Domain>>;
|
||||||
deleteDomain: (id: string) => Promise<Result<void>>;
|
deleteDomain: (id: string) => Promise<Result<void>>;
|
||||||
testConnection: (id: string) => Promise<Result<DomainWithStatus>>;
|
testConnection: (id: string) => Promise<Result<DomainWithStatus>>;
|
||||||
testDomainConnection: (params: TestDomainConnectionParams) => Promise<Result<boolean>>;
|
testDomainConnection: (
|
||||||
|
params: TestDomainConnectionParams,
|
||||||
|
) => Promise<Result<boolean>>;
|
||||||
|
|
||||||
// Browse
|
// Browse
|
||||||
getSpaces: (params: GetSpacesParams) => Promise<Result<KintoneSpace[]>>;
|
getSpaces: (params: GetSpacesParams) => Promise<Result<KintoneSpace[]>>;
|
||||||
getApps: (params: GetAppsParams) => Promise<Result<KintoneApp[]>>;
|
getApps: (params: GetAppsParams) => Promise<Result<AppResponse[]>>;
|
||||||
getAppDetail: (params: GetAppDetailParams) => Promise<Result<AppDetail>>;
|
getAppDetail: (params: GetAppDetailParams) => Promise<Result<AppDetail>>;
|
||||||
getFileContent: (
|
getFileContent: (
|
||||||
params: GetFileContentParams,
|
params: GetFileContentParams,
|
||||||
|
|||||||
@@ -1,100 +1,45 @@
|
|||||||
/**
|
/**
|
||||||
* Kintone API response types
|
* Kintone API response types
|
||||||
* Based on REQUIREMENTS.md:331-345
|
* Using SDK types where possible, custom types only for business-layer aggregation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Space types
|
import type { KintoneRestAPIClient } from "@kintone/rest-api-client";
|
||||||
export interface KintoneSpace {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
code: string;
|
|
||||||
createdAt?: string;
|
|
||||||
creator?: {
|
|
||||||
code: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// App types
|
// ==================== SDK Type Extraction ====================
|
||||||
export interface KintoneApp {
|
// Use typeof + ReturnType to extract types from SDK methods
|
||||||
appId: string;
|
type KintoneClient = KintoneRestAPIClient;
|
||||||
name: string;
|
|
||||||
code?: string;
|
|
||||||
spaceId?: string;
|
|
||||||
createdAt: string;
|
|
||||||
creator?: {
|
|
||||||
code: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
modifiedAt?: string;
|
|
||||||
modifier?: {
|
|
||||||
code: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// File configuration types
|
/** App response from getApp/getApps */
|
||||||
export interface JSFileConfig {
|
export type AppResponse = Awaited<ReturnType<KintoneClient["app"]["getApp"]>>;
|
||||||
type: "FILE" | "URL";
|
|
||||||
file?: {
|
|
||||||
fileKey: string;
|
|
||||||
name?: string; // Optional for deploy, filled by Kintone
|
|
||||||
size?: number; // Optional for deploy, filled by Kintone
|
|
||||||
};
|
|
||||||
url?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CSSFileConfig {
|
/** Apps list response */
|
||||||
type: "FILE" | "URL";
|
export type AppsResponse = Awaited<ReturnType<KintoneClient["app"]["getApps"]>>;
|
||||||
file?: {
|
|
||||||
fileKey: string;
|
|
||||||
name?: string; // Optional for deploy, filled by Kintone
|
|
||||||
size?: number; // Optional for deploy, filled by Kintone
|
|
||||||
};
|
|
||||||
url?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// App customization config
|
/** App customization response */
|
||||||
export interface AppCustomizationConfig {
|
export type AppCustomizeResponse = Awaited<
|
||||||
javascript?: {
|
ReturnType<KintoneClient["app"]["getAppCustomize"]>
|
||||||
pc?: JSFileConfig[];
|
>;
|
||||||
mobile?: JSFileConfig[];
|
|
||||||
};
|
|
||||||
stylesheet?: {
|
|
||||||
pc?: CSSFileConfig[];
|
|
||||||
mobile?: CSSFileConfig[];
|
|
||||||
};
|
|
||||||
plugins?: AppPlugin[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AppPlugin {
|
/** File upload response */
|
||||||
id: string;
|
export type FileUploadResponse = Awaited<
|
||||||
name: string;
|
ReturnType<KintoneClient["file"]["uploadFile"]>
|
||||||
enabled: boolean;
|
>;
|
||||||
}
|
|
||||||
|
|
||||||
// App detail response
|
// ==================== Custom Business Types ====================
|
||||||
export interface AppDetail {
|
// These types represent business-layer aggregation or additional metadata
|
||||||
appId: string;
|
|
||||||
name: string;
|
/**
|
||||||
code?: string;
|
* App detail - combines app info + customization
|
||||||
description?: string;
|
* This is a business-layer type that aggregates data from multiple API calls
|
||||||
spaceId?: string;
|
*/
|
||||||
spaceName?: string;
|
export interface AppDetail extends AppResponse {
|
||||||
createdAt: string;
|
|
||||||
creator: {
|
|
||||||
code: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
modifiedAt: string;
|
|
||||||
modifier: {
|
|
||||||
code: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
customization?: AppCustomizationConfig;
|
customization?: AppCustomizationConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// File content
|
/**
|
||||||
|
* File content - file metadata + content
|
||||||
|
* SDK's downloadFile only returns ArrayBuffer, we add metadata
|
||||||
|
*/
|
||||||
export interface FileContent {
|
export interface FileContent {
|
||||||
fileKey: string;
|
fileKey: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -103,7 +48,31 @@ export interface FileContent {
|
|||||||
content?: string; // Base64 encoded or text
|
content?: string; // Base64 encoded or text
|
||||||
}
|
}
|
||||||
|
|
||||||
// API Error
|
/**
|
||||||
|
* App customization config
|
||||||
|
* Uses SDK's customize types structure (desktop/mobile) but simplified for internal use
|
||||||
|
* Note: SDK uses { js: [], css: [] } but we use { javascript: { pc, mobile } } for easier UI binding
|
||||||
|
*/
|
||||||
|
export interface AppCustomizationConfig {
|
||||||
|
javascript?: {
|
||||||
|
pc?: FileConfig[];
|
||||||
|
mobile?: FileConfig[];
|
||||||
|
};
|
||||||
|
stylesheet?: {
|
||||||
|
pc?: FileConfig[];
|
||||||
|
mobile?: FileConfig[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File config for customization
|
||||||
|
* Using SDK's type directly from AppCustomizeResponse
|
||||||
|
*/
|
||||||
|
export type FileConfig = Awaited<AppCustomizeResponse>["desktop"]["js"][number];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API Error - simplified from SDK's KintoneRestAPIError
|
||||||
|
*/
|
||||||
export interface KintoneApiError {
|
export interface KintoneApiError {
|
||||||
code: string;
|
code: string;
|
||||||
message: string;
|
message: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user