@yoonion/mimi-seed-mcp 0.13.10 → 0.13.12
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.
- package/dist/admob/tools.d.ts +2 -2
- package/dist/admob/tools.js +1 -1
- package/dist/appstore/tools.d.ts +29 -6
- package/dist/appstore/tools.js +136 -56
- package/dist/auth/google-auth.js +1 -1
- package/dist/bigquery/tools.js +1 -1
- package/dist/firebase/tools.d.ts +11 -11
- package/dist/firebase/tools.js +1 -1
- package/dist/ga4/tools.d.ts +5 -5
- package/dist/ga4/tools.js +1 -1
- package/dist/gsc/tools.d.ts +5 -5
- package/dist/gsc/tools.js +1 -1
- package/dist/iam/tools.js +1 -1
- package/dist/lib/googleapis-lite.d.ts +39 -0
- package/dist/lib/googleapis-lite.js +38 -0
- package/dist/playstore/tools.d.ts +15 -15
- package/dist/playstore/tools.js +1 -1
- package/dist/registers/appstore.js +64 -13
- package/dist/video/youtube-publish.d.ts +1 -1
- package/dist/video/youtube-publish.js +1 -1
- package/package.json +1 -1
- package/tool-manifest.json +3 -1
package/dist/admob/tools.d.ts
CHANGED
|
@@ -33,8 +33,8 @@ export declare function getNetworkReport(auth: OAuth2Client, accountId: string,
|
|
|
33
33
|
year: number;
|
|
34
34
|
month: number;
|
|
35
35
|
day: number;
|
|
36
|
-
}): Promise<import("googleapis").admob_v1.Schema$GenerateNetworkReportResponse>;
|
|
37
|
-
export declare function getTodayEarnings(auth: OAuth2Client, accountId: string): Promise<import("googleapis").admob_v1.Schema$GenerateNetworkReportResponse>;
|
|
36
|
+
}): Promise<import("googleapis/build/src/apis/admob/v1.js").admob_v1.Schema$GenerateNetworkReportResponse>;
|
|
37
|
+
export declare function getTodayEarnings(auth: OAuth2Client, accountId: string): Promise<import("googleapis/build/src/apis/admob/v1.js").admob_v1.Schema$GenerateNetworkReportResponse>;
|
|
38
38
|
export type AdFormat = 'BANNER' | 'INTERSTITIAL' | 'REWARDED' | 'REWARDED_INTERSTITIAL' | 'APP_OPEN' | 'NATIVE';
|
|
39
39
|
/**
|
|
40
40
|
* adFormat → adTypes 파생 (순수 함수 — 테스트 대상).
|
package/dist/admob/tools.js
CHANGED
package/dist/appstore/tools.d.ts
CHANGED
|
@@ -170,18 +170,41 @@ export declare function submitVersionForReview(versionId: string): Promise<{
|
|
|
170
170
|
state: any;
|
|
171
171
|
}>;
|
|
172
172
|
export declare function addProductToReviewSubmission(args: {
|
|
173
|
-
appId: string;
|
|
174
173
|
internalId: string;
|
|
175
174
|
productType: AppStoreProductType;
|
|
175
|
+
}): Promise<{
|
|
176
|
+
internalId: string;
|
|
177
|
+
productType: AppStoreProductType;
|
|
178
|
+
endpoint: string;
|
|
179
|
+
submissionId?: string;
|
|
180
|
+
}>;
|
|
181
|
+
export interface ReviewSubmissionSummary {
|
|
182
|
+
id: string;
|
|
183
|
+
state?: string;
|
|
184
|
+
submittedDate: string | null;
|
|
185
|
+
items: Array<{
|
|
186
|
+
id: string;
|
|
187
|
+
state?: string;
|
|
188
|
+
targetType?: string;
|
|
189
|
+
targetId?: string;
|
|
190
|
+
versionString?: string;
|
|
191
|
+
appVersionState?: string;
|
|
192
|
+
}>;
|
|
193
|
+
}
|
|
194
|
+
export declare function listReviewSubmissions(args: {
|
|
195
|
+
appId: string;
|
|
176
196
|
platform?: string;
|
|
197
|
+
limit?: number;
|
|
177
198
|
}): Promise<{
|
|
178
|
-
submissionId: string;
|
|
179
199
|
appId: string;
|
|
180
200
|
platform: string;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
submissions: ReviewSubmissionSummary[];
|
|
202
|
+
}>;
|
|
203
|
+
/** 묶음에서 항목 제거 (removed=true PATCH). ASC 웹 "재제출" 이 내부적으로 하는 그 동작. */
|
|
204
|
+
export declare function removeReviewSubmissionItem(itemId: string): Promise<{
|
|
205
|
+
itemId: string;
|
|
206
|
+
state?: string;
|
|
207
|
+
removed: boolean;
|
|
185
208
|
}>;
|
|
186
209
|
export declare function cancelVersionReview(versionId: string): Promise<{
|
|
187
210
|
submissionId: string;
|
package/dist/appstore/tools.js
CHANGED
|
@@ -649,13 +649,23 @@ export async function submitVersionForReview(versionId) {
|
|
|
649
649
|
});
|
|
650
650
|
}
|
|
651
651
|
catch (error) {
|
|
652
|
-
if (!
|
|
652
|
+
if (!isItemAddRejected(error))
|
|
653
|
+
throw error;
|
|
654
|
+
// 2026-07-24 실측 (PenguinRun 2.0.4 재제출): 버전은 PREPARE_FOR_SUBMISSION 인데도
|
|
655
|
+
// attach 가 "appStoreVersions ... is not in valid state" 로 거부되는 케이스의 진범은
|
|
656
|
+
// 거절된 옛 묶음(UNRESOLVED_ISSUES)이 이 버전을 REJECTED 항목으로 물고 있는 것.
|
|
657
|
+
// 항목을 removed=true 로 풀면 옛 묶음이 COMPLETE 로 정리되고 attach 가 뚫린다.
|
|
658
|
+
const released = await releaseVersionFromStaleSubmissions(appId, platform, versionId);
|
|
659
|
+
if (!released && !reusedSubmission)
|
|
653
660
|
throw error;
|
|
654
|
-
// 재사용하려던 묶음이 실제로는 잠겨 있었다 — 새 묶음을 만들어 한 번만 재시도한다.
|
|
655
|
-
submissionId = await createReviewSubmission(appId, platform);
|
|
656
|
-
reusedSubmission = false;
|
|
657
661
|
recoveredFromStaleSubmission = true;
|
|
662
|
+
reusedSubmission = false;
|
|
658
663
|
alreadyAttached = false;
|
|
664
|
+
// 항목 해제 뒤 Apple 이 READY_FOR_REVIEW 초안을 자동 생성하기도 한다 (실측) —
|
|
665
|
+
// 초안이 있는데 또 만들면 충돌하므로 재조회 후 없을 때만 생성한다.
|
|
666
|
+
submissionId =
|
|
667
|
+
(await findDraftReviewSubmission(appId, platform)) ??
|
|
668
|
+
(await createReviewSubmission(appId, platform));
|
|
659
669
|
await apiPost('/reviewSubmissionItems', {
|
|
660
670
|
data: {
|
|
661
671
|
type: 'reviewSubmissionItems',
|
|
@@ -686,29 +696,68 @@ export async function submitVersionForReview(versionId) {
|
|
|
686
696
|
state: submitted?.data?.attributes?.state ?? 'WAITING_FOR_REVIEW',
|
|
687
697
|
};
|
|
688
698
|
}
|
|
689
|
-
// ─── IAP
|
|
699
|
+
// ─── IAP/구독 상품 심사 제출 ───
|
|
690
700
|
//
|
|
691
|
-
//
|
|
692
|
-
//
|
|
701
|
+
// ⚠️ 2026-07-24 실측 (PenguinRun 첫 출시): reviewSubmissionItems 는 appStoreVersion 계열
|
|
702
|
+
// 관계만 받는다. inAppPurchaseV2 / inAppPurchase / subscription 관계는 전부
|
|
703
|
+
// ENTITY_ERROR.RELATIONSHIP.UNKNOWN 으로 거부된다 — 즉 App Store Connect 웹의
|
|
704
|
+
// "버전과 함께 제출할 상품 담기" 는 공개 API 에 존재하지 않는다.
|
|
693
705
|
//
|
|
694
|
-
//
|
|
695
|
-
//
|
|
696
|
-
//
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
706
|
+
// 공개 API 가 제공하는 것은 상품 **단독** 제출뿐이다:
|
|
707
|
+
// consumable / non_consumable → POST /v1/inAppPurchaseSubmissions (관계 inAppPurchaseV2)
|
|
708
|
+
// subscription → POST /v1/subscriptionSubmissions (관계 subscription)
|
|
709
|
+
// 이 엔드포인트는 상품에 pending version 이 있어야 동작한다 — 한 번 승인된 뒤의 변경분
|
|
710
|
+
// 제출용. 앱 **첫 심사** 에 상품을 끼워 넣는 것은 ASC 웹 버전 페이지에서만 가능하며,
|
|
711
|
+
// 그 경우 Apple 이 409 "no pending version for submission" 을 반환한다 (실측 동일 문구).
|
|
712
|
+
function isNoPendingVersionError(error) {
|
|
713
|
+
const cause = error?.cause;
|
|
714
|
+
if (cause?.status !== 409)
|
|
715
|
+
return false;
|
|
716
|
+
return (cause.parsedErrors ?? []).some((e) => (e.detail ?? '').toLowerCase().includes('no pending version'));
|
|
717
|
+
}
|
|
718
|
+
export async function addProductToReviewSubmission(args) {
|
|
719
|
+
const { internalId, productType } = args;
|
|
720
|
+
const isSubscription = productType === 'subscription';
|
|
721
|
+
const path = isSubscription ? '/subscriptionSubmissions' : '/inAppPurchaseSubmissions';
|
|
722
|
+
const body = isSubscription
|
|
723
|
+
? {
|
|
724
|
+
data: {
|
|
725
|
+
type: 'subscriptionSubmissions',
|
|
726
|
+
relationships: { subscription: { data: { type: 'subscriptions', id: internalId } } },
|
|
727
|
+
},
|
|
728
|
+
}
|
|
729
|
+
: {
|
|
730
|
+
data: {
|
|
731
|
+
type: 'inAppPurchaseSubmissions',
|
|
732
|
+
relationships: { inAppPurchaseV2: { data: { type: 'inAppPurchases', id: internalId } } },
|
|
733
|
+
},
|
|
734
|
+
};
|
|
735
|
+
try {
|
|
736
|
+
const created = await apiPost(path, body);
|
|
737
|
+
return { internalId, productType, endpoint: path, submissionId: created?.data?.id };
|
|
738
|
+
}
|
|
739
|
+
catch (error) {
|
|
740
|
+
if (!isNoPendingVersionError(error))
|
|
741
|
+
throw error;
|
|
742
|
+
const enriched = new Error([
|
|
743
|
+
`상품 ${internalId} (${productType}) 은 API 로 심사 제출할 수 없는 상태야 — Apple 응답: "no pending version for submission".`,
|
|
744
|
+
'',
|
|
745
|
+
'이건 보통 **앱 첫 심사** 케이스다. 한 번도 승인된 적 없는 상품은 공개 API 로 심사에 못 넣고,',
|
|
746
|
+
'App Store Connect 웹의 해당 버전 페이지 → "앱 내 구입 및 구독" 섹션에서 상품을 선택해',
|
|
747
|
+
'버전과 같은 묶음으로 제출해야 한다 (reviewSubmissionItems 는 상품 관계를 받지 않는다 — 2026-07 실측).',
|
|
748
|
+
'버전이 이미 심사 대기 중이면 appstore_cancel_review 로 내린 뒤 웹에서 담고 재제출한다.',
|
|
749
|
+
'이미 승인된 적 있는 상품이라면: 변경분(pending version)이 실제로 있는지 확인.',
|
|
750
|
+
].join('\n'));
|
|
751
|
+
enriched.cause = error.cause;
|
|
752
|
+
throw enriched;
|
|
700
753
|
}
|
|
701
|
-
return { key: 'inAppPurchaseV2', type: 'inAppPurchases' };
|
|
702
754
|
}
|
|
703
755
|
/**
|
|
704
756
|
* **아직 제출 안 된** 묶음만 찾는다.
|
|
705
757
|
*
|
|
706
758
|
* findOpenReviewSubmission 을 그대로 쓰면 안 된다 — 그건 WAITING_FOR_REVIEW 까지
|
|
707
|
-
* 잡아오는데, 그건 이미 Apple 큐에 들어간 묶음이다.
|
|
708
|
-
*
|
|
709
|
-
* 묶음이 2개 떠 있는 상태가 정상적으로 존재한다).
|
|
710
|
-
*
|
|
711
|
-
* 콘솔의 "제출 초안" 은 READY_FOR_REVIEW 로 보인다. 그게 우리가 담을 대상이다.
|
|
759
|
+
* 잡아오는데, 그건 이미 Apple 큐에 들어간 묶음이다. 콘솔의 "제출 초안" 은
|
|
760
|
+
* READY_FOR_REVIEW 로 보인다. 그게 재사용 대상이다.
|
|
712
761
|
*/
|
|
713
762
|
async function findDraftReviewSubmission(appId, platform) {
|
|
714
763
|
const data = await apiGet('/reviewSubmissions', {
|
|
@@ -719,50 +768,81 @@ async function findDraftReviewSubmission(appId, platform) {
|
|
|
719
768
|
});
|
|
720
769
|
return data?.data?.[0]?.id ?? null;
|
|
721
770
|
}
|
|
722
|
-
export async function
|
|
723
|
-
const { appId, internalId, productType } = args;
|
|
771
|
+
export async function listReviewSubmissions(args) {
|
|
724
772
|
const platform = args.platform ?? 'IOS';
|
|
725
|
-
const
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
773
|
+
const limit = Math.min(Math.max(args.limit ?? 5, 1), 20);
|
|
774
|
+
const data = await apiGet('/reviewSubmissions', {
|
|
775
|
+
'filter[app]': args.appId,
|
|
776
|
+
'filter[platform]': platform,
|
|
777
|
+
'limit': String(limit),
|
|
778
|
+
});
|
|
779
|
+
const submissions = (data?.data ?? []);
|
|
780
|
+
const result = [];
|
|
781
|
+
for (const sub of submissions) {
|
|
782
|
+
const itemsData = await apiGet(`/reviewSubmissions/${sub.id}/items`, {
|
|
783
|
+
include: 'appStoreVersion',
|
|
784
|
+
'fields[appStoreVersions]': 'versionString,appVersionState',
|
|
785
|
+
limit: '50',
|
|
786
|
+
}).catch(() => null);
|
|
787
|
+
const included = new Map((itemsData?.included ?? []).map((inc) => [`${inc.type}:${inc.id}`, inc]));
|
|
788
|
+
const items = (itemsData?.data ?? []).map((item) => {
|
|
789
|
+
const target = Object.entries(item.relationships ?? {}).find(([key, rel]) => key !== 'reviewSubmission' && rel?.data?.id)?.[1]?.data;
|
|
790
|
+
const inc = target?.type && target.id ? included.get(`${target.type}:${target.id}`) : undefined;
|
|
791
|
+
return {
|
|
792
|
+
id: item.id,
|
|
793
|
+
state: item.attributes?.state,
|
|
794
|
+
targetType: target?.type,
|
|
795
|
+
targetId: target?.id,
|
|
796
|
+
versionString: inc?.attributes?.versionString,
|
|
797
|
+
appVersionState: inc?.attributes?.appVersionState,
|
|
798
|
+
};
|
|
735
799
|
});
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
// 같은 상품을 두 번 담으면 Apple 이 409 를 준다. 재시도가 안전하도록 먼저 확인한다.
|
|
742
|
-
const items = await apiGet(`/reviewSubmissions/${submissionId}/items`, { limit: '50' });
|
|
743
|
-
const rows = (items?.data ?? []);
|
|
744
|
-
const alreadyAttached = rows.some((row) => row?.relationships?.[relationship.key]?.data?.id === internalId);
|
|
745
|
-
if (!alreadyAttached) {
|
|
746
|
-
await apiPost('/reviewSubmissionItems', {
|
|
747
|
-
data: {
|
|
748
|
-
type: 'reviewSubmissionItems',
|
|
749
|
-
relationships: {
|
|
750
|
-
reviewSubmission: { data: { type: 'reviewSubmissions', id: submissionId } },
|
|
751
|
-
[relationship.key]: { data: { type: relationship.type, id: internalId } },
|
|
752
|
-
},
|
|
753
|
-
},
|
|
800
|
+
result.push({
|
|
801
|
+
id: sub.id,
|
|
802
|
+
state: sub.attributes?.state,
|
|
803
|
+
submittedDate: sub.attributes?.submittedDate ?? null,
|
|
804
|
+
items,
|
|
754
805
|
});
|
|
755
806
|
}
|
|
807
|
+
return { appId: args.appId, platform, submissions: result };
|
|
808
|
+
}
|
|
809
|
+
/** 묶음에서 항목 제거 (removed=true PATCH). ASC 웹 "재제출" 이 내부적으로 하는 그 동작. */
|
|
810
|
+
export async function removeReviewSubmissionItem(itemId) {
|
|
811
|
+
const patched = await apiPatch(`/reviewSubmissionItems/${encodeURIComponent(itemId)}`, {
|
|
812
|
+
data: { type: 'reviewSubmissionItems', id: itemId, attributes: { removed: true } },
|
|
813
|
+
});
|
|
756
814
|
return {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
internalId,
|
|
761
|
-
productType,
|
|
762
|
-
reusedSubmission,
|
|
763
|
-
itemAttached: !alreadyAttached,
|
|
815
|
+
itemId,
|
|
816
|
+
state: patched?.data?.attributes?.state,
|
|
817
|
+
removed: patched?.data?.attributes?.removed ?? true,
|
|
764
818
|
};
|
|
765
819
|
}
|
|
820
|
+
/**
|
|
821
|
+
* 버전을 물고 있는 낡은 묶음(UNRESOLVED_ISSUES)에서 해당 버전 항목을 removed=true 로
|
|
822
|
+
* 풀어준다. 항목이 풀리면 Apple 이 옛 묶음을 COMPLETE 로 정리하고, 종종 새
|
|
823
|
+
* READY_FOR_REVIEW 초안을 자동 생성한다 (실측). 풀어준 항목 수를 반환.
|
|
824
|
+
*/
|
|
825
|
+
async function releaseVersionFromStaleSubmissions(appId, platform, versionId) {
|
|
826
|
+
const data = await apiGet('/reviewSubmissions', {
|
|
827
|
+
'filter[app]': appId,
|
|
828
|
+
'filter[platform]': platform,
|
|
829
|
+
'filter[state]': 'UNRESOLVED_ISSUES',
|
|
830
|
+
'limit': '5',
|
|
831
|
+
}).catch(() => null);
|
|
832
|
+
const stale = (data?.data ?? []);
|
|
833
|
+
let released = 0;
|
|
834
|
+
for (const sub of stale) {
|
|
835
|
+
const items = await apiGet(`/reviewSubmissions/${sub.id}/items`, { limit: '50' }).catch(() => null);
|
|
836
|
+
const rows = (items?.data ?? []);
|
|
837
|
+
for (const row of rows) {
|
|
838
|
+
if (row?.relationships?.appStoreVersion?.data?.id !== versionId)
|
|
839
|
+
continue;
|
|
840
|
+
await removeReviewSubmissionItem(row.id);
|
|
841
|
+
released += 1;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return released;
|
|
845
|
+
}
|
|
766
846
|
// ─── 심사 철회 (Cancel Review) ───
|
|
767
847
|
// WAITING_FOR_REVIEW 상태의 reviewSubmission에만 적용 가능.
|
|
768
848
|
// IN_REVIEW 진입 후에는 Apple API가 거부함 (409).
|
package/dist/auth/google-auth.js
CHANGED
package/dist/bigquery/tools.js
CHANGED
package/dist/firebase/tools.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare function listProjects(auth: OAuth2Client): Promise<{
|
|
|
8
8
|
state: string | null | undefined;
|
|
9
9
|
projectNumber: string | null | undefined;
|
|
10
10
|
}[]>;
|
|
11
|
-
export declare function getProject(auth: OAuth2Client, projectId: string): Promise<import("googleapis").firebase_v1beta1.Schema$FirebaseProject>;
|
|
11
|
+
export declare function getProject(auth: OAuth2Client, projectId: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$FirebaseProject>;
|
|
12
12
|
/** long-running Operation 하나의 완료 여부를 판정한다. 폴링 루프에서 재사용 + 단독 테스트 가능. */
|
|
13
13
|
export declare function operationOutcome(op: {
|
|
14
14
|
done?: boolean | null;
|
|
@@ -45,39 +45,39 @@ export declare function waitForOperation(getOperation: () => Promise<{
|
|
|
45
45
|
*/
|
|
46
46
|
export declare function createProject(auth: OAuth2Client, projectId: string, displayName: string, opts?: {
|
|
47
47
|
parent?: string;
|
|
48
|
-
}): Promise<import("googleapis").firebase_v1beta1.Schema$FirebaseProject>;
|
|
48
|
+
}): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$FirebaseProject>;
|
|
49
49
|
export declare function listAndroidApps(auth: OAuth2Client, projectId: string): Promise<{
|
|
50
50
|
appId: string | null | undefined;
|
|
51
51
|
packageName: string | null | undefined;
|
|
52
52
|
displayName: string | null | undefined;
|
|
53
53
|
state: string | null | undefined;
|
|
54
54
|
}[]>;
|
|
55
|
-
export declare function createAndroidApp(auth: OAuth2Client, projectId: string, packageName: string, displayName: string): Promise<import("googleapis").firebase_v1beta1.Schema$Operation>;
|
|
55
|
+
export declare function createAndroidApp(auth: OAuth2Client, projectId: string, packageName: string, displayName: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$Operation>;
|
|
56
56
|
export declare function getAndroidConfig(auth: OAuth2Client, projectId: string, appId: string): Promise<{
|
|
57
57
|
filename: string | null | undefined;
|
|
58
58
|
content: string | null;
|
|
59
59
|
}>;
|
|
60
|
-
export declare function deleteAndroidApp(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis").firebase_v1beta1.Schema$Operation>;
|
|
60
|
+
export declare function deleteAndroidApp(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$Operation>;
|
|
61
61
|
export declare function listIosApps(auth: OAuth2Client, projectId: string): Promise<{
|
|
62
62
|
appId: string | null | undefined;
|
|
63
63
|
bundleId: string | null | undefined;
|
|
64
64
|
displayName: string | null | undefined;
|
|
65
65
|
state: string | null | undefined;
|
|
66
66
|
}[]>;
|
|
67
|
-
export declare function createIosApp(auth: OAuth2Client, projectId: string, bundleId: string, displayName: string): Promise<import("googleapis").firebase_v1beta1.Schema$Operation>;
|
|
67
|
+
export declare function createIosApp(auth: OAuth2Client, projectId: string, bundleId: string, displayName: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$Operation>;
|
|
68
68
|
export declare function getIosConfig(auth: OAuth2Client, projectId: string, appId: string): Promise<{
|
|
69
69
|
filename: string | null | undefined;
|
|
70
70
|
content: string | null;
|
|
71
71
|
}>;
|
|
72
|
-
export declare function deleteIosApp(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis").firebase_v1beta1.Schema$Operation>;
|
|
72
|
+
export declare function deleteIosApp(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$Operation>;
|
|
73
73
|
export declare function listWebApps(auth: OAuth2Client, projectId: string): Promise<{
|
|
74
74
|
appId: string | null | undefined;
|
|
75
75
|
displayName: string | null | undefined;
|
|
76
76
|
state: string | null | undefined;
|
|
77
77
|
}[]>;
|
|
78
|
-
export declare function createWebApp(auth: OAuth2Client, projectId: string, displayName: string): Promise<import("googleapis").firebase_v1beta1.Schema$Operation>;
|
|
79
|
-
export declare function getWebConfig(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis").firebase_v1beta1.Schema$WebAppConfig>;
|
|
80
|
-
export declare function deleteWebApp(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis").firebase_v1beta1.Schema$Operation>;
|
|
78
|
+
export declare function createWebApp(auth: OAuth2Client, projectId: string, displayName: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$Operation>;
|
|
79
|
+
export declare function getWebConfig(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$WebAppConfig>;
|
|
80
|
+
export declare function deleteWebApp(auth: OAuth2Client, projectId: string, appId: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$Operation>;
|
|
81
81
|
export declare function enableService(auth: OAuth2Client, projectId: string, serviceId: string): Promise<{
|
|
82
82
|
service: string;
|
|
83
83
|
state: string | null | undefined;
|
|
@@ -97,9 +97,9 @@ export declare function listEnabledServices(auth: OAuth2Client, projectId: strin
|
|
|
97
97
|
export declare function linkAnalytics(auth: OAuth2Client, projectId: string, opts?: {
|
|
98
98
|
analyticsAccountId?: string;
|
|
99
99
|
analyticsPropertyId?: string;
|
|
100
|
-
}): Promise<import("googleapis").firebase_v1beta1.Schema$Operation>;
|
|
100
|
+
}): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$Operation>;
|
|
101
101
|
/** 프로젝트의 GA4 링크 상세 — 연결된 analyticsProperty + 앱↔stream 매핑 조회. */
|
|
102
|
-
export declare function getAnalyticsDetails(auth: OAuth2Client, projectId: string): Promise<import("googleapis").firebase_v1beta1.Schema$AnalyticsDetails>;
|
|
102
|
+
export declare function getAnalyticsDetails(auth: OAuth2Client, projectId: string): Promise<import("googleapis/build/src/apis/firebase/v1beta1.js").firebase_v1beta1.Schema$AnalyticsDetails>;
|
|
103
103
|
export declare function enableCommonServices(auth: OAuth2Client, projectId: string): Promise<({
|
|
104
104
|
service: string;
|
|
105
105
|
status: string;
|
package/dist/firebase/tools.js
CHANGED
package/dist/ga4/tools.d.ts
CHANGED
|
@@ -115,15 +115,15 @@ export declare function flattenBigQueryLink(link: {
|
|
|
115
115
|
includeAdvertisingId: boolean;
|
|
116
116
|
};
|
|
117
117
|
/** 접근 가능한 GA 계정 + 각 계정의 property 요약. accountId/propertyId 를 찾는 시작점. */
|
|
118
|
-
export declare function listAccountSummaries(auth: Ga4Auth): Promise<import("googleapis").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaAccountSummary[]>;
|
|
118
|
+
export declare function listAccountSummaries(auth: Ga4Auth): Promise<import("googleapis/build/src/apis/analyticsadmin/v1beta.js").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaAccountSummary[]>;
|
|
119
119
|
/** 계정 하위 GA4 property 목록. accountId: '123' 또는 'accounts/123'. */
|
|
120
|
-
export declare function listProperties(auth: Ga4Auth, accountId: string): Promise<import("googleapis").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaProperty[]>;
|
|
120
|
+
export declare function listProperties(auth: Ga4Auth, accountId: string): Promise<import("googleapis/build/src/apis/analyticsadmin/v1beta.js").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaProperty[]>;
|
|
121
121
|
export declare function createProperty(auth: Ga4Auth, opts: {
|
|
122
122
|
accountId: string;
|
|
123
123
|
displayName: string;
|
|
124
124
|
timeZone?: string;
|
|
125
125
|
currencyCode?: string;
|
|
126
|
-
}): Promise<import("googleapis").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaProperty>;
|
|
126
|
+
}): Promise<import("googleapis/build/src/apis/analyticsadmin/v1beta.js").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaProperty>;
|
|
127
127
|
export declare function createDataStream(auth: Ga4Auth, propertyId: string, opts: {
|
|
128
128
|
platform: DataStreamPlatform;
|
|
129
129
|
displayName: string;
|
|
@@ -131,7 +131,7 @@ export declare function createDataStream(auth: Ga4Auth, propertyId: string, opts
|
|
|
131
131
|
packageName?: string;
|
|
132
132
|
bundleId?: string;
|
|
133
133
|
}): Promise<{
|
|
134
|
-
raw: import("googleapis").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaDataStream;
|
|
134
|
+
raw: import("googleapis/build/src/apis/analyticsadmin/v1beta.js").analyticsadmin_v1beta.Schema$GoogleAnalyticsAdminV1betaDataStream;
|
|
135
135
|
name: string | null;
|
|
136
136
|
type: string | null;
|
|
137
137
|
displayName: string | null;
|
|
@@ -228,4 +228,4 @@ export interface RunReportParams {
|
|
|
228
228
|
dimensions?: string[];
|
|
229
229
|
metrics?: string[];
|
|
230
230
|
}
|
|
231
|
-
export declare function runReport(auth: Ga4Auth, propertyId: string, params: RunReportParams): Promise<import("googleapis").analyticsdata_v1beta.Schema$RunReportResponse>;
|
|
231
|
+
export declare function runReport(auth: Ga4Auth, propertyId: string, params: RunReportParams): Promise<import("googleapis/build/src/apis/analyticsdata/v1beta.js").analyticsdata_v1beta.Schema$RunReportResponse>;
|
package/dist/ga4/tools.js
CHANGED
package/dist/gsc/tools.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { OAuth2Client } from 'google-auth-library';
|
|
2
2
|
export type GscAuth = OAuth2Client;
|
|
3
|
-
export declare function listSites(auth: GscAuth): Promise<import("googleapis").searchconsole_v1.Schema$WmxSite[]>;
|
|
4
|
-
export declare function listSitemaps(auth: GscAuth, siteUrl: string, sitemapIndex?: string): Promise<import("googleapis").searchconsole_v1.Schema$WmxSitemap[]>;
|
|
5
|
-
export declare function getSitemap(auth: GscAuth, siteUrl: string, feedpath: string): Promise<import("googleapis").searchconsole_v1.Schema$WmxSitemap>;
|
|
3
|
+
export declare function listSites(auth: GscAuth): Promise<import("googleapis/build/src/apis/searchconsole/v1.js").searchconsole_v1.Schema$WmxSite[]>;
|
|
4
|
+
export declare function listSitemaps(auth: GscAuth, siteUrl: string, sitemapIndex?: string): Promise<import("googleapis/build/src/apis/searchconsole/v1.js").searchconsole_v1.Schema$WmxSitemap[]>;
|
|
5
|
+
export declare function getSitemap(auth: GscAuth, siteUrl: string, feedpath: string): Promise<import("googleapis/build/src/apis/searchconsole/v1.js").searchconsole_v1.Schema$WmxSitemap>;
|
|
6
6
|
/** 사이트맵 제출 — webmasters(read-write) 스코프 필요. 응답 본문은 없음(204). */
|
|
7
7
|
export declare function submitSitemap(auth: GscAuth, siteUrl: string, feedpath: string): Promise<{
|
|
8
8
|
submitted: string;
|
|
9
9
|
siteUrl: string;
|
|
10
10
|
}>;
|
|
11
|
-
export declare function inspectUrl(auth: GscAuth, siteUrl: string, inspectionUrl: string, languageCode?: string): Promise<import("googleapis").searchconsole_v1.Schema$UrlInspectionResult>;
|
|
11
|
+
export declare function inspectUrl(auth: GscAuth, siteUrl: string, inspectionUrl: string, languageCode?: string): Promise<import("googleapis/build/src/apis/searchconsole/v1.js").searchconsole_v1.Schema$UrlInspectionResult>;
|
|
12
12
|
export interface SearchAnalyticsParams {
|
|
13
13
|
startDate: string;
|
|
14
14
|
endDate: string;
|
|
@@ -17,7 +17,7 @@ export interface SearchAnalyticsParams {
|
|
|
17
17
|
startRow?: number;
|
|
18
18
|
type?: 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
|
|
19
19
|
}
|
|
20
|
-
export declare function searchAnalytics(auth: GscAuth, siteUrl: string, params: SearchAnalyticsParams): Promise<import("googleapis").searchconsole_v1.Schema$ApiDataRow[]>;
|
|
20
|
+
export declare function searchAnalytics(auth: GscAuth, siteUrl: string, params: SearchAnalyticsParams): Promise<import("googleapis/build/src/apis/searchconsole/v1.js").searchconsole_v1.Schema$ApiDataRow[]>;
|
|
21
21
|
export interface SearchAnalyticsRow {
|
|
22
22
|
keys?: string[] | null;
|
|
23
23
|
clicks?: number | null;
|
package/dist/gsc/tools.js
CHANGED
package/dist/iam/tools.js
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* googleapis 서브패스 로더 — MCP 서버 기동 시간 방어벽.
|
|
3
|
+
*
|
|
4
|
+
* `import { google } from 'googleapis'` 는 import 시점에 400여 개 API 클라이언트를
|
|
5
|
+
* 전부 로드해 그것만으로 ~19초를 쓴다. 그 결과 MCP 서버 기동(21~36초)이 Claude Code 의
|
|
6
|
+
* MCP 연결 타임아웃(30초)을 상습 초과해, 세션에서 mimi-seed 도구가 아예 등록되지 않는
|
|
7
|
+
* 사고가 났다 (2026-07-24). 실제 사용하는 API 만 서브패스로 로드하면 ~1초대다.
|
|
8
|
+
*
|
|
9
|
+
* - 새 Google API 가 필요하면 여기에 import 한 줄 + google 객체에 한 줄 추가한다.
|
|
10
|
+
* - 다른 파일에서 `from 'googleapis'` 값 import 는 금지 — 반드시 이 모듈을 거친다.
|
|
11
|
+
* (googleapis 는 exports map 이 없어 서브패스 import 가 공식적으로 가능하다.)
|
|
12
|
+
* - `auth` 는 AuthPlus 인스턴스라 `google.auth.OAuth2` 등 기존 사용처가 그대로 동작한다.
|
|
13
|
+
*/
|
|
14
|
+
import { admob } from 'googleapis/build/src/apis/admob/index.js';
|
|
15
|
+
import { analyticsadmin } from 'googleapis/build/src/apis/analyticsadmin/index.js';
|
|
16
|
+
import { analyticsdata } from 'googleapis/build/src/apis/analyticsdata/index.js';
|
|
17
|
+
import { androidpublisher } from 'googleapis/build/src/apis/androidpublisher/index.js';
|
|
18
|
+
import { bigquery } from 'googleapis/build/src/apis/bigquery/index.js';
|
|
19
|
+
import { cloudresourcemanager } from 'googleapis/build/src/apis/cloudresourcemanager/index.js';
|
|
20
|
+
import { firebase } from 'googleapis/build/src/apis/firebase/index.js';
|
|
21
|
+
import { iam } from 'googleapis/build/src/apis/iam/index.js';
|
|
22
|
+
import { searchconsole } from 'googleapis/build/src/apis/searchconsole/index.js';
|
|
23
|
+
import { serviceusage } from 'googleapis/build/src/apis/serviceusage/index.js';
|
|
24
|
+
import { youtube } from 'googleapis/build/src/apis/youtube/index.js';
|
|
25
|
+
export type { youtube_v3 } from 'googleapis/build/src/apis/youtube/index.js';
|
|
26
|
+
export declare const google: {
|
|
27
|
+
auth: import("googleapis-common/build/src/authplus.js").AuthPlus;
|
|
28
|
+
admob: typeof admob;
|
|
29
|
+
analyticsadmin: typeof analyticsadmin;
|
|
30
|
+
analyticsdata: typeof analyticsdata;
|
|
31
|
+
androidpublisher: typeof androidpublisher;
|
|
32
|
+
bigquery: typeof bigquery;
|
|
33
|
+
cloudresourcemanager: typeof cloudresourcemanager;
|
|
34
|
+
firebase: typeof firebase;
|
|
35
|
+
iam: typeof iam;
|
|
36
|
+
searchconsole: typeof searchconsole;
|
|
37
|
+
serviceusage: typeof serviceusage;
|
|
38
|
+
youtube: typeof youtube;
|
|
39
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* googleapis 서브패스 로더 — MCP 서버 기동 시간 방어벽.
|
|
3
|
+
*
|
|
4
|
+
* `import { google } from 'googleapis'` 는 import 시점에 400여 개 API 클라이언트를
|
|
5
|
+
* 전부 로드해 그것만으로 ~19초를 쓴다. 그 결과 MCP 서버 기동(21~36초)이 Claude Code 의
|
|
6
|
+
* MCP 연결 타임아웃(30초)을 상습 초과해, 세션에서 mimi-seed 도구가 아예 등록되지 않는
|
|
7
|
+
* 사고가 났다 (2026-07-24). 실제 사용하는 API 만 서브패스로 로드하면 ~1초대다.
|
|
8
|
+
*
|
|
9
|
+
* - 새 Google API 가 필요하면 여기에 import 한 줄 + google 객체에 한 줄 추가한다.
|
|
10
|
+
* - 다른 파일에서 `from 'googleapis'` 값 import 는 금지 — 반드시 이 모듈을 거친다.
|
|
11
|
+
* (googleapis 는 exports map 이 없어 서브패스 import 가 공식적으로 가능하다.)
|
|
12
|
+
* - `auth` 는 AuthPlus 인스턴스라 `google.auth.OAuth2` 등 기존 사용처가 그대로 동작한다.
|
|
13
|
+
*/
|
|
14
|
+
import { admob } from 'googleapis/build/src/apis/admob/index.js';
|
|
15
|
+
import { analyticsadmin } from 'googleapis/build/src/apis/analyticsadmin/index.js';
|
|
16
|
+
import { analyticsdata } from 'googleapis/build/src/apis/analyticsdata/index.js';
|
|
17
|
+
import { androidpublisher } from 'googleapis/build/src/apis/androidpublisher/index.js';
|
|
18
|
+
import { bigquery } from 'googleapis/build/src/apis/bigquery/index.js';
|
|
19
|
+
import { cloudresourcemanager } from 'googleapis/build/src/apis/cloudresourcemanager/index.js';
|
|
20
|
+
import { auth, firebase } from 'googleapis/build/src/apis/firebase/index.js';
|
|
21
|
+
import { iam } from 'googleapis/build/src/apis/iam/index.js';
|
|
22
|
+
import { searchconsole } from 'googleapis/build/src/apis/searchconsole/index.js';
|
|
23
|
+
import { serviceusage } from 'googleapis/build/src/apis/serviceusage/index.js';
|
|
24
|
+
import { youtube } from 'googleapis/build/src/apis/youtube/index.js';
|
|
25
|
+
export const google = {
|
|
26
|
+
auth,
|
|
27
|
+
admob,
|
|
28
|
+
analyticsadmin,
|
|
29
|
+
analyticsdata,
|
|
30
|
+
androidpublisher,
|
|
31
|
+
bigquery,
|
|
32
|
+
cloudresourcemanager,
|
|
33
|
+
firebase,
|
|
34
|
+
iam,
|
|
35
|
+
searchconsole,
|
|
36
|
+
serviceusage,
|
|
37
|
+
youtube,
|
|
38
|
+
};
|
|
@@ -7,7 +7,7 @@ export type PlayImageType = 'featureGraphic' | 'icon' | 'phoneScreenshots' | 'pr
|
|
|
7
7
|
* 주의: 최초 앱 생성은 API로 불가 (Play Console에서만).
|
|
8
8
|
* 여기서는 기존 앱의 메타데이터, 빌드, 출시를 관리.
|
|
9
9
|
*/
|
|
10
|
-
export declare const publisher: () => import("googleapis").androidpublisher_v3.Androidpublisher;
|
|
10
|
+
export declare const publisher: () => import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Androidpublisher;
|
|
11
11
|
export type PlayVitalsMetricSet = 'anrRate' | 'crashRate' | 'errorCount';
|
|
12
12
|
export interface PlayStatisticsQuery {
|
|
13
13
|
metricSet?: PlayVitalsMetricSet;
|
|
@@ -24,29 +24,29 @@ export interface PlayStatisticsQuery {
|
|
|
24
24
|
}
|
|
25
25
|
export declare function withEdit<T>(auth: OAuth2Client | JWT, packageName: string, fn: (editId: string) => Promise<T>, commit?: boolean): Promise<T>;
|
|
26
26
|
export declare function getStatistics(auth: OAuth2Client | JWT, packageName: string, query: PlayStatisticsQuery): Promise<unknown>;
|
|
27
|
-
export declare function getAppDetails(auth: OAuth2Client | JWT, packageName: string): Promise<import("googleapis").androidpublisher_v3.Schema$AppDetails>;
|
|
27
|
+
export declare function getAppDetails(auth: OAuth2Client | JWT, packageName: string): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$AppDetails>;
|
|
28
28
|
export declare function updateAppDetails(auth: OAuth2Client | JWT, packageName: string, data: {
|
|
29
29
|
contactEmail?: string;
|
|
30
30
|
contactPhone?: string;
|
|
31
31
|
contactWebsite?: string;
|
|
32
32
|
defaultLanguage?: string;
|
|
33
|
-
}): Promise<import("googleapis").androidpublisher_v3.Schema$AppDetails>;
|
|
34
|
-
export declare function getListing(auth: OAuth2Client | JWT, packageName: string, language?: string): Promise<import("googleapis").androidpublisher_v3.Schema$Listing>;
|
|
33
|
+
}): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$AppDetails>;
|
|
34
|
+
export declare function getListing(auth: OAuth2Client | JWT, packageName: string, language?: string): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$Listing>;
|
|
35
35
|
export declare function updateListing(auth: OAuth2Client | JWT, packageName: string, language: string, data: {
|
|
36
36
|
title?: string;
|
|
37
37
|
shortDescription?: string;
|
|
38
38
|
fullDescription?: string;
|
|
39
|
-
}): Promise<import("googleapis").androidpublisher_v3.Schema$Listing>;
|
|
39
|
+
}): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$Listing>;
|
|
40
40
|
export declare function listTracks(auth: OAuth2Client | JWT, packageName: string): Promise<{
|
|
41
41
|
track: string | null | undefined;
|
|
42
42
|
releases: {
|
|
43
43
|
name: string | null | undefined;
|
|
44
44
|
status: string | null | undefined;
|
|
45
45
|
versionCodes: string[] | null | undefined;
|
|
46
|
-
releaseNotes: import("googleapis").androidpublisher_v3.Schema$LocalizedText[] | undefined;
|
|
46
|
+
releaseNotes: import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$LocalizedText[] | undefined;
|
|
47
47
|
}[];
|
|
48
48
|
}[]>;
|
|
49
|
-
export declare function updateReleaseNotes(auth: OAuth2Client | JWT, packageName: string, track: string, versionCode: string, language: string, text: string): Promise<import("googleapis").androidpublisher_v3.Schema$Track>;
|
|
49
|
+
export declare function updateReleaseNotes(auth: OAuth2Client | JWT, packageName: string, track: string, versionCode: string, language: string, text: string): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$Track>;
|
|
50
50
|
/**
|
|
51
51
|
* 최신 release (versionCode 최대값)의 releaseNotes[language]를 교체/추가.
|
|
52
52
|
* versionCode를 모를 때 편의용.
|
|
@@ -54,11 +54,11 @@ export declare function updateReleaseNotes(auth: OAuth2Client | JWT, packageName
|
|
|
54
54
|
export declare function updateLatestReleaseNotes(auth: OAuth2Client | JWT, packageName: string, track: string, language: string, text: string): Promise<{
|
|
55
55
|
updatedVersionCodes: string[] | null | undefined;
|
|
56
56
|
updatedReleaseName: string | null | undefined;
|
|
57
|
-
releases?: import("googleapis").androidpublisher_v3.Schema$TrackRelease[];
|
|
57
|
+
releases?: import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$TrackRelease[];
|
|
58
58
|
track?: string | null;
|
|
59
59
|
}>;
|
|
60
|
-
export declare function listImages(auth: OAuth2Client | JWT, packageName: string, language: string, imageType: PlayImageType): Promise<import("googleapis").androidpublisher_v3.Schema$Image[]>;
|
|
61
|
-
export declare function uploadImage(auth: OAuth2Client | JWT, packageName: string, language: string, imageType: PlayImageType, filePath: string): Promise<import("googleapis").androidpublisher_v3.Schema$Image | undefined>;
|
|
60
|
+
export declare function listImages(auth: OAuth2Client | JWT, packageName: string, language: string, imageType: PlayImageType): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$Image[]>;
|
|
61
|
+
export declare function uploadImage(auth: OAuth2Client | JWT, packageName: string, language: string, imageType: PlayImageType, filePath: string): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$Image | undefined>;
|
|
62
62
|
export declare function deleteAllImages(auth: OAuth2Client | JWT, packageName: string, language: string, imageType: PlayImageType): Promise<{
|
|
63
63
|
ok: boolean;
|
|
64
64
|
imageType: PlayImageType;
|
|
@@ -82,7 +82,7 @@ export declare function submitRelease(auth: OAuth2Client | JWT, packageName: str
|
|
|
82
82
|
previousStatus: string | null | undefined;
|
|
83
83
|
newStatus: "completed" | "draft" | "inProgress" | "halted";
|
|
84
84
|
committed: boolean;
|
|
85
|
-
result: import("googleapis").androidpublisher_v3.Schema$Track;
|
|
85
|
+
result: import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$Track;
|
|
86
86
|
}>;
|
|
87
87
|
export interface PromoteReleaseOptions {
|
|
88
88
|
status?: 'completed' | 'draft' | 'inProgress' | 'halted';
|
|
@@ -104,7 +104,7 @@ export declare function promoteRelease(auth: OAuth2Client | JWT, packageName: st
|
|
|
104
104
|
releaseName: string | null | undefined;
|
|
105
105
|
releaseNotesLanguages: (string | null | undefined)[];
|
|
106
106
|
committed: boolean;
|
|
107
|
-
result: import("googleapis").androidpublisher_v3.Schema$Track;
|
|
107
|
+
result: import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$Track;
|
|
108
108
|
}>;
|
|
109
109
|
export declare function listReviews(auth: OAuth2Client | JWT, packageName: string): Promise<{
|
|
110
110
|
reviewId: string | null | undefined;
|
|
@@ -116,7 +116,7 @@ export declare function listReviews(auth: OAuth2Client | JWT, packageName: strin
|
|
|
116
116
|
deviceMetadata: string | null | undefined;
|
|
117
117
|
}[] | undefined;
|
|
118
118
|
}[]>;
|
|
119
|
-
export declare function replyToReview(auth: OAuth2Client | JWT, packageName: string, reviewId: string, replyText: string): Promise<import("googleapis").androidpublisher_v3.Schema$ReviewsReplyResponse>;
|
|
119
|
+
export declare function replyToReview(auth: OAuth2Client | JWT, packageName: string, reviewId: string, replyText: string): Promise<import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$ReviewsReplyResponse>;
|
|
120
120
|
export declare function listInAppProducts(auth: OAuth2Client | JWT, packageName: string): Promise<{
|
|
121
121
|
productId: any;
|
|
122
122
|
listings: any;
|
|
@@ -124,8 +124,8 @@ export declare function listInAppProducts(auth: OAuth2Client | JWT, packageName:
|
|
|
124
124
|
}[]>;
|
|
125
125
|
export declare function listSubscriptions(auth: OAuth2Client | JWT, packageName: string): Promise<{
|
|
126
126
|
productId: string | null | undefined;
|
|
127
|
-
basePlans: import("googleapis").androidpublisher_v3.Schema$BasePlan[] | undefined;
|
|
128
|
-
listings: import("googleapis").androidpublisher_v3.Schema$SubscriptionListing[] | undefined;
|
|
127
|
+
basePlans: import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$BasePlan[] | undefined;
|
|
128
|
+
listings: import("googleapis/build/src/apis/androidpublisher/v3.js").androidpublisher_v3.Schema$SubscriptionListing[] | undefined;
|
|
129
129
|
}[]>;
|
|
130
130
|
export interface ProductListingInput {
|
|
131
131
|
languageCode: string;
|
package/dist/playstore/tools.js
CHANGED
|
@@ -588,16 +588,18 @@ export function registerAppstoreTools(server) {
|
|
|
588
588
|
}],
|
|
589
589
|
};
|
|
590
590
|
});
|
|
591
|
-
server.tool('appstore_add_product_to_review', 'App Store IAP
|
|
592
|
-
'
|
|
593
|
-
'⚠️
|
|
591
|
+
server.tool('appstore_add_product_to_review', 'App Store IAP/구독 상품을 **단독으로** 심사에 제출한다 — consumable/non_consumable 은 ' +
|
|
592
|
+
'POST /v1/inAppPurchaseSubmissions, subscription 은 POST /v1/subscriptionSubmissions. ' +
|
|
593
|
+
'⚠️ 호출 즉시 제출된다 ("묶음에 담기"가 아니다 — 그런 공개 API 는 존재하지 않는다. ' +
|
|
594
|
+
'reviewSubmissionItems 는 appStoreVersion 계열 관계만 받는다, 2026-07 실측). ' +
|
|
595
|
+
'이미 승인된 적 있는 상품의 변경분 제출용. **앱 첫 심사** 상품은 Apple 이 ' +
|
|
596
|
+
'"no pending version" 409 로 거부한다 — 그 경우 ASC 웹 버전 페이지의 ' +
|
|
597
|
+
'"앱 내 구입 및 구독" 섹션에서 담아 버전과 함께 제출해야 한다 (도구가 에러에 안내 첨부). ' +
|
|
594
598
|
'상품 상태가 READY_TO_SUBMIT 이어야 한다 (MISSING_METADATA 면 appstore_update_product_localization 먼저).', {
|
|
595
599
|
appId: z.string().describe('App Store 앱 ID (숫자형, appstore_list_apps 결과)'),
|
|
596
600
|
productId: z.string().describe('상품 ID (appstore_list_products 결과)'),
|
|
597
601
|
productType: z.enum(['subscription', 'consumable', 'non_consumable']).describe('상품 유형'),
|
|
598
|
-
|
|
599
|
-
.describe('플랫폼 (기본 IOS)'),
|
|
600
|
-
}, async ({ appId, productId, productType, platform }) => {
|
|
602
|
+
}, async ({ appId, productId, productType }) => {
|
|
601
603
|
const creds = requireAppStoreCreds();
|
|
602
604
|
const products = await listAppleProducts({
|
|
603
605
|
appId, keyId: creds.keyId, issuerId: creds.issuerId, privateKey: creds.privateKey,
|
|
@@ -607,22 +609,70 @@ export function registerAppstoreTools(server) {
|
|
|
607
609
|
return { content: [{ type: 'text', text: `상품을 찾을 수 없음: ${productId} (${productType})` }] };
|
|
608
610
|
}
|
|
609
611
|
const result = await appstore.addProductToReviewSubmission({
|
|
610
|
-
appId,
|
|
611
612
|
internalId: product.internalId,
|
|
612
613
|
productType,
|
|
613
|
-
platform,
|
|
614
614
|
});
|
|
615
615
|
return {
|
|
616
616
|
content: [{
|
|
617
617
|
type: 'text',
|
|
618
618
|
text: [
|
|
619
|
-
|
|
619
|
+
'✓ 상품 심사 제출 완료 (Apple 심사 대기)',
|
|
620
620
|
`productId: ${productId}`,
|
|
621
|
-
`
|
|
622
|
-
|
|
621
|
+
`endpoint: ${result.endpoint}`,
|
|
622
|
+
result.submissionId ? `submissionId: ${result.submissionId}` : '',
|
|
623
623
|
'',
|
|
624
|
-
'
|
|
625
|
-
].join('\n'),
|
|
624
|
+
'앱 버전과는 별개의 단독 제출이다. 버전 제출은 appstore_submit_for_review.',
|
|
625
|
+
].filter(Boolean).join('\n'),
|
|
626
|
+
}],
|
|
627
|
+
};
|
|
628
|
+
});
|
|
629
|
+
server.tool('appstore_list_review_submissions', 'App Store 심사 제출 묶음(reviewSubmissions) + 내부 항목 조회 — 읽기 전용. ' +
|
|
630
|
+
'각 묶음의 state(READY_FOR_REVIEW=초안 / WAITING_FOR_REVIEW=큐 / UNRESOLVED_ISSUES=거절 미해결 / COMPLETE) 와 ' +
|
|
631
|
+
'항목별 state·연결 리소스(appStoreVersion 이면 versionString 포함)를 보여준다. ' +
|
|
632
|
+
'재제출이 "appStoreVersions ... is not in valid state" 로 막힐 때 첫 번째로 볼 것 — ' +
|
|
633
|
+
'진범은 대개 UNRESOLVED_ISSUES 묶음이 버전을 REJECTED 항목으로 물고 있는 것이다 ' +
|
|
634
|
+
'(버전 자체는 PREPARE_FOR_SUBMISSION 으로 멀쩡해 보인다, 2026-07 실측). ' +
|
|
635
|
+
'해제는 appstore_remove_review_submission_item.', {
|
|
636
|
+
appId: z.string().describe('App Store 앱 ID (숫자형, appstore_list_apps 결과)'),
|
|
637
|
+
platform: z.enum(['IOS', 'MAC_OS', 'TV_OS', 'VISION_OS']).default('IOS').optional()
|
|
638
|
+
.describe('플랫폼 (기본 IOS)'),
|
|
639
|
+
limit: z.number().int().min(1).max(20).optional().describe('조회할 묶음 수 (기본 5, 최신순)'),
|
|
640
|
+
}, async ({ appId, platform, limit }) => {
|
|
641
|
+
const result = await appstore.listReviewSubmissions({ appId, platform, limit });
|
|
642
|
+
const lines = [`심사 제출 묶음 ${result.submissions.length}건 (${result.platform})`];
|
|
643
|
+
for (const sub of result.submissions) {
|
|
644
|
+
lines.push('');
|
|
645
|
+
lines.push(`● ${sub.id}`);
|
|
646
|
+
lines.push(` state: ${sub.state ?? '?'} submitted: ${sub.submittedDate ?? '(미제출)'}`);
|
|
647
|
+
if (sub.items.length === 0) {
|
|
648
|
+
lines.push(' items: (없음)');
|
|
649
|
+
}
|
|
650
|
+
for (const item of sub.items) {
|
|
651
|
+
const target = item.versionString
|
|
652
|
+
? `${item.targetType} ${item.versionString} (${item.appVersionState ?? '?'})`
|
|
653
|
+
: `${item.targetType ?? '?'} ${item.targetId ?? ''}`;
|
|
654
|
+
lines.push(` - item ${item.id}`);
|
|
655
|
+
lines.push(` state: ${item.state ?? '?'} → ${target}`);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
659
|
+
});
|
|
660
|
+
server.tool('appstore_remove_review_submission_item', '심사 제출 묶음에서 항목을 제거한다 (removed=true PATCH) — ASC 웹 "재제출" 버튼이 내부적으로 하는 동작. ' +
|
|
661
|
+
'거절된 옛 묶음(UNRESOLVED_ISSUES)이 버전을 물고 있어 재제출이 ENTITY_STATE_INVALID 로 막힐 때 해제용. ' +
|
|
662
|
+
'항목이 풀리면 옛 묶음은 COMPLETE 로 정리된다. itemId 는 appstore_list_review_submissions 결과. ' +
|
|
663
|
+
'(appstore_submit_for_review 는 이 해제를 자동으로 시도한다 — 수동 개입이 필요할 때만 직접 호출.)', {
|
|
664
|
+
itemId: z.string().describe('reviewSubmissionItem ID (appstore_list_review_submissions 결과)'),
|
|
665
|
+
}, async ({ itemId }) => {
|
|
666
|
+
const result = await appstore.removeReviewSubmissionItem(itemId);
|
|
667
|
+
return {
|
|
668
|
+
content: [{
|
|
669
|
+
type: 'text',
|
|
670
|
+
text: [
|
|
671
|
+
'✓ 묶음에서 항목 제거됨',
|
|
672
|
+
`itemId: ${result.itemId}`,
|
|
673
|
+
result.state ? `state: ${result.state}` : '',
|
|
674
|
+
'항목이 버전이었다면 이제 다른 묶음에 붙일 수 있다 (appstore_submit_for_review).',
|
|
675
|
+
].filter(Boolean).join('\n'),
|
|
626
676
|
}],
|
|
627
677
|
};
|
|
628
678
|
});
|
|
@@ -689,6 +739,7 @@ export function registerAppstoreTools(server) {
|
|
|
689
739
|
'⚠️ 비가역 작업: 제출 후엔 Apple 심사가 시작되며, 메타데이터/스크린샷/빌드를 더 못 바꿈 (REJECTED/METADATA_REJECTED 시 다시 편집 가능).',
|
|
690
740
|
'안전 가드: confirm 생략/false 시 dry-run preview 만 반환 (versionString·빌드·whatsNew 발췌). 실제 제출은 confirm: true 로 재호출.',
|
|
691
741
|
'사전 조건: 버전이 PREPARE_FOR_SUBMISSION 또는 DEVELOPER_REJECTED 상태, 빌드 attached, 모든 필수 메타데이터 채워짐.',
|
|
742
|
+
'거절된 옛 묶음(UNRESOLVED_ISSUES)이 버전을 물고 있어 attach 가 막히면 자동으로 항목을 해제(removed=true)하고 재시도한다 — 진단은 appstore_list_review_submissions.',
|
|
692
743
|
'appstore_check_submission_risks로 사전 점검 권장.',
|
|
693
744
|
].join(' '), {
|
|
694
745
|
versionId: z.string().describe('App Store 버전 ID (appstore_list_versions 결과)'),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type youtube_v3 } from 'googleapis';
|
|
1
|
+
import { type youtube_v3 } from '../lib/googleapis-lite.js';
|
|
2
2
|
import type { OAuth2Client } from 'google-auth-library';
|
|
3
3
|
import { validateVideo } from './render.js';
|
|
4
4
|
export declare const YOUTUBE_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createReadStream, existsSync, statSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { google } from 'googleapis';
|
|
3
|
+
import { google } from '../lib/googleapis-lite.js';
|
|
4
4
|
import { friendlyGoogleError } from '../lib/google-errors.js';
|
|
5
5
|
import { validateVideo } from './render.js';
|
|
6
6
|
export const YOUTUBE_SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl';
|
package/package.json
CHANGED
package/tool-manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "등록된 MCP 도구 + 도메인 메타데이터(label·credential·summary)의 SSOT. src/__tests__/tool-manifest.test.ts 가 실제 서버 등록 목록과 diff 하고 메타데이터 정합성을 검사한다. 도구 추가/삭제/개명 시 이 파일을 함께 갱신할 것 — 산문 문서에는 정확한 개수를 쓰지 말고 이 파일을 가리킬 것. mimi-seed://tools/catalog 리소스가 이 파일을 그대로 서빙한다.",
|
|
3
|
-
"total":
|
|
3
|
+
"total": 187,
|
|
4
4
|
"domains": {
|
|
5
5
|
"admob": {
|
|
6
6
|
"label": "AdMob",
|
|
@@ -76,6 +76,8 @@
|
|
|
76
76
|
"appstore_delete_product",
|
|
77
77
|
"appstore_plan_release",
|
|
78
78
|
"appstore_submit_for_review",
|
|
79
|
+
"appstore_list_review_submissions",
|
|
80
|
+
"appstore_remove_review_submission_item",
|
|
79
81
|
"appstore_cancel_review"
|
|
80
82
|
]
|
|
81
83
|
},
|