opensoma 0.5.1 → 0.7.0
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/package.json +5 -1
- package/dist/src/agent-browser-launcher.d.ts +43 -0
- package/dist/src/agent-browser-launcher.d.ts.map +1 -0
- package/dist/src/agent-browser-launcher.js +97 -0
- package/dist/src/agent-browser-launcher.js.map +1 -0
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +8 -5
- package/dist/src/cli.js.map +1 -1
- package/dist/src/client.d.ts +34 -7
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +224 -52
- package/dist/src/client.js.map +1 -1
- package/dist/src/commands/agent-browser.d.ts +3 -0
- package/dist/src/commands/agent-browser.d.ts.map +1 -0
- package/dist/src/commands/agent-browser.js +27 -0
- package/dist/src/commands/agent-browser.js.map +1 -0
- package/dist/src/commands/auth.d.ts +1 -1
- package/dist/src/commands/auth.d.ts.map +1 -1
- package/dist/src/commands/auth.js +4 -2
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/dashboard.d.ts +13 -0
- package/dist/src/commands/dashboard.d.ts.map +1 -1
- package/dist/src/commands/dashboard.js +10 -18
- package/dist/src/commands/dashboard.js.map +1 -1
- package/dist/src/commands/helpers.d.ts +1 -1
- package/dist/src/commands/helpers.d.ts.map +1 -1
- package/dist/src/commands/helpers.js +2 -2
- package/dist/src/commands/helpers.js.map +1 -1
- package/dist/src/commands/index.d.ts +3 -1
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +3 -1
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/mentoring.d.ts.map +1 -1
- package/dist/src/commands/mentoring.js +54 -29
- package/dist/src/commands/mentoring.js.map +1 -1
- package/dist/src/commands/notice.d.ts.map +1 -1
- package/dist/src/commands/notice.js +2 -1
- package/dist/src/commands/notice.js.map +1 -1
- package/dist/src/commands/report.d.ts.map +1 -1
- package/dist/src/commands/report.js +4 -2
- package/dist/src/commands/report.js.map +1 -1
- package/dist/src/commands/room.d.ts.map +1 -1
- package/dist/src/commands/room.js +125 -2
- package/dist/src/commands/room.js.map +1 -1
- package/dist/src/commands/schedule.d.ts +3 -0
- package/dist/src/commands/schedule.d.ts.map +1 -0
- package/dist/src/commands/schedule.js +27 -0
- package/dist/src/commands/schedule.js.map +1 -0
- package/dist/src/commands/team.d.ts.map +1 -1
- package/dist/src/commands/team.js +55 -4
- package/dist/src/commands/team.js.map +1 -1
- package/dist/src/commands/toz.d.ts +16 -0
- package/dist/src/commands/toz.d.ts.map +1 -0
- package/dist/src/commands/toz.js +488 -0
- package/dist/src/commands/toz.js.map +1 -0
- package/dist/src/constants.d.ts +5 -5
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +20 -8
- package/dist/src/constants.js.map +1 -1
- package/dist/src/credential-manager.d.ts +15 -0
- package/dist/src/credential-manager.d.ts.map +1 -1
- package/dist/src/credential-manager.js +46 -0
- package/dist/src/credential-manager.js.map +1 -1
- package/dist/src/formatters.d.ts +11 -3
- package/dist/src/formatters.d.ts.map +1 -1
- package/dist/src/formatters.js +281 -52
- package/dist/src/formatters.js.map +1 -1
- package/dist/src/http.d.ts +8 -0
- package/dist/src/http.d.ts.map +1 -1
- package/dist/src/http.js +29 -1
- package/dist/src/http.js.map +1 -1
- package/dist/src/index.d.ts +8 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/session-recovery.js +2 -0
- package/dist/src/session-recovery.js.map +1 -1
- package/dist/src/shared/utils/swmaestro.d.ts +34 -1
- package/dist/src/shared/utils/swmaestro.d.ts.map +1 -1
- package/dist/src/shared/utils/swmaestro.js +102 -39
- package/dist/src/shared/utils/swmaestro.js.map +1 -1
- package/dist/src/shared/utils/team-action-params.d.ts +3 -0
- package/dist/src/shared/utils/team-action-params.d.ts.map +1 -0
- package/dist/src/shared/utils/team-action-params.js +10 -0
- package/dist/src/shared/utils/team-action-params.js.map +1 -0
- package/dist/src/shared/utils/team-params.d.ts +12 -0
- package/dist/src/shared/utils/team-params.d.ts.map +1 -0
- package/dist/src/shared/utils/team-params.js +38 -0
- package/dist/src/shared/utils/team-params.js.map +1 -0
- package/dist/src/toz-client.d.ts +89 -0
- package/dist/src/toz-client.d.ts.map +1 -0
- package/dist/src/toz-client.js +204 -0
- package/dist/src/toz-client.js.map +1 -0
- package/dist/src/toz-pending-store.d.ts +30 -0
- package/dist/src/toz-pending-store.d.ts.map +1 -0
- package/dist/src/toz-pending-store.js +36 -0
- package/dist/src/toz-pending-store.js.map +1 -0
- package/dist/src/types.d.ts +147 -10
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +74 -6
- package/dist/src/types.js.map +1 -1
- package/package.json +5 -1
- package/src/agent-browser-launcher.test.ts +263 -0
- package/src/agent-browser-launcher.ts +159 -0
- package/src/cli.ts +10 -5
- package/src/client.test.ts +673 -30
- package/src/client.ts +287 -67
- package/src/commands/agent-browser.ts +33 -0
- package/src/commands/auth.test.ts +77 -26
- package/src/commands/auth.ts +5 -3
- package/src/commands/dashboard.test.ts +57 -0
- package/src/commands/dashboard.ts +22 -19
- package/src/commands/helpers.test.ts +76 -25
- package/src/commands/helpers.ts +3 -3
- package/src/commands/index.ts +3 -1
- package/src/commands/mentoring.ts +60 -29
- package/src/commands/notice.ts +2 -1
- package/src/commands/report.ts +4 -2
- package/src/commands/room.ts +160 -1
- package/src/commands/schedule.ts +32 -0
- package/src/commands/team.ts +73 -5
- package/src/commands/toz.test.ts +51 -0
- package/src/commands/toz.ts +607 -0
- package/src/constants.ts +20 -8
- package/src/credential-manager.test.ts +98 -0
- package/src/credential-manager.ts +50 -0
- package/src/formatters.test.ts +528 -33
- package/src/formatters.ts +309 -55
- package/src/http.test.ts +71 -2
- package/src/http.ts +41 -2
- package/src/index.ts +23 -1
- package/src/session-recovery.ts +2 -0
- package/src/shared/utils/swmaestro.test.ts +245 -9
- package/src/shared/utils/swmaestro.ts +150 -47
- package/src/shared/utils/team-action-params.test.ts +32 -0
- package/src/shared/utils/team-action-params.ts +10 -0
- package/src/shared/utils/team-params.test.ts +141 -0
- package/src/shared/utils/team-params.ts +53 -0
- package/src/toz-client.test.ts +243 -0
- package/src/toz-client.ts +311 -0
- package/src/toz-pending-store.test.ts +91 -0
- package/src/toz-pending-store.ts +62 -0
- package/src/types.test.ts +26 -13
- package/src/types.ts +87 -7
- package/dist/src/commands/event.d.ts +0 -3
- package/dist/src/commands/event.d.ts.map +0 -1
- package/dist/src/commands/event.js +0 -58
- package/dist/src/commands/event.js.map +0 -1
- package/src/commands/event.ts +0 -73
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-manager.d.ts","sourceRoot":"","sources":["../../src/credential-manager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAY1C,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;CAChC;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,iBAAiB,CAAQ;gBAErB,SAAS,CAAC,EAAE,MAAM;IAMxB,IAAI,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAgBjC,IAAI,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe7C,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK7C,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"credential-manager.d.ts","sourceRoot":"","sources":["../../src/credential-manager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAY1C,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;CAChC;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,iBAAiB,CAAQ;gBAErB,SAAS,CAAC,EAAE,MAAM;IAMxB,IAAI,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAgBjC,IAAI,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe7C,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK7C,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B;;;;;;;OAOG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBlC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1D,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC,cAAc,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;YAMzD,kBAAkB;YAUlB,oBAAoB;YAYpB,aAAa;YAab,aAAa;YAgBb,wBAAwB;YAYxB,wBAAwB;CAWvC"}
|
|
@@ -45,6 +45,52 @@ export class CredentialManager {
|
|
|
45
45
|
await rm(this.credentialsPath, { force: true });
|
|
46
46
|
await rm(this.encryptionKeyPath, { force: true });
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Wipe ephemeral session fields (sessionCookie, csrfToken, loggedInAt) while
|
|
50
|
+
* preserving long-term material (username, password, TOZ identity). Used when
|
|
51
|
+
* the server-side session expired but we still want automatic recovery on the
|
|
52
|
+
* next run via `recoverSession()`.
|
|
53
|
+
*
|
|
54
|
+
* No-op when no credentials file exists or no recovery material is stored.
|
|
55
|
+
*/
|
|
56
|
+
async clearSessionState() {
|
|
57
|
+
const current = await this.getCredentials();
|
|
58
|
+
if (!current) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (!current.username && !current.password && !current.tozName && !current.tozPhone) {
|
|
62
|
+
await this.remove();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
await this.setCredentials({
|
|
66
|
+
sessionCookie: '',
|
|
67
|
+
csrfToken: '',
|
|
68
|
+
username: current.username,
|
|
69
|
+
password: current.password,
|
|
70
|
+
tozName: current.tozName,
|
|
71
|
+
tozPhone: current.tozPhone,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async setTozIdentity(name, phone) {
|
|
75
|
+
const existing = await this.getCredentials();
|
|
76
|
+
if (!existing) {
|
|
77
|
+
throw new Error('SWMaestro credentials not found. Run: opensoma auth login first.');
|
|
78
|
+
}
|
|
79
|
+
await this.setCredentials({ ...existing, tozName: name, tozPhone: phone });
|
|
80
|
+
}
|
|
81
|
+
async clearTozIdentity() {
|
|
82
|
+
const existing = await this.getCredentials();
|
|
83
|
+
if (!existing)
|
|
84
|
+
return;
|
|
85
|
+
const { tozName: _name, tozPhone: _phone, ...rest } = existing;
|
|
86
|
+
await this.setCredentials(rest);
|
|
87
|
+
}
|
|
88
|
+
async getTozIdentity() {
|
|
89
|
+
const creds = await this.getCredentials();
|
|
90
|
+
if (!creds?.tozName || !creds?.tozPhone)
|
|
91
|
+
return null;
|
|
92
|
+
return { name: creds.tozName, phone: creds.tozPhone };
|
|
93
|
+
}
|
|
48
94
|
async hydrateCredentials(credentials) {
|
|
49
95
|
if (!credentials.encryptedPassword) {
|
|
50
96
|
return credentials;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-manager.js","sourceRoot":"","sources":["../../src/credential-manager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"credential-manager.js","sourceRoot":"","sources":["../../src/credential-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/src/formatters.d.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import { type ApplicationHistoryItem, type ApprovalListItem, type Dashboard, type
|
|
1
|
+
import { type ApplicationHistoryItem, type ApprovalListItem, type Dashboard, type MemberInfo, type MentoringDetail, type MentoringEditForm, type MentoringListItem, type NoticeDetail, type NoticeListItem, type Pagination, type ReportDetail, type ReportListItem, type RoomCard, type RoomReservationDetail, type RoomReservationListItem, type ScheduleListItem, type TeamInfo } from './types.js';
|
|
2
2
|
export declare function parseMentoringList(html: string): MentoringListItem[];
|
|
3
3
|
export declare function parseMentoringDetail(html: string, id?: number): MentoringDetail;
|
|
4
|
+
export declare function parseMentoringEditForm(html: string, id?: number): MentoringEditForm;
|
|
4
5
|
export declare function parseRoomList(html: string): RoomCard[];
|
|
5
6
|
export declare function parseRoomSlots(html: string): RoomCard['timeSlots'];
|
|
7
|
+
export declare function parseRoomReservationDetail(html: string): RoomReservationDetail;
|
|
8
|
+
export declare function parseRoomReservationList(html: string): RoomReservationListItem[];
|
|
6
9
|
export declare function parseDashboard(html: string): Dashboard;
|
|
7
10
|
export declare function parseNoticeList(html: string): NoticeListItem[];
|
|
8
11
|
export declare function parseNoticeDetail(html: string, id?: number): NoticeDetail;
|
|
9
12
|
export declare function parseTeamInfo(html: string): TeamInfo;
|
|
10
13
|
export declare function parseMemberInfo(html: string): MemberInfo;
|
|
11
|
-
export declare function
|
|
14
|
+
export declare function parseScheduleList(html: string): {
|
|
15
|
+
items: ScheduleListItem[];
|
|
16
|
+
pagination: Pagination;
|
|
17
|
+
};
|
|
12
18
|
export declare function parseApplicationHistory(html: string): ApplicationHistoryItem[];
|
|
13
|
-
export declare function parsePagination(html: string
|
|
19
|
+
export declare function parsePagination(html: string, options?: {
|
|
20
|
+
itemCount?: number;
|
|
21
|
+
}): Pagination;
|
|
14
22
|
export declare function parseCsrfToken(html: string): string;
|
|
15
23
|
export declare function parseReportList(html: string): ReportListItem[];
|
|
16
24
|
export declare function parseReportDetail(html: string, id?: number): ReportDetail;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/formatters.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,gBAAgB,EAErB,KAAK,SAAS,EAEd,KAAK,
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/formatters.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,gBAAgB,EAErB,KAAK,SAAS,EAEd,KAAK,UAAU,EAEf,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EAEtB,KAAK,iBAAiB,EAEtB,KAAK,YAAY,EAEjB,KAAK,cAAc,EAEnB,KAAK,UAAU,EAEf,KAAK,YAAY,EAEjB,KAAK,cAAc,EAEnB,KAAK,QAAQ,EAEb,KAAK,qBAAqB,EAE1B,KAAK,uBAAuB,EAG5B,KAAK,gBAAgB,EAErB,KAAK,QAAQ,EAEd,MAAM,SAAS,CAAA;AAIhB,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAmBpE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAI,GAAG,eAAe,CAgD1E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAI,GAAG,iBAAiB,CA4B9E;AAiDD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAiBtD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,CASlE;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAwB9E;AAmBD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,uBAAuB,EAAE,CAqBhF;AAgBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAsBtD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAW9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAI,GAAG,YAAY,CAqBpE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAWpD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAYxD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAyBrG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAkB9E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAa1F;AAuBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAoB9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAI,GAAG,YAAY,CAiEpE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,EAAE,CA0BlE"}
|
package/dist/src/formatters.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parse } from 'node-html-parser';
|
|
2
2
|
import { decodeHtmlEntities } from './shared/utils/html.js';
|
|
3
|
-
import { ApplicationHistoryItemSchema, ApprovalListItemSchema, DashboardSchema,
|
|
3
|
+
import { ApplicationHistoryItemSchema, ApprovalListItemSchema, DashboardSchema, MemberInfoSchema, MentoringDetailSchema, MentoringEditFormSchema, MentoringListItemSchema, NoticeDetailSchema, NoticeListItemSchema, PaginationSchema, ReportDetailSchema, ReportListItemSchema, RoomCardSchema, RoomReservationDetailSchema, RoomReservationListItemSchema, ScheduleListItemSchema, TeamInfoSchema, } from './types.js';
|
|
4
4
|
export function parseMentoringList(html) {
|
|
5
5
|
return findTableRows(html, 9).map((cells) => {
|
|
6
6
|
const titleLink = cells[1]?.querySelector('a');
|
|
@@ -63,6 +63,82 @@ export function parseMentoringDetail(html, id = 0) {
|
|
|
63
63
|
applicants,
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
|
+
export function parseMentoringEditForm(html, id = 0) {
|
|
67
|
+
const root = parse(html);
|
|
68
|
+
const form = root.querySelector('form#board') ?? root.querySelector('form');
|
|
69
|
+
const fields = readFormFields(form);
|
|
70
|
+
const initial = parseInitialDataBlock(html);
|
|
71
|
+
const pick = (key) => {
|
|
72
|
+
const formValue = fields[key];
|
|
73
|
+
if (formValue && formValue.trim() !== '')
|
|
74
|
+
return formValue;
|
|
75
|
+
return initial[key] ?? '';
|
|
76
|
+
};
|
|
77
|
+
const receiptType = pick('receiptType') === 'DIRECT' ? 'DIRECT' : 'UNTIL_LECTURE';
|
|
78
|
+
return MentoringEditFormSchema.parse({
|
|
79
|
+
id: id || extractNumber(fields.qustnrSn ?? ''),
|
|
80
|
+
title: fields.qustnrSj ?? '',
|
|
81
|
+
reportCd: pick('reportCd'),
|
|
82
|
+
receiptType,
|
|
83
|
+
bgndeDate: pick('bgndeDate'),
|
|
84
|
+
bgndeTime: pick('bgndeTime'),
|
|
85
|
+
enddeDate: pick('enddeDate'),
|
|
86
|
+
enddeTime: pick('enddeTime'),
|
|
87
|
+
eventDt: pick('eventDt'),
|
|
88
|
+
eventStime: pick('eventStime'),
|
|
89
|
+
eventEtime: pick('eventEtime'),
|
|
90
|
+
applyCnt: extractNumber(fields.applyCnt ?? ''),
|
|
91
|
+
place: fields.place ?? '',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function parseInitialDataBlock(html) {
|
|
95
|
+
const block = html.match(/var\s+INITIAL_DATA\s*=\s*\{([\s\S]*?)\};/)?.[1];
|
|
96
|
+
if (!block)
|
|
97
|
+
return {};
|
|
98
|
+
const fields = {};
|
|
99
|
+
for (const match of block.matchAll(/(\w+)\s*:\s*'([^']*)'/g)) {
|
|
100
|
+
fields[match[1]] = match[2];
|
|
101
|
+
}
|
|
102
|
+
return fields;
|
|
103
|
+
}
|
|
104
|
+
function readFormFields(form) {
|
|
105
|
+
if (!form)
|
|
106
|
+
return {};
|
|
107
|
+
const fields = {};
|
|
108
|
+
for (const input of form.querySelectorAll('input')) {
|
|
109
|
+
const name = input.getAttribute('name');
|
|
110
|
+
if (!name)
|
|
111
|
+
continue;
|
|
112
|
+
const type = (input.getAttribute('type') ?? '').toLowerCase();
|
|
113
|
+
if (type === 'radio' || type === 'checkbox') {
|
|
114
|
+
const rawAttrs = input.rawAttrs ?? '';
|
|
115
|
+
const isChecked = /\bchecked\b/.test(rawAttrs);
|
|
116
|
+
if (isChecked) {
|
|
117
|
+
fields[name] = input.getAttribute('value') ?? '';
|
|
118
|
+
}
|
|
119
|
+
else if (!(name in fields)) {
|
|
120
|
+
fields[name] = '';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
fields[name] = input.getAttribute('value') ?? '';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
for (const select of form.querySelectorAll('select')) {
|
|
128
|
+
const name = select.getAttribute('name');
|
|
129
|
+
if (!name)
|
|
130
|
+
continue;
|
|
131
|
+
const selected = select.querySelector('option[selected]');
|
|
132
|
+
fields[name] = selected?.getAttribute('value') ?? '';
|
|
133
|
+
}
|
|
134
|
+
for (const textarea of form.querySelectorAll('textarea')) {
|
|
135
|
+
const name = textarea.getAttribute('name');
|
|
136
|
+
if (!name)
|
|
137
|
+
continue;
|
|
138
|
+
fields[name] = textarea.text ?? '';
|
|
139
|
+
}
|
|
140
|
+
return fields;
|
|
141
|
+
}
|
|
66
142
|
export function parseRoomList(html) {
|
|
67
143
|
const root = parse(html);
|
|
68
144
|
const cards = root.querySelectorAll('ul.bbs-reserve > li.item');
|
|
@@ -87,6 +163,82 @@ export function parseRoomSlots(html) {
|
|
|
87
163
|
}
|
|
88
164
|
return slots.map(parseRoomTimeSlot).filter((slot) => Boolean(slot.time));
|
|
89
165
|
}
|
|
166
|
+
export function parseRoomReservationDetail(html) {
|
|
167
|
+
const root = parse(html);
|
|
168
|
+
const form = root.querySelector('form#frm') ?? root.querySelector('form');
|
|
169
|
+
const fields = {};
|
|
170
|
+
for (const input of form?.querySelectorAll('input, select, textarea') ?? []) {
|
|
171
|
+
const name = input.getAttribute('name');
|
|
172
|
+
if (!name)
|
|
173
|
+
continue;
|
|
174
|
+
fields[name] = input.getAttribute('value') ?? input.text ?? '';
|
|
175
|
+
}
|
|
176
|
+
const statusCode = fields.receiptStatCd ?? '';
|
|
177
|
+
return RoomReservationDetailSchema.parse({
|
|
178
|
+
rentId: extractNumber(fields.rentId ?? ''),
|
|
179
|
+
itemId: extractNumber(fields.itemId ?? ''),
|
|
180
|
+
title: fields.title ?? '',
|
|
181
|
+
date: fields.rentDt ?? extractReservationDate(fields.rentBgnde),
|
|
182
|
+
startTime: extractReservationTime(fields.rentBgnde),
|
|
183
|
+
endTime: extractReservationTime(fields.rentEndde),
|
|
184
|
+
attendees: extractNumber(fields.rentNum ?? '') || 1,
|
|
185
|
+
notes: fields.infoCn ?? '',
|
|
186
|
+
status: resolveReservationStatus(statusCode),
|
|
187
|
+
statusCode,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function extractReservationDate(value) {
|
|
191
|
+
if (!value)
|
|
192
|
+
return '';
|
|
193
|
+
return value.slice(0, 10);
|
|
194
|
+
}
|
|
195
|
+
function extractReservationTime(value) {
|
|
196
|
+
if (!value)
|
|
197
|
+
return '';
|
|
198
|
+
const match = value.match(/\d{2}:\d{2}/);
|
|
199
|
+
return match?.[0] ?? '';
|
|
200
|
+
}
|
|
201
|
+
function resolveReservationStatus(code) {
|
|
202
|
+
if (code === 'RS001')
|
|
203
|
+
return 'confirmed';
|
|
204
|
+
if (code === 'RS002')
|
|
205
|
+
return 'cancelled';
|
|
206
|
+
return 'unknown';
|
|
207
|
+
}
|
|
208
|
+
export function parseRoomReservationList(html) {
|
|
209
|
+
return findTableRows(html, 7).map((cells) => {
|
|
210
|
+
const venueLink = cells[1]?.querySelector('a');
|
|
211
|
+
const rentId = extractUrlParam(venueLink?.getAttribute('href'), 'rentId');
|
|
212
|
+
const titleLink = cells[2]?.querySelector('.rel a');
|
|
213
|
+
const periodText = cleanText(cells[3]);
|
|
214
|
+
const statusLabel = cleanText(cells[5]);
|
|
215
|
+
return RoomReservationListItemSchema.parse({
|
|
216
|
+
rentId,
|
|
217
|
+
venue: cleanText(venueLink ?? cells[1]),
|
|
218
|
+
title: cleanText(titleLink),
|
|
219
|
+
date: extractFirstDate(periodText),
|
|
220
|
+
startTime: extractReservationStartTime(periodText),
|
|
221
|
+
endTime: extractReservationEndTime(periodText),
|
|
222
|
+
author: cleanText(cells[4]),
|
|
223
|
+
status: statusLabelToStatus(statusLabel),
|
|
224
|
+
statusLabel,
|
|
225
|
+
registeredAt: cleanText(cells[6]),
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function statusLabelToStatus(label) {
|
|
230
|
+
if (label.includes('예약완료'))
|
|
231
|
+
return 'confirmed';
|
|
232
|
+
if (label.includes('예약취소') || label.includes('취소'))
|
|
233
|
+
return 'cancelled';
|
|
234
|
+
return 'unknown';
|
|
235
|
+
}
|
|
236
|
+
function extractReservationStartTime(text) {
|
|
237
|
+
return text.match(/\d{2}:\d{2}/)?.[0] ?? '';
|
|
238
|
+
}
|
|
239
|
+
function extractReservationEndTime(text) {
|
|
240
|
+
return text.match(/\d{2}:\d{2}/g)?.[1] ?? '';
|
|
241
|
+
}
|
|
90
242
|
export function parseDashboard(html) {
|
|
91
243
|
const root = parse(html);
|
|
92
244
|
const profileCard = root.querySelector('ul.dash-top > li.dash-card');
|
|
@@ -104,6 +256,7 @@ export function parseDashboard(html) {
|
|
|
104
256
|
organization: extractDashEtcValue(dashEtc, '소속'),
|
|
105
257
|
position: extractDashEtcValue(dashEtc, '직책'),
|
|
106
258
|
team: team.name || team.members || team.mentor ? team : undefined,
|
|
259
|
+
teams: [],
|
|
107
260
|
mentoringSessions: parseDashboardLinks(root, (href) => href.includes('/mentoLec/')),
|
|
108
261
|
roomReservations: parseDashboardLinks(root, (href) => href.includes('/itemRent/') || href.includes('/officeMng/')),
|
|
109
262
|
});
|
|
@@ -143,15 +296,11 @@ export function parseTeamInfo(html) {
|
|
|
143
296
|
const root = parse(html);
|
|
144
297
|
const cards = root.querySelectorAll('ul.bbs-team > li');
|
|
145
298
|
const summaryText = cleanText(root.querySelector('p.ico-team'));
|
|
146
|
-
const
|
|
299
|
+
const summary = parseTeamSummary(summaryText);
|
|
147
300
|
return TeamInfoSchema.parse({
|
|
148
|
-
teams: cards.map((card) => (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
joinStatus: extractJoinStatus(card),
|
|
152
|
-
})),
|
|
153
|
-
currentTeams: summaryNumbers ? Number.parseInt(summaryNumbers[1], 10) : 0,
|
|
154
|
-
maxTeams: summaryNumbers ? Number.parseInt(summaryNumbers[2], 10) : 0,
|
|
301
|
+
teams: cards.map((card) => parseTeamCard(card)),
|
|
302
|
+
currentTeams: summary.current,
|
|
303
|
+
maxTeams: summary.max,
|
|
155
304
|
});
|
|
156
305
|
}
|
|
157
306
|
export function parseMemberInfo(html) {
|
|
@@ -166,42 +315,72 @@ export function parseMemberInfo(html) {
|
|
|
166
315
|
position: labels['직책'] || '',
|
|
167
316
|
});
|
|
168
317
|
}
|
|
169
|
-
export function
|
|
170
|
-
|
|
171
|
-
|
|
318
|
+
export function parseScheduleList(html) {
|
|
319
|
+
const root = parse(html);
|
|
320
|
+
const monthlyScheduleTable = findTableByHeaders(root, ['날짜', '구분', '제목']);
|
|
321
|
+
const scheduleRows = monthlyScheduleTable?.querySelectorAll('tbody tr') ?? [];
|
|
322
|
+
const items = scheduleRows
|
|
323
|
+
.map((row) => row.querySelectorAll('td'))
|
|
324
|
+
.filter((cells) => cells.length === 3)
|
|
325
|
+
.map((cells, index) => ScheduleListItemSchema.parse({
|
|
326
|
+
id: index + 1,
|
|
172
327
|
category: cleanText(cells[1]),
|
|
173
|
-
title: cleanText(cells[2]
|
|
174
|
-
|
|
175
|
-
eventPeriod: extractDateRange(cleanText(cells[4])),
|
|
176
|
-
status: stripWrappingBrackets(cleanText(cells[5])),
|
|
177
|
-
createdAt: cleanText(cells[6]),
|
|
328
|
+
title: cleanText(cells[2]),
|
|
329
|
+
period: extractDateRange(cleanText(cells[0])),
|
|
178
330
|
}));
|
|
331
|
+
// SWMaestro's monthly schedule page does not render the bbs-total pagination block,
|
|
332
|
+
// so synthesize a single-page response when items exist but parsePagination found none.
|
|
333
|
+
const parsedPagination = parsePagination(html, { itemCount: items.length });
|
|
334
|
+
const pagination = parsedPagination.total === 0 && items.length > 0
|
|
335
|
+
? PaginationSchema.parse({ total: items.length, currentPage: 1, totalPages: 1 })
|
|
336
|
+
: parsedPagination;
|
|
337
|
+
return { items, pagination };
|
|
179
338
|
}
|
|
180
339
|
export function parseApplicationHistory(html) {
|
|
181
|
-
return findTableRows(html, 10).map((cells) =>
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
340
|
+
return findTableRows(html, 10).map((cells) => {
|
|
341
|
+
const link = cells[2]?.querySelector('a');
|
|
342
|
+
const url = link?.getAttribute('href');
|
|
343
|
+
return ApplicationHistoryItemSchema.parse({
|
|
344
|
+
id: extractNumber(cleanText(cells[0])),
|
|
345
|
+
category: cleanText(cells[1]),
|
|
346
|
+
title: cleanText(link ?? cells[2]),
|
|
347
|
+
...(url ? { url } : {}),
|
|
348
|
+
author: cleanText(cells[3]),
|
|
349
|
+
sessionDate: normalizeDate(cleanText(cells[4])),
|
|
350
|
+
appliedAt: cleanText(cells[5]),
|
|
351
|
+
applicationStatus: stripWrappingBrackets(cleanText(cells[6])),
|
|
352
|
+
approvalStatus: stripWrappingBrackets(cleanText(cells[7])),
|
|
353
|
+
applicationDetail: cleanText(cells[8]),
|
|
354
|
+
note: cleanText(cells[9]),
|
|
355
|
+
});
|
|
356
|
+
});
|
|
193
357
|
}
|
|
194
|
-
export function parsePagination(html) {
|
|
358
|
+
export function parsePagination(html, options) {
|
|
195
359
|
const root = parse(html);
|
|
196
360
|
const items = root.querySelectorAll('ul.bbs-total > li').map((item) => cleanText(item));
|
|
197
361
|
const total = extractNumber(items.find((item) => item.includes('Total')) ?? '');
|
|
198
362
|
const pageMatch = items.find((item) => item.includes('Page'))?.match(/(\d+)\s*\/\s*(\d+)\s*Page/i);
|
|
363
|
+
const currentPage = pageMatch ? Number.parseInt(pageMatch[1], 10) : 1;
|
|
364
|
+
const parsedTotalPages = pageMatch ? Number.parseInt(pageMatch[2], 10) : 1;
|
|
199
365
|
return PaginationSchema.parse({
|
|
200
366
|
total,
|
|
201
|
-
currentPage
|
|
202
|
-
totalPages:
|
|
367
|
+
currentPage,
|
|
368
|
+
totalPages: deriveTotalPages({ total, currentPage, parsedTotalPages, itemCount: options?.itemCount }),
|
|
203
369
|
});
|
|
204
370
|
}
|
|
371
|
+
function deriveTotalPages({ total, currentPage, parsedTotalPages, itemCount, }) {
|
|
372
|
+
if (total <= 0)
|
|
373
|
+
return 1;
|
|
374
|
+
const fallback = Math.max(1, parsedTotalPages, currentPage);
|
|
375
|
+
if (itemCount === undefined)
|
|
376
|
+
return fallback;
|
|
377
|
+
// SWMaestro's `1/50 Page` text is unreliable on some lists (e.g. report) — the server emits a
|
|
378
|
+
// hardcoded cap regardless of actual data. When the visible items already cover the total,
|
|
379
|
+
// there is only one page; correct the bogus value rather than echo it.
|
|
380
|
+
if (currentPage === 1 && total <= itemCount)
|
|
381
|
+
return 1;
|
|
382
|
+
return fallback;
|
|
383
|
+
}
|
|
205
384
|
export function parseCsrfToken(html) {
|
|
206
385
|
const token = parse(html).querySelector('input[name="csrfToken"]')?.getAttribute('value');
|
|
207
386
|
if (!token) {
|
|
@@ -211,11 +390,15 @@ export function parseCsrfToken(html) {
|
|
|
211
390
|
}
|
|
212
391
|
export function parseReportList(html) {
|
|
213
392
|
return findTableRows(html, 9).map((cells) => {
|
|
214
|
-
|
|
393
|
+
// Native list cell layout: `td.tit > div.date_m > span.l > a` holds the
|
|
394
|
+
// category, and `td.tit > div.rel > a` holds the actual title that matches
|
|
395
|
+
// the `제목` label on the detail page (e.g. "[자유 멘토링] 2026년 04월 30일
|
|
396
|
+
// 멘토링 보고"). Prefer the `.rel a` so list and detail titles agree.
|
|
397
|
+
const titleLink = cells[2]?.querySelector('div.rel a') ?? cells[2]?.querySelector('a');
|
|
215
398
|
return ReportListItemSchema.parse({
|
|
216
|
-
id: extractUrlParam(
|
|
399
|
+
id: extractUrlParam(titleLink?.getAttribute('href'), 'reportId'),
|
|
217
400
|
category: cleanText(cells[1]),
|
|
218
|
-
title: cleanText(
|
|
401
|
+
title: cleanText(titleLink ?? cells[2]),
|
|
219
402
|
progressDate: cleanText(cells[3]),
|
|
220
403
|
status: cleanText(cells[4]),
|
|
221
404
|
author: cleanText(cells[5]),
|
|
@@ -317,6 +500,12 @@ function findTableRows(html, cellCount) {
|
|
|
317
500
|
.map((row) => row.querySelectorAll('td'))
|
|
318
501
|
.filter((cells) => cells.length === cellCount);
|
|
319
502
|
}
|
|
503
|
+
function findTableByHeaders(root, headers) {
|
|
504
|
+
return root.querySelectorAll('table').find((table) => {
|
|
505
|
+
const tableHeaders = table.querySelectorAll('thead th').map((header) => cleanText(header));
|
|
506
|
+
return headers.every((header, index) => tableHeaders[index] === header);
|
|
507
|
+
});
|
|
508
|
+
}
|
|
320
509
|
function extractLabelMap(root) {
|
|
321
510
|
const map = {};
|
|
322
511
|
for (const row of root.querySelectorAll('tr')) {
|
|
@@ -441,16 +630,6 @@ function extractUrlParam(url, key) {
|
|
|
441
630
|
return 0;
|
|
442
631
|
}
|
|
443
632
|
}
|
|
444
|
-
function extractLinkParam(cell, keys) {
|
|
445
|
-
const href = cell?.querySelector('a')?.getAttribute('href');
|
|
446
|
-
for (const key of keys) {
|
|
447
|
-
const value = extractUrlParam(href, key);
|
|
448
|
-
if (value > 0) {
|
|
449
|
-
return value;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
return 0;
|
|
453
|
-
}
|
|
454
633
|
function extractDateRange(text) {
|
|
455
634
|
const dates = text.match(/\d{4}[.-]\d{2}[.-]\d{2}/g)?.map(normalizeDate) ?? [];
|
|
456
635
|
return { start: dates[0] ?? '', end: dates[1] ?? '' };
|
|
@@ -476,15 +655,65 @@ function extractCapacity(text) {
|
|
|
476
655
|
const match = text.match(/(\d+)\s*인/);
|
|
477
656
|
return match ? Number.parseInt(match[1], 10) : 0;
|
|
478
657
|
}
|
|
479
|
-
function
|
|
480
|
-
const
|
|
481
|
-
|
|
658
|
+
function parseTeamCard(card) {
|
|
659
|
+
const titleAnchor = card.querySelector('.top strong.t a');
|
|
660
|
+
const teamPageGoArgs = parseTeamPageGoArgs(titleAnchor?.getAttribute('onclick') ?? '');
|
|
661
|
+
const infoItems = card.querySelectorAll('.top ul.info > li');
|
|
662
|
+
const ictItems = card.querySelectorAll('.bot ul.ict > li');
|
|
663
|
+
return {
|
|
664
|
+
name: cleanText(titleAnchor),
|
|
665
|
+
projectName: cleanText(card.querySelector('.top .add-txt')),
|
|
666
|
+
ownerId: teamPageGoArgs[1] ?? '',
|
|
667
|
+
teamId: teamPageGoArgs[2] ?? '',
|
|
668
|
+
leader: extractInfoLeader(infoItems),
|
|
669
|
+
members: extractInfoMembers(infoItems, '팀원'),
|
|
670
|
+
mentors: extractInfoMembers(infoItems, '멘토'),
|
|
671
|
+
ictCategoryMajor: extractIctCategory(ictItems, '대'),
|
|
672
|
+
ictCategoryMinor: extractIctCategory(ictItems, '중'),
|
|
673
|
+
teamCompleted: card.querySelector('.team-com .t1') !== null,
|
|
674
|
+
mentorCompleted: card.querySelector('.team-com .t2') !== null,
|
|
675
|
+
joinStatus: extractJoinStatus(card),
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
function parseTeamSummary(text) {
|
|
679
|
+
const match = text.match(/(\d+)\s*(?:\/\s*(\d+))?\s*팀/);
|
|
680
|
+
return {
|
|
681
|
+
current: match ? Number.parseInt(match[1], 10) : 0,
|
|
682
|
+
max: match?.[2] ? Number.parseInt(match[2], 10) : 0,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
function parseTeamPageGoArgs(onclick) {
|
|
686
|
+
// teamPageGo('전수열','f6d192...','ef9d3b...');
|
|
687
|
+
const match = onclick.match(/teamPageGo\(\s*'([^']*)'\s*,\s*'([^']*)'\s*,\s*'([^']*)'\s*\)/);
|
|
688
|
+
return match ? [match[1], match[2], match[3]] : [];
|
|
689
|
+
}
|
|
690
|
+
function findInfoItemByLabel(items, label) {
|
|
691
|
+
return items.find((item) => cleanText(item.querySelector('strong')).startsWith(label));
|
|
692
|
+
}
|
|
693
|
+
function extractInfoLeader(items) {
|
|
694
|
+
const leaderItem = findInfoItemByLabel(items, '팀장');
|
|
695
|
+
return cleanText(leaderItem?.querySelector('span a')) || cleanText(leaderItem?.querySelector('span'));
|
|
696
|
+
}
|
|
697
|
+
function extractInfoMembers(items, label) {
|
|
698
|
+
const item = findInfoItemByLabel(items, label);
|
|
699
|
+
if (!item)
|
|
700
|
+
return [];
|
|
701
|
+
return item.querySelectorAll('span a').map((anchor) => ({
|
|
702
|
+
name: cleanText(anchor),
|
|
703
|
+
userId: extractPopuserUserId(anchor.getAttribute('href') ?? ''),
|
|
704
|
+
}));
|
|
705
|
+
}
|
|
706
|
+
function extractPopuserUserId(href) {
|
|
707
|
+
// javascript: popuser('113889210806408397ea7db2ea855f71')
|
|
708
|
+
const match = href.match(/popuser\(\s*'([^']*)'/);
|
|
709
|
+
return match ? match[1] : '';
|
|
710
|
+
}
|
|
711
|
+
function extractIctCategory(items, group) {
|
|
712
|
+
const item = items.find((node) => cleanText(node).includes(`(${group})`));
|
|
713
|
+
return cleanText(item?.querySelector('span'));
|
|
482
714
|
}
|
|
483
715
|
function extractJoinStatus(card) {
|
|
484
|
-
return
|
|
485
|
-
cleanText(card.querySelector('.btn')) ||
|
|
486
|
-
cleanText(card.querySelector('[class*="join"]')) ||
|
|
487
|
-
'');
|
|
716
|
+
return cleanText(card.querySelector('.bot .btn_w .btn-team'));
|
|
488
717
|
}
|
|
489
718
|
function extractTrailingStatus(text) {
|
|
490
719
|
const match = text.match(/(예약완료|예약중|대기|접수중|마감|승인완료|신청완료)$/);
|