@robosystems/client 0.3.39 → 0.3.41
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/artifacts/LedgerClient.d.ts +35 -41
- package/artifacts/LedgerClient.js +61 -102
- package/artifacts/LedgerClient.ts +82 -119
- package/artifacts/graphql/generated/graphql.d.ts +48 -3
- package/artifacts/graphql/generated/graphql.js +70 -2
- package/artifacts/graphql/generated/graphql.ts +123 -3
- package/artifacts/graphql/queries/ledger/reportDownloadUrl.d.ts +11 -0
- package/artifacts/graphql/queries/ledger/reportDownloadUrl.js +29 -0
- package/artifacts/graphql/queries/ledger/reportDownloadUrl.ts +27 -0
- package/bin/create-feature.sh +5 -3
- package/index.ts +2 -2
- package/package.json +1 -2
- package/sdk/index.d.ts +2 -2
- package/sdk/index.js +3 -3
- package/sdk/index.ts +2 -2
- package/sdk/sdk.gen.d.ts +13 -11
- package/sdk/sdk.gen.js +23 -17
- package/sdk/sdk.gen.ts +22 -16
- package/sdk/types.gen.d.ts +191 -110
- package/sdk/types.gen.ts +199 -115
- package/sdk.gen.d.ts +13 -11
- package/sdk.gen.js +23 -17
- package/sdk.gen.ts +22 -16
- package/types.gen.d.ts +191 -110
- package/types.gen.ts +199 -115
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AssociationResponse, AutoMapElementsOperation, CreateAgentRequest, CreateEventBlockRequest, CreateEventHandlerRequest, CreateInformationBlockRequest, CreateMappingAssociationOperation, CreateTaxonomyBlockRequest, CreateViewRequest, DeleteInformationBlockRequest, DeleteInformationBlockResponse, DeleteMappingAssociationOperation, DeleteResult, DeleteTaxonomyBlockRequest, DeleteTaxonomyBlockResponse, EntityTaxonomyResponse, EvaluateRulesRequest, EvaluateRulesResponse, EventBlockEnvelope, EventHandlerResponse, FinancialStatementAnalysisRequest, InformationBlockEnvelope, JournalEntryResponse, LedgerAgentResponse, LinkEntityTaxonomyRequest, LiveFinancialStatementRequest, OperationEnvelope, PreviewEventBlockResponse, PublishListMemberResponse, PublishListResponse, ReportResponse, ShareReportResponse, TaxonomyBlockEnvelope, UpdateAgentRequest, UpdateEntityRequest, UpdateEventBlockRequest, UpdateEventHandlerRequest, UpdateInformationBlockRequest, UpdateJournalEntryRequest, UpdateTaxonomyBlockRequest } from '../types.gen';
|
|
2
2
|
import type { TokenProvider } from './graphql/client';
|
|
3
|
-
import { type GetInformationBlockQuery, type GetLedgerAccountRollupsQuery, type GetLedgerAccountTreeQuery, type GetLedgerAgentQuery, type GetLedgerClosingBookStructuresQuery, type GetLedgerEntityQuery, type GetLedgerEventBlockQuery, type GetLedgerFiscalCalendarQuery, type GetLedgerMappedTrialBalanceQuery, type GetLedgerMappingCoverageQuery, type GetLedgerMappingQuery, type GetLedgerPeriodCloseStatusQuery, type GetLedgerPeriodDraftsQuery, type GetLedgerPublishListQuery, type GetLedgerReportingTaxonomyQuery, type GetLedgerReportPackageQuery, type GetLedgerReportQuery, type GetLedgerStatementQuery, type GetLedgerSummaryQuery, type GetLedgerTransactionQuery, type GetLedgerTrialBalanceQuery, type ListInformationBlocksQuery, type ListLedgerAccountsQuery, type ListLedgerAgentsQuery, type ListLedgerElementsQuery, type ListLedgerEntitiesQuery, type ListLedgerEventBlocksQuery, type ListLedgerMappingsQuery, type ListLedgerPublishListsQuery, type ListLedgerReportsQuery, type ListLedgerStructuresQuery, type ListLedgerTaxonomiesQuery, type ListLedgerTransactionsQuery, type ListLedgerUnmappedElementsQuery, type MappingCandidatesQuery } from './graphql/generated/graphql';
|
|
3
|
+
import { type GetInformationBlockQuery, type GetLedgerAccountRollupsQuery, type GetLedgerAccountTreeQuery, type GetLedgerAgentQuery, type GetLedgerClosingBookStructuresQuery, type GetLedgerEntityQuery, type GetLedgerEventBlockQuery, type GetLedgerFiscalCalendarQuery, type GetLedgerMappedTrialBalanceQuery, type GetLedgerMappingCoverageQuery, type GetLedgerMappingQuery, type GetLedgerPeriodCloseStatusQuery, type GetLedgerPeriodDraftsQuery, type GetLedgerPublishListQuery, type GetLedgerReportingTaxonomyQuery, type GetLedgerReportPackageQuery, type GetLedgerReportQuery, type GetLedgerStatementQuery, type GetLedgerSummaryQuery, type GetLedgerTransactionQuery, type GetLedgerTrialBalanceQuery, type ListInformationBlocksQuery, type ListLedgerAccountsQuery, type ListLedgerAgentsQuery, type ListLedgerElementsQuery, type ListLedgerEntitiesQuery, type ListLedgerEventBlocksQuery, type ListLedgerMappingsQuery, type ListLedgerPublishListsQuery, type ListLedgerReportsQuery, type ListLedgerStructuresQuery, type ListLedgerTaxonomiesQuery, type ListLedgerTransactionsQuery, type ListLedgerUnmappedElementsQuery, type MappingCandidatesQuery, type ReportDownloadFormat } from './graphql/generated/graphql';
|
|
4
4
|
export type LedgerEntity = NonNullable<GetLedgerEntityQuery['entity']>;
|
|
5
5
|
export type LedgerEntitySummary = ListLedgerEntitiesQuery['entities'][number];
|
|
6
6
|
export type LedgerSummary = NonNullable<GetLedgerSummaryQuery['summary']>;
|
|
@@ -56,7 +56,7 @@ export type PublishListMember = PublishListDetail['members'][number];
|
|
|
56
56
|
/**
|
|
57
57
|
* Presigned-URL response for a Report bundle download.
|
|
58
58
|
*
|
|
59
|
-
* Returned by ``LedgerClient.
|
|
59
|
+
* Returned by ``LedgerClient.getReportDownloadUrl`` — the
|
|
60
60
|
* ``downloadUrl`` is a time-limited URL that streams the
|
|
61
61
|
* serialization artifact directly from object storage. Browser
|
|
62
62
|
* callers typically follow the URL via ``window.location.href`` or
|
|
@@ -69,7 +69,7 @@ export interface ReportBundleDownloadResponse {
|
|
|
69
69
|
expiresAt: string;
|
|
70
70
|
/** MIME type of the artifact behind the URL. */
|
|
71
71
|
contentType: string;
|
|
72
|
-
/** Serialization flavor — ``jsonld``
|
|
72
|
+
/** Serialization flavor — ``jsonld`` or ``xbrl-2.1``. */
|
|
73
73
|
format: string;
|
|
74
74
|
/** Bundle generation number stamped on the Report. */
|
|
75
75
|
generationCount: number;
|
|
@@ -406,6 +406,22 @@ export declare class LedgerClient {
|
|
|
406
406
|
}): Promise<InformationBlockEnvelope>;
|
|
407
407
|
/** Permanently delete a schedule (cascades through facts + associations). */
|
|
408
408
|
deleteSchedule(graphId: string, structureId: string): Promise<DeleteInformationBlockResponse>;
|
|
409
|
+
/**
|
|
410
|
+
* Rebuild a schedule in place — atomic alternative to
|
|
411
|
+
* delete-then-recreate (which orphans pending obligations). Preserves
|
|
412
|
+
* the structure id, element associations, and taxonomy; voids the old
|
|
413
|
+
* pending obligation chain; deletes the old facts + SumEquals rules;
|
|
414
|
+
* and regenerates fresh forward facts + a fresh obligation chain from
|
|
415
|
+
* the schedule's stored definition. The historical-vs-in-scope split
|
|
416
|
+
* is re-derived from the CURRENT fiscal calendar `closed_through`, so
|
|
417
|
+
* a rebuild re-scopes the schedule to today's close state. Use this to
|
|
418
|
+
* pick up a fixed generator without orphaning obligations.
|
|
419
|
+
*
|
|
420
|
+
* Returns the same shape as `createSchedule`.
|
|
421
|
+
*/
|
|
422
|
+
rebuildSchedule(graphId: string, structureId: string, options?: {
|
|
423
|
+
idempotencyKey?: string;
|
|
424
|
+
}): Promise<ScheduleCreated>;
|
|
409
425
|
/**
|
|
410
426
|
* Dispose of a schedule asset — atomically truncates forward facts,
|
|
411
427
|
* deletes the SumEquals rule, and posts a balanced disposal entry.
|
|
@@ -587,51 +603,29 @@ export declare class LedgerClient {
|
|
|
587
603
|
* Get a short-lived presigned URL for downloading a published
|
|
588
604
|
* Report's serialization bundle.
|
|
589
605
|
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
606
|
+
* A download is a read, so this resolves through GraphQL
|
|
607
|
+
* (`reportDownloadUrl`) — the retired `GET .../reports/{id}/download`
|
|
608
|
+
* REST resource is gone. Every flavor resolves to a presigned S3 URL:
|
|
609
|
+
* JSON-LD is stamped at publish time; XBRL is materialized + cached
|
|
610
|
+
* on first request. The returned `downloadUrl` is valid for
|
|
611
|
+
* `expiresIn` seconds (default 300, max 3600); browser callers
|
|
612
|
+
* navigate to it via `window.location.href` (or an `<a href>` click)
|
|
613
|
+
* to trigger the download — the server-set Content-Disposition forces
|
|
614
|
+
* "attachment" with a versioned filename.
|
|
595
615
|
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
* to an `<a href>` and click) to trigger the file download; the
|
|
600
|
-
* server-set Content-Disposition forces "attachment" with a
|
|
601
|
-
* versioned filename.
|
|
616
|
+
* Returns `null` when the report doesn't exist. A report that has
|
|
617
|
+
* never been published surfaces a `REPORT_BUNDLE_NOT_AVAILABLE`
|
|
618
|
+
* GraphQL error (regenerate it to produce a bundle).
|
|
602
619
|
*
|
|
603
620
|
* @param graphId Graph identifier owning the Report.
|
|
604
621
|
* @param reportId Report identifier (rpt_-prefixed ULID).
|
|
605
|
-
* @param options.format Serialization flavor —
|
|
622
|
+
* @param options.format Serialization flavor — `JSONLD` (default) or `XBRL_2_1`.
|
|
606
623
|
* @param options.expiresIn Presigned URL lifetime, in seconds.
|
|
607
624
|
*/
|
|
608
|
-
|
|
609
|
-
format?:
|
|
625
|
+
getReportDownloadUrl(graphId: string, reportId: string, options?: {
|
|
626
|
+
format?: ReportDownloadFormat;
|
|
610
627
|
expiresIn?: number;
|
|
611
|
-
}): Promise<ReportBundleDownloadResponse>;
|
|
612
|
-
/**
|
|
613
|
-
* Download the Report's serialization bundle as an XBRL 2.1 zip.
|
|
614
|
-
*
|
|
615
|
-
* Rebuilds the bundle on the server and streams the zip body
|
|
616
|
-
* directly — no S3 presigned URL is involved (XBRL is on-demand
|
|
617
|
-
* emit, per the serialization spec). The returned ``Blob`` can be
|
|
618
|
-
* saved via URL.createObjectURL + a temporary anchor click to
|
|
619
|
-
* trigger the browser download dialog.
|
|
620
|
-
*
|
|
621
|
-
* The zip contains five files: ``instance.xml``, ``report.xsd``,
|
|
622
|
-
* ``report-pre.xml``, ``report-cal.xml``, ``report-def.xml``.
|
|
623
|
-
*
|
|
624
|
-
* @param graphId Graph identifier owning the Report.
|
|
625
|
-
* @param reportId Report identifier (rpt_-prefixed ULID).
|
|
626
|
-
* @param options.flavor XBRL flavor (default ``'xbrl-2.1'``).
|
|
627
|
-
*/
|
|
628
|
-
getReportBundleXbrlZip(graphId: string, reportId: string, options?: {
|
|
629
|
-
flavor?: string;
|
|
630
|
-
}): Promise<{
|
|
631
|
-
blob: Blob;
|
|
632
|
-
filename: string;
|
|
633
|
-
generationCount: number | null;
|
|
634
|
-
}>;
|
|
628
|
+
}): Promise<ReportBundleDownloadResponse | null>;
|
|
635
629
|
/**
|
|
636
630
|
* Share a published report to every member of a publish list. Each
|
|
637
631
|
* target graph receives a snapshot copy of the report's facts.
|
|
@@ -357,6 +357,38 @@ class LedgerClient {
|
|
|
357
357
|
const envelope = await this.callOperation('Delete schedule', (0, sdk_gen_1.opDeleteInformationBlock)({ path: { graph_id: graphId }, body }));
|
|
358
358
|
return (envelope.result ?? { deleted: true });
|
|
359
359
|
}
|
|
360
|
+
/**
|
|
361
|
+
* Rebuild a schedule in place — atomic alternative to
|
|
362
|
+
* delete-then-recreate (which orphans pending obligations). Preserves
|
|
363
|
+
* the structure id, element associations, and taxonomy; voids the old
|
|
364
|
+
* pending obligation chain; deletes the old facts + SumEquals rules;
|
|
365
|
+
* and regenerates fresh forward facts + a fresh obligation chain from
|
|
366
|
+
* the schedule's stored definition. The historical-vs-in-scope split
|
|
367
|
+
* is re-derived from the CURRENT fiscal calendar `closed_through`, so
|
|
368
|
+
* a rebuild re-scopes the schedule to today's close state. Use this to
|
|
369
|
+
* pick up a fixed generator without orphaning obligations.
|
|
370
|
+
*
|
|
371
|
+
* Returns the same shape as `createSchedule`.
|
|
372
|
+
*/
|
|
373
|
+
async rebuildSchedule(graphId, structureId, options) {
|
|
374
|
+
const body = { structure_id: structureId };
|
|
375
|
+
const envelope = await this.callOperation('Rebuild schedule', (0, sdk_gen_1.opRebuildSchedule)({
|
|
376
|
+
path: { graph_id: graphId },
|
|
377
|
+
body,
|
|
378
|
+
headers: options?.idempotencyKey
|
|
379
|
+
? { 'Idempotency-Key': options.idempotencyKey }
|
|
380
|
+
: undefined,
|
|
381
|
+
}));
|
|
382
|
+
const raw = envelope.result;
|
|
383
|
+
return {
|
|
384
|
+
structureId: raw.structure_id,
|
|
385
|
+
name: raw.name,
|
|
386
|
+
taxonomyId: raw.taxonomy_id,
|
|
387
|
+
totalPeriods: raw.total_periods,
|
|
388
|
+
totalFacts: raw.total_facts,
|
|
389
|
+
ruleSummary: raw.rule_summary ?? null,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
360
392
|
/**
|
|
361
393
|
* Dispose of a schedule asset — atomically truncates forward facts,
|
|
362
394
|
* deletes the SumEquals rule, and posts a balanced disposal entry.
|
|
@@ -768,115 +800,42 @@ class LedgerClient {
|
|
|
768
800
|
* Get a short-lived presigned URL for downloading a published
|
|
769
801
|
* Report's serialization bundle.
|
|
770
802
|
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
*
|
|
803
|
+
* A download is a read, so this resolves through GraphQL
|
|
804
|
+
* (`reportDownloadUrl`) — the retired `GET .../reports/{id}/download`
|
|
805
|
+
* REST resource is gone. Every flavor resolves to a presigned S3 URL:
|
|
806
|
+
* JSON-LD is stamped at publish time; XBRL is materialized + cached
|
|
807
|
+
* on first request. The returned `downloadUrl` is valid for
|
|
808
|
+
* `expiresIn` seconds (default 300, max 3600); browser callers
|
|
809
|
+
* navigate to it via `window.location.href` (or an `<a href>` click)
|
|
810
|
+
* to trigger the download — the server-set Content-Disposition forces
|
|
811
|
+
* "attachment" with a versioned filename.
|
|
776
812
|
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
* to an `<a href>` and click) to trigger the file download; the
|
|
781
|
-
* server-set Content-Disposition forces "attachment" with a
|
|
782
|
-
* versioned filename.
|
|
813
|
+
* Returns `null` when the report doesn't exist. A report that has
|
|
814
|
+
* never been published surfaces a `REPORT_BUNDLE_NOT_AVAILABLE`
|
|
815
|
+
* GraphQL error (regenerate it to produce a bundle).
|
|
783
816
|
*
|
|
784
817
|
* @param graphId Graph identifier owning the Report.
|
|
785
818
|
* @param reportId Report identifier (rpt_-prefixed ULID).
|
|
786
|
-
* @param options.format Serialization flavor —
|
|
819
|
+
* @param options.format Serialization flavor — `JSONLD` (default) or `XBRL_2_1`.
|
|
787
820
|
* @param options.expiresIn Presigned URL lifetime, in seconds.
|
|
788
821
|
*/
|
|
789
|
-
async
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
}
|
|
805
|
-
else {
|
|
806
|
-
headers.set('Authorization', `Bearer ${token}`);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
const response = await fetch(url, {
|
|
810
|
-
method: 'GET',
|
|
811
|
-
headers,
|
|
812
|
-
credentials: this.config.credentials,
|
|
813
|
-
});
|
|
814
|
-
if (!response.ok) {
|
|
815
|
-
const body = await response.text();
|
|
816
|
-
throw new Error(`Get report bundle download URL failed (${response.status}): ${body}`);
|
|
817
|
-
}
|
|
818
|
-
const raw = (await response.json());
|
|
819
|
-
return {
|
|
820
|
-
downloadUrl: raw.download_url,
|
|
821
|
-
expiresAt: raw.expires_at,
|
|
822
|
-
contentType: raw.content_type,
|
|
823
|
-
format: raw.format,
|
|
824
|
-
generationCount: raw.generation_count,
|
|
825
|
-
};
|
|
826
|
-
}
|
|
827
|
-
/**
|
|
828
|
-
* Download the Report's serialization bundle as an XBRL 2.1 zip.
|
|
829
|
-
*
|
|
830
|
-
* Rebuilds the bundle on the server and streams the zip body
|
|
831
|
-
* directly — no S3 presigned URL is involved (XBRL is on-demand
|
|
832
|
-
* emit, per the serialization spec). The returned ``Blob`` can be
|
|
833
|
-
* saved via URL.createObjectURL + a temporary anchor click to
|
|
834
|
-
* trigger the browser download dialog.
|
|
835
|
-
*
|
|
836
|
-
* The zip contains five files: ``instance.xml``, ``report.xsd``,
|
|
837
|
-
* ``report-pre.xml``, ``report-cal.xml``, ``report-def.xml``.
|
|
838
|
-
*
|
|
839
|
-
* @param graphId Graph identifier owning the Report.
|
|
840
|
-
* @param reportId Report identifier (rpt_-prefixed ULID).
|
|
841
|
-
* @param options.flavor XBRL flavor (default ``'xbrl-2.1'``).
|
|
842
|
-
*/
|
|
843
|
-
async getReportBundleXbrlZip(graphId, reportId, options = {}) {
|
|
844
|
-
const flavor = options.flavor ?? 'xbrl-2.1';
|
|
845
|
-
const url = `${this.config.baseUrl.replace(/\/$/, '')}` +
|
|
846
|
-
`/extensions/roboledger/${encodeURIComponent(graphId)}` +
|
|
847
|
-
`/reports/${encodeURIComponent(reportId)}/download` +
|
|
848
|
-
`?format=${encodeURIComponent(flavor)}`;
|
|
849
|
-
const headers = new Headers({
|
|
850
|
-
Accept: 'application/zip',
|
|
851
|
-
...(this.config.headers ?? {}),
|
|
852
|
-
});
|
|
853
|
-
const token = await this.resolveToken();
|
|
854
|
-
if (token) {
|
|
855
|
-
if (token.startsWith('rfs')) {
|
|
856
|
-
headers.set('X-API-Key', token);
|
|
857
|
-
}
|
|
858
|
-
else {
|
|
859
|
-
headers.set('Authorization', `Bearer ${token}`);
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
const response = await fetch(url, {
|
|
863
|
-
method: 'GET',
|
|
864
|
-
headers,
|
|
865
|
-
credentials: this.config.credentials,
|
|
822
|
+
async getReportDownloadUrl(graphId, reportId, options = {}) {
|
|
823
|
+
return this.gqlQuery(graphId, graphql_1.GetLedgerReportDownloadUrlDocument, {
|
|
824
|
+
reportId,
|
|
825
|
+
format: options.format ?? 'JSONLD',
|
|
826
|
+
expiresIn: options.expiresIn ?? 300,
|
|
827
|
+
}, 'Get report download URL', (data) => {
|
|
828
|
+
const node = data.reportDownloadUrl;
|
|
829
|
+
if (!node)
|
|
830
|
+
return null;
|
|
831
|
+
return {
|
|
832
|
+
downloadUrl: node.downloadUrl,
|
|
833
|
+
expiresAt: node.expiresAt,
|
|
834
|
+
contentType: node.contentType,
|
|
835
|
+
format: node.format,
|
|
836
|
+
generationCount: node.generationCount,
|
|
837
|
+
};
|
|
866
838
|
});
|
|
867
|
-
if (!response.ok) {
|
|
868
|
-
const body = await response.text();
|
|
869
|
-
throw new Error(`Get report bundle XBRL zip failed (${response.status}): ${body}`);
|
|
870
|
-
}
|
|
871
|
-
const blob = await response.blob();
|
|
872
|
-
// Parse Content-Disposition for the server-suggested filename;
|
|
873
|
-
// fall back to a sensible default if absent.
|
|
874
|
-
const disposition = response.headers.get('Content-Disposition') ?? '';
|
|
875
|
-
const filenameMatch = disposition.match(/filename="?([^";]+)"?/i);
|
|
876
|
-
const filename = filenameMatch ? filenameMatch[1] : `${reportId}.zip`;
|
|
877
|
-
const generationHeader = response.headers.get('X-Bundle-Generation');
|
|
878
|
-
const generationCount = generationHeader ? Number.parseInt(generationHeader, 10) : null;
|
|
879
|
-
return { blob, filename, generationCount };
|
|
880
839
|
}
|
|
881
840
|
/**
|
|
882
841
|
* Share a published report to every member of a publish list. Each
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
opLinkEntityTaxonomy,
|
|
51
51
|
opLiveFinancialStatement,
|
|
52
52
|
opPreviewEventBlock,
|
|
53
|
+
opRebuildSchedule,
|
|
53
54
|
opRegenerateReport,
|
|
54
55
|
opRemovePublishListMember,
|
|
55
56
|
opReopenPeriod,
|
|
@@ -103,6 +104,7 @@ import type {
|
|
|
103
104
|
PreviewEventBlockResponse,
|
|
104
105
|
PublishListMemberResponse,
|
|
105
106
|
PublishListResponse,
|
|
107
|
+
RebuildScheduleRequest,
|
|
106
108
|
ReopenPeriodOperation,
|
|
107
109
|
ReportResponse,
|
|
108
110
|
SetCloseTargetOperation,
|
|
@@ -136,6 +138,7 @@ import {
|
|
|
136
138
|
GetLedgerPeriodDraftsDocument,
|
|
137
139
|
GetLedgerPublishListDocument,
|
|
138
140
|
GetLedgerReportDocument,
|
|
141
|
+
GetLedgerReportDownloadUrlDocument,
|
|
139
142
|
GetLedgerReportingTaxonomyDocument,
|
|
140
143
|
GetLedgerReportPackageDocument,
|
|
141
144
|
GetLedgerStatementDocument,
|
|
@@ -191,6 +194,7 @@ import {
|
|
|
191
194
|
type ListLedgerTransactionsQuery,
|
|
192
195
|
type ListLedgerUnmappedElementsQuery,
|
|
193
196
|
type MappingCandidatesQuery,
|
|
197
|
+
type ReportDownloadFormat,
|
|
194
198
|
} from './graphql/generated/graphql'
|
|
195
199
|
|
|
196
200
|
// ── Friendly types derived from GraphQL codegen ────────────────────────
|
|
@@ -283,7 +287,7 @@ export type PublishListMember = PublishListDetail['members'][number]
|
|
|
283
287
|
/**
|
|
284
288
|
* Presigned-URL response for a Report bundle download.
|
|
285
289
|
*
|
|
286
|
-
* Returned by ``LedgerClient.
|
|
290
|
+
* Returned by ``LedgerClient.getReportDownloadUrl`` — the
|
|
287
291
|
* ``downloadUrl`` is a time-limited URL that streams the
|
|
288
292
|
* serialization artifact directly from object storage. Browser
|
|
289
293
|
* callers typically follow the URL via ``window.location.href`` or
|
|
@@ -296,20 +300,12 @@ export interface ReportBundleDownloadResponse {
|
|
|
296
300
|
expiresAt: string
|
|
297
301
|
/** MIME type of the artifact behind the URL. */
|
|
298
302
|
contentType: string
|
|
299
|
-
/** Serialization flavor — ``jsonld``
|
|
303
|
+
/** Serialization flavor — ``jsonld`` or ``xbrl-2.1``. */
|
|
300
304
|
format: string
|
|
301
305
|
/** Bundle generation number stamped on the Report. */
|
|
302
306
|
generationCount: number
|
|
303
307
|
}
|
|
304
308
|
|
|
305
|
-
interface RawReportBundleDownloadResponse {
|
|
306
|
-
download_url: string
|
|
307
|
-
expires_at: string
|
|
308
|
-
content_type: string
|
|
309
|
-
format: string
|
|
310
|
-
generation_count: number
|
|
311
|
-
}
|
|
312
|
-
|
|
313
309
|
export interface PeriodSpecInput {
|
|
314
310
|
start: string
|
|
315
311
|
end: string
|
|
@@ -1237,6 +1233,46 @@ export class LedgerClient {
|
|
|
1237
1233
|
return (envelope.result ?? { deleted: true }) as DeleteInformationBlockResponse
|
|
1238
1234
|
}
|
|
1239
1235
|
|
|
1236
|
+
/**
|
|
1237
|
+
* Rebuild a schedule in place — atomic alternative to
|
|
1238
|
+
* delete-then-recreate (which orphans pending obligations). Preserves
|
|
1239
|
+
* the structure id, element associations, and taxonomy; voids the old
|
|
1240
|
+
* pending obligation chain; deletes the old facts + SumEquals rules;
|
|
1241
|
+
* and regenerates fresh forward facts + a fresh obligation chain from
|
|
1242
|
+
* the schedule's stored definition. The historical-vs-in-scope split
|
|
1243
|
+
* is re-derived from the CURRENT fiscal calendar `closed_through`, so
|
|
1244
|
+
* a rebuild re-scopes the schedule to today's close state. Use this to
|
|
1245
|
+
* pick up a fixed generator without orphaning obligations.
|
|
1246
|
+
*
|
|
1247
|
+
* Returns the same shape as `createSchedule`.
|
|
1248
|
+
*/
|
|
1249
|
+
async rebuildSchedule(
|
|
1250
|
+
graphId: string,
|
|
1251
|
+
structureId: string,
|
|
1252
|
+
options?: { idempotencyKey?: string }
|
|
1253
|
+
): Promise<ScheduleCreated> {
|
|
1254
|
+
const body: RebuildScheduleRequest = { structure_id: structureId }
|
|
1255
|
+
const envelope = await this.callOperation(
|
|
1256
|
+
'Rebuild schedule',
|
|
1257
|
+
opRebuildSchedule({
|
|
1258
|
+
path: { graph_id: graphId },
|
|
1259
|
+
body,
|
|
1260
|
+
headers: options?.idempotencyKey
|
|
1261
|
+
? { 'Idempotency-Key': options.idempotencyKey }
|
|
1262
|
+
: undefined,
|
|
1263
|
+
})
|
|
1264
|
+
)
|
|
1265
|
+
const raw = envelope.result as unknown as RawScheduleCreatedResult
|
|
1266
|
+
return {
|
|
1267
|
+
structureId: raw.structure_id,
|
|
1268
|
+
name: raw.name,
|
|
1269
|
+
taxonomyId: raw.taxonomy_id,
|
|
1270
|
+
totalPeriods: raw.total_periods,
|
|
1271
|
+
totalFacts: raw.total_facts,
|
|
1272
|
+
ruleSummary: raw.rule_summary ?? null,
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1240
1276
|
/**
|
|
1241
1277
|
* Dispose of a schedule asset — atomically truncates forward facts,
|
|
1242
1278
|
* deletes the SumEquals rule, and posts a balanced disposal entry.
|
|
@@ -1903,124 +1939,51 @@ export class LedgerClient {
|
|
|
1903
1939
|
* Get a short-lived presigned URL for downloading a published
|
|
1904
1940
|
* Report's serialization bundle.
|
|
1905
1941
|
*
|
|
1906
|
-
*
|
|
1907
|
-
*
|
|
1908
|
-
*
|
|
1909
|
-
*
|
|
1910
|
-
*
|
|
1942
|
+
* A download is a read, so this resolves through GraphQL
|
|
1943
|
+
* (`reportDownloadUrl`) — the retired `GET .../reports/{id}/download`
|
|
1944
|
+
* REST resource is gone. Every flavor resolves to a presigned S3 URL:
|
|
1945
|
+
* JSON-LD is stamped at publish time; XBRL is materialized + cached
|
|
1946
|
+
* on first request. The returned `downloadUrl` is valid for
|
|
1947
|
+
* `expiresIn` seconds (default 300, max 3600); browser callers
|
|
1948
|
+
* navigate to it via `window.location.href` (or an `<a href>` click)
|
|
1949
|
+
* to trigger the download — the server-set Content-Disposition forces
|
|
1950
|
+
* "attachment" with a versioned filename.
|
|
1911
1951
|
*
|
|
1912
|
-
*
|
|
1913
|
-
*
|
|
1914
|
-
*
|
|
1915
|
-
* to an `<a href>` and click) to trigger the file download; the
|
|
1916
|
-
* server-set Content-Disposition forces "attachment" with a
|
|
1917
|
-
* versioned filename.
|
|
1952
|
+
* Returns `null` when the report doesn't exist. A report that has
|
|
1953
|
+
* never been published surfaces a `REPORT_BUNDLE_NOT_AVAILABLE`
|
|
1954
|
+
* GraphQL error (regenerate it to produce a bundle).
|
|
1918
1955
|
*
|
|
1919
1956
|
* @param graphId Graph identifier owning the Report.
|
|
1920
1957
|
* @param reportId Report identifier (rpt_-prefixed ULID).
|
|
1921
|
-
* @param options.format Serialization flavor —
|
|
1958
|
+
* @param options.format Serialization flavor — `JSONLD` (default) or `XBRL_2_1`.
|
|
1922
1959
|
* @param options.expiresIn Presigned URL lifetime, in seconds.
|
|
1923
1960
|
*/
|
|
1924
|
-
async
|
|
1961
|
+
async getReportDownloadUrl(
|
|
1925
1962
|
graphId: string,
|
|
1926
1963
|
reportId: string,
|
|
1927
|
-
options: { format?:
|
|
1928
|
-
): Promise<ReportBundleDownloadResponse> {
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
const response = await fetch(url, {
|
|
1949
|
-
method: 'GET',
|
|
1950
|
-
headers,
|
|
1951
|
-
credentials: this.config.credentials,
|
|
1952
|
-
})
|
|
1953
|
-
if (!response.ok) {
|
|
1954
|
-
const body = await response.text()
|
|
1955
|
-
throw new Error(`Get report bundle download URL failed (${response.status}): ${body}`)
|
|
1956
|
-
}
|
|
1957
|
-
const raw = (await response.json()) as RawReportBundleDownloadResponse
|
|
1958
|
-
return {
|
|
1959
|
-
downloadUrl: raw.download_url,
|
|
1960
|
-
expiresAt: raw.expires_at,
|
|
1961
|
-
contentType: raw.content_type,
|
|
1962
|
-
format: raw.format,
|
|
1963
|
-
generationCount: raw.generation_count,
|
|
1964
|
-
}
|
|
1965
|
-
}
|
|
1966
|
-
|
|
1967
|
-
/**
|
|
1968
|
-
* Download the Report's serialization bundle as an XBRL 2.1 zip.
|
|
1969
|
-
*
|
|
1970
|
-
* Rebuilds the bundle on the server and streams the zip body
|
|
1971
|
-
* directly — no S3 presigned URL is involved (XBRL is on-demand
|
|
1972
|
-
* emit, per the serialization spec). The returned ``Blob`` can be
|
|
1973
|
-
* saved via URL.createObjectURL + a temporary anchor click to
|
|
1974
|
-
* trigger the browser download dialog.
|
|
1975
|
-
*
|
|
1976
|
-
* The zip contains five files: ``instance.xml``, ``report.xsd``,
|
|
1977
|
-
* ``report-pre.xml``, ``report-cal.xml``, ``report-def.xml``.
|
|
1978
|
-
*
|
|
1979
|
-
* @param graphId Graph identifier owning the Report.
|
|
1980
|
-
* @param reportId Report identifier (rpt_-prefixed ULID).
|
|
1981
|
-
* @param options.flavor XBRL flavor (default ``'xbrl-2.1'``).
|
|
1982
|
-
*/
|
|
1983
|
-
async getReportBundleXbrlZip(
|
|
1984
|
-
graphId: string,
|
|
1985
|
-
reportId: string,
|
|
1986
|
-
options: { flavor?: string } = {}
|
|
1987
|
-
): Promise<{ blob: Blob; filename: string; generationCount: number | null }> {
|
|
1988
|
-
const flavor = options.flavor ?? 'xbrl-2.1'
|
|
1989
|
-
const url =
|
|
1990
|
-
`${this.config.baseUrl.replace(/\/$/, '')}` +
|
|
1991
|
-
`/extensions/roboledger/${encodeURIComponent(graphId)}` +
|
|
1992
|
-
`/reports/${encodeURIComponent(reportId)}/download` +
|
|
1993
|
-
`?format=${encodeURIComponent(flavor)}`
|
|
1994
|
-
const headers = new Headers({
|
|
1995
|
-
Accept: 'application/zip',
|
|
1996
|
-
...(this.config.headers ?? {}),
|
|
1997
|
-
})
|
|
1998
|
-
const token = await this.resolveToken()
|
|
1999
|
-
if (token) {
|
|
2000
|
-
if (token.startsWith('rfs')) {
|
|
2001
|
-
headers.set('X-API-Key', token)
|
|
2002
|
-
} else {
|
|
2003
|
-
headers.set('Authorization', `Bearer ${token}`)
|
|
1964
|
+
options: { format?: ReportDownloadFormat; expiresIn?: number } = {}
|
|
1965
|
+
): Promise<ReportBundleDownloadResponse | null> {
|
|
1966
|
+
return this.gqlQuery(
|
|
1967
|
+
graphId,
|
|
1968
|
+
GetLedgerReportDownloadUrlDocument,
|
|
1969
|
+
{
|
|
1970
|
+
reportId,
|
|
1971
|
+
format: options.format ?? 'JSONLD',
|
|
1972
|
+
expiresIn: options.expiresIn ?? 300,
|
|
1973
|
+
},
|
|
1974
|
+
'Get report download URL',
|
|
1975
|
+
(data) => {
|
|
1976
|
+
const node = data.reportDownloadUrl
|
|
1977
|
+
if (!node) return null
|
|
1978
|
+
return {
|
|
1979
|
+
downloadUrl: node.downloadUrl,
|
|
1980
|
+
expiresAt: node.expiresAt,
|
|
1981
|
+
contentType: node.contentType,
|
|
1982
|
+
format: node.format,
|
|
1983
|
+
generationCount: node.generationCount,
|
|
1984
|
+
}
|
|
2004
1985
|
}
|
|
2005
|
-
|
|
2006
|
-
const response = await fetch(url, {
|
|
2007
|
-
method: 'GET',
|
|
2008
|
-
headers,
|
|
2009
|
-
credentials: this.config.credentials,
|
|
2010
|
-
})
|
|
2011
|
-
if (!response.ok) {
|
|
2012
|
-
const body = await response.text()
|
|
2013
|
-
throw new Error(`Get report bundle XBRL zip failed (${response.status}): ${body}`)
|
|
2014
|
-
}
|
|
2015
|
-
const blob = await response.blob()
|
|
2016
|
-
// Parse Content-Disposition for the server-suggested filename;
|
|
2017
|
-
// fall back to a sensible default if absent.
|
|
2018
|
-
const disposition = response.headers.get('Content-Disposition') ?? ''
|
|
2019
|
-
const filenameMatch = disposition.match(/filename="?([^";]+)"?/i)
|
|
2020
|
-
const filename = filenameMatch ? filenameMatch[1] : `${reportId}.zip`
|
|
2021
|
-
const generationHeader = response.headers.get('X-Bundle-Generation')
|
|
2022
|
-
const generationCount = generationHeader ? Number.parseInt(generationHeader, 10) : null
|
|
2023
|
-
return { blob, filename, generationCount }
|
|
1986
|
+
)
|
|
2024
1987
|
}
|
|
2025
1988
|
|
|
2026
1989
|
/**
|