mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
Merge branch 'feature/public-api-initial-setup-N8N-3170' into feature/n8n-public-api
This commit is contained in:
commit
e1bd9fc510
|
@ -580,6 +580,15 @@ const config = convict({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
publicApiEndpoints: {
|
||||||
|
path: {
|
||||||
|
format: String,
|
||||||
|
default: 'api',
|
||||||
|
env: 'N8N_PUBLIC_API_ENDPOINT',
|
||||||
|
doc: 'Path for the public api endpoints',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
workflowTagsDisabled: {
|
workflowTagsDisabled: {
|
||||||
format: Boolean,
|
format: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
"bin": "n8n"
|
"bin": "n8n"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc && cp -r ./src/UserManagement/email/templates ./dist/src/UserManagement/email",
|
"build": "tsc && cp -r ./src/UserManagement/email/templates ./dist/src/UserManagement/email && rsync -a --include='*/' --include='*.yml' --exclude='*' ./src/PublicApi/ ./dist/src/PublicApi/",
|
||||||
"dev": "concurrently -k -n \"TypeScript,Node\" -c \"yellow.bold,cyan.bold\" \"npm run watch\" \"nodemon\"",
|
"dev": "concurrently -k -n \"TypeScript,Node\" -c \"yellow.bold,cyan.bold\" \"npm run watch\" \"nodemon\"",
|
||||||
"format": "cd ../.. && node_modules/prettier/bin-prettier.js packages/cli/**/**.ts --write",
|
"format": "cd ../.. && node_modules/prettier/bin-prettier.js packages/cli/**/**.ts --write",
|
||||||
"lint": "cd ../.. && node_modules/eslint/bin/eslint.js packages/cli",
|
"lint": "cd ../.. && node_modules/eslint/bin/eslint.js packages/cli",
|
||||||
|
@ -114,6 +114,7 @@
|
||||||
"csrf": "^3.1.0",
|
"csrf": "^3.1.0",
|
||||||
"dotenv": "^8.0.0",
|
"dotenv": "^8.0.0",
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
|
"express-openapi-validator": "^4.13.6",
|
||||||
"fast-glob": "^3.2.5",
|
"fast-glob": "^3.2.5",
|
||||||
"flatted": "^3.2.4",
|
"flatted": "^3.2.4",
|
||||||
"google-timezones-json": "^1.0.2",
|
"google-timezones-json": "^1.0.2",
|
||||||
|
|
39
packages/cli/src/PublicApi/v1/index.ts
Normal file
39
packages/cli/src/PublicApi/v1/index.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
import {
|
||||||
|
Application,
|
||||||
|
} from 'express';
|
||||||
|
|
||||||
|
import * as OpenApiValidator from 'express-openapi-validator';
|
||||||
|
|
||||||
|
import path = require('path');
|
||||||
|
|
||||||
|
import express = require('express');
|
||||||
|
|
||||||
|
export interface N8nApp {
|
||||||
|
app: Application;
|
||||||
|
}
|
||||||
|
|
||||||
|
const publicApiController = express.Router();
|
||||||
|
|
||||||
|
export const getRoutes = (): express.Router => {
|
||||||
|
|
||||||
|
publicApiController.use(`/v1`,
|
||||||
|
OpenApiValidator.middleware({
|
||||||
|
apiSpec: path.join(__dirname, 'openapi.yml'),
|
||||||
|
operationHandlers: path.join(__dirname),
|
||||||
|
validateRequests: true, // (default)
|
||||||
|
validateApiSpec: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
//add error handler
|
||||||
|
//@ts-ignore
|
||||||
|
publicApiController.use((err, req, res, next) => {
|
||||||
|
res.status(err.status || 500).json({
|
||||||
|
message: err.message,
|
||||||
|
errors: err.errors,
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return publicApiController;
|
||||||
|
};
|
292
packages/cli/src/PublicApi/v1/openapi.yml
Normal file
292
packages/cli/src/PublicApi/v1/openapi.yml
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
---
|
||||||
|
openapi: 3.0.0
|
||||||
|
info:
|
||||||
|
title: Public n8n API
|
||||||
|
description: n8n Public API
|
||||||
|
termsOfService: https://n8n.io/legal/terms
|
||||||
|
contact:
|
||||||
|
email: hello@n8n.io
|
||||||
|
license:
|
||||||
|
name: Apache 2.0 with Commons Clause
|
||||||
|
url: https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md
|
||||||
|
version: 1.0.0
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about Swagger
|
||||||
|
url: http://swagger.io
|
||||||
|
servers:
|
||||||
|
- url: /api/v1
|
||||||
|
tags:
|
||||||
|
- name: user
|
||||||
|
description: Operations about user
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about our store
|
||||||
|
url: http://swagger.io
|
||||||
|
paths:
|
||||||
|
/users:
|
||||||
|
get:
|
||||||
|
x-eov-operation-id: getUsers
|
||||||
|
x-eov-operation-handler: routes/Users
|
||||||
|
tags:
|
||||||
|
- users
|
||||||
|
summary: Retrieve all users
|
||||||
|
description: Retrieve all users from your instance. Only available for the instance owner.
|
||||||
|
parameters:
|
||||||
|
- name: select
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
style: form
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Comma-separted list of the properties to return. Use a to return all properties. Dot notation be use for nested properties
|
||||||
|
example: email,firstName
|
||||||
|
- name: limit
|
||||||
|
in: query
|
||||||
|
description: The maximum number of items to return
|
||||||
|
required: false
|
||||||
|
style: form
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: number
|
||||||
|
example: 100
|
||||||
|
default: 100
|
||||||
|
- name: cursor
|
||||||
|
in: query
|
||||||
|
description: Paginate through users by setting the cursor parameter to a nextCursor attribute returned by a previous request's response_metadata. Default value fetches the first "page" of the collection. See pagination for more detail.
|
||||||
|
required: false
|
||||||
|
style: form
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/inline_response_200'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
post:
|
||||||
|
x-eov-operation-id: createUsers
|
||||||
|
x-eov-operation-handler: routes/Users
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Invite a user
|
||||||
|
description: Invites a user to your instance. Only available for the instance owner.
|
||||||
|
operationId: createUser
|
||||||
|
requestBody:
|
||||||
|
description: Created user object
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Users'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: A User object
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Users'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
"422":
|
||||||
|
description: Unprocessable Entity
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InputValidationError'
|
||||||
|
/users/{userId}:
|
||||||
|
get:
|
||||||
|
x-eov-operation-id: getUser
|
||||||
|
x-eov-operation-handler: routes/Users
|
||||||
|
tags:
|
||||||
|
- users
|
||||||
|
summary: Get user by ID/Email
|
||||||
|
description: Retrieve a user from your instance. Only available for the instance owner.
|
||||||
|
operationId: getUser
|
||||||
|
parameters:
|
||||||
|
- name: userId
|
||||||
|
in: path
|
||||||
|
description: The ID or email of the user
|
||||||
|
required: true
|
||||||
|
style: simple
|
||||||
|
explode: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
delete:
|
||||||
|
x-eov-operation-id: deleteUser
|
||||||
|
x-eov-operation-handler: routes/Users
|
||||||
|
tags:
|
||||||
|
- users
|
||||||
|
summary: Delete user by ID/Email
|
||||||
|
description: Deletes a user from your instance. Only available for the instance owner.
|
||||||
|
operationId: deleteUser
|
||||||
|
parameters:
|
||||||
|
- name: userId
|
||||||
|
in: path
|
||||||
|
description: The name that needs to be deleted
|
||||||
|
required: true
|
||||||
|
style: simple
|
||||||
|
explode: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: transferId
|
||||||
|
in: query
|
||||||
|
description: ID of the user to transfer workflows and credentials to.
|
||||||
|
required: true
|
||||||
|
style: form
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: User deleted successfully
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
"404":
|
||||||
|
description: User not found
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
InputValidationError:
|
||||||
|
required:
|
||||||
|
- code
|
||||||
|
- description
|
||||||
|
- message
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
errors:
|
||||||
|
$ref: '#/components/schemas/Errors'
|
||||||
|
Error:
|
||||||
|
required:
|
||||||
|
- code
|
||||||
|
- description
|
||||||
|
- message
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
Errors:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
Users:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
User:
|
||||||
|
required:
|
||||||
|
- email
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
readOnly: true
|
||||||
|
example: 123e4567-e89b-12d3-a456-426614174000
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
example: jhon.doe@company.com
|
||||||
|
firstName:
|
||||||
|
maxLength: 32
|
||||||
|
type: string
|
||||||
|
description: User's first name
|
||||||
|
example: jhon
|
||||||
|
lastName:
|
||||||
|
maxLength: 32
|
||||||
|
type: string
|
||||||
|
description: User's last name
|
||||||
|
example: doe
|
||||||
|
finishedSetup:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the user finished setting up the invitation or not
|
||||||
|
readOnly: true
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
description: Time the user was created
|
||||||
|
format: date-time
|
||||||
|
readOnly: true
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
description: Last time the user was updaded
|
||||||
|
format: date-time
|
||||||
|
readOnly: true
|
||||||
|
inline_response_200:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
users:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
nextCursor:
|
||||||
|
type: string
|
||||||
|
description: Paginate through users by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection.
|
||||||
|
nullable: true
|
||||||
|
example: MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDA
|
||||||
|
responses:
|
||||||
|
NotFound:
|
||||||
|
description: The specified resource was not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
Unauthorized:
|
||||||
|
description: Unauthorized
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
Forbidden:
|
||||||
|
description: Forbidden
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
UnprocessableEntity:
|
||||||
|
description: Unprocessable Entity
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InputValidationError'
|
||||||
|
securitySchemes:
|
||||||
|
ApiKeyAuth:
|
||||||
|
type: apiKey
|
||||||
|
in: header
|
||||||
|
name: X-N8N-API-KEY
|
||||||
|
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
19
packages/cli/src/PublicApi/v1/routes/Users/index.ts
Normal file
19
packages/cli/src/PublicApi/v1/routes/Users/index.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import express = require('express');
|
||||||
|
|
||||||
|
import { UserRequest } from '../../../../requests';
|
||||||
|
|
||||||
|
export = {
|
||||||
|
createUsers: async (req: UserRequest.Invite, res: express.Response) => {
|
||||||
|
res.json({ success: true});
|
||||||
|
},
|
||||||
|
deleteUser: async (req: UserRequest.Delete, res: express.Response) => {
|
||||||
|
console.log('aja')
|
||||||
|
res.json({ success: true });
|
||||||
|
},
|
||||||
|
getUser: async (req: UserRequest.Get, res: express.Response) => {
|
||||||
|
res.json({ success: true });
|
||||||
|
},
|
||||||
|
getUsers: async (req: UserRequest.Get, res: express.Response) => {
|
||||||
|
res.json({ success: true });
|
||||||
|
},
|
||||||
|
};
|
|
@ -111,9 +111,11 @@ import {
|
||||||
Db,
|
Db,
|
||||||
ExternalHooks,
|
ExternalHooks,
|
||||||
GenericHelpers,
|
GenericHelpers,
|
||||||
|
getCredentialForUser,
|
||||||
ICredentialsDb,
|
ICredentialsDb,
|
||||||
ICredentialsOverwrite,
|
ICredentialsOverwrite,
|
||||||
ICustomRequest,
|
ICustomRequest,
|
||||||
|
IDiagnosticInfo,
|
||||||
IExecutionFlattedDb,
|
IExecutionFlattedDb,
|
||||||
IExecutionFlattedResponse,
|
IExecutionFlattedResponse,
|
||||||
IExecutionPushResponse,
|
IExecutionPushResponse,
|
||||||
|
@ -122,7 +124,6 @@ import {
|
||||||
IExecutionsStopData,
|
IExecutionsStopData,
|
||||||
IExecutionsSummary,
|
IExecutionsSummary,
|
||||||
IExternalHooksClass,
|
IExternalHooksClass,
|
||||||
IDiagnosticInfo,
|
|
||||||
IN8nUISettings,
|
IN8nUISettings,
|
||||||
IPackageVersions,
|
IPackageVersions,
|
||||||
ITagWithCountDb,
|
ITagWithCountDb,
|
||||||
|
@ -139,7 +140,6 @@ import {
|
||||||
WorkflowExecuteAdditionalData,
|
WorkflowExecuteAdditionalData,
|
||||||
WorkflowHelpers,
|
WorkflowHelpers,
|
||||||
WorkflowRunner,
|
WorkflowRunner,
|
||||||
getCredentialForUser,
|
|
||||||
} from '.';
|
} from '.';
|
||||||
|
|
||||||
import * as config from '../config';
|
import * as config from '../config';
|
||||||
|
@ -158,13 +158,13 @@ import { resolveJwt } from './UserManagement/auth/jwt';
|
||||||
import { User } from './databases/entities/User';
|
import { User } from './databases/entities/User';
|
||||||
import { CredentialsEntity } from './databases/entities/CredentialsEntity';
|
import { CredentialsEntity } from './databases/entities/CredentialsEntity';
|
||||||
import type {
|
import type {
|
||||||
|
AuthenticatedRequest,
|
||||||
CredentialRequest,
|
CredentialRequest,
|
||||||
ExecutionRequest,
|
ExecutionRequest,
|
||||||
WorkflowRequest,
|
|
||||||
NodeParameterOptionsRequest,
|
NodeParameterOptionsRequest,
|
||||||
OAuthRequest,
|
OAuthRequest,
|
||||||
AuthenticatedRequest,
|
|
||||||
TagsRequest,
|
TagsRequest,
|
||||||
|
WorkflowRequest,
|
||||||
} from './requests';
|
} from './requests';
|
||||||
import { DEFAULT_EXECUTIONS_GET_ALL_LIMIT, validateEntity } from './GenericHelpers';
|
import { DEFAULT_EXECUTIONS_GET_ALL_LIMIT, validateEntity } from './GenericHelpers';
|
||||||
import { ExecutionEntity } from './databases/entities/ExecutionEntity';
|
import { ExecutionEntity } from './databases/entities/ExecutionEntity';
|
||||||
|
@ -172,6 +172,7 @@ import { SharedWorkflow } from './databases/entities/SharedWorkflow';
|
||||||
import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from './constants';
|
import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from './constants';
|
||||||
import { credentialsController } from './api/credentials.api';
|
import { credentialsController } from './api/credentials.api';
|
||||||
import { getInstanceBaseUrl, isEmailSetUp } from './UserManagement/UserManagementHelper';
|
import { getInstanceBaseUrl, isEmailSetUp } from './UserManagement/UserManagementHelper';
|
||||||
|
import * as publicApiv1Routes from './PublicApi/v1';
|
||||||
|
|
||||||
require('body-parser-xml')(bodyParser);
|
require('body-parser-xml')(bodyParser);
|
||||||
|
|
||||||
|
@ -220,6 +221,8 @@ class App {
|
||||||
|
|
||||||
restEndpoint: string;
|
restEndpoint: string;
|
||||||
|
|
||||||
|
publicApiEndpoint: string;
|
||||||
|
|
||||||
frontendSettings: IN8nUISettings;
|
frontendSettings: IN8nUISettings;
|
||||||
|
|
||||||
protocol: string;
|
protocol: string;
|
||||||
|
@ -252,6 +255,7 @@ class App {
|
||||||
this.payloadSizeMax = config.get('endpoints.payloadSizeMax') as number;
|
this.payloadSizeMax = config.get('endpoints.payloadSizeMax') as number;
|
||||||
this.timezone = config.get('generic.timezone') as string;
|
this.timezone = config.get('generic.timezone') as string;
|
||||||
this.restEndpoint = config.get('endpoints.rest') as string;
|
this.restEndpoint = config.get('endpoints.rest') as string;
|
||||||
|
this.publicApiEndpoint = config.get('publicApiEndpoints.path') as string;
|
||||||
|
|
||||||
this.activeWorkflowRunner = ActiveWorkflowRunner.getInstance();
|
this.activeWorkflowRunner = ActiveWorkflowRunner.getInstance();
|
||||||
this.testWebhooks = TestWebhooks.getInstance();
|
this.testWebhooks = TestWebhooks.getInstance();
|
||||||
|
@ -386,6 +390,7 @@ class App {
|
||||||
this.endpointWebhook,
|
this.endpointWebhook,
|
||||||
this.endpointWebhookTest,
|
this.endpointWebhookTest,
|
||||||
this.endpointPresetCredentials,
|
this.endpointPresetCredentials,
|
||||||
|
this.publicApiEndpoint,
|
||||||
];
|
];
|
||||||
// eslint-disable-next-line prefer-spread
|
// eslint-disable-next-line prefer-spread
|
||||||
ignoredEndpoints.push.apply(ignoredEndpoints, excludeEndpoints.split(':'));
|
ignoredEndpoints.push.apply(ignoredEndpoints, excludeEndpoints.split(':'));
|
||||||
|
@ -495,8 +500,9 @@ class App {
|
||||||
|
|
||||||
// eslint-disable-next-line no-inner-declarations
|
// eslint-disable-next-line no-inner-declarations
|
||||||
function isTenantAllowed(decodedToken: object): boolean {
|
function isTenantAllowed(decodedToken: object): boolean {
|
||||||
if (jwtNamespace === '' || jwtAllowedTenantKey === '' || jwtAllowedTenant === '')
|
if (jwtNamespace === '' || jwtAllowedTenantKey === '' || jwtAllowedTenant === '') {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(decodedToken)) {
|
for (const [k, v] of Object.entries(decodedToken)) {
|
||||||
if (k === jwtNamespace) {
|
if (k === jwtNamespace) {
|
||||||
|
@ -554,6 +560,12 @@ class App {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Public API
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
|
this.app.use(`/${this.publicApiEndpoint}`, publicApiv1Routes.getRoutes());
|
||||||
|
|
||||||
// Parse cookies for easier access
|
// Parse cookies for easier access
|
||||||
this.app.use(cookieParser());
|
this.app.use(cookieParser());
|
||||||
|
|
||||||
|
@ -3081,7 +3093,7 @@ async function getExecutionsCount(
|
||||||
try {
|
try {
|
||||||
// Get an estimate of rows count.
|
// Get an estimate of rows count.
|
||||||
const estimateRowsNumberSql =
|
const estimateRowsNumberSql =
|
||||||
"SELECT n_live_tup FROM pg_stat_all_tables WHERE relname = 'execution_entity';";
|
'SELECT n_live_tup FROM pg_stat_all_tables WHERE relname = \'execution_entity\';';
|
||||||
const rows: Array<{ n_live_tup: string }> = await Db.collections.Execution!.query(
|
const rows: Array<{ n_live_tup: string }> = await Db.collections.Execution!.query(
|
||||||
estimateRowsNumberSql,
|
estimateRowsNumberSql,
|
||||||
);
|
);
|
||||||
|
|
4
packages/cli/src/requests.d.ts
vendored
4
packages/cli/src/requests.d.ts
vendored
|
@ -196,7 +196,9 @@ export declare namespace UserRequest {
|
||||||
{ inviterId?: string; inviteeId?: string }
|
{ inviterId?: string; inviteeId?: string }
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type Delete = AuthenticatedRequest<{ id: string }, {}, {}, { transferId?: string }>;
|
export type Delete = AuthenticatedRequest<{ id: string, email: string }, {}, {}, { transferId?: string }>;
|
||||||
|
|
||||||
|
export type Get = AuthenticatedRequest<{ id: string, email: string }, {}, {}, { limit: string, cursor: string }>;
|
||||||
|
|
||||||
export type Reinvite = AuthenticatedRequest<{ id: string }>;
|
export type Reinvite = AuthenticatedRequest<{ id: string }>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue