@updraft-solutions/mcrit-sdk 0.14.12 → 0.14.13
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/{chunk-KKSV5OWH.cjs → chunk-DV2IZVDB.cjs} +57 -1
- package/dist/{chunk-QCA4OD7R.js → chunk-LL3XK7X2.js} +57 -1
- package/dist/{fbo-7EyTUlqN.d.cts → fbo-sWpm3mI6.d.cts} +17229 -16923
- package/dist/{fbo-7EyTUlqN.d.ts → fbo-sWpm3mI6.d.ts} +17229 -16923
- package/dist/index.cjs +16 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +15 -1
- package/dist/schemas/index.cjs +16 -2
- package/dist/schemas/index.d.cts +121 -121
- package/dist/schemas/index.d.ts +121 -121
- package/dist/schemas/index.js +15 -1
- package/dist/types/index.d.cts +579 -3
- package/dist/types/index.d.ts +579 -3
- package/package.json +1 -1
- package/src/index.ts +43 -0
- package/src/schemas/fbo.spec.ts +116 -0
- package/src/schemas/fbo.ts +99 -0
- package/src/types/fbo.ts +7 -0
- package/dist/operating-hours-BLJOADcx.d.cts +0 -574
- package/dist/operating-hours-D0OI71DZ.d.ts +0 -574
package/src/schemas/fbo.spec.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
fboActivitySchema,
|
|
4
|
+
fboCompanyGrantSchema,
|
|
4
5
|
fboCompanyMemberSchema,
|
|
6
|
+
fboCompanySchema,
|
|
5
7
|
fboDutyAffectedSchema,
|
|
6
8
|
fboDutySchema,
|
|
7
9
|
fboDutySeriesResponseSchema,
|
|
8
10
|
fboFlightDocumentSchema,
|
|
9
11
|
fboFlightSchema,
|
|
10
12
|
fboFlightStatusSchema,
|
|
13
|
+
fboGrantAbilitySchema,
|
|
11
14
|
fboMaterialiseResultSchema,
|
|
15
|
+
fboMetaSchema,
|
|
12
16
|
fboOccupationSchema,
|
|
13
17
|
fboOperationsSchema,
|
|
14
18
|
fboPersonSchema,
|
|
@@ -473,3 +477,115 @@ describe("fboFlightSchema — POB, documents and the customs mail stamp", () =>
|
|
|
473
477
|
expect(fboFlightSchema.safeParse(bad).success).toBe(false);
|
|
474
478
|
});
|
|
475
479
|
});
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Fixtures copied from `CompanyGrantResource`, the FBO meta endpoint and the
|
|
483
|
+
* attached-companies index, so a schema that drifts from the payload fails
|
|
484
|
+
* here rather than at runtime in the app.
|
|
485
|
+
*/
|
|
486
|
+
const grantPayload = {
|
|
487
|
+
id: 12,
|
|
488
|
+
grantee: { id: 34, name: "Alpha Handling" },
|
|
489
|
+
target: { id: 35, name: "Bravo Charter" },
|
|
490
|
+
ability: "duties.view",
|
|
491
|
+
ability_label: "Dienstpläne einsehen",
|
|
492
|
+
granted_by: { id: 7, name: "Erika Muster" },
|
|
493
|
+
created_at: "2026-08-29T09:00:00.000000Z",
|
|
494
|
+
can: { delete: true },
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
describe("fboCompanyGrantSchema", () => {
|
|
498
|
+
it("parses a grant exactly as the register emits it", () => {
|
|
499
|
+
expect(fboCompanyGrantSchema.parse(grantPayload).ability).toBe("duties.view");
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
it("parses a migrated grant nobody signed — granted_by is null", () => {
|
|
503
|
+
expect(fboCompanyGrantSchema.parse({ ...grantPayload, granted_by: null }).granted_by).toBeNull();
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it("parses a side whose company left the FBO domain — the ref is null, not missing", () => {
|
|
507
|
+
expect(fboCompanyGrantSchema.parse({ ...grantPayload, target: null }).target).toBeNull();
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it("rejects an ability outside the register's vocabulary", () => {
|
|
511
|
+
expect(fboCompanyGrantSchema.safeParse({ ...grantPayload, ability: "flights.view" }).success).toBe(false);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it("rejects a row without its ability label — the UI has no copy of its own", () => {
|
|
515
|
+
const { ability_label: _label, ...withoutLabel } = grantPayload;
|
|
516
|
+
expect(fboCompanyGrantSchema.safeParse(withoutLabel).success).toBe(false);
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
describe("fboGrantAbilitySchema", () => {
|
|
521
|
+
it("accepts the one ability the register knows", () => {
|
|
522
|
+
expect(fboGrantAbilitySchema.parse("duties.view")).toBe("duties.view");
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
it("rejects an ability the client cannot render", () => {
|
|
526
|
+
expect(fboGrantAbilitySchema.safeParse("traffic.details").success).toBe(false);
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
describe("fboMetaSchema", () => {
|
|
531
|
+
const metaPayload = {
|
|
532
|
+
roles: ["fbo", "operator"],
|
|
533
|
+
root_id: 34,
|
|
534
|
+
can_decide: true,
|
|
535
|
+
can_view_own_flights: false,
|
|
536
|
+
grant_abilities: [{ value: "duties.view", label: "View duty rosters" }],
|
|
537
|
+
can_manage_grants: true,
|
|
538
|
+
companies: [{ id: 34, name: "Alpha Handling" }],
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
it("parses the meta payload as the API emits it", () => {
|
|
542
|
+
const parsed = fboMetaSchema.parse(metaPayload);
|
|
543
|
+
expect(parsed.grant_abilities?.[0]?.value).toBe("duties.view");
|
|
544
|
+
expect(parsed.can_manage_grants).toBe(true);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it("parses a payload from an API that predates the grant register — only roles is required", () => {
|
|
548
|
+
const parsed = fboMetaSchema.parse({ roles: [] });
|
|
549
|
+
expect(parsed.grant_abilities).toBeUndefined();
|
|
550
|
+
expect(parsed.can_view_own_flights).toBeUndefined();
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it("rejects a grant ability option the client cannot render", () => {
|
|
554
|
+
const bad = { ...metaPayload, grant_abilities: [{ value: "duties.edit", label: "Edit" }] };
|
|
555
|
+
expect(fboMetaSchema.safeParse(bad).success).toBe(false);
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
describe("fboCompanySchema", () => {
|
|
560
|
+
const companyPayload = {
|
|
561
|
+
id: 35,
|
|
562
|
+
name: "Bravo Charter",
|
|
563
|
+
email: "ops@bravo.test",
|
|
564
|
+
phone: null,
|
|
565
|
+
description: null,
|
|
566
|
+
contact_name: "Erika Muster",
|
|
567
|
+
companyType: "interface",
|
|
568
|
+
is_ima_imported: true,
|
|
569
|
+
fbo: { role: "operator", flights_require_approval: true, notify_on_movement: false, has_duties: true, has_airplanes: false },
|
|
570
|
+
members_count: 4,
|
|
571
|
+
movements_count: 92,
|
|
572
|
+
grants_out_count: 1,
|
|
573
|
+
grants_in_count: 0,
|
|
574
|
+
can: { update: true, updateIdentity: true },
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
it("parses an attached company with both grant counts", () => {
|
|
578
|
+
const parsed = fboCompanySchema.parse(companyPayload);
|
|
579
|
+
expect(parsed.grants_out_count).toBe(1);
|
|
580
|
+
expect(parsed.grants_in_count).toBe(0);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it("parses a payload from an API that does not count grants yet", () => {
|
|
584
|
+
const { grants_out_count: _out, grants_in_count: _in, ...withoutCounts } = companyPayload;
|
|
585
|
+
expect(fboCompanySchema.parse(withoutCounts).grants_out_count).toBeUndefined();
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it("parses a company with no FBO profile at all", () => {
|
|
589
|
+
expect(fboCompanySchema.parse({ ...companyPayload, fbo: null }).fbo).toBeNull();
|
|
590
|
+
});
|
|
591
|
+
});
|
package/src/schemas/fbo.ts
CHANGED
|
@@ -436,3 +436,102 @@ export const fboMaterialiseResultSchema = z.object({
|
|
|
436
436
|
skipped_existing: z.number(),
|
|
437
437
|
skipped_closed: z.number(),
|
|
438
438
|
});
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* What one company may exercise on another company's data inside the same FBO
|
|
442
|
+
* tree — the vocabulary of the root's grant register. Mirrors the API enum
|
|
443
|
+
* exactly; a value outside it means the register grew an ability this client
|
|
444
|
+
* does not know how to render, and failing here is the point.
|
|
445
|
+
*/
|
|
446
|
+
export const fboGrantAbilitySchema = z.enum(["duties.view"]);
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* One entry of `GET fbo/meta`'s `grant_abilities` — the ability vocabulary
|
|
450
|
+
* with the label the API already translated, so no client hardcodes copy for
|
|
451
|
+
* an ability it may not know.
|
|
452
|
+
*/
|
|
453
|
+
export const fboGrantAbilityOptionSchema = z.object({
|
|
454
|
+
value: fboGrantAbilitySchema,
|
|
455
|
+
label: z.string(),
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* A company side of a grant. Rendered as `{id, name}` rather than a full
|
|
460
|
+
* company payload: a grant is a relation between two companies, not a view of
|
|
461
|
+
* either. Null only when that company stopped taking part in the FBO domain.
|
|
462
|
+
*/
|
|
463
|
+
export const fboGrantCompanyRefSchema = z.object({
|
|
464
|
+
id: z.number(),
|
|
465
|
+
name: z.string().nullable(),
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* One row of the root's company-grant register — `CompanyGrantResource`.
|
|
470
|
+
* `granted_by` is null for a grant the migration wrote rather than a person.
|
|
471
|
+
* `can.delete` is always true on a row that reached the client at all (only
|
|
472
|
+
* `fbo.company.manage` at the tree root can read the register), but it is
|
|
473
|
+
* read as a gate like every other row's, never assumed.
|
|
474
|
+
*/
|
|
475
|
+
export const fboCompanyGrantSchema = z.object({
|
|
476
|
+
id: z.number(),
|
|
477
|
+
grantee: fboGrantCompanyRefSchema.nullable(),
|
|
478
|
+
target: fboGrantCompanyRefSchema.nullable(),
|
|
479
|
+
ability: fboGrantAbilitySchema,
|
|
480
|
+
ability_label: z.string(),
|
|
481
|
+
granted_by: z.object({ id: z.number(), name: z.string() }).nullable(),
|
|
482
|
+
created_at: z.string().nullable(),
|
|
483
|
+
can: z.object({ delete: z.boolean() }).optional(),
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
/** `POST companies/{id}/fbo/company-grants` — the register's write shape. */
|
|
487
|
+
export const fboCompanyGrantInputSchema = z.object({
|
|
488
|
+
grantee_company_id: z.number(),
|
|
489
|
+
target_company_id: z.number(),
|
|
490
|
+
ability: fboGrantAbilitySchema,
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* `GET companies/{id}/fbo/meta` — the FBO vocabulary and the caller's
|
|
495
|
+
* root-evaluated capabilities, served so no client hardcodes either.
|
|
496
|
+
*
|
|
497
|
+
* Every key but `roles` is optional: the endpoint is the one surface an
|
|
498
|
+
* own-author filer can reach before anything else is known, and it has grown
|
|
499
|
+
* keys over time — a client pinned to an older API must still parse it.
|
|
500
|
+
*
|
|
501
|
+
* `can_view_own_flights` is the TIER, not the bare permission: true only when
|
|
502
|
+
* this caller's sight of movements is the own-author one (false for a decider
|
|
503
|
+
* or an operator, who hold the wider `fbo.flight.viewAny`).
|
|
504
|
+
*/
|
|
505
|
+
export const fboMetaSchema = z.object({
|
|
506
|
+
roles: z.array(z.string()),
|
|
507
|
+
root_id: z.number().nullable().optional(),
|
|
508
|
+
can_decide: z.boolean().optional(),
|
|
509
|
+
can_view_own_flights: z.boolean().optional(),
|
|
510
|
+
grant_abilities: z.array(fboGrantAbilityOptionSchema).optional(),
|
|
511
|
+
can_manage_grants: z.boolean().optional(),
|
|
512
|
+
companies: z.array(fboGrantCompanyRefSchema).optional(),
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* A company attached to the FBO as its root's admin reads it —
|
|
517
|
+
* `CompanyResource` under `GET companies/{fbo}/fbo/companies`. The three
|
|
518
|
+
* counts are aggregates the index adds (`withCount`) and are null on any
|
|
519
|
+
* payload that did not compute them; `grants_out_count`/`grants_in_count`
|
|
520
|
+
* are additionally optional, being newer than the surface itself.
|
|
521
|
+
*/
|
|
522
|
+
export const fboCompanySchema = z.object({
|
|
523
|
+
id: z.number(),
|
|
524
|
+
name: z.string(),
|
|
525
|
+
email: z.string().nullable(),
|
|
526
|
+
phone: z.string().nullable(),
|
|
527
|
+
description: z.string().nullable(),
|
|
528
|
+
contact_name: z.string().nullable(),
|
|
529
|
+
companyType: z.string(),
|
|
530
|
+
is_ima_imported: z.boolean(),
|
|
531
|
+
fbo: fboCompanyProfileSchema.nullable(),
|
|
532
|
+
members_count: z.number().nullable(),
|
|
533
|
+
movements_count: z.number().nullable(),
|
|
534
|
+
grants_out_count: z.number().nullable().optional(),
|
|
535
|
+
grants_in_count: z.number().nullable().optional(),
|
|
536
|
+
can: z.object({ update: z.boolean(), updateIdentity: z.boolean() }),
|
|
537
|
+
});
|
package/src/types/fbo.ts
CHANGED
|
@@ -36,3 +36,10 @@ export type FboActivityChanges = z.infer<typeof Fbo.fboActivityChangesSchema>;
|
|
|
36
36
|
export type FboActivity = z.infer<typeof Fbo.fboActivitySchema>;
|
|
37
37
|
export type FboRecurringFlight = z.infer<typeof Fbo.fboRecurringFlightSchema>;
|
|
38
38
|
export type FboMaterialiseResult = z.infer<typeof Fbo.fboMaterialiseResultSchema>;
|
|
39
|
+
export type FboGrantAbility = z.infer<typeof Fbo.fboGrantAbilitySchema>;
|
|
40
|
+
export type FboGrantAbilityOption = z.infer<typeof Fbo.fboGrantAbilityOptionSchema>;
|
|
41
|
+
export type FboGrantCompanyRef = z.infer<typeof Fbo.fboGrantCompanyRefSchema>;
|
|
42
|
+
export type FboCompanyGrant = z.infer<typeof Fbo.fboCompanyGrantSchema>;
|
|
43
|
+
export type FboCompanyGrantInput = z.infer<typeof Fbo.fboCompanyGrantInputSchema>;
|
|
44
|
+
export type FboMeta = z.infer<typeof Fbo.fboMetaSchema>;
|
|
45
|
+
export type FboCompany = z.infer<typeof Fbo.fboCompanySchema>;
|