timeback-studio 0.1.6 → 0.1.7
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/bin.js +238 -24
- package/dist/cli/commands/credentials/create-account.d.ts +37 -0
- package/dist/cli/commands/credentials/create-account.d.ts.map +1 -0
- package/dist/cli/commands/credentials/email.d.ts.map +1 -1
- package/dist/index.js +235 -21
- package/dist/server/controllers/bootstrap.d.ts +3 -0
- package/dist/server/controllers/bootstrap.d.ts.map +1 -1
- package/dist/server/services/status.d.ts +7 -4
- package/dist/server/services/status.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -16854,13 +16854,14 @@ async function validateEmailWithTimeback(environment, clientId, clientSecret, em
|
|
|
16854
16854
|
if (page.data.length === 0) {
|
|
16855
16855
|
return {
|
|
16856
16856
|
valid: false,
|
|
16857
|
+
reason: "not_found",
|
|
16857
16858
|
error: `No user found with email "${email3}" in ${environment}`
|
|
16858
16859
|
};
|
|
16859
16860
|
}
|
|
16860
16861
|
return { valid: true };
|
|
16861
16862
|
} catch (error48) {
|
|
16862
16863
|
const message = error48 instanceof Error ? error48.message : "Unknown error";
|
|
16863
|
-
return { valid: false, error: `Failed to validate email: ${message}` };
|
|
16864
|
+
return { valid: false, reason: "api_error", error: `Failed to validate email: ${message}` };
|
|
16864
16865
|
}
|
|
16865
16866
|
}
|
|
16866
16867
|
|
|
@@ -17162,6 +17163,8 @@ var ActivityCompletedInput = exports_external.object({
|
|
|
17162
17163
|
metricsId: exports_external.string().optional(),
|
|
17163
17164
|
id: exports_external.string().optional(),
|
|
17164
17165
|
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
|
|
17166
|
+
edApp: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional(),
|
|
17167
|
+
session: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional(),
|
|
17165
17168
|
attempt: exports_external.number().int().min(1).optional(),
|
|
17166
17169
|
generatedExtensions: exports_external.object({
|
|
17167
17170
|
pctCompleteApp: exports_external.number().optional()
|
|
@@ -17174,7 +17177,9 @@ var TimeSpentInput = exports_external.object({
|
|
|
17174
17177
|
eventTime: IsoDateTimeString.optional(),
|
|
17175
17178
|
metricsId: exports_external.string().optional(),
|
|
17176
17179
|
id: exports_external.string().optional(),
|
|
17177
|
-
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
17180
|
+
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
|
|
17181
|
+
edApp: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional(),
|
|
17182
|
+
session: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional()
|
|
17178
17183
|
}).strict();
|
|
17179
17184
|
var TimebackEvent = exports_external.union([TimebackActivityEvent, TimebackTimeSpentEvent]);
|
|
17180
17185
|
var CaliperEnvelope = exports_external.object({
|
|
@@ -17364,7 +17369,7 @@ var TimebackConfig = exports_external.object({
|
|
|
17364
17369
|
path: ["courses"]
|
|
17365
17370
|
});
|
|
17366
17371
|
// ../types/src/zod/edubridge.ts
|
|
17367
|
-
var EdubridgeDateString = IsoDateTimeString;
|
|
17372
|
+
var EdubridgeDateString = exports_external.union([IsoDateTimeString, IsoDateString]);
|
|
17368
17373
|
var EduBridgeEnrollment = exports_external.object({
|
|
17369
17374
|
id: exports_external.string(),
|
|
17370
17375
|
role: exports_external.string(),
|
|
@@ -19465,6 +19470,184 @@ async function addCredentials(options = {}) {
|
|
|
19465
19470
|
if (exitOnComplete)
|
|
19466
19471
|
process.exit(0);
|
|
19467
19472
|
}
|
|
19473
|
+
// src/cli/commands/credentials/create-account.ts
|
|
19474
|
+
import { randomUUID } from "node:crypto";
|
|
19475
|
+
import { TimebackClient as TimebackClient2 } from "@timeback/core";
|
|
19476
|
+
async function promptName(label) {
|
|
19477
|
+
const value = await he({
|
|
19478
|
+
message: label,
|
|
19479
|
+
placeholder: "Enter name",
|
|
19480
|
+
validate: (v2) => {
|
|
19481
|
+
if (!v2?.trim())
|
|
19482
|
+
return `${label} is required`;
|
|
19483
|
+
}
|
|
19484
|
+
});
|
|
19485
|
+
if (isCancelled(value))
|
|
19486
|
+
return null;
|
|
19487
|
+
return value.trim();
|
|
19488
|
+
}
|
|
19489
|
+
async function searchOrganizations(client, query) {
|
|
19490
|
+
const allOrgs = await client.oneroster.orgs.listAll({
|
|
19491
|
+
where: { status: "active" },
|
|
19492
|
+
max: 100
|
|
19493
|
+
});
|
|
19494
|
+
if (!query.trim())
|
|
19495
|
+
return allOrgs;
|
|
19496
|
+
const lowerQuery = query.toLowerCase().trim();
|
|
19497
|
+
return allOrgs.filter((org) => org.name?.toLowerCase().includes(lowerQuery));
|
|
19498
|
+
}
|
|
19499
|
+
async function searchForOrganization(client) {
|
|
19500
|
+
const query = await he({
|
|
19501
|
+
message: "Search for organization",
|
|
19502
|
+
placeholder: "Enter organization name to search"
|
|
19503
|
+
});
|
|
19504
|
+
if (isCancelled(query))
|
|
19505
|
+
return null;
|
|
19506
|
+
const s = Y2();
|
|
19507
|
+
s.start("Searching organizations...");
|
|
19508
|
+
let results;
|
|
19509
|
+
try {
|
|
19510
|
+
results = await searchOrganizations(client, query);
|
|
19511
|
+
s.stop(green(`Found ${results.length} result${results.length === 1 ? "" : "s"}`));
|
|
19512
|
+
} catch (error48) {
|
|
19513
|
+
s.stop(red("Failed to search organizations"));
|
|
19514
|
+
M2.error(error48 instanceof Error ? error48.message : "Unknown error");
|
|
19515
|
+
return null;
|
|
19516
|
+
}
|
|
19517
|
+
if (results.length === 0) {
|
|
19518
|
+
M2.warn("No organizations found matching your search");
|
|
19519
|
+
return promptOrganization(client);
|
|
19520
|
+
}
|
|
19521
|
+
const validResults = results.filter((org) => org.sourcedId);
|
|
19522
|
+
if (validResults.length === 0) {
|
|
19523
|
+
M2.warn("No valid organizations found (missing IDs)");
|
|
19524
|
+
return promptOrganization(client);
|
|
19525
|
+
}
|
|
19526
|
+
const options = validResults.map((org) => ({
|
|
19527
|
+
value: org.sourcedId,
|
|
19528
|
+
label: org.name ?? "Unnamed Organization"
|
|
19529
|
+
}));
|
|
19530
|
+
options.push({ value: "__back__", label: `${dim("←")} Back to options` });
|
|
19531
|
+
const selection = await ve({
|
|
19532
|
+
message: "Select an organization",
|
|
19533
|
+
options
|
|
19534
|
+
});
|
|
19535
|
+
if (isCancelled(selection))
|
|
19536
|
+
return null;
|
|
19537
|
+
if (selection === "__back__") {
|
|
19538
|
+
return promptOrganization(client);
|
|
19539
|
+
}
|
|
19540
|
+
return validResults.find((org) => org.sourcedId === selection) ?? null;
|
|
19541
|
+
}
|
|
19542
|
+
async function promptOrganization(client) {
|
|
19543
|
+
const action = await ve({
|
|
19544
|
+
message: "Organization",
|
|
19545
|
+
options: [
|
|
19546
|
+
{ value: "search", label: "Search for existing organization" },
|
|
19547
|
+
{ value: "create", label: "Create new organization" }
|
|
19548
|
+
]
|
|
19549
|
+
});
|
|
19550
|
+
if (isCancelled(action))
|
|
19551
|
+
return null;
|
|
19552
|
+
if (action === "create") {
|
|
19553
|
+
return createNewOrganization(client);
|
|
19554
|
+
}
|
|
19555
|
+
return searchForOrganization(client);
|
|
19556
|
+
}
|
|
19557
|
+
async function createNewOrganization(client) {
|
|
19558
|
+
const name = await he({
|
|
19559
|
+
message: "Organization name",
|
|
19560
|
+
placeholder: "Enter organization name",
|
|
19561
|
+
validate: (v2) => {
|
|
19562
|
+
if (!v2?.trim())
|
|
19563
|
+
return "Organization name is required";
|
|
19564
|
+
}
|
|
19565
|
+
});
|
|
19566
|
+
if (isCancelled(name))
|
|
19567
|
+
return null;
|
|
19568
|
+
const s = Y2();
|
|
19569
|
+
s.start("Creating organization...");
|
|
19570
|
+
const sourcedId = randomUUID();
|
|
19571
|
+
try {
|
|
19572
|
+
await client.oneroster.orgs.create({
|
|
19573
|
+
sourcedId,
|
|
19574
|
+
name: name.trim(),
|
|
19575
|
+
type: "school",
|
|
19576
|
+
status: "active"
|
|
19577
|
+
});
|
|
19578
|
+
const organization = await client.oneroster.orgs.get(sourcedId);
|
|
19579
|
+
s.stop(green(`Organization "${name}" created`));
|
|
19580
|
+
return organization;
|
|
19581
|
+
} catch (error48) {
|
|
19582
|
+
s.stop(red("Failed to create organization"));
|
|
19583
|
+
M2.error(error48 instanceof Error ? error48.message : "Unknown error");
|
|
19584
|
+
return null;
|
|
19585
|
+
}
|
|
19586
|
+
}
|
|
19587
|
+
async function createUser(client, email3, givenName, familyName, organizationId) {
|
|
19588
|
+
const s = Y2();
|
|
19589
|
+
s.start("Creating account...");
|
|
19590
|
+
const sourcedId = randomUUID();
|
|
19591
|
+
try {
|
|
19592
|
+
await client.oneroster.users.create({
|
|
19593
|
+
sourcedId,
|
|
19594
|
+
givenName,
|
|
19595
|
+
familyName,
|
|
19596
|
+
email: email3.toLowerCase(),
|
|
19597
|
+
enabledUser: true,
|
|
19598
|
+
status: "active",
|
|
19599
|
+
roles: [
|
|
19600
|
+
{
|
|
19601
|
+
roleType: "primary",
|
|
19602
|
+
role: "administrator",
|
|
19603
|
+
org: { sourcedId: organizationId }
|
|
19604
|
+
}
|
|
19605
|
+
]
|
|
19606
|
+
});
|
|
19607
|
+
const user = await client.oneroster.users.get(sourcedId);
|
|
19608
|
+
s.stop(green("Account created successfully"));
|
|
19609
|
+
return user;
|
|
19610
|
+
} catch (error48) {
|
|
19611
|
+
s.stop(red("Failed to create account"));
|
|
19612
|
+
M2.error(error48 instanceof Error ? error48.message : "Unknown error");
|
|
19613
|
+
return null;
|
|
19614
|
+
}
|
|
19615
|
+
}
|
|
19616
|
+
async function createAccountFlow(options) {
|
|
19617
|
+
const { environment, clientId, clientSecret, email: email3 } = options;
|
|
19618
|
+
M2.info("");
|
|
19619
|
+
M2.info(`No account found for ${dim(email3)} in ${environment}`);
|
|
19620
|
+
const shouldCreate = await ye({
|
|
19621
|
+
message: "Would you like to create a new account?",
|
|
19622
|
+
initialValue: true
|
|
19623
|
+
});
|
|
19624
|
+
if (isCancelled(shouldCreate)) {
|
|
19625
|
+
return { success: false };
|
|
19626
|
+
}
|
|
19627
|
+
if (!shouldCreate) {
|
|
19628
|
+
return { success: false, declined: true };
|
|
19629
|
+
}
|
|
19630
|
+
const client = new TimebackClient2({
|
|
19631
|
+
env: environment,
|
|
19632
|
+
auth: { clientId, clientSecret }
|
|
19633
|
+
});
|
|
19634
|
+
const givenName = await promptName("First name");
|
|
19635
|
+
if (!givenName)
|
|
19636
|
+
return { success: false };
|
|
19637
|
+
const familyName = await promptName("Last name");
|
|
19638
|
+
if (!familyName)
|
|
19639
|
+
return { success: false };
|
|
19640
|
+
const organization = await promptOrganization(client);
|
|
19641
|
+
if (!organization?.sourcedId)
|
|
19642
|
+
return { success: false };
|
|
19643
|
+
const user = await createUser(client, email3, givenName, familyName, organization.sourcedId);
|
|
19644
|
+
if (!user) {
|
|
19645
|
+
return { success: false };
|
|
19646
|
+
}
|
|
19647
|
+
M2.success(`Account created for ${user.givenName} ${user.familyName}`);
|
|
19648
|
+
return { success: true };
|
|
19649
|
+
}
|
|
19650
|
+
|
|
19468
19651
|
// src/cli/commands/credentials/email.ts
|
|
19469
19652
|
async function updateEmail(options = {}) {
|
|
19470
19653
|
const { exitOnComplete = true, inline = false } = options;
|
|
@@ -19533,32 +19716,58 @@ async function updateEmail(options = {}) {
|
|
|
19533
19716
|
return;
|
|
19534
19717
|
}
|
|
19535
19718
|
const emailUnchanged = email3 === (currentEmail ?? "");
|
|
19536
|
-
if (emailUnchanged) {
|
|
19537
|
-
if (!inline)
|
|
19538
|
-
outro.info("Email unchanged");
|
|
19539
|
-
if (exitOnComplete)
|
|
19540
|
-
process.exit(0);
|
|
19541
|
-
return;
|
|
19542
|
-
}
|
|
19543
19719
|
if (email3) {
|
|
19544
19720
|
const s = Y2();
|
|
19545
|
-
s.start("
|
|
19721
|
+
s.start("Checking account...");
|
|
19546
19722
|
const result = await validateEmailWithTimeback(targetEnv, currentCreds.clientId, currentCreds.clientSecret, email3);
|
|
19547
19723
|
if (!result.valid) {
|
|
19548
|
-
|
|
19549
|
-
|
|
19550
|
-
|
|
19724
|
+
if (result.reason !== "not_found") {
|
|
19725
|
+
s.stop(red("Account check failed"));
|
|
19726
|
+
M2.error(result.error ?? "Unknown error");
|
|
19727
|
+
if (!inline)
|
|
19728
|
+
outro.error("Account check failed");
|
|
19729
|
+
if (exitOnComplete)
|
|
19730
|
+
process.exit(1);
|
|
19731
|
+
return;
|
|
19732
|
+
}
|
|
19733
|
+
s.stop(red("No account found"));
|
|
19734
|
+
const { success: accountCreated, declined } = await createAccountFlow({
|
|
19735
|
+
environment: targetEnv,
|
|
19736
|
+
clientId: currentCreds.clientId,
|
|
19737
|
+
clientSecret: currentCreds.clientSecret,
|
|
19738
|
+
email: email3
|
|
19739
|
+
});
|
|
19740
|
+
if (!emailUnchanged) {
|
|
19741
|
+
await saveCredentials(targetEnv, {
|
|
19742
|
+
...currentCreds,
|
|
19743
|
+
email: email3
|
|
19744
|
+
});
|
|
19745
|
+
M2.success(`Email saved for ${targetEnv}`);
|
|
19746
|
+
}
|
|
19747
|
+
if (!inline) {
|
|
19748
|
+
if (accountCreated || declined) {
|
|
19749
|
+
outro.success();
|
|
19750
|
+
} else {
|
|
19751
|
+
outro.info("Setup incomplete - run this command again to finish");
|
|
19752
|
+
}
|
|
19753
|
+
}
|
|
19754
|
+
if (exitOnComplete)
|
|
19755
|
+
process.exit(0);
|
|
19756
|
+
return;
|
|
19757
|
+
}
|
|
19758
|
+
s.stop(green("Account verified"));
|
|
19759
|
+
if (emailUnchanged) {
|
|
19551
19760
|
if (!inline)
|
|
19552
|
-
outro.
|
|
19761
|
+
outro.info("Email unchanged");
|
|
19553
19762
|
if (exitOnComplete)
|
|
19554
|
-
process.exit(
|
|
19763
|
+
process.exit(0);
|
|
19555
19764
|
return;
|
|
19556
19765
|
}
|
|
19557
19766
|
await saveCredentials(targetEnv, {
|
|
19558
19767
|
...currentCreds,
|
|
19559
19768
|
email: email3
|
|
19560
19769
|
});
|
|
19561
|
-
|
|
19770
|
+
M2.success(`Email updated for ${targetEnv}`);
|
|
19562
19771
|
if (!inline)
|
|
19563
19772
|
outro.success();
|
|
19564
19773
|
if (exitOnComplete)
|
|
@@ -19874,7 +20083,7 @@ function printError3(error48, opts = {}) {
|
|
|
19874
20083
|
parser.printError(error48);
|
|
19875
20084
|
}
|
|
19876
20085
|
// src/cli/lib/courses.ts
|
|
19877
|
-
import { TimebackClient as
|
|
20086
|
+
import { TimebackClient as TimebackClient3 } from "@timeback/core";
|
|
19878
20087
|
async function fetchCoursesByIds(client, ids) {
|
|
19879
20088
|
const courses = [];
|
|
19880
20089
|
for (const id of ids) {
|
|
@@ -19886,7 +20095,7 @@ async function fetchCoursesByIds(client, ids) {
|
|
|
19886
20095
|
return courses;
|
|
19887
20096
|
}
|
|
19888
20097
|
async function fetchCourses(creds, env2, ids) {
|
|
19889
|
-
const client = new
|
|
20098
|
+
const client = new TimebackClient3({
|
|
19890
20099
|
env: env2,
|
|
19891
20100
|
auth: { clientId: creds.clientId, clientSecret: creds.clientSecret }
|
|
19892
20101
|
});
|
|
@@ -19908,7 +20117,7 @@ async function checkCoursesManaged(creds, env2, ids) {
|
|
|
19908
20117
|
if (ids.length === 0) {
|
|
19909
20118
|
return { allManaged: true, unmanagedCourses: [] };
|
|
19910
20119
|
}
|
|
19911
|
-
const client = new
|
|
20120
|
+
const client = new TimebackClient3({
|
|
19912
20121
|
env: env2,
|
|
19913
20122
|
auth: { clientId: creds.clientId, clientSecret: creds.clientSecret }
|
|
19914
20123
|
});
|
|
@@ -19956,7 +20165,7 @@ async function handleCredentialSetup(options = {}) {
|
|
|
19956
20165
|
};
|
|
19957
20166
|
}
|
|
19958
20167
|
// src/cli/lib/onboarding/import.ts
|
|
19959
|
-
import { TimebackClient as
|
|
20168
|
+
import { TimebackClient as TimebackClient4 } from "@timeback/core";
|
|
19960
20169
|
async function promptImportApp(credentials, configuredEnvs) {
|
|
19961
20170
|
let env2;
|
|
19962
20171
|
if (configuredEnvs.length === 1 && configuredEnvs[0]) {
|
|
@@ -19969,7 +20178,7 @@ async function promptImportApp(credentials, configuredEnvs) {
|
|
|
19969
20178
|
env2 = selectedEnv;
|
|
19970
20179
|
}
|
|
19971
20180
|
const creds = credentials[env2];
|
|
19972
|
-
const client = new
|
|
20181
|
+
const client = new TimebackClient4({
|
|
19973
20182
|
env: env2,
|
|
19974
20183
|
auth: { clientId: creds.clientId, clientSecret: creds.clientSecret }
|
|
19975
20184
|
});
|
|
@@ -22399,7 +22608,8 @@ var cors = (options) => {
|
|
|
22399
22608
|
async function handleBootstrap(c, ctx) {
|
|
22400
22609
|
const { bootstrap } = c.get("services");
|
|
22401
22610
|
const env2 = c.get("env");
|
|
22402
|
-
const
|
|
22611
|
+
const freshCredentials = await getSavedCredentials(env2);
|
|
22612
|
+
const email3 = freshCredentials?.email;
|
|
22403
22613
|
const courseIds = ctx.userConfig.courseIds[env2];
|
|
22404
22614
|
const result = await bootstrap.getBootstrap({ email: email3, courseIds });
|
|
22405
22615
|
return c.json(result);
|
|
@@ -23331,11 +23541,15 @@ class StatusService {
|
|
|
23331
23541
|
}
|
|
23332
23542
|
async getStatus() {
|
|
23333
23543
|
const configuredEnvironments = await getConfiguredEnvironments();
|
|
23544
|
+
const [stagingCreds, productionCreds] = await Promise.all([
|
|
23545
|
+
getSavedCredentials("staging"),
|
|
23546
|
+
getSavedCredentials("production")
|
|
23547
|
+
]);
|
|
23334
23548
|
return {
|
|
23335
23549
|
config: this.ctx.userConfig,
|
|
23336
23550
|
environment: this.ctx.defaultEnvironment,
|
|
23337
23551
|
configuredEnvironments,
|
|
23338
|
-
hasEmail: !!
|
|
23552
|
+
hasEmail: !!stagingCreds?.email || !!productionCreds?.email
|
|
23339
23553
|
};
|
|
23340
23554
|
}
|
|
23341
23555
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account Creation
|
|
3
|
+
*
|
|
4
|
+
* Interactive CLI flow for creating a new Timeback user account
|
|
5
|
+
* when no matching account exists for the provided email.
|
|
6
|
+
*/
|
|
7
|
+
import type { CredentialEnvironment } from '@timeback/internal-cli-infra';
|
|
8
|
+
/**
|
|
9
|
+
* Options for creating a new account.
|
|
10
|
+
*/
|
|
11
|
+
interface CreateAccountOptions {
|
|
12
|
+
environment: CredentialEnvironment;
|
|
13
|
+
clientId: string;
|
|
14
|
+
clientSecret: string;
|
|
15
|
+
email: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result of the account creation flow.
|
|
19
|
+
*/
|
|
20
|
+
interface CreateAccountResult {
|
|
21
|
+
success: boolean;
|
|
22
|
+
/** User explicitly declined to create an account (vs cancelled or failed) */
|
|
23
|
+
declined?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Interactive flow to create a new Timeback account.
|
|
27
|
+
*
|
|
28
|
+
* Called when no matching user is found for the provided email.
|
|
29
|
+
* Guides the user through entering their name and selecting/creating
|
|
30
|
+
* an organization.
|
|
31
|
+
*
|
|
32
|
+
* @param options - Account creation options
|
|
33
|
+
* @returns Result indicating success and the created user
|
|
34
|
+
*/
|
|
35
|
+
export declare function createAccountFlow(options: CreateAccountOptions): Promise<CreateAccountResult>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=create-account.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-account.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/credentials/create-account.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAGzE;;GAEG;AACH,UAAU,oBAAoB;IAC7B,WAAW,EAAE,qBAAqB,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,UAAU,mBAAmB;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB;AA2ND;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA0CnG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/credentials/email.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/credentials/email.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAE3C;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqJ7E"}
|
package/dist/index.js
CHANGED
|
@@ -14744,13 +14744,14 @@ async function validateEmailWithTimeback(environment, clientId, clientSecret, em
|
|
|
14744
14744
|
if (page.data.length === 0) {
|
|
14745
14745
|
return {
|
|
14746
14746
|
valid: false,
|
|
14747
|
+
reason: "not_found",
|
|
14747
14748
|
error: `No user found with email "${email3}" in ${environment}`
|
|
14748
14749
|
};
|
|
14749
14750
|
}
|
|
14750
14751
|
return { valid: true };
|
|
14751
14752
|
} catch (error48) {
|
|
14752
14753
|
const message = error48 instanceof Error ? error48.message : "Unknown error";
|
|
14753
|
-
return { valid: false, error: `Failed to validate email: ${message}` };
|
|
14754
|
+
return { valid: false, reason: "api_error", error: `Failed to validate email: ${message}` };
|
|
14754
14755
|
}
|
|
14755
14756
|
}
|
|
14756
14757
|
|
|
@@ -15052,6 +15053,8 @@ var ActivityCompletedInput = exports_external.object({
|
|
|
15052
15053
|
metricsId: exports_external.string().optional(),
|
|
15053
15054
|
id: exports_external.string().optional(),
|
|
15054
15055
|
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
|
|
15056
|
+
edApp: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional(),
|
|
15057
|
+
session: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional(),
|
|
15055
15058
|
attempt: exports_external.number().int().min(1).optional(),
|
|
15056
15059
|
generatedExtensions: exports_external.object({
|
|
15057
15060
|
pctCompleteApp: exports_external.number().optional()
|
|
@@ -15064,7 +15067,9 @@ var TimeSpentInput = exports_external.object({
|
|
|
15064
15067
|
eventTime: IsoDateTimeString.optional(),
|
|
15065
15068
|
metricsId: exports_external.string().optional(),
|
|
15066
15069
|
id: exports_external.string().optional(),
|
|
15067
|
-
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
15070
|
+
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
|
|
15071
|
+
edApp: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional(),
|
|
15072
|
+
session: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]).optional()
|
|
15068
15073
|
}).strict();
|
|
15069
15074
|
var TimebackEvent = exports_external.union([TimebackActivityEvent, TimebackTimeSpentEvent]);
|
|
15070
15075
|
var CaliperEnvelope = exports_external.object({
|
|
@@ -15254,7 +15259,7 @@ var TimebackConfig = exports_external.object({
|
|
|
15254
15259
|
path: ["courses"]
|
|
15255
15260
|
});
|
|
15256
15261
|
// ../types/src/zod/edubridge.ts
|
|
15257
|
-
var EdubridgeDateString = IsoDateTimeString;
|
|
15262
|
+
var EdubridgeDateString = exports_external.union([IsoDateTimeString, IsoDateString]);
|
|
15258
15263
|
var EduBridgeEnrollment = exports_external.object({
|
|
15259
15264
|
id: exports_external.string(),
|
|
15260
15265
|
role: exports_external.string(),
|
|
@@ -17540,6 +17545,184 @@ async function addCredentials(options = {}) {
|
|
|
17540
17545
|
if (exitOnComplete)
|
|
17541
17546
|
process.exit(0);
|
|
17542
17547
|
}
|
|
17548
|
+
// src/cli/commands/credentials/create-account.ts
|
|
17549
|
+
import { randomUUID } from "node:crypto";
|
|
17550
|
+
import { TimebackClient as TimebackClient3 } from "@timeback/core";
|
|
17551
|
+
async function promptName(label) {
|
|
17552
|
+
const value = await he({
|
|
17553
|
+
message: label,
|
|
17554
|
+
placeholder: "Enter name",
|
|
17555
|
+
validate: (v2) => {
|
|
17556
|
+
if (!v2?.trim())
|
|
17557
|
+
return `${label} is required`;
|
|
17558
|
+
}
|
|
17559
|
+
});
|
|
17560
|
+
if (isCancelled(value))
|
|
17561
|
+
return null;
|
|
17562
|
+
return value.trim();
|
|
17563
|
+
}
|
|
17564
|
+
async function searchOrganizations(client, query) {
|
|
17565
|
+
const allOrgs = await client.oneroster.orgs.listAll({
|
|
17566
|
+
where: { status: "active" },
|
|
17567
|
+
max: 100
|
|
17568
|
+
});
|
|
17569
|
+
if (!query.trim())
|
|
17570
|
+
return allOrgs;
|
|
17571
|
+
const lowerQuery = query.toLowerCase().trim();
|
|
17572
|
+
return allOrgs.filter((org) => org.name?.toLowerCase().includes(lowerQuery));
|
|
17573
|
+
}
|
|
17574
|
+
async function searchForOrganization(client) {
|
|
17575
|
+
const query = await he({
|
|
17576
|
+
message: "Search for organization",
|
|
17577
|
+
placeholder: "Enter organization name to search"
|
|
17578
|
+
});
|
|
17579
|
+
if (isCancelled(query))
|
|
17580
|
+
return null;
|
|
17581
|
+
const s = Y2();
|
|
17582
|
+
s.start("Searching organizations...");
|
|
17583
|
+
let results;
|
|
17584
|
+
try {
|
|
17585
|
+
results = await searchOrganizations(client, query);
|
|
17586
|
+
s.stop(green(`Found ${results.length} result${results.length === 1 ? "" : "s"}`));
|
|
17587
|
+
} catch (error48) {
|
|
17588
|
+
s.stop(red("Failed to search organizations"));
|
|
17589
|
+
M2.error(error48 instanceof Error ? error48.message : "Unknown error");
|
|
17590
|
+
return null;
|
|
17591
|
+
}
|
|
17592
|
+
if (results.length === 0) {
|
|
17593
|
+
M2.warn("No organizations found matching your search");
|
|
17594
|
+
return promptOrganization(client);
|
|
17595
|
+
}
|
|
17596
|
+
const validResults = results.filter((org) => org.sourcedId);
|
|
17597
|
+
if (validResults.length === 0) {
|
|
17598
|
+
M2.warn("No valid organizations found (missing IDs)");
|
|
17599
|
+
return promptOrganization(client);
|
|
17600
|
+
}
|
|
17601
|
+
const options = validResults.map((org) => ({
|
|
17602
|
+
value: org.sourcedId,
|
|
17603
|
+
label: org.name ?? "Unnamed Organization"
|
|
17604
|
+
}));
|
|
17605
|
+
options.push({ value: "__back__", label: `${dim("←")} Back to options` });
|
|
17606
|
+
const selection = await ve({
|
|
17607
|
+
message: "Select an organization",
|
|
17608
|
+
options
|
|
17609
|
+
});
|
|
17610
|
+
if (isCancelled(selection))
|
|
17611
|
+
return null;
|
|
17612
|
+
if (selection === "__back__") {
|
|
17613
|
+
return promptOrganization(client);
|
|
17614
|
+
}
|
|
17615
|
+
return validResults.find((org) => org.sourcedId === selection) ?? null;
|
|
17616
|
+
}
|
|
17617
|
+
async function promptOrganization(client) {
|
|
17618
|
+
const action = await ve({
|
|
17619
|
+
message: "Organization",
|
|
17620
|
+
options: [
|
|
17621
|
+
{ value: "search", label: "Search for existing organization" },
|
|
17622
|
+
{ value: "create", label: "Create new organization" }
|
|
17623
|
+
]
|
|
17624
|
+
});
|
|
17625
|
+
if (isCancelled(action))
|
|
17626
|
+
return null;
|
|
17627
|
+
if (action === "create") {
|
|
17628
|
+
return createNewOrganization(client);
|
|
17629
|
+
}
|
|
17630
|
+
return searchForOrganization(client);
|
|
17631
|
+
}
|
|
17632
|
+
async function createNewOrganization(client) {
|
|
17633
|
+
const name = await he({
|
|
17634
|
+
message: "Organization name",
|
|
17635
|
+
placeholder: "Enter organization name",
|
|
17636
|
+
validate: (v2) => {
|
|
17637
|
+
if (!v2?.trim())
|
|
17638
|
+
return "Organization name is required";
|
|
17639
|
+
}
|
|
17640
|
+
});
|
|
17641
|
+
if (isCancelled(name))
|
|
17642
|
+
return null;
|
|
17643
|
+
const s = Y2();
|
|
17644
|
+
s.start("Creating organization...");
|
|
17645
|
+
const sourcedId = randomUUID();
|
|
17646
|
+
try {
|
|
17647
|
+
await client.oneroster.orgs.create({
|
|
17648
|
+
sourcedId,
|
|
17649
|
+
name: name.trim(),
|
|
17650
|
+
type: "school",
|
|
17651
|
+
status: "active"
|
|
17652
|
+
});
|
|
17653
|
+
const organization = await client.oneroster.orgs.get(sourcedId);
|
|
17654
|
+
s.stop(green(`Organization "${name}" created`));
|
|
17655
|
+
return organization;
|
|
17656
|
+
} catch (error48) {
|
|
17657
|
+
s.stop(red("Failed to create organization"));
|
|
17658
|
+
M2.error(error48 instanceof Error ? error48.message : "Unknown error");
|
|
17659
|
+
return null;
|
|
17660
|
+
}
|
|
17661
|
+
}
|
|
17662
|
+
async function createUser(client, email3, givenName, familyName, organizationId) {
|
|
17663
|
+
const s = Y2();
|
|
17664
|
+
s.start("Creating account...");
|
|
17665
|
+
const sourcedId = randomUUID();
|
|
17666
|
+
try {
|
|
17667
|
+
await client.oneroster.users.create({
|
|
17668
|
+
sourcedId,
|
|
17669
|
+
givenName,
|
|
17670
|
+
familyName,
|
|
17671
|
+
email: email3.toLowerCase(),
|
|
17672
|
+
enabledUser: true,
|
|
17673
|
+
status: "active",
|
|
17674
|
+
roles: [
|
|
17675
|
+
{
|
|
17676
|
+
roleType: "primary",
|
|
17677
|
+
role: "administrator",
|
|
17678
|
+
org: { sourcedId: organizationId }
|
|
17679
|
+
}
|
|
17680
|
+
]
|
|
17681
|
+
});
|
|
17682
|
+
const user = await client.oneroster.users.get(sourcedId);
|
|
17683
|
+
s.stop(green("Account created successfully"));
|
|
17684
|
+
return user;
|
|
17685
|
+
} catch (error48) {
|
|
17686
|
+
s.stop(red("Failed to create account"));
|
|
17687
|
+
M2.error(error48 instanceof Error ? error48.message : "Unknown error");
|
|
17688
|
+
return null;
|
|
17689
|
+
}
|
|
17690
|
+
}
|
|
17691
|
+
async function createAccountFlow(options) {
|
|
17692
|
+
const { environment, clientId, clientSecret, email: email3 } = options;
|
|
17693
|
+
M2.info("");
|
|
17694
|
+
M2.info(`No account found for ${dim(email3)} in ${environment}`);
|
|
17695
|
+
const shouldCreate = await ye({
|
|
17696
|
+
message: "Would you like to create a new account?",
|
|
17697
|
+
initialValue: true
|
|
17698
|
+
});
|
|
17699
|
+
if (isCancelled(shouldCreate)) {
|
|
17700
|
+
return { success: false };
|
|
17701
|
+
}
|
|
17702
|
+
if (!shouldCreate) {
|
|
17703
|
+
return { success: false, declined: true };
|
|
17704
|
+
}
|
|
17705
|
+
const client = new TimebackClient3({
|
|
17706
|
+
env: environment,
|
|
17707
|
+
auth: { clientId, clientSecret }
|
|
17708
|
+
});
|
|
17709
|
+
const givenName = await promptName("First name");
|
|
17710
|
+
if (!givenName)
|
|
17711
|
+
return { success: false };
|
|
17712
|
+
const familyName = await promptName("Last name");
|
|
17713
|
+
if (!familyName)
|
|
17714
|
+
return { success: false };
|
|
17715
|
+
const organization = await promptOrganization(client);
|
|
17716
|
+
if (!organization?.sourcedId)
|
|
17717
|
+
return { success: false };
|
|
17718
|
+
const user = await createUser(client, email3, givenName, familyName, organization.sourcedId);
|
|
17719
|
+
if (!user) {
|
|
17720
|
+
return { success: false };
|
|
17721
|
+
}
|
|
17722
|
+
M2.success(`Account created for ${user.givenName} ${user.familyName}`);
|
|
17723
|
+
return { success: true };
|
|
17724
|
+
}
|
|
17725
|
+
|
|
17543
17726
|
// src/cli/commands/credentials/email.ts
|
|
17544
17727
|
async function updateEmail(options = {}) {
|
|
17545
17728
|
const { exitOnComplete = true, inline = false } = options;
|
|
@@ -17608,32 +17791,58 @@ async function updateEmail(options = {}) {
|
|
|
17608
17791
|
return;
|
|
17609
17792
|
}
|
|
17610
17793
|
const emailUnchanged = email3 === (currentEmail ?? "");
|
|
17611
|
-
if (emailUnchanged) {
|
|
17612
|
-
if (!inline)
|
|
17613
|
-
outro.info("Email unchanged");
|
|
17614
|
-
if (exitOnComplete)
|
|
17615
|
-
process.exit(0);
|
|
17616
|
-
return;
|
|
17617
|
-
}
|
|
17618
17794
|
if (email3) {
|
|
17619
17795
|
const s = Y2();
|
|
17620
|
-
s.start("
|
|
17796
|
+
s.start("Checking account...");
|
|
17621
17797
|
const result = await validateEmailWithTimeback(targetEnv, currentCreds.clientId, currentCreds.clientSecret, email3);
|
|
17622
17798
|
if (!result.valid) {
|
|
17623
|
-
|
|
17624
|
-
|
|
17625
|
-
|
|
17799
|
+
if (result.reason !== "not_found") {
|
|
17800
|
+
s.stop(red("Account check failed"));
|
|
17801
|
+
M2.error(result.error ?? "Unknown error");
|
|
17802
|
+
if (!inline)
|
|
17803
|
+
outro.error("Account check failed");
|
|
17804
|
+
if (exitOnComplete)
|
|
17805
|
+
process.exit(1);
|
|
17806
|
+
return;
|
|
17807
|
+
}
|
|
17808
|
+
s.stop(red("No account found"));
|
|
17809
|
+
const { success: accountCreated, declined } = await createAccountFlow({
|
|
17810
|
+
environment: targetEnv,
|
|
17811
|
+
clientId: currentCreds.clientId,
|
|
17812
|
+
clientSecret: currentCreds.clientSecret,
|
|
17813
|
+
email: email3
|
|
17814
|
+
});
|
|
17815
|
+
if (!emailUnchanged) {
|
|
17816
|
+
await saveCredentials(targetEnv, {
|
|
17817
|
+
...currentCreds,
|
|
17818
|
+
email: email3
|
|
17819
|
+
});
|
|
17820
|
+
M2.success(`Email saved for ${targetEnv}`);
|
|
17821
|
+
}
|
|
17822
|
+
if (!inline) {
|
|
17823
|
+
if (accountCreated || declined) {
|
|
17824
|
+
outro.success();
|
|
17825
|
+
} else {
|
|
17826
|
+
outro.info("Setup incomplete - run this command again to finish");
|
|
17827
|
+
}
|
|
17828
|
+
}
|
|
17829
|
+
if (exitOnComplete)
|
|
17830
|
+
process.exit(0);
|
|
17831
|
+
return;
|
|
17832
|
+
}
|
|
17833
|
+
s.stop(green("Account verified"));
|
|
17834
|
+
if (emailUnchanged) {
|
|
17626
17835
|
if (!inline)
|
|
17627
|
-
outro.
|
|
17836
|
+
outro.info("Email unchanged");
|
|
17628
17837
|
if (exitOnComplete)
|
|
17629
|
-
process.exit(
|
|
17838
|
+
process.exit(0);
|
|
17630
17839
|
return;
|
|
17631
17840
|
}
|
|
17632
17841
|
await saveCredentials(targetEnv, {
|
|
17633
17842
|
...currentCreds,
|
|
17634
17843
|
email: email3
|
|
17635
17844
|
});
|
|
17636
|
-
|
|
17845
|
+
M2.success(`Email updated for ${targetEnv}`);
|
|
17637
17846
|
if (!inline)
|
|
17638
17847
|
outro.success();
|
|
17639
17848
|
if (exitOnComplete)
|
|
@@ -17846,7 +18055,7 @@ async function handleCredentialSetup(options = {}) {
|
|
|
17846
18055
|
};
|
|
17847
18056
|
}
|
|
17848
18057
|
// src/cli/lib/onboarding/import.ts
|
|
17849
|
-
import { TimebackClient as
|
|
18058
|
+
import { TimebackClient as TimebackClient4 } from "@timeback/core";
|
|
17850
18059
|
async function promptImportApp(credentials, configuredEnvs) {
|
|
17851
18060
|
let env2;
|
|
17852
18061
|
if (configuredEnvs.length === 1 && configuredEnvs[0]) {
|
|
@@ -17859,7 +18068,7 @@ async function promptImportApp(credentials, configuredEnvs) {
|
|
|
17859
18068
|
env2 = selectedEnv;
|
|
17860
18069
|
}
|
|
17861
18070
|
const creds = credentials[env2];
|
|
17862
|
-
const client = new
|
|
18071
|
+
const client = new TimebackClient4({
|
|
17863
18072
|
env: env2,
|
|
17864
18073
|
auth: { clientId: creds.clientId, clientSecret: creds.clientSecret }
|
|
17865
18074
|
});
|
|
@@ -20289,7 +20498,8 @@ var cors = (options) => {
|
|
|
20289
20498
|
async function handleBootstrap(c, ctx) {
|
|
20290
20499
|
const { bootstrap } = c.get("services");
|
|
20291
20500
|
const env2 = c.get("env");
|
|
20292
|
-
const
|
|
20501
|
+
const freshCredentials = await getSavedCredentials(env2);
|
|
20502
|
+
const email3 = freshCredentials?.email;
|
|
20293
20503
|
const courseIds = ctx.userConfig.courseIds[env2];
|
|
20294
20504
|
const result = await bootstrap.getBootstrap({ email: email3, courseIds });
|
|
20295
20505
|
return c.json(result);
|
|
@@ -21221,11 +21431,15 @@ class StatusService {
|
|
|
21221
21431
|
}
|
|
21222
21432
|
async getStatus() {
|
|
21223
21433
|
const configuredEnvironments = await getConfiguredEnvironments();
|
|
21434
|
+
const [stagingCreds, productionCreds] = await Promise.all([
|
|
21435
|
+
getSavedCredentials("staging"),
|
|
21436
|
+
getSavedCredentials("production")
|
|
21437
|
+
]);
|
|
21224
21438
|
return {
|
|
21225
21439
|
config: this.ctx.userConfig,
|
|
21226
21440
|
environment: this.ctx.defaultEnvironment,
|
|
21227
21441
|
configuredEnvironments,
|
|
21228
|
-
hasEmail: !!
|
|
21442
|
+
hasEmail: !!stagingCreds?.email || !!productionCreds?.email
|
|
21229
21443
|
};
|
|
21230
21444
|
}
|
|
21231
21445
|
}
|
|
@@ -11,6 +11,9 @@ import type { EnvVariables } from '../lib';
|
|
|
11
11
|
*
|
|
12
12
|
* Requires env middleware to set `env` and `client` context variables.
|
|
13
13
|
*
|
|
14
|
+
* NOTE: We read credentials fresh from disk to pick up changes made via CLI
|
|
15
|
+
* (e.g., email updates, account creation) without requiring a server restart.
|
|
16
|
+
*
|
|
14
17
|
* @param c - Hono context with env variables
|
|
15
18
|
* @param ctx - App context
|
|
16
19
|
* @returns JSON response with user and courses
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/server/controllers/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/server/controllers/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAE1C;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,OAAO,CAAC;IAAE,SAAS,EAAE,YAAY,CAAA;CAAE,CAAC,EAAE,GAAG,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAW7F"}
|
|
@@ -15,10 +15,13 @@ export declare class StatusService {
|
|
|
15
15
|
private readonly ctx;
|
|
16
16
|
constructor(ctx: AppContext);
|
|
17
17
|
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
* Build the status payload.
|
|
19
|
+
*
|
|
20
|
+
* NOTE: We read credentials fresh from disk to pick up changes made via CLI
|
|
21
|
+
* (e.g., email updates, account creation) without requiring a server restart.
|
|
22
|
+
*
|
|
23
|
+
* @returns Status payload object
|
|
24
|
+
*/
|
|
22
25
|
getStatus(): Promise<StatusEventPayload>;
|
|
23
26
|
}
|
|
24
27
|
//# sourceMappingURL=status.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/server/services/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAErD;;;;;GAKG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAEhC,YAAY,GAAG,EAAE,UAAU,EAE1B;IAED
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/server/services/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAErD;;;;;GAKG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAEhC,YAAY,GAAG,EAAE,UAAU,EAE1B;IAED;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAc7C;CACD"}
|