@secondlayer/shared 4.3.4 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.d.ts +50 -1
- package/dist/src/index.js +347 -1
- package/dist/src/index.js.map +5 -4
- package/dist/src/schemas/index.d.ts +9 -0
- package/dist/src/schemas/index.js.map +1 -1
- package/dist/src/schemas/subgraphs.d.ts +9 -0
- package/dist/src/schemas/subgraphs.js.map +1 -1
- package/dist/src/subgraphs/spec.d.ts +104 -0
- package/dist/src/subgraphs/spec.js +366 -0
- package/dist/src/subgraphs/spec.js.map +10 -0
- package/package.json +5 -1
package/dist/src/index.d.ts
CHANGED
|
@@ -841,8 +841,12 @@ interface SubgraphSyncInfo {
|
|
|
841
841
|
interface SubgraphDetail {
|
|
842
842
|
name: string;
|
|
843
843
|
version: string;
|
|
844
|
+
schemaHash?: string;
|
|
844
845
|
status: string;
|
|
845
846
|
lastProcessedBlock: number;
|
|
847
|
+
description?: string;
|
|
848
|
+
sources?: Record<string, unknown>;
|
|
849
|
+
definition?: Record<string, unknown>;
|
|
846
850
|
health: {
|
|
847
851
|
totalProcessed: number
|
|
848
852
|
totalErrors: number
|
|
@@ -856,9 +860,14 @@ interface SubgraphDetail {
|
|
|
856
860
|
columns: Record<string, {
|
|
857
861
|
type: string
|
|
858
862
|
nullable?: boolean
|
|
863
|
+
indexed?: boolean
|
|
864
|
+
searchable?: boolean
|
|
865
|
+
default?: string | number | boolean
|
|
859
866
|
}>
|
|
860
867
|
rowCount: number
|
|
861
868
|
example: string
|
|
869
|
+
indexes?: string[][]
|
|
870
|
+
uniqueKeys?: string[][]
|
|
862
871
|
}>;
|
|
863
872
|
createdAt: string;
|
|
864
873
|
updatedAt: string;
|
|
@@ -1036,6 +1045,46 @@ declare function validateSubscriptionFilterForTable(input: {
|
|
|
1036
1045
|
filter?: unknown
|
|
1037
1046
|
tables: SubscriptionSchemaTables
|
|
1038
1047
|
}): string[];
|
|
1048
|
+
type SubgraphSpecFormat = "openapi" | "agent" | "markdown";
|
|
1049
|
+
interface SubgraphSpecOptions {
|
|
1050
|
+
serverUrl?: string;
|
|
1051
|
+
generatedAt?: string;
|
|
1052
|
+
}
|
|
1053
|
+
interface SubgraphAgentSchema {
|
|
1054
|
+
name: string;
|
|
1055
|
+
version: string;
|
|
1056
|
+
description?: string;
|
|
1057
|
+
schemaHash?: string;
|
|
1058
|
+
generatedAt: string;
|
|
1059
|
+
serverUrl: string;
|
|
1060
|
+
sources?: Record<string, unknown>;
|
|
1061
|
+
tables: Record<string, {
|
|
1062
|
+
endpoint: string
|
|
1063
|
+
countEndpoint: string
|
|
1064
|
+
rowCount: number
|
|
1065
|
+
columns: SubgraphDetail["tables"][string]["columns"]
|
|
1066
|
+
indexes?: string[][]
|
|
1067
|
+
uniqueKeys?: string[][]
|
|
1068
|
+
query: {
|
|
1069
|
+
parameters: string[]
|
|
1070
|
+
sortable: string[]
|
|
1071
|
+
selectable: string[]
|
|
1072
|
+
searchable: string[]
|
|
1073
|
+
filters: string[]
|
|
1074
|
+
}
|
|
1075
|
+
examples: {
|
|
1076
|
+
list: Record<string, unknown>
|
|
1077
|
+
count: {
|
|
1078
|
+
count: number
|
|
1079
|
+
}
|
|
1080
|
+
curl: string
|
|
1081
|
+
}
|
|
1082
|
+
}>;
|
|
1083
|
+
}
|
|
1084
|
+
declare function generateSubgraphAgentSchema(detail: SubgraphDetail, options?: SubgraphSpecOptions): SubgraphAgentSchema;
|
|
1085
|
+
declare function generateSubgraphOpenApi(detail: SubgraphDetail, options?: SubgraphSpecOptions): Record<string, unknown>;
|
|
1086
|
+
declare function generateSubgraphMarkdown(detail: SubgraphDetail, options?: SubgraphSpecOptions): string;
|
|
1087
|
+
declare function generateSubgraphSpec(detail: SubgraphDetail, format: SubgraphSpecFormat, options?: SubgraphSpecOptions): Record<string, unknown> | SubgraphAgentSchema | string;
|
|
1039
1088
|
declare namespace exports_hmac {
|
|
1040
1089
|
export { verifySignatureHeader, verifySignature, signPayload, generateSecret, createSignatureHeader };
|
|
1041
1090
|
}
|
|
@@ -1064,4 +1113,4 @@ declare function createSignatureHeader(payload: string, secret: string, timestam
|
|
|
1064
1113
|
* Returns true if valid, false otherwise
|
|
1065
1114
|
*/
|
|
1066
1115
|
declare function verifySignatureHeader(payload: string, header: string, secret: string, toleranceSeconds?: number): boolean;
|
|
1067
|
-
export { validateSubscriptionFilterForTable, sql, parseJsonb, logger, jsonb, getTargetDb, getSourceDb, getRawClient, getErrorMessage, getEnv, getDb, formatSubscriptionSchemaErrors, exports_hmac as crypto, closeDb, WaitlistTable, VersionConflictError, ValidationError, UsageSnapshotsTable, UsageSnapshot, UsageDailyTable, UsageDaily, UpdateTransaction, UpdateTenantUsageMonthly, UpdateTenantComputeAddon, UpdateTenant, UpdateSubscriptionRequestSchema, UpdateSubscriptionRequest, UpdateSubscriptionOutbox, UpdateSubscription, UpdateSubgraphOperation, UpdateSubgraph, UpdateProject, UpdateProfileRequestSchema, UpdateProfileRequest, UpdateIndexProgress, UpdateEvent, UpdateChatSession, UpdateBlock, UpdateApiKey, UpdateAccountSpendCap, TransactionsTable, Transaction, TenantsTable, TenantUsageMonthlyTable, TenantUsageMonthly, TenantSuspendedError, TenantStatus, TenantComputeAddonsTable, TenantComputeAddon, Tenant, TeamMembersTable, TeamMember, TeamInvitationsTable, TeamInvitation, SubscriptionsTable, SubscriptionSummary, SubscriptionStatusSchema, SubscriptionStatus, SubscriptionSchemaTables, SubscriptionSchemaTable, SubscriptionSchemaColumn, SubscriptionRuntimeSchema, SubscriptionRuntime, SubscriptionOutboxTable, SubscriptionOutbox, SubscriptionFormatSchema, SubscriptionFormat, SubscriptionFilterSchema, SubscriptionFilterPrimitiveSchema, SubscriptionFilterPrimitive, SubscriptionFilterOperatorSchema, SubscriptionFilterOperator, SubscriptionFilterClauseSchema, SubscriptionFilterClause, SubscriptionFilter, SubscriptionDetail, SubscriptionDelivery, SubscriptionDeliveriesTable, Subscription, SubgraphsTable, SubgraphUsageDailyTable, SubgraphUsageDaily, SubgraphTableSnapshotsTable, SubgraphSyncInfo, SubgraphSummary, SubgraphQueryParams, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGapsResponse, SubgraphGapRange, SubgraphGapEntry, SubgraphGap, SubgraphDetail, Subgraph, StxTransferFilterSchema, StxTransferFilter, StxMintFilterSchema, StxMintFilter, StxLockFilterSchema, StxLockFilter, StxBurnFilterSchema, StxBurnFilter, SessionsTable, Session, SecondLayerError, SUBSCRIPTION_STATUSES, SUBSCRIPTION_RUNTIMES, SUBSCRIPTION_FORMATS, SUBSCRIPTION_FILTER_OPERATORS, RotateSecretResponse, ReplaySubscriptionRequestSchema, ReplaySubscriptionRequest, ReplayResult, ReindexResponse, RateLimitError, ProvisioningAuditStatus, ProvisioningAuditLogTable, ProvisioningAuditLog, ProvisioningAuditEvent, ProjectsTable, Project, PrintEventFilterSchema, PrintEventFilter, ParsedUpdateSubscriptionRequest, ParsedReplaySubscriptionRequest, ParsedCreateSubscriptionRequest, OutboxStatus, NotFoundError, NftTransferFilterSchema, NftTransferFilter, NftMintFilterSchema, NftMintFilter, NftBurnFilterSchema, NftBurnFilter, MagicLinksTable, MagicLink, KeyRotatedError, InsertTransaction, InsertTenantUsageMonthly, InsertTenantComputeAddon, InsertTenant, InsertTeamMember, InsertTeamInvitation, InsertSubscriptionOutbox, InsertSubscriptionDelivery, InsertSubscription, InsertSubgraphUsageDaily, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertProvisioningAuditLog, InsertProject, InsertMagicLink, InsertIndexProgress, InsertEvent, InsertChatSession, InsertChatMessage, InsertBlock, InsertApiKey, InsertAccountSpendCap, InsertAccountInsight, InsertAccountAgentRun, InsertAccount, IndexProgressTable, IndexProgress, FtTransferFilterSchema, FtTransferFilter, FtMintFilterSchema, FtMintFilter, FtBurnFilterSchema, FtBurnFilter, ForbiddenError, EventsTable, EventFilterSchema, EventFilter, Event, ErrorCodes, ErrorCode, Env, DeploySubgraphResponse, DeploySubgraphRequestSchema, DeploySubgraphRequest, DeliveryRow, DeadRow, DatabaseError, Database, CreateSubscriptionResponse, CreateSubscriptionRequestSchema, CreateSubscriptionRequest, ContractDeployFilterSchema, ContractDeployFilter, ContractCallFilterSchema, ContractCallFilter, ChatSessionsTable, ChatSession, ChatMessagesTable, ChatMessage, CODE_TO_STATUS, BlocksTable, Block, AuthorizationError, AuthenticationError, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountInsightsTable, AccountInsight, AccountAgentRunsTable, AccountAgentRun, Account };
|
|
1116
|
+
export { validateSubscriptionFilterForTable, sql, parseJsonb, logger, jsonb, getTargetDb, getSourceDb, getRawClient, getErrorMessage, getEnv, getDb, generateSubgraphSpec, generateSubgraphOpenApi, generateSubgraphMarkdown, generateSubgraphAgentSchema, formatSubscriptionSchemaErrors, exports_hmac as crypto, closeDb, WaitlistTable, VersionConflictError, ValidationError, UsageSnapshotsTable, UsageSnapshot, UsageDailyTable, UsageDaily, UpdateTransaction, UpdateTenantUsageMonthly, UpdateTenantComputeAddon, UpdateTenant, UpdateSubscriptionRequestSchema, UpdateSubscriptionRequest, UpdateSubscriptionOutbox, UpdateSubscription, UpdateSubgraphOperation, UpdateSubgraph, UpdateProject, UpdateProfileRequestSchema, UpdateProfileRequest, UpdateIndexProgress, UpdateEvent, UpdateChatSession, UpdateBlock, UpdateApiKey, UpdateAccountSpendCap, TransactionsTable, Transaction, TenantsTable, TenantUsageMonthlyTable, TenantUsageMonthly, TenantSuspendedError, TenantStatus, TenantComputeAddonsTable, TenantComputeAddon, Tenant, TeamMembersTable, TeamMember, TeamInvitationsTable, TeamInvitation, SubscriptionsTable, SubscriptionSummary, SubscriptionStatusSchema, SubscriptionStatus, SubscriptionSchemaTables, SubscriptionSchemaTable, SubscriptionSchemaColumn, SubscriptionRuntimeSchema, SubscriptionRuntime, SubscriptionOutboxTable, SubscriptionOutbox, SubscriptionFormatSchema, SubscriptionFormat, SubscriptionFilterSchema, SubscriptionFilterPrimitiveSchema, SubscriptionFilterPrimitive, SubscriptionFilterOperatorSchema, SubscriptionFilterOperator, SubscriptionFilterClauseSchema, SubscriptionFilterClause, SubscriptionFilter, SubscriptionDetail, SubscriptionDelivery, SubscriptionDeliveriesTable, Subscription, SubgraphsTable, SubgraphUsageDailyTable, SubgraphUsageDaily, SubgraphTableSnapshotsTable, SubgraphSyncInfo, SubgraphSummary, SubgraphSpecOptions, SubgraphSpecFormat, SubgraphQueryParams, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGapsResponse, SubgraphGapRange, SubgraphGapEntry, SubgraphGap, SubgraphDetail, SubgraphAgentSchema, Subgraph, StxTransferFilterSchema, StxTransferFilter, StxMintFilterSchema, StxMintFilter, StxLockFilterSchema, StxLockFilter, StxBurnFilterSchema, StxBurnFilter, SessionsTable, Session, SecondLayerError, SUBSCRIPTION_STATUSES, SUBSCRIPTION_RUNTIMES, SUBSCRIPTION_FORMATS, SUBSCRIPTION_FILTER_OPERATORS, RotateSecretResponse, ReplaySubscriptionRequestSchema, ReplaySubscriptionRequest, ReplayResult, ReindexResponse, RateLimitError, ProvisioningAuditStatus, ProvisioningAuditLogTable, ProvisioningAuditLog, ProvisioningAuditEvent, ProjectsTable, Project, PrintEventFilterSchema, PrintEventFilter, ParsedUpdateSubscriptionRequest, ParsedReplaySubscriptionRequest, ParsedCreateSubscriptionRequest, OutboxStatus, NotFoundError, NftTransferFilterSchema, NftTransferFilter, NftMintFilterSchema, NftMintFilter, NftBurnFilterSchema, NftBurnFilter, MagicLinksTable, MagicLink, KeyRotatedError, InsertTransaction, InsertTenantUsageMonthly, InsertTenantComputeAddon, InsertTenant, InsertTeamMember, InsertTeamInvitation, InsertSubscriptionOutbox, InsertSubscriptionDelivery, InsertSubscription, InsertSubgraphUsageDaily, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertProvisioningAuditLog, InsertProject, InsertMagicLink, InsertIndexProgress, InsertEvent, InsertChatSession, InsertChatMessage, InsertBlock, InsertApiKey, InsertAccountSpendCap, InsertAccountInsight, InsertAccountAgentRun, InsertAccount, IndexProgressTable, IndexProgress, FtTransferFilterSchema, FtTransferFilter, FtMintFilterSchema, FtMintFilter, FtBurnFilterSchema, FtBurnFilter, ForbiddenError, EventsTable, EventFilterSchema, EventFilter, Event, ErrorCodes, ErrorCode, Env, DeploySubgraphResponse, DeploySubgraphRequestSchema, DeploySubgraphRequest, DeliveryRow, DeadRow, DatabaseError, Database, CreateSubscriptionResponse, CreateSubscriptionRequestSchema, CreateSubscriptionRequest, ContractDeployFilterSchema, ContractDeployFilter, ContractCallFilterSchema, ContractCallFilter, ChatSessionsTable, ChatSession, ChatMessagesTable, ChatMessage, CODE_TO_STATUS, BlocksTable, Block, AuthorizationError, AuthenticationError, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountInsightsTable, AccountInsight, AccountAgentRunsTable, AccountAgentRun, Account };
|
package/dist/src/index.js
CHANGED
|
@@ -596,6 +596,348 @@ function validateSubscriptionFilterForTable(input) {
|
|
|
596
596
|
}
|
|
597
597
|
return errors;
|
|
598
598
|
}
|
|
599
|
+
// src/subgraphs/spec.ts
|
|
600
|
+
var SYSTEM_COLUMNS = ["_id", "_block_height", "_tx_id", "_created_at"];
|
|
601
|
+
var BASE_QUERY_PARAMS = ["_limit", "_offset", "_sort", "_order", "_fields"];
|
|
602
|
+
var COMPARISON_OPS = ["neq", "gt", "gte", "lt", "lte"];
|
|
603
|
+
function generatedAt(options) {
|
|
604
|
+
return options.generatedAt ?? new Date().toISOString();
|
|
605
|
+
}
|
|
606
|
+
function normalizeServerUrl(serverUrl) {
|
|
607
|
+
return (serverUrl ?? "https://api.secondlayer.tools").replace(/\/+$/, "");
|
|
608
|
+
}
|
|
609
|
+
function tablePath(subgraphName, tableName) {
|
|
610
|
+
return `/api/subgraphs/${subgraphName}/${tableName}`;
|
|
611
|
+
}
|
|
612
|
+
function countPath(subgraphName, tableName) {
|
|
613
|
+
return `${tablePath(subgraphName, tableName)}/count`;
|
|
614
|
+
}
|
|
615
|
+
function isTextLike(type) {
|
|
616
|
+
return type === "text" || type === "principal" || type === "timestamp";
|
|
617
|
+
}
|
|
618
|
+
function isComparable(type) {
|
|
619
|
+
return type === "uint" || type === "int" || type === "bigint" || type === "serial" || type === "timestamp";
|
|
620
|
+
}
|
|
621
|
+
function exampleForColumn(type) {
|
|
622
|
+
switch (type) {
|
|
623
|
+
case "uint":
|
|
624
|
+
case "int":
|
|
625
|
+
case "bigint":
|
|
626
|
+
return "1000";
|
|
627
|
+
case "serial":
|
|
628
|
+
return 1;
|
|
629
|
+
case "principal":
|
|
630
|
+
return "SP000000000000000000002Q6VF78";
|
|
631
|
+
case "timestamp":
|
|
632
|
+
return "2026-01-01T00:00:00.000Z";
|
|
633
|
+
case "boolean":
|
|
634
|
+
return true;
|
|
635
|
+
case "jsonb":
|
|
636
|
+
return { example: true };
|
|
637
|
+
default:
|
|
638
|
+
return "example";
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
function openApiSchemaForColumn(col) {
|
|
642
|
+
let schema;
|
|
643
|
+
switch (col.type) {
|
|
644
|
+
case "uint":
|
|
645
|
+
case "int":
|
|
646
|
+
case "bigint":
|
|
647
|
+
schema = { type: "string", pattern: "^-?\\d+(\\.\\d+)?$" };
|
|
648
|
+
break;
|
|
649
|
+
case "serial":
|
|
650
|
+
schema = { type: "integer" };
|
|
651
|
+
break;
|
|
652
|
+
case "principal":
|
|
653
|
+
case "text":
|
|
654
|
+
schema = { type: "string" };
|
|
655
|
+
break;
|
|
656
|
+
case "timestamp":
|
|
657
|
+
schema = { type: "string", format: "date-time" };
|
|
658
|
+
break;
|
|
659
|
+
case "boolean":
|
|
660
|
+
schema = { type: "boolean" };
|
|
661
|
+
break;
|
|
662
|
+
case "jsonb":
|
|
663
|
+
schema = { type: "object", additionalProperties: true };
|
|
664
|
+
break;
|
|
665
|
+
default:
|
|
666
|
+
schema = {};
|
|
667
|
+
break;
|
|
668
|
+
}
|
|
669
|
+
if (col.nullable) {
|
|
670
|
+
const type = schema.type;
|
|
671
|
+
if (typeof type === "string")
|
|
672
|
+
schema.type = [type, "null"];
|
|
673
|
+
}
|
|
674
|
+
return schema;
|
|
675
|
+
}
|
|
676
|
+
function columnEntries(table) {
|
|
677
|
+
return Object.entries(table.columns);
|
|
678
|
+
}
|
|
679
|
+
function selectableColumns(table) {
|
|
680
|
+
return columnEntries(table).map(([name2]) => name2);
|
|
681
|
+
}
|
|
682
|
+
function searchableColumns(table) {
|
|
683
|
+
return columnEntries(table).filter(([, col]) => col.searchable).map(([name2]) => name2);
|
|
684
|
+
}
|
|
685
|
+
function filterNames(table) {
|
|
686
|
+
const result = [];
|
|
687
|
+
for (const [name2, col] of columnEntries(table)) {
|
|
688
|
+
result.push(name2);
|
|
689
|
+
result.push(`${name2}.neq`);
|
|
690
|
+
if (isComparable(col.type)) {
|
|
691
|
+
for (const op of COMPARISON_OPS.filter((op2) => op2 !== "neq")) {
|
|
692
|
+
result.push(`${name2}.${op}`);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
if (isTextLike(col.type))
|
|
696
|
+
result.push(`${name2}.like`);
|
|
697
|
+
}
|
|
698
|
+
return result;
|
|
699
|
+
}
|
|
700
|
+
function queryParameters(table) {
|
|
701
|
+
const params = [...BASE_QUERY_PARAMS];
|
|
702
|
+
if (searchableColumns(table).length > 0)
|
|
703
|
+
params.push("_search");
|
|
704
|
+
return params;
|
|
705
|
+
}
|
|
706
|
+
function rowExample(table) {
|
|
707
|
+
const row = {};
|
|
708
|
+
for (const [name2, col] of columnEntries(table)) {
|
|
709
|
+
row[name2] = exampleForColumn(col.type);
|
|
710
|
+
}
|
|
711
|
+
return row;
|
|
712
|
+
}
|
|
713
|
+
function openApiParameter(name2, description, schema = { type: "string" }) {
|
|
714
|
+
return {
|
|
715
|
+
name: name2,
|
|
716
|
+
in: "query",
|
|
717
|
+
required: false,
|
|
718
|
+
description,
|
|
719
|
+
schema
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
function tableParameters(table) {
|
|
723
|
+
const parameters = [
|
|
724
|
+
openApiParameter("_limit", "Maximum rows to return.", {
|
|
725
|
+
type: "integer",
|
|
726
|
+
default: 50,
|
|
727
|
+
minimum: 1,
|
|
728
|
+
maximum: 1000
|
|
729
|
+
}),
|
|
730
|
+
openApiParameter("_offset", "Rows to skip for pagination.", {
|
|
731
|
+
type: "integer",
|
|
732
|
+
default: 0,
|
|
733
|
+
minimum: 0
|
|
734
|
+
}),
|
|
735
|
+
openApiParameter("_sort", "Column to sort by.", {
|
|
736
|
+
type: "string",
|
|
737
|
+
enum: selectableColumns(table)
|
|
738
|
+
}),
|
|
739
|
+
openApiParameter("_order", "Sort direction.", {
|
|
740
|
+
type: "string",
|
|
741
|
+
enum: ["asc", "desc"],
|
|
742
|
+
default: "asc"
|
|
743
|
+
}),
|
|
744
|
+
openApiParameter("_fields", "Comma-separated columns to include.", {
|
|
745
|
+
type: "string"
|
|
746
|
+
})
|
|
747
|
+
];
|
|
748
|
+
if (searchableColumns(table).length > 0) {
|
|
749
|
+
parameters.push(openApiParameter("_search", "Search across searchable columns.", {
|
|
750
|
+
type: "string"
|
|
751
|
+
}));
|
|
752
|
+
}
|
|
753
|
+
for (const [name2, col] of columnEntries(table)) {
|
|
754
|
+
parameters.push(openApiParameter(name2, `Filter ${name2} by equality.`, {
|
|
755
|
+
type: "string"
|
|
756
|
+
}));
|
|
757
|
+
parameters.push(openApiParameter(`${name2}.neq`, `Filter ${name2} by inequality.`, {
|
|
758
|
+
type: "string"
|
|
759
|
+
}));
|
|
760
|
+
if (isComparable(col.type)) {
|
|
761
|
+
for (const op of ["gt", "gte", "lt", "lte"]) {
|
|
762
|
+
parameters.push(openApiParameter(`${name2}.${op}`, `Filter ${name2} with ${op}.`, {
|
|
763
|
+
type: "string"
|
|
764
|
+
}));
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
if (isTextLike(col.type)) {
|
|
768
|
+
parameters.push(openApiParameter(`${name2}.like`, `Case-insensitive contains filter for ${name2}.`, {
|
|
769
|
+
type: "string"
|
|
770
|
+
}));
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return parameters;
|
|
774
|
+
}
|
|
775
|
+
function generateSubgraphAgentSchema(detail, options = {}) {
|
|
776
|
+
const serverUrl = normalizeServerUrl(options.serverUrl);
|
|
777
|
+
const tables = {};
|
|
778
|
+
for (const [tableName, table] of Object.entries(detail.tables)) {
|
|
779
|
+
const path = tablePath(detail.name, tableName);
|
|
780
|
+
tables[tableName] = {
|
|
781
|
+
endpoint: `${serverUrl}${path}`,
|
|
782
|
+
countEndpoint: `${serverUrl}${countPath(detail.name, tableName)}`,
|
|
783
|
+
rowCount: table.rowCount,
|
|
784
|
+
columns: table.columns,
|
|
785
|
+
...table.indexes ? { indexes: table.indexes } : {},
|
|
786
|
+
...table.uniqueKeys ? { uniqueKeys: table.uniqueKeys } : {},
|
|
787
|
+
query: {
|
|
788
|
+
parameters: queryParameters(table),
|
|
789
|
+
sortable: selectableColumns(table),
|
|
790
|
+
selectable: selectableColumns(table),
|
|
791
|
+
searchable: searchableColumns(table),
|
|
792
|
+
filters: filterNames(table)
|
|
793
|
+
},
|
|
794
|
+
examples: {
|
|
795
|
+
list: rowExample(table),
|
|
796
|
+
count: { count: table.rowCount },
|
|
797
|
+
curl: `curl '${serverUrl}${path}?_limit=10&_sort=_block_height&_order=desc'`
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
return {
|
|
802
|
+
name: detail.name,
|
|
803
|
+
version: detail.version,
|
|
804
|
+
...detail.description ? { description: detail.description } : {},
|
|
805
|
+
...detail.schemaHash ? { schemaHash: detail.schemaHash } : {},
|
|
806
|
+
generatedAt: generatedAt(options),
|
|
807
|
+
serverUrl,
|
|
808
|
+
...detail.sources ? { sources: detail.sources } : {},
|
|
809
|
+
tables
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function generateSubgraphOpenApi(detail, options = {}) {
|
|
813
|
+
const serverUrl = normalizeServerUrl(options.serverUrl);
|
|
814
|
+
const paths = {};
|
|
815
|
+
const schemas = {};
|
|
816
|
+
for (const [tableName, table] of Object.entries(detail.tables)) {
|
|
817
|
+
const schemaName = `${tableName}Row`;
|
|
818
|
+
const properties = {};
|
|
819
|
+
const required = [];
|
|
820
|
+
for (const [columnName, column] of columnEntries(table)) {
|
|
821
|
+
properties[columnName] = openApiSchemaForColumn(column);
|
|
822
|
+
if (!column.nullable)
|
|
823
|
+
required.push(columnName);
|
|
824
|
+
}
|
|
825
|
+
schemas[schemaName] = {
|
|
826
|
+
type: "object",
|
|
827
|
+
properties,
|
|
828
|
+
required,
|
|
829
|
+
example: rowExample(table)
|
|
830
|
+
};
|
|
831
|
+
paths[tablePath(detail.name, tableName)] = {
|
|
832
|
+
get: {
|
|
833
|
+
summary: `Query ${detail.name}.${tableName}`,
|
|
834
|
+
operationId: `query_${detail.name.replace(/-/g, "_")}_${tableName}`,
|
|
835
|
+
parameters: tableParameters(table),
|
|
836
|
+
responses: {
|
|
837
|
+
"200": {
|
|
838
|
+
description: "Rows returned from the subgraph table.",
|
|
839
|
+
content: {
|
|
840
|
+
"application/json": {
|
|
841
|
+
schema: {
|
|
842
|
+
type: "object",
|
|
843
|
+
properties: {
|
|
844
|
+
data: {
|
|
845
|
+
type: "array",
|
|
846
|
+
items: { $ref: `#/components/schemas/${schemaName}` }
|
|
847
|
+
},
|
|
848
|
+
meta: {
|
|
849
|
+
type: "object",
|
|
850
|
+
properties: {
|
|
851
|
+
total: { type: "integer" },
|
|
852
|
+
limit: { type: "integer" },
|
|
853
|
+
offset: { type: "integer" }
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
paths[countPath(detail.name, tableName)] = {
|
|
865
|
+
get: {
|
|
866
|
+
summary: `Count ${detail.name}.${tableName}`,
|
|
867
|
+
operationId: `count_${detail.name.replace(/-/g, "_")}_${tableName}`,
|
|
868
|
+
parameters: tableParameters(table),
|
|
869
|
+
responses: {
|
|
870
|
+
"200": {
|
|
871
|
+
description: "Row count for the filtered table query.",
|
|
872
|
+
content: {
|
|
873
|
+
"application/json": {
|
|
874
|
+
schema: {
|
|
875
|
+
type: "object",
|
|
876
|
+
properties: { count: { type: "integer" } },
|
|
877
|
+
required: ["count"],
|
|
878
|
+
example: { count: table.rowCount }
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
return {
|
|
888
|
+
openapi: "3.1.0",
|
|
889
|
+
info: {
|
|
890
|
+
title: `${detail.name} Subgraph API`,
|
|
891
|
+
version: detail.version,
|
|
892
|
+
...detail.description ? { description: detail.description } : {}
|
|
893
|
+
},
|
|
894
|
+
servers: [{ url: serverUrl }],
|
|
895
|
+
paths,
|
|
896
|
+
components: { schemas },
|
|
897
|
+
"x-secondlayer-subgraph": detail.name,
|
|
898
|
+
"x-secondlayer-version": detail.version,
|
|
899
|
+
"x-secondlayer-schema-hash": detail.schemaHash,
|
|
900
|
+
"x-secondlayer-generated-at": generatedAt(options),
|
|
901
|
+
"x-secondlayer-sources": detail.sources ?? {},
|
|
902
|
+
"x-secondlayer-tables": Object.keys(detail.tables)
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
function generateSubgraphMarkdown(detail, options = {}) {
|
|
906
|
+
const agent = generateSubgraphAgentSchema(detail, options);
|
|
907
|
+
const lines = [
|
|
908
|
+
`# ${detail.name} Subgraph API`,
|
|
909
|
+
"",
|
|
910
|
+
`Version: ${detail.version}`,
|
|
911
|
+
detail.schemaHash ? `Schema hash: ${detail.schemaHash}` : undefined,
|
|
912
|
+
`Server: ${agent.serverUrl}`,
|
|
913
|
+
"",
|
|
914
|
+
detail.description
|
|
915
|
+
].filter((line) => line !== undefined && line !== "");
|
|
916
|
+
for (const [tableName, table] of Object.entries(agent.tables)) {
|
|
917
|
+
lines.push("", `## ${tableName}`, "", `GET ${table.endpoint}`, `GET ${table.countEndpoint}`, "", `Rows: ${table.rowCount}`, "", "### Columns", "", "| Column | Type | Attributes |", "| --- | --- | --- |");
|
|
918
|
+
for (const [columnName, col] of Object.entries(table.columns)) {
|
|
919
|
+
const attrs = [
|
|
920
|
+
SYSTEM_COLUMNS.includes(columnName) ? "system" : undefined,
|
|
921
|
+
col.nullable ? "nullable" : undefined,
|
|
922
|
+
col.indexed ? "indexed" : undefined,
|
|
923
|
+
col.searchable ? "searchable" : undefined
|
|
924
|
+
].filter(Boolean).join(", ");
|
|
925
|
+
lines.push(`| \`${columnName}\` | \`${col.type}\` | ${attrs || "-"} |`);
|
|
926
|
+
}
|
|
927
|
+
lines.push("", "### Query", "", `Parameters: ${table.query.parameters.map((p) => `\`${p}\``).join(", ")}`, `Filters: ${table.query.filters.map((p) => `\`${p}\``).join(", ")}`, "", "### Example", "", "```bash", table.examples.curl, "```");
|
|
928
|
+
}
|
|
929
|
+
return `${lines.join(`
|
|
930
|
+
`)}
|
|
931
|
+
`;
|
|
932
|
+
}
|
|
933
|
+
function generateSubgraphSpec(detail, format, options = {}) {
|
|
934
|
+
if (format === "openapi")
|
|
935
|
+
return generateSubgraphOpenApi(detail, options);
|
|
936
|
+
if (format === "agent")
|
|
937
|
+
return generateSubgraphAgentSchema(detail, options);
|
|
938
|
+
return generateSubgraphMarkdown(detail, options);
|
|
939
|
+
}
|
|
940
|
+
|
|
599
941
|
// src/crypto/hmac.ts
|
|
600
942
|
var exports_hmac = {};
|
|
601
943
|
__export(exports_hmac, {
|
|
@@ -661,6 +1003,10 @@ export {
|
|
|
661
1003
|
getErrorMessage,
|
|
662
1004
|
getEnv,
|
|
663
1005
|
getDb,
|
|
1006
|
+
generateSubgraphSpec,
|
|
1007
|
+
generateSubgraphOpenApi,
|
|
1008
|
+
generateSubgraphMarkdown,
|
|
1009
|
+
generateSubgraphAgentSchema,
|
|
664
1010
|
formatSubscriptionSchemaErrors,
|
|
665
1011
|
exports_hmac as crypto,
|
|
666
1012
|
closeDb,
|
|
@@ -709,5 +1055,5 @@ export {
|
|
|
709
1055
|
AuthenticationError
|
|
710
1056
|
};
|
|
711
1057
|
|
|
712
|
-
//# debugId=
|
|
1058
|
+
//# debugId=F03F167A347C5EE364756E2164756E21
|
|
713
1059
|
//# sourceMappingURL=index.js.map
|