diff --git a/lexicons/webhook/create.json b/lexicons/webhook/create.json new file mode 100644 index 000000000..a2d844b37 --- /dev/null +++ b/lexicons/webhook/create.json @@ -0,0 +1,60 @@ +{ + "lexicon": 1, + "id": "org.tangled.webhook.create", + "defs": { + "main": { + "type": "procedure", + "description": "Create a new webhook for a repository.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["repoDid", "url", "events"], + "properties": { + "repoDid": { + "type": "string", + "format": "did", + "description": "DID of the repository as minted by the knot." + }, + "url": { + "type": "string", + "format": "uri", + "description": "Endpoint URL that will receive webhook payloads." + }, + "secret": { + "type": "string", + "description": "Optional HMAC secret used to sign payloads. If omitted, payloads are not signed." + }, + "active": { + "type": "boolean", + "description": "Whether the webhook should be active immediately. Defaults to true." + }, + "events": { + "type": "array", + "description": "Event types to subscribe to (e.g. 'push', 'repository:renamed').", + "items": { + "type": "string" + } + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "type": "integer", + "description": "ID of the newly created webhook." + } + } + } + }, + "errors": [ + { "name": "NoEventsSelected", "description": "At least one event type must be specified." } + ] + } + } +} diff --git a/lexicons/webhook/delete.json b/lexicons/webhook/delete.json new file mode 100644 index 000000000..dce8bb4ad --- /dev/null +++ b/lexicons/webhook/delete.json @@ -0,0 +1,31 @@ +{ + "lexicon": 1, + "id": "org.tangled.webhook.delete", + "defs": { + "main": { + "type": "procedure", + "description": "Delete a webhook from a repository.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["repoDid", "id"], + "properties": { + "repoDid": { + "type": "string", + "format": "did", + "description": "DID of the repository as minted by the knot." + }, + "id": { + "type": "integer", + "description": "Webhook ID to delete." + } + } + } + }, + "errors": [ + { "name": "WebhookNotFound" } + ] + } + } +} diff --git a/lexicons/webhook/list.json b/lexicons/webhook/list.json new file mode 100644 index 000000000..9dd121fa7 --- /dev/null +++ b/lexicons/webhook/list.json @@ -0,0 +1,71 @@ +{ + "lexicon": 1, + "id": "org.tangled.webhook.list", + "defs": { + "main": { + "type": "query", + "description": "List webhooks configured for a repository.", + "parameters": { + "type": "params", + "required": ["repoDid"], + "properties": { + "repoDid": { + "type": "string", + "format": "did", + "description": "DID of the repository as minted by the knot." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["webhooks"], + "properties": { + "webhooks": { + "type": "array", + "items": { + "type": "ref", + "ref": "#webhook" + } + } + } + } + } + }, + "webhook": { + "type": "object", + "required": ["id", "url", "active", "events", "createdAt"], + "properties": { + "id": { + "type": "integer", + "description": "Webhook identifier." + }, + "url": { + "type": "string", + "format": "uri", + "description": "Endpoint URL that receives webhook payloads." + }, + "active": { + "type": "boolean", + "description": "Whether the webhook is currently enabled." + }, + "events": { + "type": "array", + "description": "Event types this webhook is subscribed to (e.g. 'push', 'repository:renamed').", + "items": { + "type": "string" + } + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "updatedAt": { + "type": "string", + "format": "datetime" + } + } + } + } +} diff --git a/lexicons/webhook/listDeliveries.json b/lexicons/webhook/listDeliveries.json new file mode 100644 index 000000000..92558bb0c --- /dev/null +++ b/lexicons/webhook/listDeliveries.json @@ -0,0 +1,83 @@ +{ + "lexicon": 1, + "id": "org.tangled.webhook.listDeliveries", + "defs": { + "main": { + "type": "query", + "description": "List recent delivery attempts for a webhook.", + "parameters": { + "type": "params", + "required": ["repoDid", "id"], + "properties": { + "repoDid": { + "type": "string", + "format": "did", + "description": "DID of the repository as minted by the knot." + }, + "id": { + "type": "integer", + "description": "Webhook ID." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["deliveries"], + "properties": { + "deliveries": { + "type": "array", + "items": { + "type": "ref", + "ref": "#delivery" + } + } + } + } + } + }, + "delivery": { + "type": "object", + "required": ["id", "deliveryId", "event", "url", "success", "createdAt"], + "properties": { + "id": { + "type": "integer" + }, + "deliveryId": { + "type": "string", + "description": "UUID for tracking this delivery attempt." + }, + "event": { + "type": "string", + "description": "Event type that triggered the delivery." + }, + "url": { + "type": "string", + "format": "uri" + }, + "requestBody": { + "type": "string" + }, + "responseCode": { + "type": "integer" + }, + "responseBody": { + "type": "string" + }, + "success": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + } +} diff --git a/lexicons/webhook/retryDelivery.json b/lexicons/webhook/retryDelivery.json new file mode 100644 index 000000000..37c900596 --- /dev/null +++ b/lexicons/webhook/retryDelivery.json @@ -0,0 +1,36 @@ +{ + "lexicon": 1, + "id": "org.tangled.webhook.retryDelivery", + "defs": { + "main": { + "type": "procedure", + "description": "Re-send a specific webhook delivery.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["repoDid", "webhookId", "deliveryId"], + "properties": { + "repoDid": { + "type": "string", + "format": "did", + "description": "DID of the repository as minted by the knot." + }, + "webhookId": { + "type": "integer", + "description": "Webhook ID that owns the delivery." + }, + "deliveryId": { + "type": "string", + "description": "UUID of the delivery to retry." + } + } + } + }, + "errors": [ + { "name": "WebhookNotFound" }, + { "name": "DeliveryNotFound" } + ] + } + } +} diff --git a/lexicons/webhook/toggle.json b/lexicons/webhook/toggle.json new file mode 100644 index 000000000..e28ce4887 --- /dev/null +++ b/lexicons/webhook/toggle.json @@ -0,0 +1,44 @@ +{ + "lexicon": 1, + "id": "org.tangled.webhook.toggle", + "defs": { + "main": { + "type": "procedure", + "description": "Toggle the active state of a webhook.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["repoDid", "id"], + "properties": { + "repoDid": { + "type": "string", + "format": "did", + "description": "DID of the repository as minted by the knot." + }, + "id": { + "type": "integer", + "description": "Webhook ID to toggle." + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["active"], + "properties": { + "active": { + "type": "boolean", + "description": "New active state of the webhook." + } + } + } + }, + "errors": [ + { "name": "WebhookNotFound" } + ] + } + } +} diff --git a/lexicons/webhook/update.json b/lexicons/webhook/update.json new file mode 100644 index 000000000..c853db7d2 --- /dev/null +++ b/lexicons/webhook/update.json @@ -0,0 +1,47 @@ +{ + "lexicon": 1, + "id": "org.tangled.webhook.update", + "defs": { + "main": { + "type": "procedure", + "description": "Update an existing webhook. Only supplied fields are changed.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["repoDid", "id"], + "properties": { + "repoDid": { + "type": "string", + "format": "did", + "description": "DID of the repository as minted by the knot." + }, + "id": { + "type": "integer", + "description": "Webhook ID to update." + }, + "url": { + "type": "string", + "format": "uri" + }, + "secret": { + "type": "string" + }, + "active": { + "type": "boolean" + }, + "events": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "errors": [ + { "name": "WebhookNotFound" } + ] + } + } +}