@jackie-chan/jobtrack 0.1.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/LICENSE +21 -0
- package/README.md +133 -0
- package/dist/commands/company.command.d.ts +3 -0
- package/dist/commands/company.command.d.ts.map +1 -0
- package/dist/commands/company.command.js +29 -0
- package/dist/commands/company.command.js.map +1 -0
- package/dist/commands/db.command.d.ts +3 -0
- package/dist/commands/db.command.d.ts.map +1 -0
- package/dist/commands/db.command.js +17 -0
- package/dist/commands/db.command.js.map +1 -0
- package/dist/commands/job.command.d.ts +8 -0
- package/dist/commands/job.command.d.ts.map +1 -0
- package/dist/commands/job.command.js +91 -0
- package/dist/commands/job.command.js.map +1 -0
- package/dist/commands/location.command.d.ts +3 -0
- package/dist/commands/location.command.d.ts.map +1 -0
- package/dist/commands/location.command.js +21 -0
- package/dist/commands/location.command.js.map +1 -0
- package/dist/commands/profile.command.d.ts +3 -0
- package/dist/commands/profile.command.d.ts.map +1 -0
- package/dist/commands/profile.command.js +29 -0
- package/dist/commands/profile.command.js.map +1 -0
- package/dist/commands/serve.command.d.ts +3 -0
- package/dist/commands/serve.command.d.ts.map +1 -0
- package/dist/commands/serve.command.js +9 -0
- package/dist/commands/serve.command.js.map +1 -0
- package/dist/controllers/cli/companyController.d.ts +11 -0
- package/dist/controllers/cli/companyController.d.ts.map +1 -0
- package/dist/controllers/cli/companyController.js +57 -0
- package/dist/controllers/cli/companyController.js.map +1 -0
- package/dist/controllers/cli/db.controller.d.ts +4 -0
- package/dist/controllers/cli/db.controller.d.ts.map +1 -0
- package/dist/controllers/cli/db.controller.js +71 -0
- package/dist/controllers/cli/db.controller.js.map +1 -0
- package/dist/controllers/cli/job.controller.d.ts +8 -0
- package/dist/controllers/cli/job.controller.d.ts.map +1 -0
- package/dist/controllers/cli/job.controller.js +68 -0
- package/dist/controllers/cli/job.controller.js.map +1 -0
- package/dist/controllers/cli/locationController.d.ts +5 -0
- package/dist/controllers/cli/locationController.d.ts.map +1 -0
- package/dist/controllers/cli/locationController.js +57 -0
- package/dist/controllers/cli/locationController.js.map +1 -0
- package/dist/controllers/cli/profile.controller.d.ts +6 -0
- package/dist/controllers/cli/profile.controller.d.ts.map +1 -0
- package/dist/controllers/cli/profile.controller.js +42 -0
- package/dist/controllers/cli/profile.controller.js.map +1 -0
- package/dist/controllers/httpController.d.ts +8 -0
- package/dist/controllers/httpController.d.ts.map +1 -0
- package/dist/controllers/httpController.js +76 -0
- package/dist/controllers/httpController.js.map +1 -0
- package/dist/database/database.d.ts +4 -0
- package/dist/database/database.d.ts.map +1 -0
- package/dist/database/database.js +203 -0
- package/dist/database/database.js.map +1 -0
- package/dist/database/types/companies.type.d.ts +10 -0
- package/dist/database/types/companies.type.d.ts.map +1 -0
- package/dist/database/types/companies.type.js +2 -0
- package/dist/database/types/companies.type.js.map +1 -0
- package/dist/database/types/contacts.type.d.ts +13 -0
- package/dist/database/types/contacts.type.d.ts.map +1 -0
- package/dist/database/types/contacts.type.js +2 -0
- package/dist/database/types/contacts.type.js.map +1 -0
- package/dist/database/types/interviews.type.d.ts +11 -0
- package/dist/database/types/interviews.type.d.ts.map +1 -0
- package/dist/database/types/interviews.type.js +2 -0
- package/dist/database/types/interviews.type.js.map +1 -0
- package/dist/database/types/jobactivity.type.d.ts +7 -0
- package/dist/database/types/jobactivity.type.d.ts.map +1 -0
- package/dist/database/types/jobactivity.type.js +2 -0
- package/dist/database/types/jobactivity.type.js.map +1 -0
- package/dist/database/types/jobcontacts.type.d.ts +5 -0
- package/dist/database/types/jobcontacts.type.d.ts.map +1 -0
- package/dist/database/types/jobcontacts.type.js +2 -0
- package/dist/database/types/jobcontacts.type.js.map +1 -0
- package/dist/database/types/jobdocs.type.d.ts +9 -0
- package/dist/database/types/jobdocs.type.d.ts.map +1 -0
- package/dist/database/types/jobdocs.type.js +2 -0
- package/dist/database/types/jobdocs.type.js.map +1 -0
- package/dist/database/types/joblocation.type.d.ts +5 -0
- package/dist/database/types/joblocation.type.d.ts.map +1 -0
- package/dist/database/types/joblocation.type.js +2 -0
- package/dist/database/types/joblocation.type.js.map +1 -0
- package/dist/database/types/jobpriority.type.d.ts +6 -0
- package/dist/database/types/jobpriority.type.d.ts.map +1 -0
- package/dist/database/types/jobpriority.type.js +2 -0
- package/dist/database/types/jobpriority.type.js.map +1 -0
- package/dist/database/types/jobs.type.d.ts +37 -0
- package/dist/database/types/jobs.type.d.ts.map +1 -0
- package/dist/database/types/jobs.type.js +2 -0
- package/dist/database/types/jobs.type.js.map +1 -0
- package/dist/database/types/jobsource.type.d.ts +5 -0
- package/dist/database/types/jobsource.type.d.ts.map +1 -0
- package/dist/database/types/jobsource.type.js +2 -0
- package/dist/database/types/jobsource.type.js.map +1 -0
- package/dist/database/types/jobstatuses.type.d.ts +6 -0
- package/dist/database/types/jobstatuses.type.d.ts.map +1 -0
- package/dist/database/types/jobstatuses.type.js +2 -0
- package/dist/database/types/jobstatuses.type.js.map +1 -0
- package/dist/database/types/jobstatushistory.type.d.ts +8 -0
- package/dist/database/types/jobstatushistory.type.d.ts.map +1 -0
- package/dist/database/types/jobstatushistory.type.js +2 -0
- package/dist/database/types/jobstatushistory.type.js.map +1 -0
- package/dist/database/types/jobtags.type.d.ts +6 -0
- package/dist/database/types/jobtags.type.d.ts.map +1 -0
- package/dist/database/types/jobtags.type.js +2 -0
- package/dist/database/types/jobtags.type.js.map +1 -0
- package/dist/database/types/jobtasks.type.d.ts +10 -0
- package/dist/database/types/jobtasks.type.d.ts.map +1 -0
- package/dist/database/types/jobtasks.type.js +2 -0
- package/dist/database/types/jobtasks.type.js.map +1 -0
- package/dist/database/types/profile.type.d.ts +7 -0
- package/dist/database/types/profile.type.d.ts.map +1 -0
- package/dist/database/types/profile.type.js +2 -0
- package/dist/database/types/profile.type.js.map +1 -0
- package/dist/database/types/settings.type.d.ts +7 -0
- package/dist/database/types/settings.type.d.ts.map +1 -0
- package/dist/database/types/settings.type.js +2 -0
- package/dist/database/types/settings.type.js.map +1 -0
- package/dist/database/types/tags.type.d.ts +7 -0
- package/dist/database/types/tags.type.d.ts.map +1 -0
- package/dist/database/types/tags.type.js +2 -0
- package/dist/database/types/tags.type.js.map +1 -0
- package/dist/database/types.d.ts +79 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +18 -0
- package/dist/database/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/repository/companyRepository.d.ts +8 -0
- package/dist/repository/companyRepository.d.ts.map +1 -0
- package/dist/repository/companyRepository.js +53 -0
- package/dist/repository/companyRepository.js.map +1 -0
- package/dist/repository/core.repository.d.ts +16 -0
- package/dist/repository/core.repository.d.ts.map +1 -0
- package/dist/repository/core.repository.js +57 -0
- package/dist/repository/core.repository.js.map +1 -0
- package/dist/repository/jobsRepository.d.ts +14 -0
- package/dist/repository/jobsRepository.d.ts.map +1 -0
- package/dist/repository/jobsRepository.js +186 -0
- package/dist/repository/jobsRepository.js.map +1 -0
- package/dist/repository/locationRepository.d.ts +11 -0
- package/dist/repository/locationRepository.d.ts.map +1 -0
- package/dist/repository/locationRepository.js +33 -0
- package/dist/repository/locationRepository.js.map +1 -0
- package/dist/repository/profileRepository.d.ts +7 -0
- package/dist/repository/profileRepository.d.ts.map +1 -0
- package/dist/repository/profileRepository.js +25 -0
- package/dist/repository/profileRepository.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +16 -0
- package/dist/server.js.map +1 -0
- package/dist/service/companyService.d.ts +6 -0
- package/dist/service/companyService.d.ts.map +1 -0
- package/dist/service/companyService.js +32 -0
- package/dist/service/companyService.js.map +1 -0
- package/dist/service/jobService.d.ts +18 -0
- package/dist/service/jobService.d.ts.map +1 -0
- package/dist/service/jobService.js +48 -0
- package/dist/service/jobService.js.map +1 -0
- package/dist/service/locationService.d.ts +6 -0
- package/dist/service/locationService.d.ts.map +1 -0
- package/dist/service/locationService.js +31 -0
- package/dist/service/locationService.js.map +1 -0
- package/dist/service/profileService.d.ts +10 -0
- package/dist/service/profileService.d.ts.map +1 -0
- package/dist/service/profileService.js +42 -0
- package/dist/service/profileService.js.map +1 -0
- package/dist/session/session.d.ts +12 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/session/session.js +22 -0
- package/dist/session/session.js.map +1 -0
- package/dist/transformers/output.d.ts +10 -0
- package/dist/transformers/output.d.ts.map +1 -0
- package/dist/transformers/output.js +67 -0
- package/dist/transformers/output.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { database } from "../database/database.js";
|
|
2
|
+
// Every SQL statement in the whole app lives in this one file.
|
|
3
|
+
// This layer is also the only place that translates between human-readable
|
|
4
|
+
// names ("applied", "Remote") and the numeric IDs the schema actually stores.
|
|
5
|
+
function findOrCreateCompany(profileId, name) {
|
|
6
|
+
const existing = database
|
|
7
|
+
.prepare(`SELECT id FROM companies WHERE profile_id = ? AND name = ?`)
|
|
8
|
+
.get(profileId, name);
|
|
9
|
+
if (existing)
|
|
10
|
+
return existing.id;
|
|
11
|
+
const result = database
|
|
12
|
+
.prepare(`INSERT INTO companies (profile_id, name) VALUES (?, ?)`)
|
|
13
|
+
.run(profileId, name);
|
|
14
|
+
return Number(result.lastInsertRowid);
|
|
15
|
+
}
|
|
16
|
+
// Generic helper: look up a lookup table row's ID by name.
|
|
17
|
+
// Used for every FK the schema now has (status, source, location, mode,
|
|
18
|
+
// priority, salary_period) so we're not repeating this five times.
|
|
19
|
+
function getLookupId(table, name) {
|
|
20
|
+
const row = database
|
|
21
|
+
.prepare(`SELECT id FROM ${table} WHERE name = ?`)
|
|
22
|
+
.get(name);
|
|
23
|
+
return row ? row.id : null;
|
|
24
|
+
}
|
|
25
|
+
function requireLookupId(table, name) {
|
|
26
|
+
const id = getLookupId(table, name);
|
|
27
|
+
if (id === null) {
|
|
28
|
+
throw new Error(`"${name}" is not a valid value for ${table}.`);
|
|
29
|
+
}
|
|
30
|
+
return id;
|
|
31
|
+
}
|
|
32
|
+
export function insertJob(profileId, data) {
|
|
33
|
+
const companyId = findOrCreateCompany(profileId, data.company_name);
|
|
34
|
+
const statusId = requireLookupId("job_statuses", data.status ?? "applied");
|
|
35
|
+
const sourceId = data.source_name ? getLookupId("job_sources", data.source_name) : null;
|
|
36
|
+
const locationId = data.location_name
|
|
37
|
+
? getLookupId("job_locations", data.location_name)
|
|
38
|
+
: null;
|
|
39
|
+
const modeId = data.mode_name ? getLookupId("job_modes", data.mode_name) : null;
|
|
40
|
+
const priorityId = data.priority_name
|
|
41
|
+
? getLookupId("job_priorities", data.priority_name)
|
|
42
|
+
: null;
|
|
43
|
+
const salaryPeriodId = data.salary_period_name
|
|
44
|
+
? getLookupId("salary_periods", data.salary_period_name)
|
|
45
|
+
: null;
|
|
46
|
+
const stmt = database.prepare(`
|
|
47
|
+
INSERT INTO jobs (
|
|
48
|
+
profile_id, company_id, role, status_id, source_id, location_id,
|
|
49
|
+
mode_id, priority_id, date_applied, link, notes,
|
|
50
|
+
salary_min, salary_max, salary_currency, salary_period_id
|
|
51
|
+
) VALUES (
|
|
52
|
+
@profile_id, @company_id, @role, @status_id, @source_id, @location_id,
|
|
53
|
+
@mode_id, @priority_id, @date_applied, @link, @notes,
|
|
54
|
+
@salary_min, @salary_max, @salary_currency, @salary_period_id
|
|
55
|
+
)
|
|
56
|
+
`);
|
|
57
|
+
const result = stmt.run({
|
|
58
|
+
profile_id: profileId,
|
|
59
|
+
company_id: companyId,
|
|
60
|
+
role: data.role,
|
|
61
|
+
status_id: statusId,
|
|
62
|
+
source_id: sourceId,
|
|
63
|
+
location_id: locationId,
|
|
64
|
+
mode_id: modeId,
|
|
65
|
+
priority_id: priorityId,
|
|
66
|
+
date_applied: data.date_applied,
|
|
67
|
+
link: data.link ?? null,
|
|
68
|
+
notes: data.notes ?? null,
|
|
69
|
+
salary_min: data.salary_min ?? null,
|
|
70
|
+
salary_max: data.salary_max ?? null,
|
|
71
|
+
salary_currency: data.salary_currency ?? "USD",
|
|
72
|
+
salary_period_id: salaryPeriodId,
|
|
73
|
+
});
|
|
74
|
+
const jobId = Number(result.lastInsertRowid);
|
|
75
|
+
database
|
|
76
|
+
.prepare(`INSERT INTO job_status_history (job_id, status_id) VALUES (?, ?)`)
|
|
77
|
+
.run(jobId, statusId);
|
|
78
|
+
return jobId;
|
|
79
|
+
}
|
|
80
|
+
// One shared SELECT shape, joining every lookup table so the caller always
|
|
81
|
+
// gets names back, never raw IDs.
|
|
82
|
+
const JOB_WITH_DETAILS_SELECT = `
|
|
83
|
+
SELECT
|
|
84
|
+
jobs.*,
|
|
85
|
+
companies.name AS company_name,
|
|
86
|
+
job_statuses.name AS status,
|
|
87
|
+
job_sources.name AS source_name,
|
|
88
|
+
job_locations.name AS location_name,
|
|
89
|
+
job_modes.name AS mode_name,
|
|
90
|
+
job_priorities.name AS priority_name,
|
|
91
|
+
salary_periods.name AS salary_period_name
|
|
92
|
+
FROM jobs
|
|
93
|
+
JOIN companies ON companies.id = jobs.company_id
|
|
94
|
+
JOIN job_statuses ON job_statuses.id = jobs.status_id
|
|
95
|
+
LEFT JOIN job_sources ON job_sources.id = jobs.source_id
|
|
96
|
+
LEFT JOIN job_locations ON job_locations.id = jobs.location_id
|
|
97
|
+
LEFT JOIN job_modes ON job_modes.id = jobs.mode_id
|
|
98
|
+
LEFT JOIN job_priorities ON job_priorities.id = jobs.priority_id
|
|
99
|
+
LEFT JOIN salary_periods ON salary_periods.id = jobs.salary_period_id
|
|
100
|
+
`;
|
|
101
|
+
export function getAllJobs(profileId) {
|
|
102
|
+
return database
|
|
103
|
+
.prepare(`${JOB_WITH_DETAILS_SELECT} WHERE jobs.profile_id = ? ORDER BY jobs.date_applied DESC`)
|
|
104
|
+
.all(profileId);
|
|
105
|
+
}
|
|
106
|
+
export function getJobById(profileId, id) {
|
|
107
|
+
return database
|
|
108
|
+
.prepare(`${JOB_WITH_DETAILS_SELECT} WHERE jobs.profile_id = ? AND jobs.id = ?`)
|
|
109
|
+
.get(profileId, id);
|
|
110
|
+
}
|
|
111
|
+
// Partial update -- only columns present in `data` are touched. Name-based
|
|
112
|
+
// fields go back through the same lookup helpers insertJob uses, so this
|
|
113
|
+
// stays the only place that resolves names to IDs for jobs.
|
|
114
|
+
export function updateJob(profileId, id, data) {
|
|
115
|
+
const fields = {};
|
|
116
|
+
if (data.company_name !== undefined) {
|
|
117
|
+
fields.company_id = findOrCreateCompany(profileId, data.company_name);
|
|
118
|
+
}
|
|
119
|
+
if (data.role !== undefined)
|
|
120
|
+
fields.role = data.role;
|
|
121
|
+
if (data.status !== undefined)
|
|
122
|
+
fields.status_id = requireLookupId("job_statuses", data.status);
|
|
123
|
+
if (data.date_applied !== undefined)
|
|
124
|
+
fields.date_applied = data.date_applied;
|
|
125
|
+
if (data.link !== undefined)
|
|
126
|
+
fields.link = data.link;
|
|
127
|
+
if (data.notes !== undefined)
|
|
128
|
+
fields.notes = data.notes;
|
|
129
|
+
if (data.source_name !== undefined)
|
|
130
|
+
fields.source_id = getLookupId("job_sources", data.source_name);
|
|
131
|
+
if (data.location_name !== undefined)
|
|
132
|
+
fields.location_id = getLookupId("job_locations", data.location_name);
|
|
133
|
+
if (data.mode_name !== undefined)
|
|
134
|
+
fields.mode_id = getLookupId("job_modes", data.mode_name);
|
|
135
|
+
if (data.priority_name !== undefined)
|
|
136
|
+
fields.priority_id = getLookupId("job_priorities", data.priority_name);
|
|
137
|
+
if (data.salary_min !== undefined)
|
|
138
|
+
fields.salary_min = data.salary_min;
|
|
139
|
+
if (data.salary_max !== undefined)
|
|
140
|
+
fields.salary_max = data.salary_max;
|
|
141
|
+
if (data.salary_currency !== undefined)
|
|
142
|
+
fields.salary_currency = data.salary_currency;
|
|
143
|
+
if (data.salary_period_name !== undefined) {
|
|
144
|
+
fields.salary_period_id = data.salary_period_name
|
|
145
|
+
? getLookupId("salary_periods", data.salary_period_name)
|
|
146
|
+
: null;
|
|
147
|
+
}
|
|
148
|
+
if (Object.keys(fields).length === 0)
|
|
149
|
+
return;
|
|
150
|
+
const setClause = Object.keys(fields)
|
|
151
|
+
.map((k) => `${k} = @${k}`)
|
|
152
|
+
.join(", ");
|
|
153
|
+
database
|
|
154
|
+
.prepare(`UPDATE jobs SET ${setClause}, updated_at = CURRENT_TIMESTAMP WHERE id = @id AND profile_id = @profileId`)
|
|
155
|
+
.run({ ...fields, id, profileId });
|
|
156
|
+
// A status change is significant enough to leave a trail, same as insertJob
|
|
157
|
+
// does on create.
|
|
158
|
+
if (fields.status_id !== undefined) {
|
|
159
|
+
database
|
|
160
|
+
.prepare(`INSERT INTO job_status_history (job_id, status_id, note) VALUES (?, ?, ?)`)
|
|
161
|
+
.run(id, fields.status_id, data.status_note ?? null);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Dedicated status-change path for the `jobtrack status` command -- same
|
|
165
|
+
// effect as calling updateJob with just `status` (+ optional note), but
|
|
166
|
+
// reads better at the call site for what is really the most common edit.
|
|
167
|
+
export function updateJobStatus(profileId, id, status, note) {
|
|
168
|
+
updateJob(profileId, id, { status, ...(note !== undefined ? { status_note: note } : {}) });
|
|
169
|
+
}
|
|
170
|
+
export function getJobStatusHistory(profileId, jobId) {
|
|
171
|
+
return database
|
|
172
|
+
.prepare(`
|
|
173
|
+
SELECT job_status_history.id, job_statuses.name AS status,
|
|
174
|
+
job_status_history.changed_at, job_status_history.note
|
|
175
|
+
FROM job_status_history
|
|
176
|
+
JOIN job_statuses ON job_statuses.id = job_status_history.status_id
|
|
177
|
+
JOIN jobs ON jobs.id = job_status_history.job_id
|
|
178
|
+
WHERE jobs.profile_id = ? AND job_status_history.job_id = ?
|
|
179
|
+
ORDER BY job_status_history.changed_at ASC
|
|
180
|
+
`)
|
|
181
|
+
.all(profileId, jobId);
|
|
182
|
+
}
|
|
183
|
+
export function deleteJob(profileId, id) {
|
|
184
|
+
database.prepare(`DELETE FROM jobs WHERE id = ? AND profile_id = ?`).run(id, profileId);
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=jobsRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobsRepository.js","sourceRoot":"","sources":["../../src/repository/jobsRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface JobLocation {
|
|
2
|
+
id: number;
|
|
3
|
+
name: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function getAllLocations(): JobLocation[];
|
|
6
|
+
export declare function getLocationById(id: number): JobLocation | undefined;
|
|
7
|
+
export declare function getLocationByName(name: string): JobLocation | undefined;
|
|
8
|
+
export declare function addLocation(name: string): JobLocation;
|
|
9
|
+
export declare function updateLocation(id: number, name: string): void;
|
|
10
|
+
export declare function deleteLocation(id: number): void;
|
|
11
|
+
//# sourceMappingURL=locationRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locationRepository.d.ts","sourceRoot":"","sources":["../../src/repository/locationRepository.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,eAAe,IAAI,WAAW,EAAE,CAI/C;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAInE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAIvE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAKrD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI7D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAI/C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { database } from "../database/database.js";
|
|
2
|
+
export function getAllLocations() {
|
|
3
|
+
return database
|
|
4
|
+
.prepare(`SELECT * FROM job_locations ORDER BY name ASC`)
|
|
5
|
+
.all();
|
|
6
|
+
}
|
|
7
|
+
export function getLocationById(id) {
|
|
8
|
+
return database
|
|
9
|
+
.prepare(`SELECT * FROM job_locations WHERE id = ?`)
|
|
10
|
+
.get(id);
|
|
11
|
+
}
|
|
12
|
+
export function getLocationByName(name) {
|
|
13
|
+
return database
|
|
14
|
+
.prepare(`SELECT * FROM job_locations WHERE LOWER(name) = LOWER(?)`)
|
|
15
|
+
.get(name);
|
|
16
|
+
}
|
|
17
|
+
export function addLocation(name) {
|
|
18
|
+
const result = database
|
|
19
|
+
.prepare(`INSERT INTO job_locations (name) VALUES (?)`)
|
|
20
|
+
.run(name);
|
|
21
|
+
return getLocationById(Number(result.lastInsertRowid));
|
|
22
|
+
}
|
|
23
|
+
export function updateLocation(id, name) {
|
|
24
|
+
database
|
|
25
|
+
.prepare(`UPDATE job_locations SET name = ? WHERE id = ?`)
|
|
26
|
+
.run(name, id);
|
|
27
|
+
}
|
|
28
|
+
export function deleteLocation(id) {
|
|
29
|
+
database
|
|
30
|
+
.prepare(`DELETE FROM job_locations WHERE id = ?`)
|
|
31
|
+
.run(id);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=locationRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locationRepository.js","sourceRoot":"","sources":["../../src/repository/locationRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAOnD,MAAM,UAAU,eAAe;IAC7B,OAAO,QAAQ;SACZ,OAAO,CAAC,+CAA+C,CAAC;SACxD,GAAG,EAAmB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,OAAO,QAAQ;SACZ,OAAO,CAAC,0CAA0C,CAAC;SACnD,GAAG,CAAC,EAAE,CAA4B,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,QAAQ;SACZ,OAAO,CAAC,0DAA0D,CAAC;SACnE,GAAG,CAAC,IAAI,CAA4B,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,MAAM,GAAG,QAAQ;SACpB,OAAO,CAAC,6CAA6C,CAAC;SACtD,GAAG,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAU,EAAE,IAAY;IACrD,QAAQ;SACL,OAAO,CAAC,gDAAgD,CAAC;SACzD,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,QAAQ;SACL,OAAO,CAAC,wCAAwC,CAAC;SACjD,GAAG,CAAC,EAAE,CAAC,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Profile } from "../database/types.js";
|
|
2
|
+
export declare function createProfile(username: string, displayName?: string): Profile;
|
|
3
|
+
export declare function getProfileById(id: number): Profile | undefined;
|
|
4
|
+
export declare function getProfileByUsername(username: string): Profile | undefined;
|
|
5
|
+
export declare function getAllProfiles(): Profile[];
|
|
6
|
+
export declare function updateProfile(id: number, displayName: string): void;
|
|
7
|
+
//# sourceMappingURL=profileRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileRepository.d.ts","sourceRoot":"","sources":["../../src/repository/profileRepository.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAM7E;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAI9D;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAI1E;AAED,wBAAgB,cAAc,IAAI,OAAO,EAAE,CAI1C;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAInE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { database } from "../database/database.js";
|
|
2
|
+
export function createProfile(username, displayName) {
|
|
3
|
+
const stmt = database.prepare(`INSERT INTO profiles (username, display_name) VALUES (?, ?)`);
|
|
4
|
+
const result = stmt.run(username, displayName ?? null);
|
|
5
|
+
return getProfileById(Number(result.lastInsertRowid));
|
|
6
|
+
}
|
|
7
|
+
export function getProfileById(id) {
|
|
8
|
+
return database.prepare(`SELECT * FROM profiles WHERE id = ?`).get(id);
|
|
9
|
+
}
|
|
10
|
+
export function getProfileByUsername(username) {
|
|
11
|
+
return database
|
|
12
|
+
.prepare(`SELECT * FROM profiles WHERE username = ?`)
|
|
13
|
+
.get(username);
|
|
14
|
+
}
|
|
15
|
+
export function getAllProfiles() {
|
|
16
|
+
return database
|
|
17
|
+
.prepare(`SELECT * FROM profiles ORDER BY created_at ASC`)
|
|
18
|
+
.all();
|
|
19
|
+
}
|
|
20
|
+
export function updateProfile(id, displayName) {
|
|
21
|
+
database
|
|
22
|
+
.prepare(`UPDATE profiles SET display_name = ? WHERE id = ?`)
|
|
23
|
+
.run(displayName, id);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=profileRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileRepository.js","sourceRoot":"","sources":["../../src/repository/profileRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,WAAoB;IAClE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAC3B,6DAA6D,CAC9D,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,IAAI,IAAI,CAAC,CAAC;IACvD,OAAO,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAE,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,OAAO,QAAQ,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,GAAG,CAAC,EAAE,CAExD,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO,QAAQ;SACZ,OAAO,CAAC,2CAA2C,CAAC;SACpD,GAAG,CAAC,QAAQ,CAAwB,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ;SACZ,OAAO,CAAC,gDAAgD,CAAC;SACzD,GAAG,EAAe,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAU,EAAE,WAAmB;IAC3D,QAAQ;SACL,OAAO,CAAC,mDAAmD,CAAC;SAC5D,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAUA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,QAevC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { getJobs, postJob, getWhoami, getProfiles, postProfile, postProfileSwitch, } from "./controllers/httpController.js";
|
|
3
|
+
export function startServer(port) {
|
|
4
|
+
const app = express();
|
|
5
|
+
app.use(express.json());
|
|
6
|
+
app.get("/api/jobs", getJobs);
|
|
7
|
+
app.post("/api/jobs", postJob);
|
|
8
|
+
app.get("/api/profile/whoami", getWhoami);
|
|
9
|
+
app.get("/api/profiles", getProfiles);
|
|
10
|
+
app.post("/api/profiles", postProfile);
|
|
11
|
+
app.post("/api/profiles/switch", postProfileSwitch);
|
|
12
|
+
app.listen(port, () => {
|
|
13
|
+
console.log(`jobtrack server running at http://localhost:${port}`);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EACH,OAAO,EACP,OAAO,EACP,SAAS,EACT,WAAW,EACX,WAAW,EACX,iBAAiB,GACpB,MAAM,iCAAiC,CAAC;AAEzC,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExB,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9B,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAE/B,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;IAC1C,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IACtC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IACvC,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAC;IAEpD,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QAClB,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Company } from "../database/types.js";
|
|
2
|
+
export declare function addCompanyService(name: string, industry?: string, website?: string): Company;
|
|
3
|
+
export declare function listCompaniesService(): Company[];
|
|
4
|
+
export declare function updateCompanyService(id: number, industry?: string, website?: string): Company;
|
|
5
|
+
export declare function deleteCompanyService(id: number): void;
|
|
6
|
+
//# sourceMappingURL=companyService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companyService.d.ts","sourceRoot":"","sources":["../../src/service/companyService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,WASlF;AAED,wBAAgB,oBAAoB,IAAI,OAAO,EAAE,CAGhD;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAU7F;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CASrD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { requireActiveProfile } from "../session/session.js";
|
|
2
|
+
import { getCompaniesByProfileId, getCompanyById, updateCompany, deleteCompany, addCompany, getCompanyByName } from "../repository/companyRepository.js";
|
|
3
|
+
export function addCompanyService(name, industry, website) {
|
|
4
|
+
const profile = requireActiveProfile();
|
|
5
|
+
const existing = getCompanyByName(name, profile.id);
|
|
6
|
+
if (existing) {
|
|
7
|
+
throw new Error(`A company named "${existing.name}" already exists in your profile.`);
|
|
8
|
+
}
|
|
9
|
+
return addCompany(profile.id, name, industry, website);
|
|
10
|
+
}
|
|
11
|
+
export function listCompaniesService() {
|
|
12
|
+
const profile = requireActiveProfile();
|
|
13
|
+
return getCompaniesByProfileId(profile.id);
|
|
14
|
+
}
|
|
15
|
+
export function updateCompanyService(id, industry, website) {
|
|
16
|
+
const profile = requireActiveProfile();
|
|
17
|
+
const existing = getCompanyById(id, profile.id);
|
|
18
|
+
if (!existing) {
|
|
19
|
+
throw new Error(`Company with ID ${id} not found for your profile.`);
|
|
20
|
+
}
|
|
21
|
+
updateCompany(id, profile.id, industry, website);
|
|
22
|
+
return getCompanyById(id, profile.id);
|
|
23
|
+
}
|
|
24
|
+
export function deleteCompanyService(id) {
|
|
25
|
+
const profile = requireActiveProfile();
|
|
26
|
+
const existing = getCompanyById(id, profile.id);
|
|
27
|
+
if (!existing) {
|
|
28
|
+
throw new Error(`Company with ID ${id} not found for your profile.`);
|
|
29
|
+
}
|
|
30
|
+
deleteCompany(id, profile.id);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=companyService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companyService.js","sourceRoot":"","sources":["../../src/service/companyService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGzJ,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,QAAiB,EAAE,OAAgB;IACjF,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IAEvC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,IAAI,mCAAmC,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,OAAO,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAU,EAAE,QAAiB,EAAE,OAAgB;IAClF,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IAEvC,MAAM,QAAQ,GAAG,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,mBAAmB,EAAE,8BAA8B,CAAC,CAAC;IACvE,CAAC;IAED,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAU;IAC7C,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IAEvC,MAAM,QAAQ,GAAG,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,mBAAmB,EAAE,8BAA8B,CAAC,CAAC;IACvE,CAAC;IAED,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { NewJob, UpdateJob, JobWithDetails, Status } from "../database/types.js";
|
|
2
|
+
export declare function addJob(data: NewJob): {
|
|
3
|
+
id: number;
|
|
4
|
+
role: string;
|
|
5
|
+
company_name: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function listJobs(): JobWithDetails[];
|
|
8
|
+
export declare function getJob(id: number): JobWithDetails;
|
|
9
|
+
export declare function updateJobService(id: number, data: UpdateJob): JobWithDetails;
|
|
10
|
+
export declare function updateJobStatusService(id: number, status: Status, note?: string): JobWithDetails;
|
|
11
|
+
export declare function deleteJobService(id: number): void;
|
|
12
|
+
export declare function getJobHistoryService(id: number): {
|
|
13
|
+
id: number;
|
|
14
|
+
status: Status;
|
|
15
|
+
changed_at: string;
|
|
16
|
+
note: string | null;
|
|
17
|
+
}[];
|
|
18
|
+
//# sourceMappingURL=jobService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobService.d.ts","sourceRoot":"","sources":["../../src/service/jobService.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AActF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAIvF;AAED,wBAAgB,QAAQ,IAAI,cAAc,EAAE,CAG3C;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,CAGjD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,cAAc,CAK5E;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAKhG;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM;;;;;IAI9C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { insertJob, getAllJobs, getJobById, updateJob, updateJobStatus, deleteJob, getJobStatusHistory, } from "../repository/jobsRepository.js";
|
|
2
|
+
import { requireActiveProfile } from "../session/session.js";
|
|
3
|
+
// Services never print, never touch chalk or cli-table3, never know what's
|
|
4
|
+
// calling them. They take input, talk to the repository, and return plain
|
|
5
|
+
// data or throw errors. Controllers decide what to do with the result.
|
|
6
|
+
function requireJob(profileId, id) {
|
|
7
|
+
const job = getJobById(profileId, id);
|
|
8
|
+
if (!job) {
|
|
9
|
+
throw new Error(`Job application with ID ${id} not found for your profile.`);
|
|
10
|
+
}
|
|
11
|
+
return job;
|
|
12
|
+
}
|
|
13
|
+
export function addJob(data) {
|
|
14
|
+
const profile = requireActiveProfile();
|
|
15
|
+
const id = insertJob(profile.id, data);
|
|
16
|
+
return { id, role: data.role, company_name: data.company_name };
|
|
17
|
+
}
|
|
18
|
+
export function listJobs() {
|
|
19
|
+
const profile = requireActiveProfile();
|
|
20
|
+
return getAllJobs(profile.id);
|
|
21
|
+
}
|
|
22
|
+
export function getJob(id) {
|
|
23
|
+
const profile = requireActiveProfile();
|
|
24
|
+
return requireJob(profile.id, id);
|
|
25
|
+
}
|
|
26
|
+
export function updateJobService(id, data) {
|
|
27
|
+
const profile = requireActiveProfile();
|
|
28
|
+
requireJob(profile.id, id);
|
|
29
|
+
updateJob(profile.id, id, data);
|
|
30
|
+
return requireJob(profile.id, id);
|
|
31
|
+
}
|
|
32
|
+
export function updateJobStatusService(id, status, note) {
|
|
33
|
+
const profile = requireActiveProfile();
|
|
34
|
+
requireJob(profile.id, id);
|
|
35
|
+
updateJobStatus(profile.id, id, status, note);
|
|
36
|
+
return requireJob(profile.id, id);
|
|
37
|
+
}
|
|
38
|
+
export function deleteJobService(id) {
|
|
39
|
+
const profile = requireActiveProfile();
|
|
40
|
+
requireJob(profile.id, id);
|
|
41
|
+
deleteJob(profile.id, id);
|
|
42
|
+
}
|
|
43
|
+
export function getJobHistoryService(id) {
|
|
44
|
+
const profile = requireActiveProfile();
|
|
45
|
+
requireJob(profile.id, id);
|
|
46
|
+
return getJobStatusHistory(profile.id, id);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=jobService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobService.js","sourceRoot":"","sources":["../../src/service/jobService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,EACT,eAAe,EACf,SAAS,EACT,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AAEvE,SAAS,UAAU,CAAC,SAAiB,EAAE,EAAU;IAC/C,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,8BAA8B,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,OAAO,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,EAAU;IAC/B,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,OAAO,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU,EAAE,IAAe;IAC1D,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3B,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IAChC,OAAO,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,EAAU,EAAE,MAAc,EAAE,IAAa;IAC9E,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3B,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3B,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAU;IAC7C,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,mBAAmB,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type JobLocation } from "../repository/locationRepository.js";
|
|
2
|
+
export declare function listLocationsService(): JobLocation[];
|
|
3
|
+
export declare function addLocationService(name: string): JobLocation;
|
|
4
|
+
export declare function updateLocationService(id: number, name: string): JobLocation;
|
|
5
|
+
export declare function deleteLocationService(id: number): void;
|
|
6
|
+
//# sourceMappingURL=locationService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locationService.d.ts","sourceRoot":"","sources":["../../src/service/locationService.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,qCAAqC,CAAC;AAE7C,wBAAgB,oBAAoB,IAAI,WAAW,EAAE,CAEpD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAM5D;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAa3E;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAMtD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getAllLocations, getLocationById, getLocationByName, addLocation, updateLocation, deleteLocation, } from "../repository/locationRepository.js";
|
|
2
|
+
export function listLocationsService() {
|
|
3
|
+
return getAllLocations();
|
|
4
|
+
}
|
|
5
|
+
export function addLocationService(name) {
|
|
6
|
+
const existing = getLocationByName(name);
|
|
7
|
+
if (existing) {
|
|
8
|
+
throw new Error(`Location "${existing.name}" already exists.`);
|
|
9
|
+
}
|
|
10
|
+
return addLocation(name);
|
|
11
|
+
}
|
|
12
|
+
export function updateLocationService(id, name) {
|
|
13
|
+
const existing = getLocationById(id);
|
|
14
|
+
if (!existing) {
|
|
15
|
+
throw new Error(`Location with ID ${id} not found.`);
|
|
16
|
+
}
|
|
17
|
+
const duplicate = getLocationByName(name);
|
|
18
|
+
if (duplicate && duplicate.id !== id) {
|
|
19
|
+
throw new Error(`Location "${name}" already exists.`);
|
|
20
|
+
}
|
|
21
|
+
updateLocation(id, name);
|
|
22
|
+
return getLocationById(id);
|
|
23
|
+
}
|
|
24
|
+
export function deleteLocationService(id) {
|
|
25
|
+
const existing = getLocationById(id);
|
|
26
|
+
if (!existing) {
|
|
27
|
+
throw new Error(`Location with ID ${id} not found.`);
|
|
28
|
+
}
|
|
29
|
+
deleteLocation(id);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=locationService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locationService.js","sourceRoot":"","sources":["../../src/service/locationService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,cAAc,GAEf,MAAM,qCAAqC,CAAC;AAE7C,MAAM,UAAU,oBAAoB;IAClC,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,aAAa,QAAQ,CAAC,IAAI,mBAAmB,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAU,EAAE,IAAY;IAC5D,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,aAAa,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,SAAS,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,mBAAmB,CAAC,CAAC;IACxD,CAAC;IAED,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACzB,OAAO,eAAe,CAAC,EAAE,CAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,aAAa,CAAC,CAAC;IACvD,CAAC;IACD,cAAc,CAAC,EAAE,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Profile } from "../database/types.js";
|
|
2
|
+
export declare function createProfileService(username: string, displayName?: string): Profile;
|
|
3
|
+
export declare function switchProfileService(username: string): Profile;
|
|
4
|
+
export declare function listProfilesService(): {
|
|
5
|
+
profiles: Profile[];
|
|
6
|
+
activeProfileId: number | null;
|
|
7
|
+
};
|
|
8
|
+
export declare function whoamiService(): string | null;
|
|
9
|
+
export declare function updateProfileService(newName: string): Profile;
|
|
10
|
+
//# sourceMappingURL=profileService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileService.d.ts","sourceRoot":"","sources":["../../src/service/profileService.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAKpD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CASpF;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAS9D;AAED,wBAAgB,mBAAmB,IAAI;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAI7F;AAED,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAe7D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { createProfile, getProfileByUsername, getAllProfiles, } from "../repository/profileRepository.js";
|
|
2
|
+
import { setActiveProfile, getSession, requireActiveProfile } from "../session/session.js";
|
|
3
|
+
import { updateProfile, getProfileById } from "../repository/profileRepository.js";
|
|
4
|
+
// Same rule as jobService: data and errors only, no printing.
|
|
5
|
+
export function createProfileService(username, displayName) {
|
|
6
|
+
const existing = getProfileByUsername(username);
|
|
7
|
+
if (existing) {
|
|
8
|
+
throw new Error(`A profile named "${username}" already exists.`);
|
|
9
|
+
}
|
|
10
|
+
const profile = createProfile(username, displayName);
|
|
11
|
+
setActiveProfile(profile.id, profile.username);
|
|
12
|
+
return profile;
|
|
13
|
+
}
|
|
14
|
+
export function switchProfileService(username) {
|
|
15
|
+
const profile = getProfileByUsername(username);
|
|
16
|
+
if (!profile) {
|
|
17
|
+
throw new Error(`No profile named "${username}". Run \`jobtrack profile list\` to see available profiles.`);
|
|
18
|
+
}
|
|
19
|
+
setActiveProfile(profile.id, profile.username);
|
|
20
|
+
return profile;
|
|
21
|
+
}
|
|
22
|
+
export function listProfilesService() {
|
|
23
|
+
const profiles = getAllProfiles();
|
|
24
|
+
const session = getSession();
|
|
25
|
+
return { profiles, activeProfileId: session.activeProfileId };
|
|
26
|
+
}
|
|
27
|
+
export function whoamiService() {
|
|
28
|
+
return getSession().activeUsername;
|
|
29
|
+
}
|
|
30
|
+
export function updateProfileService(newName) {
|
|
31
|
+
const activeSession = requireActiveProfile();
|
|
32
|
+
// 1. Update the database
|
|
33
|
+
updateProfile(activeSession.id, newName);
|
|
34
|
+
// 2. Fetch the updated record
|
|
35
|
+
const updatedProfile = getProfileById(activeSession.id);
|
|
36
|
+
// 3. Ensure it exists and explicitly return it
|
|
37
|
+
if (!updatedProfile) {
|
|
38
|
+
throw new Error("Active profile missing from database. Session may be out of sync.");
|
|
39
|
+
}
|
|
40
|
+
return updatedProfile;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=profileService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileService.js","sourceRoot":"","sources":["../../src/service/profileService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,cAAc,GACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE3F,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEnF,8DAA8D;AAE9D,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,WAAoB;IACzE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,mBAAmB,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACrD,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,6DAA6D,CAC3F,CAAC;IACJ,CAAC;IACD,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,EAAE,CAAC,cAAc,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,aAAa,GAAG,oBAAoB,EAAE,CAAC;IAE7C,yBAAyB;IACzB,aAAa,CAAC,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAEzC,8BAA8B;IAC9B,MAAM,cAAc,GAAG,cAAc,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IAExD,+CAA+C;IAC/C,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Session {
|
|
2
|
+
activeProfileId: number | null;
|
|
3
|
+
activeUsername: string | null;
|
|
4
|
+
}
|
|
5
|
+
export declare function getSession(): Session;
|
|
6
|
+
export declare function setActiveProfile(id: number, username: string): void;
|
|
7
|
+
export declare function requireActiveProfile(): {
|
|
8
|
+
id: number;
|
|
9
|
+
username: string;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"AAMA,UAAU,OAAO;IACf,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,wBAAgB,UAAU,IAAI,OAAO,CAKpC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAGnE;AAED,wBAAgB,oBAAoB,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAQvE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
const SESSION_PATH = path.join(os.homedir(), ".jobtrack", "session.json");
|
|
5
|
+
export function getSession() {
|
|
6
|
+
if (!fs.existsSync(SESSION_PATH)) {
|
|
7
|
+
return { activeProfileId: null, activeUsername: null };
|
|
8
|
+
}
|
|
9
|
+
return JSON.parse(fs.readFileSync(SESSION_PATH, "utf-8"));
|
|
10
|
+
}
|
|
11
|
+
export function setActiveProfile(id, username) {
|
|
12
|
+
const session = { activeProfileId: id, activeUsername: username };
|
|
13
|
+
fs.writeFileSync(SESSION_PATH, JSON.stringify(session, null, 2));
|
|
14
|
+
}
|
|
15
|
+
export function requireActiveProfile() {
|
|
16
|
+
const session = getSession();
|
|
17
|
+
if (session.activeProfileId === null || session.activeUsername === null) {
|
|
18
|
+
throw new Error("No active profile. Run `jobtrack profile create <username>` to get started.");
|
|
19
|
+
}
|
|
20
|
+
return { id: session.activeProfileId, username: session.activeUsername };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;AAO1E,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU,EAAE,QAAgB;IAC3D,MAAM,OAAO,GAAY,EAAE,eAAe,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC;IAC3E,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,eAAe,KAAK,IAAI,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { JobWithDetails, Profile } from "../database/types.js";
|
|
2
|
+
export declare function printAddedConfirmation(id: number, role: string, company: string): void;
|
|
3
|
+
export declare function printEmptyState(message: string): void;
|
|
4
|
+
export declare function printApplicationsTable(rows: JobWithDetails[]): void;
|
|
5
|
+
export declare function printSuccess(message: string): void;
|
|
6
|
+
export declare function printError(message: string): void;
|
|
7
|
+
export declare function printEmpty(message: string): void;
|
|
8
|
+
export declare function printProfileList(profiles: Profile[], activeProfileId: number | null): void;
|
|
9
|
+
export declare function printJobDetails(job: JobWithDetails): void;
|
|
10
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/transformers/output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAU,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAe5E,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAK/E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,QAE9C;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,EAAE,QAY5D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,QAE3C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,QAEzC;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,QAEzC;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,QASnF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,QAkBlD"}
|