Merge branch 'v4' into build-transformer

This commit is contained in:
Sam 2022-02-01 12:53:35 +02:00 committed by GitHub
commit 0aa6d60bec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
146 changed files with 2237 additions and 1938 deletions

5
.pnp.cjs generated
View File

@ -5207,7 +5207,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@lowdefy/blocks-markdown", "workspace:packages/plugins/blocks/blocks-markdown"],
["@lowdefy/connection-axios-http", "workspace:packages/plugins/connections/connection-axios-http"],
["@lowdefy/connection-elasticsearch", "workspace:packages/plugins/connections/connection-elasticsearch"],
["@lowdefy/connection-google-sheets", "workspace:packages/plugins/connections/connection-google-sheets"],
["@lowdefy/connection-knex", "workspace:packages/plugins/connections/connection-knex"],
["@lowdefy/connection-mongodb", "workspace:packages/plugins/connections/connection-mongodb"],
["@lowdefy/connection-redis", "workspace:packages/plugins/connections/connection-redis"],
["@lowdefy/connection-sendgrid", "workspace:packages/plugins/connections/connection-sendgrid"],
["@lowdefy/connection-stripe", "workspace:packages/plugins/connections/connection-stripe"],
["@lowdefy/helpers", "workspace:packages/utils/helpers"],
["@lowdefy/node-utils", "workspace:packages/utils/node-utils"],
["@lowdefy/nunjucks", "workspace:packages/utils/nunjucks"],

View File

@ -64,7 +64,12 @@
"@lowdefy/blocks-markdown": "4.0.0-alpha.6",
"@lowdefy/connection-axios-http": "4.0.0-alpha.6",
"@lowdefy/connection-elasticsearch": "4.0.0-alpha.6",
"@lowdefy/connection-google-sheets": "4.0.0-alpha.6",
"@lowdefy/connection-knex": "4.0.0-alpha.6",
"@lowdefy/connection-mongodb": "4.0.0-alpha.6",
"@lowdefy/connection-redis": "4.0.0-alpha.6",
"@lowdefy/connection-sendgrid": "4.0.0-alpha.6",
"@lowdefy/connection-stripe": "4.0.0-alpha.6",
"@lowdefy/operators-change-case": "4.0.0-alpha.6",
"@lowdefy/operators-diff": "4.0.0-alpha.6",
"@lowdefy/operators-js": "4.0.0-alpha.6",
@ -80,4 +85,4 @@
"publishConfig": {
"access": "public"
}
}
}

View File

@ -28,7 +28,12 @@ const defaultPackages = [
'@lowdefy/blocks-markdown',
'@lowdefy/connection-axios-http',
'@lowdefy/connection-elasticsearch',
'@lowdefy/connection-google-sheets',
'@lowdefy/connection-knex',
'@lowdefy/connection-mongodb',
'@lowdefy/connection-redis',
'@lowdefy/connection-sendgrid',
'@lowdefy/connection-stripe',
'@lowdefy/operators-change-case',
// '@lowdefy/operators-diff',
'@lowdefy/operators-js',

View File

@ -27,8 +27,8 @@
},
"type": "module",
"exports": {
".": "./dist/index.js",
"./connections/*": "./dist/connections/*"
"./connections": "./dist/connections.js",
"./types": "./dist/types.js"
},
"files": [
"dist/*"

View File

@ -14,13 +14,4 @@
limitations under the License.
*/
export default {
import: {
path: 'connections/Knex/KnexRaw/KnexRaw.js',
schema: 'connections/Knex/KnexRaw/KnexRawSchema.json',
},
meta: {
checkRead: false,
checkWrite: false,
},
};
export { default as GoogleSheet } from './connections/GoogleSheet/GoogleSheet.js';

View File

@ -21,11 +21,10 @@ import GoogleSheetGetMany from './GoogleSheetGetMany/GoogleSheetGetMany.js';
import GoogleSheetGetOne from './GoogleSheetGetOne/GoogleSheetGetOne.js';
import GoogleSheetUpdateOne from './GoogleSheetUpdateOne/GoogleSheetUpdateOne.js';
import GoogleSheetUpdateMany from './GoogleSheetUpdateMany/GoogleSheetUpdateMany.js';
import schema from './schema.js';
export default {
import: {
schema: 'connections/GoogleSheet/GoogleSheetSchema.json',
},
schema,
requests: {
GoogleSheetAppendMany,
GoogleSheetAppendOne,

View File

@ -16,7 +16,8 @@
import { validate } from '@lowdefy/ajv';
import GoogleSheet from './GoogleSheet.js';
import schema from './GoogleSheetSchema.json';
const schema = GoogleSheet.schema;
test('All requests are present', () => {
expect(GoogleSheet.requests.GoogleSheetAppendOne).toBeDefined();

View File

@ -16,8 +16,9 @@
import getSheet from '../getSheet.js';
import { transformWrite } from '../transformTypes.js';
import schema from './schema.js';
async function googleSheetAppendMany({ request, connection }) {
async function GoogleSheetAppendMany({ request, connection }) {
const { rows, options = {} } = request;
const { raw } = options;
const sheet = await getSheet({ connection });
@ -27,4 +28,10 @@ async function googleSheetAppendMany({ request, connection }) {
};
}
export default googleSheetAppendMany;
GoogleSheetAppendMany.schema = schema;
GoogleSheetAppendMany.meta = {
checkRead: false,
checkWrite: true,
};
export default GoogleSheetAppendMany;

View File

@ -15,11 +15,11 @@
*/
import { validate } from '@lowdefy/ajv';
import googleSheetAppendMany from './GoogleSheetAppendMany.js';
import requestIndex from './index.js';
import schema from './GoogleSheetAppendManySchema.json';
import GoogleSheetAppendMany from './GoogleSheetAppendMany.js';
const { checkRead, checkWrite } = GoogleSheetAppendMany.meta;
const schema = GoogleSheetAppendMany.schema;
const { checkRead, checkWrite } = requestIndex.meta;
const mockAddRows = jest.fn();
jest.mock('../getSheet', () => () => ({
addRows: mockAddRows,
@ -29,7 +29,7 @@ const mockAddRowsDefaultImp = (rows) => rows.map((row) => ({ ...row, _sheet: {}
test('googleSheetAppendMany, one row', async () => {
mockAddRows.mockImplementation(mockAddRowsDefaultImp);
const res = await googleSheetAppendMany({
const res = await GoogleSheetAppendMany({
request: {
rows: [{ id: '1', name: 'John', age: '34', birth_date: '2020/04/26', married: 'TRUE' }],
},
@ -58,7 +58,7 @@ test('googleSheetAppendMany, one row', async () => {
test('googleSheetAppendMany, two rows', async () => {
mockAddRows.mockImplementation(mockAddRowsDefaultImp);
const res = await googleSheetAppendMany({
const res = await GoogleSheetAppendMany({
request: {
rows: [
{ id: '1', name: 'John', age: '34', birth_date: '2020/04/26', married: 'TRUE' },
@ -97,7 +97,7 @@ test('googleSheetAppendMany, two rows', async () => {
test('googleSheetAppendMany, rows empty array', async () => {
mockAddRows.mockImplementation(mockAddRowsDefaultImp);
const res = await googleSheetAppendMany({
const res = await GoogleSheetAppendMany({
request: {
rows: [],
},
@ -118,7 +118,7 @@ test('googleSheetAppendMany, rows empty array', async () => {
test('googleSheetAppendMany, transform types', async () => {
mockAddRows.mockImplementation(mockAddRowsDefaultImp);
const res = await googleSheetAppendMany({
const res = await GoogleSheetAppendMany({
request: {
rows: [
{
@ -162,7 +162,7 @@ test('googleSheetAppendMany, transform types', async () => {
test('googleSheetAppendMany, one row, raw true', async () => {
mockAddRows.mockImplementation(mockAddRowsDefaultImp);
const res = await googleSheetAppendMany({
const res = await GoogleSheetAppendMany({
request: {
rows: [{ id: '1', name: 'John', age: '34', birth_date: '2020/04/26', married: 'TRUE' }],
options: {

View File

@ -1,40 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - GoogleSheetAppendMany",
"type": "object",
"required": ["rows"],
"properties": {
"rows": {
"type": "array",
"description": "The rows to insert into the sheet. An an array of objects where keys are the column names and values are the values to insert.",
"errorMessage": {
"type": "GoogleSheetAppendMany request property \"rows\" should be an array."
},
"items": {
"type": "object",
"description": "The row to insert into the sheet. An object where keys are the column names and values are the values to insert.",
"errorMessage": {
"type": "GoogleSheetAppendMany request property \"rows\" should be an array of objects."
}
}
},
"options": {
"type": "object",
"properties": {
"raw": {
"type": "boolean",
"description": "Store raw values instead of converting as if typed into the sheets UI.",
"errorMessage": {
"type": "GoogleSheetAppendMany request property \"options.raw\" should be a boolean."
}
}
}
}
},
"errorMessage": {
"type": "GoogleSheetAppendMany request properties should be an object.",
"required": {
"rows": "GoogleSheetAppendMany request should have required property \"rows\"."
}
}
}

View File

@ -0,0 +1,58 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - GoogleSheetAppendMany',
type: 'object',
required: ['rows'],
properties: {
rows: {
type: 'array',
description:
'The rows to insert into the sheet. An an array of objects where keys are the column names and values are the values to insert.',
errorMessage: {
type: 'GoogleSheetAppendMany request property "rows" should be an array.',
},
items: {
type: 'object',
description:
'The row to insert into the sheet. An object where keys are the column names and values are the values to insert.',
errorMessage: {
type: 'GoogleSheetAppendMany request property "rows" should be an array of objects.',
},
},
},
options: {
type: 'object',
properties: {
raw: {
type: 'boolean',
description: 'Store raw values instead of converting as if typed into the sheets UI.',
errorMessage: {
type: 'GoogleSheetAppendMany request property "options.raw" should be a boolean.',
},
},
},
},
},
errorMessage: {
type: 'GoogleSheetAppendMany request properties should be an object.',
required: {
rows: 'GoogleSheetAppendMany request should have required property "rows".',
},
},
};

View File

@ -17,8 +17,9 @@
import getSheet from '../getSheet.js';
import cleanRows from '../cleanRows.js';
import { transformWrite } from '../transformTypes.js';
import schema from './schema.js';
async function googleSheetAppendOne({ request, connection }) {
async function GoogleSheetAppendOne({ request, connection }) {
const { row, options = {} } = request;
const { raw } = options;
const sheet = await getSheet({ connection });
@ -32,4 +33,10 @@ async function googleSheetAppendOne({ request, connection }) {
};
}
export default googleSheetAppendOne;
GoogleSheetAppendOne.schema = schema;
GoogleSheetAppendOne.meta = {
checkRead: false,
checkWrite: true,
};
export default GoogleSheetAppendOne;

View File

@ -15,11 +15,10 @@
*/
import { validate } from '@lowdefy/ajv';
import googleSheetAppendOne from './GoogleSheetAppendOne.js';
import requestIndex from './index.js';
import schema from './GoogleSheetAppendOneSchema.json';
import GoogleSheetAppendOne from './GoogleSheetAppendOne.js';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = GoogleSheetAppendOne.meta;
const schema = GoogleSheetAppendOne.schema;
const mockAddRow = jest.fn();
jest.mock('../getSheet', () => () => ({
@ -30,7 +29,7 @@ const mockAddRowDefaultImp = (row) => ({ ...row, _sheet: {} });
test('googleSheetAppendOne', async () => {
mockAddRow.mockImplementation(mockAddRowDefaultImp);
const res = await googleSheetAppendOne({
const res = await GoogleSheetAppendOne({
request: {
row: { id: '1', name: 'John', age: '34', birth_date: '2020/04/26', married: 'TRUE' },
},
@ -66,7 +65,7 @@ test('googleSheetAppendOne', async () => {
test('googleSheetAppendOne, transform types', async () => {
mockAddRow.mockImplementation(mockAddRowDefaultImp);
const res = await googleSheetAppendOne({
const res = await GoogleSheetAppendOne({
request: {
row: {
id: '1',
@ -115,7 +114,7 @@ test('googleSheetAppendOne, transform types', async () => {
test('googleSheetAppendOne, raw true', async () => {
mockAddRow.mockImplementation(mockAddRowDefaultImp);
const res = await googleSheetAppendOne({
const res = await GoogleSheetAppendOne({
request: {
row: { id: '1', name: 'John', age: '34', birth_date: '2020/04/26', married: 'TRUE' },
options: {

View File

@ -1,33 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - GoogleSheetAppendOne",
"type": "object",
"required": ["row"],
"properties": {
"row": {
"type": "object",
"description": "The row to insert into the sheet. An object where keys are the column names and values are the values to insert.",
"errorMessage": {
"type": "GoogleSheetAppendOne request property \"row\" should be an object."
}
},
"options": {
"type": "object",
"properties": {
"raw": {
"type": "boolean",
"description": "Store raw values instead of converting as if typed into the sheets UI.",
"errorMessage": {
"type": "GoogleSheetAppendOne request property \"options.raw\" should be a boolean."
}
}
}
}
},
"errorMessage": {
"type": "GoogleSheetAppendOne request properties should be an object.",
"required": {
"row": "GoogleSheetAppendOne request should have required property \"row\"."
}
}
}

View File

@ -0,0 +1,50 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - GoogleSheetAppendOne',
type: 'object',
required: ['row'],
properties: {
row: {
type: 'object',
description:
'The row to insert into the sheet. An object where keys are the column names and values are the values to insert.',
errorMessage: {
type: 'GoogleSheetAppendOne request property "row" should be an object.',
},
},
options: {
type: 'object',
properties: {
raw: {
type: 'boolean',
description: 'Store raw values instead of converting as if typed into the sheets UI.',
errorMessage: {
type: 'GoogleSheetAppendOne request property "options.raw" should be a boolean.',
},
},
},
},
},
errorMessage: {
type: 'GoogleSheetAppendOne request properties should be an object.',
required: {
row: 'GoogleSheetAppendOne request should have required property "row".',
},
},
};

View File

@ -18,8 +18,9 @@ import cleanRows from '../cleanRows.js';
import getSheet from '../getSheet.js';
import { transformRead } from '../transformTypes.js';
import mingoFilter from '../mingoFilter.js';
import schema from './schema.js';
async function googleSheetDeleteOne({ request, connection }) {
async function GoogleSheetDeleteOne({ request, connection }) {
const { filter, options = {} } = request;
const { limit, skip } = options;
const sheet = await getSheet({ connection });
@ -39,4 +40,10 @@ async function googleSheetDeleteOne({ request, connection }) {
};
}
export default googleSheetDeleteOne;
GoogleSheetDeleteOne.schema = schema;
GoogleSheetDeleteOne.meta = {
checkRead: false,
checkWrite: true,
};
export default GoogleSheetDeleteOne;

View File

@ -15,11 +15,10 @@
*/
import { validate } from '@lowdefy/ajv';
import googleSheetDeleteOne from './GoogleSheetDeleteOne.js';
import requestIndex from './index.js';
import schema from './GoogleSheetDeleteOneSchema.json';
import GoogleSheetDeleteOne from './GoogleSheetDeleteOne.js';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = GoogleSheetDeleteOne.meta;
const schema = GoogleSheetDeleteOne.schema;
const mockGetRows = jest.fn();
const mockDelete = jest.fn();
@ -79,7 +78,7 @@ const mockGetRowsDefaultImp = ({ limit, offset }) => {
test('googleSheetDeleteMany, match one', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetDeleteOne({
const res = await GoogleSheetDeleteOne({
request: {
filter: { id: '1' },
},
@ -103,7 +102,7 @@ test('googleSheetDeleteMany, match one', async () => {
test('googleSheetDeleteMany, match nothing', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetDeleteOne({
const res = await GoogleSheetDeleteOne({
request: {
filter: { id: 'does_not_exist' },
},
@ -117,7 +116,7 @@ test('googleSheetDeleteMany, match nothing', async () => {
test('googleSheetDeleteMany, match more than one', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetDeleteOne({
const res = await GoogleSheetDeleteOne({
request: {
filter: { _rowNumber: { $gt: 3 } },
},

View File

@ -1,40 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - GoogleSheetDeleteOne",
"type": "object",
"required": ["filter"],
"properties": {
"filter": {
"type": "object",
"description": "A MongoDB query expression to filter the data. The first row matched by the filter will be deleted.",
"errorMessage": {
"type": "GoogleSheetDeleteOne request property \"filter\" should be an object."
}
},
"options": {
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "The maximum number of rows to fetch.",
"errorMessage": {
"type": "GoogleSheetDeleteOne request property \"options.limit\" should be a number."
}
},
"skip": {
"type": "number",
"description": "The number of rows to skip from the top of the sheet.",
"errorMessage": {
"type": "GoogleSheetDeleteOne request property \"options.skip\" should be a number."
}
}
}
}
},
"errorMessage": {
"type": "GoogleSheetDeleteOne request properties should be an object.",
"required": {
"filter": "GoogleSheetDeleteOne request should have required property \"filter\"."
}
}
}

View File

@ -0,0 +1,57 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - GoogleSheetDeleteOne',
type: 'object',
required: ['filter'],
properties: {
filter: {
type: 'object',
description:
'A MongoDB query expression to filter the data. The first row matched by the filter will be deleted.',
errorMessage: {
type: 'GoogleSheetDeleteOne request property "filter" should be an object.',
},
},
options: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'The maximum number of rows to fetch.',
errorMessage: {
type: 'GoogleSheetDeleteOne request property "options.limit" should be a number.',
},
},
skip: {
type: 'number',
description: 'The number of rows to skip from the top of the sheet.',
errorMessage: {
type: 'GoogleSheetDeleteOne request property "options.skip" should be a number.',
},
},
},
},
},
errorMessage: {
type: 'GoogleSheetDeleteOne request properties should be an object.',
required: {
filter: 'GoogleSheetDeleteOne request should have required property "filter".',
},
},
};

View File

@ -19,8 +19,9 @@ import getSheet from '../getSheet.js';
import { transformRead } from '../transformTypes.js';
import mingoAggregation from '../mingoAggregation.js';
import mingoFilter from '../mingoFilter.js';
import schema from './schema.js';
async function googleSheetGetMany({ request, connection }) {
async function GoogleSheetGetMany({ request, connection }) {
const { filter, pipeline, options = {} } = request;
const { limit, skip } = options;
const sheet = await getSheet({ connection });
@ -36,4 +37,10 @@ async function googleSheetGetMany({ request, connection }) {
return rows;
}
export default googleSheetGetMany;
GoogleSheetGetMany.schema = schema;
GoogleSheetGetMany.meta = {
checkRead: true,
checkWrite: false,
};
export default GoogleSheetGetMany;

View File

@ -15,11 +15,10 @@
*/
import { validate } from '@lowdefy/ajv';
import googleSheetGetMany from './GoogleSheetGetMany.js';
import requestIndex from './index.js';
import schema from './GoogleSheetGetManySchema.json';
import GoogleSheetGetMany from './GoogleSheetGetMany.js';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = GoogleSheetGetMany.meta;
const schema = GoogleSheetGetMany.schema;
const mockGetRows = jest.fn();
jest.mock('../getSheet', () => () => ({
@ -74,7 +73,7 @@ const mockGetRowsDefaultImp = ({ limit, offset }) => {
test('googleSheetGetMany, all rows', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({ request: {}, connection: {} });
const res = await GoogleSheetGetMany({ request: {}, connection: {} });
expect(res).toEqual([
{
_rowNumber: 2,
@ -117,13 +116,13 @@ test('googleSheetGetMany, all rows', async () => {
test('googleSheetGetMany, empty rows returned', async () => {
mockGetRows.mockImplementation(() => []);
const res = await googleSheetGetMany({ request: {}, connection: {} });
const res = await GoogleSheetGetMany({ request: {}, connection: {} });
expect(res).toEqual([]);
});
test('googleSheetGetMany, limit', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({ request: { options: { limit: 2 } }, connection: {} });
const res = await GoogleSheetGetMany({ request: { options: { limit: 2 } }, connection: {} });
expect(res).toEqual([
{
_rowNumber: 2,
@ -148,7 +147,7 @@ test('googleSheetGetMany, limit', async () => {
test('googleSheetGetMany, skip', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({ request: { options: { skip: 2 } }, connection: {} });
const res = await GoogleSheetGetMany({ request: { options: { skip: 2 } }, connection: {} });
expect(res).toEqual([
{
_rowNumber: 4,
@ -173,7 +172,7 @@ test('googleSheetGetMany, skip', async () => {
test('googleSheetGetMany, skip and limit', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({
const res = await GoogleSheetGetMany({
request: { options: { skip: 2, limit: 1 } },
connection: {},
});
@ -192,7 +191,7 @@ test('googleSheetGetMany, skip and limit', async () => {
test('googleSheetGetMany, filter', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({ request: { filter: { name: 'Tim' } }, connection: {} });
const res = await GoogleSheetGetMany({ request: { filter: { name: 'Tim' } }, connection: {} });
expect(res).toEqual([
{
_rowNumber: 4,
@ -208,13 +207,13 @@ test('googleSheetGetMany, filter', async () => {
test('googleSheetGetMany, filter filters all', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({ request: { filter: { name: 'Nobody' } }, connection: {} });
const res = await GoogleSheetGetMany({ request: { filter: { name: 'Nobody' } }, connection: {} });
expect(res).toEqual([]);
});
test('googleSheetGetMany, filter _rowNumber', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({
const res = await GoogleSheetGetMany({
request: { filter: { _rowNumber: { $gt: 3 } } },
connection: {},
});
@ -242,7 +241,7 @@ test('googleSheetGetMany, filter _rowNumber', async () => {
test('googleSheetGetMany, pipeline count', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({
const res = await GoogleSheetGetMany({
request: { pipeline: [{ $group: { _id: 0, count: { $sum: 1 } } }] },
connection: {},
});
@ -256,7 +255,7 @@ test('googleSheetGetMany, pipeline count', async () => {
test('googleSheetGetMany, columnTypes', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetMany({
const res = await GoogleSheetGetMany({
request: {},
connection: {
columnTypes: {

View File

@ -1,43 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - GoogleSheetGetMany",
"type": "object",
"properties": {
"filter": {
"type": "object",
"description": "A MongoDB query expression to filter the data.",
"errorMessage": {
"type": "GoogleSheetGetMany request property \"filter\" should be an object."
}
},
"pipeline": {
"type": "array",
"description": "A MongoDB aggregation pipeline to transform the data.",
"errorMessage": {
"type": "GoogleSheetGetMany request property \"pipeline\" should be an array."
}
},
"options": {
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "The maximum number of rows to fetch.",
"errorMessage": {
"type": "GoogleSheetGetMany request property \"options.limit\" should be a number."
}
},
"skip": {
"type": "number",
"description": "The number of rows to skip from the top of the sheet.",
"errorMessage": {
"type": "GoogleSheetGetMany request property \"options.skip\" should be a number."
}
}
}
}
},
"errorMessage": {
"type": "GoogleSheetGetMany request properties should be an object."
}
}

View File

@ -0,0 +1,59 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - GoogleSheetGetMany',
type: 'object',
properties: {
filter: {
type: 'object',
description: 'A MongoDB query expression to filter the data.',
errorMessage: {
type: 'GoogleSheetGetMany request property "filter" should be an object.',
},
},
pipeline: {
type: 'array',
description: 'A MongoDB aggregation pipeline to transform the data.',
errorMessage: {
type: 'GoogleSheetGetMany request property "pipeline" should be an array.',
},
},
options: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'The maximum number of rows to fetch.',
errorMessage: {
type: 'GoogleSheetGetMany request property "options.limit" should be a number.',
},
},
skip: {
type: 'number',
description: 'The number of rows to skip from the top of the sheet.',
errorMessage: {
type: 'GoogleSheetGetMany request property "options.skip" should be a number.',
},
},
},
},
},
errorMessage: {
type: 'GoogleSheetGetMany request properties should be an object.',
},
};

View File

@ -18,8 +18,9 @@ import cleanRows from '../cleanRows.js';
import getSheet from '../getSheet.js';
import { transformRead } from '../transformTypes.js';
import mingoFilter from '../mingoFilter.js';
import schema from './schema.js';
async function googleSheetGetOne({ request, connection }) {
async function GoogleSheetGetOne({ request, connection }) {
const { filter, options = {} } = request;
const { limit, skip } = options;
const sheet = await getSheet({ connection });
@ -32,4 +33,10 @@ async function googleSheetGetOne({ request, connection }) {
return rows[0] || null;
}
export default googleSheetGetOne;
GoogleSheetGetOne.schema = schema;
GoogleSheetGetOne.meta = {
checkRead: true,
checkWrite: false,
};
export default GoogleSheetGetOne;

View File

@ -15,11 +15,10 @@
*/
import { validate } from '@lowdefy/ajv';
import googleSheetGetOne from './GoogleSheetGetOne';
import requestIndex from './index.js';
import schema from './GoogleSheetGetOneSchema.json';
import GoogleSheetGetOne from './GoogleSheetGetOne.js';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = GoogleSheetGetOne.meta;
const schema = GoogleSheetGetOne.schema;
const mockGetRows = jest.fn();
jest.mock('../getSheet', () => () => ({
@ -74,7 +73,7 @@ const mockGetRowsDefaultImp = ({ limit, offset }) => {
test('googleSheetGetOne, first row is returned', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({ request: {}, connection: {} });
const res = await GoogleSheetGetOne({ request: {}, connection: {} });
expect(res).toEqual({
_rowNumber: 2,
_rawData: ['1', 'John', '34', '2020/04/26', 'TRUE'],
@ -88,13 +87,13 @@ test('googleSheetGetOne, first row is returned', async () => {
test('googleSheetGetOne, empty rows returned', async () => {
mockGetRows.mockImplementation(() => []);
const res = await googleSheetGetOne({ request: {}, connection: {} });
const res = await GoogleSheetGetOne({ request: {}, connection: {} });
expect(res).toEqual(null);
});
test('googleSheetGetOne, limit', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({ request: { options: { limit: 2 } }, connection: {} });
const res = await GoogleSheetGetOne({ request: { options: { limit: 2 } }, connection: {} });
expect(res).toEqual({
_rowNumber: 2,
_rawData: ['1', 'John', '34', '2020/04/26', 'TRUE'],
@ -108,7 +107,7 @@ test('googleSheetGetOne, limit', async () => {
test('googleSheetGetOne, skip', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({ request: { options: { skip: 2 } }, connection: {} });
const res = await GoogleSheetGetOne({ request: { options: { skip: 2 } }, connection: {} });
expect(res).toEqual({
_rowNumber: 4,
_rawData: ['3', 'Tim', '34', '2020/04/28', 'FALSE'],
@ -122,7 +121,7 @@ test('googleSheetGetOne, skip', async () => {
test('googleSheetGetOne, skip and limit', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({
const res = await GoogleSheetGetOne({
request: { options: { skip: 2, limit: 1 } },
connection: {},
});
@ -139,7 +138,7 @@ test('googleSheetGetOne, skip and limit', async () => {
test('googleSheetGetOne, filter', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({ request: { filter: { name: 'Tim' } }, connection: {} });
const res = await GoogleSheetGetOne({ request: { filter: { name: 'Tim' } }, connection: {} });
expect(res).toEqual({
_rowNumber: 4,
_rawData: ['3', 'Tim', '34', '2020/04/28', 'FALSE'],
@ -153,7 +152,7 @@ test('googleSheetGetOne, filter', async () => {
test('googleSheetGetOne, limit before filter', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({
const res = await GoogleSheetGetOne({
request: { filter: { name: 'Tim' }, options: { limit: 2 } },
connection: {},
});
@ -162,7 +161,7 @@ test('googleSheetGetOne, limit before filter', async () => {
test('googleSheetGetOne, skip before filter', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({
const res = await GoogleSheetGetOne({
request: { filter: { married: 'TRUE' }, options: { skip: 2 } },
connection: {},
});
@ -179,13 +178,13 @@ test('googleSheetGetOne, skip before filter', async () => {
test('googleSheetGetOne, filter filters all', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({ request: { filter: { name: 'Nobody' } }, connection: {} });
const res = await GoogleSheetGetOne({ request: { filter: { name: 'Nobody' } }, connection: {} });
expect(res).toEqual(null);
});
test('googleSheetGetOne, filter _rowNumber', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({
const res = await GoogleSheetGetOne({
request: { filter: { _rowNumber: { $gt: 3 } } },
connection: {},
});
@ -202,7 +201,7 @@ test('googleSheetGetOne, filter _rowNumber', async () => {
test('googleSheetGetOne, columnTypes', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetGetOne({
const res = await GoogleSheetGetOne({
request: {},
connection: {
columnTypes: {

View File

@ -1,36 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - GoogleSheetGetOne",
"type": "object",
"properties": {
"filter": {
"type": "object",
"description": "A MongoDB query expression to filter the data.",
"errorMessage": {
"type": "GoogleSheetGetOne request property \"filter\" should be an object."
}
},
"options": {
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "The maximum number of rows to fetch.",
"errorMessage": {
"type": "GoogleSheetGetOne request property \"options.limit\" should be a number."
}
},
"skip": {
"type": "number",
"description": "The number of rows to skip from the top of the sheet.",
"errorMessage": {
"type": "GoogleSheetGetOne request property \"options.skip\" should be a number."
}
}
}
}
},
"errorMessage": {
"type": "GoogleSheetGetOne request properties should be an object."
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/GoogleSheet/GoogleSheetGetOne/GoogleSheetGetOne.js',
schema: 'connections/GoogleSheet/GoogleSheetGetOne/GoogleSheetGetOneSchema.json',
},
meta: {
checkRead: true,
checkWrite: false,
},
};

View File

@ -0,0 +1,52 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - GoogleSheetGetOne',
type: 'object',
properties: {
filter: {
type: 'object',
description: 'A MongoDB query expression to filter the data.',
errorMessage: {
type: 'GoogleSheetGetOne request property "filter" should be an object.',
},
},
options: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'The maximum number of rows to fetch.',
errorMessage: {
type: 'GoogleSheetGetOne request property "options.limit" should be a number.',
},
},
skip: {
type: 'number',
description: 'The number of rows to skip from the top of the sheet.',
errorMessage: {
type: 'GoogleSheetGetOne request property "options.skip" should be a number.',
},
},
},
},
},
errorMessage: {
type: 'GoogleSheetGetOne request properties should be an object.',
},
};

View File

@ -1,88 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Connection Schema - GoogleSheet",
"type": "object",
"required": ["spreadsheetId"],
"properties": {
"apiKey": {
"type": "string",
"description": "API key for your google project.",
"errorMessage": {
"type": "GoogleSheet connection property \"apiKey\" should be a string."
}
},
"client_email": {
"type": "string",
"description": "The email of your service account.",
"errorMessage": {
"type": "GoogleSheet connection property \"client_email\" should be a string."
}
},
"private_key": {
"type": "string",
"description": "The private key for your service account.",
"errorMessage": {
"type": "GoogleSheet connection property \"private_key\" should be a string."
}
},
"sheetId": {
"type": "string",
"description": "The ID of the worksheet. Can be found in the URL as the \"gid\" parameter. One of \"sheetId\" or \"sheetIndex\" is required.",
"errorMessage": {
"type": "GoogleSheet connection property \"sheetId\" should be a string."
}
},
"sheetIndex": {
"type": "number",
"description": "The position of the worksheet as they appear in the Google sheets UI. Starts from 0. One of \"sheetId\" or \"sheetIndex\" is required.",
"errorMessage": {
"type": "GoogleSheet connection property \"sheetIndex\" should be a number."
}
},
"spreadsheetId": {
"type": "string",
"description": "document ID from the URL of the spreadsheet.",
"errorMessage": {
"type": "GoogleSheet connection property \"spreadsheetId\" should be a string."
}
},
"columnTypes": {
"type": "object",
"description": "Define types for columns in the spreadsheet.",
"patternProperties": {
"^.*$": {
"type": "string",
"enum": ["string", "number", "boolean", "date", "json"],
"errorMessage": {
"enum": "GoogleSheet connection property \"{{ instancePath }}\" should be one of \"string\", \"number\", \"boolean\", \"date\", or \"json\"."
}
}
},
"errorMessage": {
"type": "GoogleSheet connection property \"columnTypes\" should be an object."
}
},
"read": {
"type": "boolean",
"default": true,
"description": "Allow reads from the spreadsheet.",
"errorMessage": {
"type": "GoogleSheet connection property \"read\" should be a boolean."
}
},
"write": {
"type": "boolean",
"default": false,
"description": "Allow writes to the spreadsheet.",
"errorMessage": {
"type": "GoogleSheet connection property \"write\" should be a boolean."
}
}
},
"errorMessage": {
"type": "GoogleSheet connection properties should be an object.",
"required": {
"spreadsheetId": "GoogleSheet connection should have required property \"spreadsheetId\"."
}
}
}

View File

@ -17,8 +17,9 @@
import getSheet from '../getSheet.js';
import { transformRead, transformWrite } from '../transformTypes.js';
import mingoFilter from '../mingoFilter.js';
import schema from './schema.js';
async function googleSheetUpdateMany({ request, connection }) {
async function GoogleSheetUpdateMany({ request, connection }) {
const { filter, update, options = {} } = request;
const { limit, skip, raw } = options;
const sheet = await getSheet({ connection });
@ -41,4 +42,10 @@ async function googleSheetUpdateMany({ request, connection }) {
};
}
export default googleSheetUpdateMany;
GoogleSheetUpdateMany.schema = schema;
GoogleSheetUpdateMany.meta = {
checkRead: false,
checkWrite: true,
};
export default GoogleSheetUpdateMany;

View File

@ -15,11 +15,10 @@
*/
import { validate } from '@lowdefy/ajv';
import googleSheetUpdateMany from './GoogleSheetUpdateMany';
import requestIndex from './index.js';
import schema from './GoogleSheetUpdateManySchema.json';
import GoogleSheetUpdateMany from './GoogleSheetUpdateMany.js';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = GoogleSheetUpdateMany.meta;
const schema = GoogleSheetUpdateMany.schema;
const mockGetRows = jest.fn();
const mockSave = jest.fn();
@ -79,7 +78,7 @@ const mockGetRowsDefaultImp = ({ limit, offset }) => {
test('googleSheetUpdateMany, match one', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateMany({
const res = await GoogleSheetUpdateMany({
request: {
filter: { id: '1' },
update: {
@ -104,7 +103,7 @@ test('googleSheetUpdateMany, match one', async () => {
test('googleSheetUpdateMany, match one, raw true', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateMany({
const res = await GoogleSheetUpdateMany({
request: {
filter: { id: '1' },
update: {
@ -132,7 +131,7 @@ test('googleSheetUpdateMany, match one, raw true', async () => {
test('googleSheetUpdateMany, match nothing', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateMany({
const res = await GoogleSheetUpdateMany({
request: {
filter: { id: 'does_not_exist' },
update: {
@ -149,7 +148,7 @@ test('googleSheetUpdateMany, match nothing', async () => {
test('googleSheetUpdateMany, match more than one', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateMany({
const res = await GoogleSheetUpdateMany({
request: {
filter: { _rowNumber: { $gt: 3 } },
update: {

View File

@ -1,55 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - GoogleSheetUpdateMany",
"type": "object",
"required": ["update", "filter"],
"properties": {
"filter": {
"type": "object",
"description": "A MongoDB query expression to filter the data. All rows matched by the filter will be updated.",
"errorMessage": {
"type": "GoogleSheetUpdateMany request property \"filter\" should be an object."
}
},
"update": {
"type": "object",
"description": "The update to apply to the row. An object where keys are the column names and values are the updated values.",
"errorMessage": {
"type": "GoogleSheetUpdateMany request property \"update\" should be an object."
}
},
"options": {
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "The maximum number of rows to fetch.",
"errorMessage": {
"type": "GoogleSheetUpdateMany request property \"options.limit\" should be a number."
}
},
"raw": {
"type": "boolean",
"description": "Store raw values instead of converting as if typed into the sheets UI.",
"errorMessage": {
"type": "GoogleSheetUpdateMany request property \"options.raw\" should be a boolean."
}
},
"skip": {
"type": "number",
"description": "The number of rows to skip from the top of the sheet.",
"errorMessage": {
"type": "GoogleSheetUpdateMany request property \"options.skip\" should be a number."
}
}
}
}
},
"errorMessage": {
"type": "GoogleSheetUpdateMany request properties should be an object.",
"required": {
"filter": "GoogleSheetUpdateMany request should have required property \"filter\".",
"update": "GoogleSheetUpdateMany request should have required property \"update\"."
}
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/GoogleSheet/GoogleSheetUpdateMany/GoogleSheetUpdateMany.js',
schema: 'connections/GoogleSheet/GoogleSheetUpdateMany/GoogleSheetUpdateManySchema.json',
},
meta: {
checkRead: false,
checkWrite: true,
},
};

View File

@ -0,0 +1,73 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - GoogleSheetUpdateMany',
type: 'object',
required: ['update', 'filter'],
properties: {
filter: {
type: 'object',
description:
'A MongoDB query expression to filter the data. All rows matched by the filter will be updated.',
errorMessage: {
type: 'GoogleSheetUpdateMany request property "filter" should be an object.',
},
},
update: {
type: 'object',
description:
'The update to apply to the row. An object where keys are the column names and values are the updated values.',
errorMessage: {
type: 'GoogleSheetUpdateMany request property "update" should be an object.',
},
},
options: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'The maximum number of rows to fetch.',
errorMessage: {
type: 'GoogleSheetUpdateMany request property "options.limit" should be a number.',
},
},
raw: {
type: 'boolean',
description: 'Store raw values instead of converting as if typed into the sheets UI.',
errorMessage: {
type: 'GoogleSheetUpdateMany request property "options.raw" should be a boolean.',
},
},
skip: {
type: 'number',
description: 'The number of rows to skip from the top of the sheet.',
errorMessage: {
type: 'GoogleSheetUpdateMany request property "options.skip" should be a number.',
},
},
},
},
},
errorMessage: {
type: 'GoogleSheetUpdateMany request properties should be an object.',
required: {
filter: 'GoogleSheetUpdateMany request should have required property "filter".',
update: 'GoogleSheetUpdateMany request should have required property "update".',
},
},
};

View File

@ -18,8 +18,9 @@ import cleanRows from '../cleanRows.js';
import getSheet from '../getSheet.js';
import { transformRead, transformWrite } from '../transformTypes.js';
import mingoFilter from '../mingoFilter.js';
import schema from './schema.js';
async function googleSheetUpdateOne({ request, connection }) {
async function GoogleSheetUpdateOne({ request, connection }) {
const { filter, update, options = {} } = request;
const { limit, skip, upsert, raw } = options;
const sheet = await getSheet({ connection });
@ -51,4 +52,10 @@ async function googleSheetUpdateOne({ request, connection }) {
};
}
export default googleSheetUpdateOne;
GoogleSheetUpdateOne.schema = schema;
GoogleSheetUpdateOne.meta = {
checkRead: false,
checkWrite: true,
};
export default GoogleSheetUpdateOne;

View File

@ -15,11 +15,10 @@
*/
import { validate } from '@lowdefy/ajv';
import googleSheetUpdateOne from './GoogleSheetUpdateOne';
import requestIndex from './index.js';
import schema from './GoogleSheetUpdateOneSchema.json';
import GoogleSheetUpdateOne from './GoogleSheetUpdateOne.js';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = GoogleSheetUpdateOne.meta;
const schema = GoogleSheetUpdateOne.schema;
const mockGetRows = jest.fn();
const mockAddRow = jest.fn();
@ -83,7 +82,7 @@ const mockGetRowsDefaultImp = ({ limit, offset }) => {
test('googleSheetUpdateOne, match one', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateOne({
const res = await GoogleSheetUpdateOne({
request: {
filter: { id: '1' },
update: {
@ -119,7 +118,7 @@ test('googleSheetUpdateOne, match one', async () => {
test('googleSheetUpdateOne, match one, raw true', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateOne({
const res = await GoogleSheetUpdateOne({
request: {
filter: { id: '1' },
update: {
@ -158,7 +157,7 @@ test('googleSheetUpdateOne, match one, raw true', async () => {
test('googleSheetUpdateOne, match nothing', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateOne({
const res = await GoogleSheetUpdateOne({
request: {
filter: { id: 'does_not_exist' },
update: {
@ -177,7 +176,7 @@ test('googleSheetUpdateOne, match nothing', async () => {
test('googleSheetUpdateOne, match nothing, upsert true', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
mockAddRow.mockImplementation(mockAddRowDefaultImp);
const res = await googleSheetUpdateOne({
const res = await GoogleSheetUpdateOne({
request: {
filter: { id: 'does_not_exist' },
update: {
@ -212,7 +211,7 @@ test('googleSheetUpdateOne, match nothing, upsert true', async () => {
test('googleSheetUpdateOne, match more than one', async () => {
mockGetRows.mockImplementation(mockGetRowsDefaultImp);
const res = await googleSheetUpdateOne({
const res = await GoogleSheetUpdateOne({
request: {
filter: { _rowNumber: { $gt: 3 } },
update: {

View File

@ -1,62 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - GoogleSheetUpdateOne",
"type": "object",
"required": ["update", "filter"],
"properties": {
"filter": {
"type": "object",
"description": "A MongoDB query expression to filter the data. The first row matched by the filter will be updated.",
"errorMessage": {
"type": "GoogleSheetUpdateOne request property \"filter\" should be an object."
}
},
"update": {
"type": "object",
"description": "The update to apply to the row. An object where keys are the column names and values are the updated values.",
"errorMessage": {
"type": "GoogleSheetUpdateOne request property \"update\" should be an object."
}
},
"options": {
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "The maximum number of rows to fetch.",
"errorMessage": {
"type": "GoogleSheetUpdateOne request property \"options.limit\" should be a number."
}
},
"raw": {
"type": "boolean",
"description": "Store raw values instead of converting as if typed into the sheets UI.",
"errorMessage": {
"type": "GoogleSheetUpdateOne request property \"options.raw\" should be a boolean."
}
},
"skip": {
"type": "number",
"description": "The number of rows to skip from the top of the sheet.",
"errorMessage": {
"type": "GoogleSheetUpdateOne request property \"options.skip\" should be a number."
}
},
"upsert": {
"type": "boolean",
"description": "Insert the row if no rows are matched by the filter.",
"errorMessage": {
"type": "GoogleSheetUpdateOne request property \"options.upsert\" should be a boolean."
}
}
}
}
},
"errorMessage": {
"type": "GoogleSheetUpdateOne request properties should be an object.",
"required": {
"filter": "GoogleSheetUpdateOne request should have required property \"filter\".",
"update": "GoogleSheetUpdateOne request should have required property \"update\"."
}
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/GoogleSheet/GoogleSheetUpdateOne/GoogleSheetUpdateOne.js',
schema: 'connections/GoogleSheet/GoogleSheetUpdateOne/GoogleSheetUpdateOneSchema.json',
},
meta: {
checkRead: false,
checkWrite: true,
},
};

View File

@ -0,0 +1,80 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - GoogleSheetUpdateOne',
type: 'object',
required: ['update', 'filter'],
properties: {
filter: {
type: 'object',
description:
'A MongoDB query expression to filter the data. The first row matched by the filter will be updated.',
errorMessage: {
type: 'GoogleSheetUpdateOne request property "filter" should be an object.',
},
},
update: {
type: 'object',
description:
'The update to apply to the row. An object where keys are the column names and values are the updated values.',
errorMessage: {
type: 'GoogleSheetUpdateOne request property "update" should be an object.',
},
},
options: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'The maximum number of rows to fetch.',
errorMessage: {
type: 'GoogleSheetUpdateOne request property "options.limit" should be a number.',
},
},
raw: {
type: 'boolean',
description: 'Store raw values instead of converting as if typed into the sheets UI.',
errorMessage: {
type: 'GoogleSheetUpdateOne request property "options.raw" should be a boolean.',
},
},
skip: {
type: 'number',
description: 'The number of rows to skip from the top of the sheet.',
errorMessage: {
type: 'GoogleSheetUpdateOne request property "options.skip" should be a number.',
},
},
upsert: {
type: 'boolean',
description: 'Insert the row if no rows are matched by the filter.',
errorMessage: {
type: 'GoogleSheetUpdateOne request property "options.upsert" should be a boolean.',
},
},
},
},
},
errorMessage: {
type: 'GoogleSheetUpdateOne request properties should be an object.',
required: {
filter: 'GoogleSheetUpdateOne request should have required property "filter".',
update: 'GoogleSheetUpdateOne request should have required property "update".',
},
},
};

View File

@ -14,7 +14,7 @@
limitations under the License.
*/
import cleanRows from './cleanRows';
import cleanRows from './cleanRows.js';
test('cleanRows removes objects with key _sheet from an array of rows', () => {
expect(

View File

@ -17,7 +17,7 @@
import { wait } from '@lowdefy/helpers';
// eslint-disable-next-line no-unused-vars
import { GoogleSpreadsheet } from 'google-spreadsheet';
import getSheet from './getSheet';
import getSheet from './getSheet.js';
// Not testing if spreadsheetId is given to GoogleSpreadsheet class in
// const doc = new GoogleSpreadsheet(spreadsheetId);

View File

@ -16,18 +16,22 @@
import { type } from '@lowdefy/helpers';
import mingo from 'mingo';
import { useOperators, OperatorType } from 'mingo/core';
import * as accumulatorOperators from 'mingo/operators/accumulator';
import * as expressionOperators from 'mingo/operators/expression';
import * as pipelineOperators from 'mingo/operators/pipeline';
import * as queryOperators from 'mingo/operators/query';
import * as projectionOperators from 'mingo/operators/projection';
import { useOperators, OperatorType } from 'mingo/core.js';
import * as accumulatorOperators from 'mingo/operators/accumulator/index.js';
import * as expressionOperators from 'mingo/operators/expression/index.js';
import * as pipelineOperators from 'mingo/operators/pipeline/index.js';
import * as queryOperators from 'mingo/operators/query/index.js';
import * as projectionOperators from 'mingo/operators/projection/index.js';
useOperators(OperatorType.ACCUMULATOR, accumulatorOperators);
useOperators(OperatorType.EXPRESSION, expressionOperators);
useOperators(OperatorType.PIPELINE, pipelineOperators);
useOperators(OperatorType.PROJECTION, queryOperators);
useOperators(OperatorType.QUERY, projectionOperators);
// "import * as" is returning different object structures when the connection is being
// imported in the build or when running the tests.
// So we check for the a default object with all the named exports, otherwise the
// returned object has all the named exports.
useOperators(OperatorType.ACCUMULATOR, accumulatorOperators.default || accumulatorOperators);
useOperators(OperatorType.EXPRESSION, expressionOperators.default || expressionOperators);
useOperators(OperatorType.PIPELINE, pipelineOperators.default || pipelineOperators);
useOperators(OperatorType.QUERY, queryOperators.default || queryOperators);
useOperators(OperatorType.PROJECTION, projectionOperators.default || projectionOperators);
function mingoAggregation({ input = [], pipeline = [] }) {
if (!type.isArray(input)) {

View File

@ -14,7 +14,7 @@
limitations under the License.
*/
import mingoAggregation from './mingoAggregation';
import mingoAggregation from './mingoAggregation.js';
test('mingoAggregation sort', () => {
const pipeline = [

View File

@ -15,7 +15,7 @@
*/
import { type } from '@lowdefy/helpers';
import mingoAggregation from './mingoAggregation';
import mingoAggregation from './mingoAggregation.js';
function mingoFilter({ input = [], filter = {} }) {
if (!type.isObject(filter)) {

View File

@ -14,7 +14,7 @@
limitations under the License.
*/
import mingoFilter from './mingoFilter';
import mingoFilter from './mingoFilter.js';
test('mingoFilter equals shorthand', () => {
const filter = { id: 1 };

View File

@ -0,0 +1,106 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Connection Schema - GoogleSheet',
type: 'object',
required: ['spreadsheetId'],
properties: {
apiKey: {
type: 'string',
description: 'API key for your google project.',
errorMessage: {
type: 'GoogleSheet connection property "apiKey" should be a string.',
},
},
client_email: {
type: 'string',
description: 'The email of your service account.',
errorMessage: {
type: 'GoogleSheet connection property "client_email" should be a string.',
},
},
private_key: {
type: 'string',
description: 'The private key for your service account.',
errorMessage: {
type: 'GoogleSheet connection property "private_key" should be a string.',
},
},
sheetId: {
type: 'string',
description:
'The ID of the worksheet. Can be found in the URL as the "gid" parameter. One of "sheetId" or "sheetIndex" is required.',
errorMessage: {
type: 'GoogleSheet connection property "sheetId" should be a string.',
},
},
sheetIndex: {
type: 'number',
description:
'The position of the worksheet as they appear in the Google sheets UI. Starts from 0. One of "sheetId" or "sheetIndex" is required.',
errorMessage: {
type: 'GoogleSheet connection property "sheetIndex" should be a number.',
},
},
spreadsheetId: {
type: 'string',
description: 'document ID from the URL of the spreadsheet.',
errorMessage: {
type: 'GoogleSheet connection property "spreadsheetId" should be a string.',
},
},
columnTypes: {
type: 'object',
description: 'Define types for columns in the spreadsheet.',
patternProperties: {
'^.*$': {
type: 'string',
enum: ['string', 'number', 'boolean', 'date', 'json'],
errorMessage: {
enum: 'GoogleSheet connection property "{{ instancePath }}" should be one of "string", "number", "boolean", "date", or "json".',
},
},
},
errorMessage: {
type: 'GoogleSheet connection property "columnTypes" should be an object.',
},
},
read: {
type: 'boolean',
default: true,
description: 'Allow reads from the spreadsheet.',
errorMessage: {
type: 'GoogleSheet connection property "read" should be a boolean.',
},
},
write: {
type: 'boolean',
default: false,
description: 'Allow writes to the spreadsheet.',
errorMessage: {
type: 'GoogleSheet connection property "write" should be a boolean.',
},
},
},
errorMessage: {
type: 'GoogleSheet connection properties should be an object.',
required: {
spreadsheetId: 'GoogleSheet connection should have required property "spreadsheetId".',
},
},
};

View File

@ -14,7 +14,7 @@
limitations under the License.
*/
import { transformRead } from './transformTypes';
import { transformRead } from './transformTypes.js';
test('transformRead invalid input', () => {
expect(() => transformRead({ input: 1 })).toThrow(

View File

@ -14,7 +14,7 @@
limitations under the License.
*/
import { transformWrite } from './transformTypes';
import { transformWrite } from './transformTypes.js';
test('transformWrite invalid input', () => {
expect(() => transformWrite({ input: 1 })).toThrow(

View File

@ -1,7 +0,0 @@
import GoogleSheet from './connections/GoogleSheet/GoogleSheet.js';
export const connections = {
GoogleSheet,
};
export default { connections };

View File

@ -1,3 +1,4 @@
/* eslint-disable import/namespace */
/*
Copyright 2020-2021 Lowdefy, Inc
@ -14,13 +15,24 @@
limitations under the License.
*/
import * as connections from './connections.js';
export default {
import: {
path: 'connections/GoogleSheet/GoogleSheetAppendOneSchema/GoogleSheetAppendOne.js',
schema: 'connections/GoogleSheet/GoogleSheetAppendOneSchema/GoogleSheetAppendOneSchema.json',
},
meta: {
checkRead: false,
checkWrite: true,
},
connections: Object.keys(connections),
requests: Object.keys(connections)
.map((connection) => Object.keys(connections[connection].requests))
.flat(),
};
// export default {
// connections: ['GoogleSheet'],
// requests: [
// GoogleSheetAppendMany,
// GoogleSheetAppendOne,
// GoogleSheetDeleteOne,
// GoogleSheetGetMany,
// GoogleSheetGetOne,
// GoogleSheetUpdateOne,
// GoogleSheetUpdateMany,
// ],
// };

View File

@ -27,8 +27,8 @@
},
"type": "module",
"exports": {
".": "./dist/index.js",
"./connections/*": "./dist/connections/*"
"./connections": "./dist/connections.js",
"./types": "./dist/types.js"
},
"files": [
"dist/*"

View File

@ -14,13 +14,4 @@
limitations under the License.
*/
export default {
import: {
path: 'connections/Knex/KnexBuilder/KnexBuilder.js',
schema: 'connections/Knex/KnexBuilder/KnexBuilderSchema.json',
},
meta: {
checkRead: false,
checkWrite: false,
},
};
export { default as Knex } from './connections/Knex/Knex.js';

View File

@ -17,10 +17,10 @@
import KnexBuilder from './KnexBuilder/KnexBuilder.js';
import KnexRaw from './KnexRaw/KnexRaw.js';
import schema from './schema.js';
export default {
import: {
schema: 'connections/Knex/KnexSchema.json',
},
schema,
requests: {
KnexBuilder,
KnexRaw,

View File

@ -16,7 +16,8 @@
import { validate } from '@lowdefy/ajv';
import Knex from './Knex.js';
import schema from './KnexSchema.json';
const schema = Knex.schema;
test('All requests are present', () => {
expect(Knex.requests.KnexRaw).toBeDefined();

View File

@ -16,8 +16,9 @@
import knex from 'knex';
import { type } from '@lowdefy/helpers';
import schema from './schema.js';
async function knexBuilder({ request, connection }) {
async function KnexBuilder({ request, connection }) {
let client = knex(connection);
if (request.tableName) {
client = client(request.tableName);
@ -47,4 +48,10 @@ async function knexBuilder({ request, connection }) {
return client;
}
export default knexBuilder;
KnexBuilder.schema = schema;
KnexBuilder.meta = {
checkRead: false,
checkWrite: false,
};
export default KnexBuilder;

View File

@ -16,8 +16,10 @@
import { validate } from '@lowdefy/ajv';
import knex from 'knex';
import knexBuilder from './KnexBuilder.js';
import schema from './KnexBuilderSchema.json';
import KnexBuilder from './KnexBuilder.js';
const { checkRead, checkWrite } = KnexBuilder.meta;
const schema = KnexBuilder.schema;
const mockKnexClient = jest.fn(() => mockKnexClient);
@ -44,7 +46,7 @@ test('KnexBuilder with tableName', async () => {
query: [{ select: ['*'] }, { where: ['name', 'steve'] }],
tableName: 'table',
};
const res = await knexBuilder({ request, connection });
const res = await KnexBuilder({ request, connection });
expect(knex.mock.calls).toEqual([
[
{
@ -74,7 +76,7 @@ test('KnexBuilder', async () => {
const request = {
query: [{ select: ['*'] }, { from: ['table'] }, { where: ['name', 'steve'] }],
};
const res = await knexBuilder({ request, connection });
const res = await KnexBuilder({ request, connection });
expect(knex.mock.calls).toEqual([
[
{
@ -97,7 +99,7 @@ test('KnexBuilder, invalid method', async () => {
const request = {
query: [{ invalid: ['*'] }],
};
await expect(knexBuilder({ request, connection })).rejects.toThrow(
await expect(KnexBuilder({ request, connection })).rejects.toThrow(
'Invalid query builder method "invalid".'
);
});
@ -106,7 +108,7 @@ test('KnexBuilder, more than one method', async () => {
const request = {
query: [{ select: ['*'], where: ['name', 'steve'] }],
};
await expect(knexBuilder({ request, connection })).rejects.toThrow(
await expect(KnexBuilder({ request, connection })).rejects.toThrow(
'Invalid query, more than one method defined in a method object, received ["select","where"].'
);
});
@ -115,7 +117,7 @@ test('KnexBuilder, method args not an array', async () => {
const request = {
query: [{ select: '*' }],
};
await expect(knexBuilder({ request, connection })).rejects.toThrow(
await expect(KnexBuilder({ request, connection })).rejects.toThrow(
'Invalid query, method "select" arguments should be an array, received "*".'
);
});
@ -143,3 +145,11 @@ test('query missing', () => {
'KnexBuilder request should have required property "query".'
);
});
test('checkRead should be false', async () => {
expect(checkRead).toBe(false);
});
test('checkWrite should be false', async () => {
expect(checkWrite).toBe(false);
});

View File

@ -1,28 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - KnexBuilder",
"type": "object",
"required": ["query"],
"properties": {
"query": {
"type": "array",
"description": "SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.",
"errorMessage": {
"type": "KnexBuilder request property \"query\" should be an array."
}
},
"tableName": {
"type": ["string", "object"],
"description": "The name of the table to query from.",
"errorMessage": {
"type": "KnexBuilder request property \"tableName\" should be a string or object"
}
}
},
"errorMessage": {
"type": "KnexBuilder request properties should be an object.",
"required": {
"query": "KnexBuilder request should have required property \"query\"."
}
}
}

View File

@ -0,0 +1,45 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - KnexBuilder',
type: 'object',
required: ['query'],
properties: {
query: {
type: 'array',
description:
'SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.',
errorMessage: {
type: 'KnexBuilder request property "query" should be an array.',
},
},
tableName: {
type: ['string', 'object'],
description: 'The name of the table to query from.',
errorMessage: {
type: 'KnexBuilder request property "tableName" should be a string or object',
},
},
},
errorMessage: {
type: 'KnexBuilder request properties should be an object.',
required: {
query: 'KnexBuilder request should have required property "query".',
},
},
};

View File

@ -15,8 +15,9 @@
*/
import knex from 'knex';
import schema from './schema.js';
async function knexRaw({ request, connection }) {
async function KnexRaw({ request, connection }) {
const client = knex(connection);
const res = await client.raw(request.query, request.parameters);
Object.keys(res).forEach((key) => {
@ -27,4 +28,10 @@ async function knexRaw({ request, connection }) {
return res;
}
export default knexRaw;
KnexRaw.schema = schema;
KnexRaw.meta = {
checkRead: false,
checkWrite: false,
};
export default KnexRaw;

View File

@ -16,8 +16,10 @@
import { validate } from '@lowdefy/ajv';
import knex from 'knex';
import knexRaw from './KnexRaw.js';
import schema from './KnexRawSchema.json';
import KnexRaw from './KnexRaw.js';
const { checkRead, checkWrite } = KnexRaw.meta;
const schema = KnexRaw.schema;
const mockRaw = jest.fn(() => {
return Promise.resolve({ rows: [{ name: 'name' }], _types: 'types' });
@ -39,7 +41,7 @@ const connection = {
};
test('knexRaw', async () => {
const res = await knexRaw({ request, connection });
const res = await KnexRaw({ request, connection });
expect(knex.mock.calls).toEqual([
[
{
@ -88,3 +90,11 @@ test('query missing', () => {
'KnexRaw request should have required property "query".'
);
});
test('checkRead should be false', async () => {
expect(checkRead).toBe(false);
});
test('checkWrite should be false', async () => {
expect(checkWrite).toBe(false);
});

View File

@ -1,28 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - KnexRaw",
"type": "object",
"required": ["query"],
"properties": {
"query": {
"type": "string",
"description": "SQL query string.",
"errorMessage": {
"type": "KnexRaw request property \"query\" should be a string."
}
},
"parameters": {
"type": ["string","number", "array", "object"],
"description": "SQL query parameters.",
"errorMessage": {
"type": "KnexRaw request property \"parameters\" should be a string, number, array, or object."
}
}
},
"errorMessage": {
"type": "KnexRaw request properties should be an object.",
"required": {
"query": "KnexRaw request should have required property \"query\"."
}
}
}

View File

@ -0,0 +1,44 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - KnexRaw',
type: 'object',
required: ['query'],
properties: {
query: {
type: 'string',
description: 'SQL query string.',
errorMessage: {
type: 'KnexRaw request property "query" should be a string.',
},
},
parameters: {
type: ['string', 'number', 'array', 'object'],
description: 'SQL query parameters.',
errorMessage: {
type: 'KnexRaw request property "parameters" should be a string, number, array, or object.',
},
},
},
errorMessage: {
type: 'KnexRaw request properties should be an object.',
required: {
query: 'KnexRaw request should have required property "query".',
},
},
};

View File

@ -1,43 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Connection Schema - Knex",
"type": "object",
"required": ["client", "connection"],
"properties": {
"client": {
"type": "string",
"description": "SQL query string.",
"errorMessage": {
"type": "Knex connection property \"client\" should be a string."
}
},
"connection": {
"type": ["string", "object"],
"description": "SQL query string.",
"errorMessage": {
"type": "Knex connection property \"connection\" should be a string or object."
}
},
"searchPath": {
"type": "string",
"description": "Set PostgreSQL search path.",
"errorMessage": {
"type": "Knex connection property \"searchPath\" should be a string."
}
},
"version": {
"type": "string",
"description": "Set database version.",
"errorMessage": {
"type": "Knex connection property \"version\" should be a string."
}
}
},
"errorMessage": {
"type": "Knex connection properties should be an object.",
"required": {
"client": "Knex connection should have required property \"client\".",
"connection": "Knex connection should have required property \"connection\"."
}
}
}

View File

@ -0,0 +1,59 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Connection Schema - Knex',
type: 'object',
required: ['client', 'connection'],
properties: {
client: {
type: 'string',
description: 'SQL query string.',
errorMessage: {
type: 'Knex connection property "client" should be a string.',
},
},
connection: {
type: ['string', 'object'],
description: 'SQL query string.',
errorMessage: {
type: 'Knex connection property "connection" should be a string or object.',
},
},
searchPath: {
type: 'string',
description: 'Set PostgreSQL search path.',
errorMessage: {
type: 'Knex connection property "searchPath" should be a string.',
},
},
version: {
type: 'string',
description: 'Set database version.',
errorMessage: {
type: 'Knex connection property "version" should be a string.',
},
},
},
errorMessage: {
type: 'Knex connection properties should be an object.',
required: {
client: 'Knex connection should have required property "client".',
connection: 'Knex connection should have required property "connection".',
},
},
};

View File

@ -1,7 +0,0 @@
import Knex from './connections/Knex/Knex.js';
export const connections = {
Knex,
};
export default { connections };

View File

@ -1,3 +1,4 @@
/* eslint-disable import/namespace */
/*
Copyright 2020-2021 Lowdefy, Inc
@ -13,14 +14,16 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
import * as connections from './connections.js';
export default {
import: {
path: 'connections/GoogleSheet/GoogleSheetAppendMany/GoogleSheetAppendMany.js',
schema: 'connections/GoogleSheet/GoogleSheetAppendMany/GoogleSheetAppendManySchema.json',
},
meta: {
checkRead: false,
checkWrite: true,
},
connections: Object.keys(connections),
requests: Object.keys(connections)
.map((connection) => Object.keys(connections[connection].requests))
.flat(),
};
// export default {
// connections: ['Knex'],
// requests: ['KnexBuilder', 'KnexRaw'],
// };

View File

@ -27,8 +27,8 @@
},
"type": "module",
"exports": {
".": "./dist/index.js",
"./connections/*": "./dist/connections/*"
"./connections": "./dist/connections.js",
"./types": "./dist/types.js"
},
"files": [
"dist/*"

View File

@ -14,13 +14,4 @@
limitations under the License.
*/
export default {
import: {
path: 'connections/Stripe/StripeRequest/StripeRequest.js',
schema: 'connections/Stripe/StripeRequest/StripeRequestSchema.json',
},
meta: {
checkRead: false,
checkWrite: false,
},
};
export { default as MongoDBCollection } from './connections/MongoDBCollection/MongoDBCollection.js';

View File

@ -16,6 +16,7 @@
import getCollection from '../getCollection.js';
import { serialize, deserialize } from '../serialize.js';
import schema from './schema.js';
function checkOutAndMerge({ pipeline, connection }) {
if (connection.write !== true) {
@ -29,7 +30,7 @@ function checkOutAndMerge({ pipeline, connection }) {
}
}
async function mongodbAggregation({ request, connection }) {
async function MongodbAggregation({ request, connection }) {
const deserializedRequest = deserialize(request);
const { pipeline, options } = deserializedRequest;
checkOutAndMerge({ pipeline, connection });
@ -46,4 +47,10 @@ async function mongodbAggregation({ request, connection }) {
return serialize(res);
}
export default mongodbAggregation;
MongodbAggregation.schema = schema;
MongodbAggregation.meta = {
checkRead: true,
checkWrite: false,
};
export default MongodbAggregation;

View File

@ -15,12 +15,11 @@
*/
import { validate } from '@lowdefy/ajv';
import mongoDBAggregation from './MongoDBAggregation.js';
import MongoDBAggregation from './MongoDBAggregation.js';
import populateTestMongoDb from '../../../../test/populateTestMongoDb.js';
import requestIndex from './index.js';
import schema from './MongoDBAggregationSchema.json';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = MongoDBAggregation.meta;
const schema = MongoDBAggregation.schema;
const pipeline = [
{
@ -52,7 +51,7 @@ test('aggregation', async () => {
collection,
read: true,
};
const res = await mongoDBAggregation({ request, connection });
const res = await MongoDBAggregation({ request, connection });
expect(res).toEqual([
{
_id: 1,
@ -69,7 +68,7 @@ test('aggregation connection error', async () => {
collection,
read: true,
};
await expect(mongoDBAggregation({ request, connection })).rejects.toThrow(
await expect(MongoDBAggregation({ request, connection })).rejects.toThrow(
'Invalid connection string'
);
});
@ -82,7 +81,7 @@ test('aggregation mongodb error', async () => {
collection,
read: true,
};
await expect(mongoDBAggregation({ request, connection })).rejects.toThrow(
await expect(MongoDBAggregation({ request, connection })).rejects.toThrow(
"Unrecognized pipeline stage name: '$badStage'"
);
});
@ -111,7 +110,7 @@ test('aggregation match dates', async () => {
collection,
read: true,
};
const res = await mongoDBAggregation({ request, connection });
const res = await MongoDBAggregation({ request, connection });
expect(res).toEqual([
{
_id: 2,
@ -159,7 +158,7 @@ test('$out is not allowed with write undefined', async () => {
databaseName,
collection,
};
await expect(mongoDBAggregation({ request, connection })).rejects.toThrow(
await expect(MongoDBAggregation({ request, connection })).rejects.toThrow(
'Connection does not allow writes and aggregation pipeline contains a "$merge" or "$out" stage.'
);
});
@ -172,7 +171,7 @@ test('$out is not allowed with write false', async () => {
collection,
write: false,
};
await expect(mongoDBAggregation({ request, connection })).rejects.toThrow(
await expect(MongoDBAggregation({ request, connection })).rejects.toThrow(
'Connection does not allow writes and aggregation pipeline contains a "$merge" or "$out" stage.'
);
});
@ -185,7 +184,7 @@ test('$out is allowed with write true', async () => {
collection,
write: true,
};
const res = await mongoDBAggregation({ request, connection });
const res = await MongoDBAggregation({ request, connection });
expect(res).toEqual([]);
});
@ -196,7 +195,7 @@ test('$merge is not allowed with write undefined', async () => {
databaseName,
collection,
};
await expect(mongoDBAggregation({ request, connection })).rejects.toThrow(
await expect(MongoDBAggregation({ request, connection })).rejects.toThrow(
'Connection does not allow writes and aggregation pipeline contains a "$merge" or "$out" stage.'
);
});
@ -209,7 +208,7 @@ test('$merge is not allowed with write false', async () => {
collection,
write: false,
};
await expect(mongoDBAggregation({ request, connection })).rejects.toThrow(
await expect(MongoDBAggregation({ request, connection })).rejects.toThrow(
'Connection does not allow writes and aggregation pipeline contains a "$merge" or "$out" stage.'
);
});

View File

@ -1,26 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - MongoDBAggregation",
"type": "object",
"required": ["pipeline"],
"properties": {
"pipeline": {
"type": "array",
"description": "Array containing all the aggregation framework commands for the execution.",
"errorMessage": {
"type": "MongoDBAggregation request property \"pipeline\" should be an array."
}
},
"options": {
"type": "object",
"description": "Optional settings.",
"errorMessage": {
"type": "MongoDBAggregation request property \"options\" should be an object."
}
}
},
"errorMessage": {
"type": "MongoDBAggregation request properties should be an object.",
"required": "MongoDBAggregation request should have required property \"pipeline\"."
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/MongoDBCollection/MongoDBAggregation/MongoDBAggregation.js',
schema: 'connections/MongoDBCollection/MongoDBAggregation/MongoDBAggregationSchema.json',
},
meta: {
checkRead: true,
checkWrite: false,
},
};

View File

@ -0,0 +1,42 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - MongoDBAggregation',
type: 'object',
required: ['pipeline'],
properties: {
pipeline: {
type: 'array',
description: 'Array containing all the aggregation framework commands for the execution.',
errorMessage: {
type: 'MongoDBAggregation request property "pipeline" should be an array.',
},
},
options: {
type: 'object',
description: 'Optional settings.',
errorMessage: {
type: 'MongoDBAggregation request property "options" should be an object.',
},
},
},
errorMessage: {
type: 'MongoDBAggregation request properties should be an object.',
required: 'MongoDBAggregation request should have required property "pipeline".',
},
};

View File

@ -23,11 +23,10 @@ import MongoDBInsertMany from './MongoDBInsertMany/MongoDBInsertMany.js';
import MongoDBInsertOne from './MongoDBInsertOne/MongoDBInsertOne.js';
import MongoDBUpdateMany from './MongoDBUpdateMany/MongoDBUpdateMany.js';
import MongoDBUpdateOne from './MongoDBUpdateOne/MongoDBUpdateOne.js';
import schema from './schema.js';
export default {
import: {
schema: 'connections/MongoDBCollection/MongoDBCollectionSchema.json',
},
schema,
requests: {
MongoDBAggregation,
MongoDBDeleteMany,

View File

@ -16,7 +16,8 @@
import { validate } from '@lowdefy/ajv';
import MongoDBCollection from './MongoDBCollection.js';
import schema from './MongoDBCollectionSchema.json';
const schema = MongoDBCollection.schema;
test('All requests are present', () => {
expect(MongoDBCollection.requests.MongoDBAggregation).toBeDefined();

View File

@ -1,52 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Connection Schema - MongoDBCollection",
"type": "object",
"required": ["databaseUri", "collection"],
"properties": {
"databaseUri": {
"type": "string",
"description": "Connection uri string for the MongoDb deployment.",
"errorMessage": {
"type": "MongoDBCollection connection property \"databaseUri\" should be a string."
}
},
"databaseName": {
"type": "string",
"description": "AWS IAM secret access key with s3 access.",
"errorMessage": {
"type": "MongoDBCollection connection property \"databaseName\" should be a string."
}
},
"collection": {
"type": "string",
"description": "AWS region the bucket is located in.",
"errorMessage": {
"type": "MongoDBCollection connection property \"collection\" should be a string."
}
},
"read": {
"type": "boolean",
"default": true,
"description": "Allow reads from the collection.",
"errorMessage": {
"type": "MongoDBCollection connection property \"read\" should be a boolean."
}
},
"write": {
"type": "boolean",
"default": false,
"description": "Allow writes to the collection.",
"errorMessage": {
"type": "MongoDBCollection connection property \"write\" should be a boolean."
}
}
},
"errorMessage": {
"type": "MongoDBCollection connection properties should be an object.",
"required": {
"databaseUri": "MongoDBCollection connection should have required property \"databaseUri\".",
"collection": "MongoDBCollection connection should have required property \"collection\"."
}
}
}

View File

@ -16,8 +16,9 @@
import getCollection from '../getCollection.js';
import { serialize, deserialize } from '../serialize.js';
import schema from './schema.js';
async function mongodbDeleteMany({ request, connection }) {
async function MongodbDeleteMany({ request, connection }) {
const deserializedRequest = deserialize(request);
const { filter, options } = deserializedRequest;
const { collection, client } = await getCollection({ connection });
@ -33,4 +34,10 @@ async function mongodbDeleteMany({ request, connection }) {
return { deletedCount };
}
export default mongodbDeleteMany;
MongodbDeleteMany.schema = schema;
MongodbDeleteMany.meta = {
checkRead: false,
checkWrite: true,
};
export default MongodbDeleteMany;

View File

@ -15,12 +15,11 @@
*/
import { validate } from '@lowdefy/ajv';
import mongoDBDeleteMany from './MongoDBDeleteMany.js';
import MongoDBDeleteMany from './MongoDBDeleteMany.js';
import populateTestMongoDb from '../../../../test/populateTestMongoDb.js';
import requestIndex from './index.js';
import schema from './MongoDBDeleteManySchema.json';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = MongoDBDeleteMany.meta;
const schema = MongoDBDeleteMany.schema;
const databaseUri = process.env.MONGO_URL;
const databaseName = 'test';
@ -49,7 +48,7 @@ test('deleteMany - Single Document', async () => {
collection,
write: true,
};
const res = await mongoDBDeleteMany({ request, connection });
const res = await MongoDBDeleteMany({ request, connection });
expect(res).toEqual({
deletedCount: 1,
});
@ -65,7 +64,7 @@ test('deleteMany - Multiple Documents', async () => {
collection,
write: true,
};
const res = await mongoDBDeleteMany({ request, connection });
const res = await MongoDBDeleteMany({ request, connection });
expect(res).toEqual({
deletedCount: 3,
});
@ -81,7 +80,7 @@ test('deleteMany - Multiple Documents one field', async () => {
collection,
write: true,
};
const res = await mongoDBDeleteMany({ request, connection });
const res = await MongoDBDeleteMany({ request, connection });
expect(res).toEqual({
deletedCount: 3,
});
@ -97,7 +96,7 @@ test('deleteMany connection error', async () => {
collection,
write: true,
};
await expect(mongoDBDeleteMany({ request, connection })).rejects.toThrow(
await expect(MongoDBDeleteMany({ request, connection })).rejects.toThrow(
'Invalid connection string'
);
});
@ -113,7 +112,7 @@ test('deleteMany mongodb error', async () => {
collection,
write: true,
};
await expect(mongoDBDeleteMany({ request, connection })).rejects.toThrow(
await expect(MongoDBDeleteMany({ request, connection })).rejects.toThrow(
'w has to be a number or a string'
);
});

View File

@ -1,26 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - MongoDBDeleteMany",
"type": "object",
"required": ["filter"],
"properties": {
"filter": {
"type": "object",
"description": "The filter used to select the document to update.",
"errorMessage": {
"type": "MongoDBDeleteMany request property \"filter\" should be an object."
}
},
"options": {
"type": "object",
"description": "Optional settings.",
"errorMessage": {
"type": "MongoDBDeleteMany request property \"options\" should be an object."
}
}
},
"errorMessage": {
"type": "MongoDBDeleteMany request properties should be an object.",
"required": "MongoDBDeleteMany request should have required property \"filter\"."
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/MongoDBCollection/MongoDBDeleteMany/MongoDBDeleteMany.js',
schema: 'connections/MongoDBCollection/MongoDBDeleteMany/MongoDBDeleteManySchema.json',
},
meta: {
checkRead: false,
checkWrite: true,
},
};

View File

@ -0,0 +1,42 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - MongoDBDeleteMany',
type: 'object',
required: ['filter'],
properties: {
filter: {
type: 'object',
description: 'The filter used to select the document to update.',
errorMessage: {
type: 'MongoDBDeleteMany request property "filter" should be an object.',
},
},
options: {
type: 'object',
description: 'Optional settings.',
errorMessage: {
type: 'MongoDBDeleteMany request property "options" should be an object.',
},
},
},
errorMessage: {
type: 'MongoDBDeleteMany request properties should be an object.',
required: 'MongoDBDeleteMany request should have required property "filter".',
},
};

View File

@ -16,8 +16,9 @@
import getCollection from '../getCollection.js';
import { serialize, deserialize } from '../serialize.js';
import schema from './schema.js';
async function mongodbDeleteOne({ request, connection }) {
async function MongodbDeleteOne({ request, connection }) {
const deserializedRequest = deserialize(request);
const { filter, options } = deserializedRequest;
const { collection, client } = await getCollection({ connection });
@ -33,4 +34,10 @@ async function mongodbDeleteOne({ request, connection }) {
return { deletedCount };
}
export default mongodbDeleteOne;
MongodbDeleteOne.schema = schema;
MongodbDeleteOne.meta = {
checkRead: false,
checkWrite: true,
};
export default MongodbDeleteOne;

View File

@ -15,12 +15,11 @@
*/
import { validate } from '@lowdefy/ajv';
import mongoDBDeleteOne from './MongoDBDeleteOne.js';
import MongoDBDeleteOne from './MongoDBDeleteOne.js';
import populateTestMongoDb from '../../../../test/populateTestMongoDb.js';
import requestIndex from './index.js';
import schema from './MongoDBDeleteOneSchema.json';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = MongoDBDeleteOne.meta;
const schema = MongoDBDeleteOne.schema;
const databaseUri = process.env.MONGO_URL;
const databaseName = 'test';
@ -41,7 +40,7 @@ test('deleteOne', async () => {
collection,
write: true,
};
const res = await mongoDBDeleteOne({ request, connection });
const res = await MongoDBDeleteOne({ request, connection });
expect(res).toEqual({
deletedCount: 1,
});
@ -57,7 +56,7 @@ test('deleteOne connection error', async () => {
collection,
write: true,
};
await expect(mongoDBDeleteOne({ request, connection })).rejects.toThrow(
await expect(MongoDBDeleteOne({ request, connection })).rejects.toThrow(
'Invalid connection string'
);
});
@ -81,7 +80,7 @@ test('deleteOne catch invalid options', async () => {
collection,
write: true,
};
await expect(mongoDBDeleteOne({ request, connection })).rejects.toThrow(
await expect(MongoDBDeleteOne({ request, connection })).rejects.toThrow(
'w has to be a number or a string'
);
});

View File

@ -1,26 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - MongoDBDeleteOne",
"type": "object",
"required": ["filter"],
"properties": {
"filter": {
"type": "object",
"description": "The filter used to select the document to update.",
"errorMessage": {
"type": "MongoDBDeleteOne request property \"filter\" should be an object."
}
},
"options": {
"type": "object",
"description": "Optional settings.",
"errorMessage": {
"type": "MongoDBDeleteOne request property \"options\" should be an object."
}
}
},
"errorMessage": {
"type": "MongoDBDeleteOne request properties should be an object.",
"required": "MongoDBDeleteOne request should have required property \"filter\"."
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/MongoDBCollection/MongoDBDeleteOne/MongoDBDeleteOne.js',
schema: 'connections/MongoDBCollection/MongoDBDeleteOne/MongoDBDeleteOneSchema.json',
},
meta: {
checkRead: false,
checkWrite: true,
},
};

View File

@ -0,0 +1,42 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - MongoDBDeleteOne',
type: 'object',
required: ['filter'],
properties: {
filter: {
type: 'object',
description: 'The filter used to select the document to update.',
errorMessage: {
type: 'MongoDBDeleteOne request property "filter" should be an object.',
},
},
options: {
type: 'object',
description: 'Optional settings.',
errorMessage: {
type: 'MongoDBDeleteOne request property "options" should be an object.',
},
},
},
errorMessage: {
type: 'MongoDBDeleteOne request properties should be an object.',
required: 'MongoDBDeleteOne request should have required property "filter".',
},
};

View File

@ -16,8 +16,9 @@
import getCollection from '../getCollection.js';
import { serialize, deserialize } from '../serialize.js';
import schema from './schema.js';
async function mongodbFind({ request, connection }) {
async function MongodbFind({ request, connection }) {
const deserializedRequest = deserialize(request);
const { query, options } = deserializedRequest;
const { collection, client } = await getCollection({ connection });
@ -33,4 +34,10 @@ async function mongodbFind({ request, connection }) {
return serialize(res);
}
export default mongodbFind;
MongodbFind.schema = schema;
MongodbFind.meta = {
checkRead: true,
checkWrite: false,
};
export default MongodbFind;

View File

@ -15,12 +15,11 @@
*/
import { validate } from '@lowdefy/ajv';
import mongoDBFind from './MongoDBFind.js';
import MongoDBFind from './MongoDBFind.js';
import populateTestMongoDb from '../../../../test/populateTestMongoDb.js';
import requestIndex from './index.js';
import schema from './MongoDBFindSchema.json';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = MongoDBFind.meta;
const schema = MongoDBFind.schema;
const query = { _id: 1 };
@ -41,7 +40,7 @@ test('find', async () => {
collection,
read: true,
};
const res = await mongoDBFind({ request, connection });
const res = await MongoDBFind({ request, connection });
expect(res).toEqual([
{
_id: 1,
@ -60,7 +59,7 @@ test('find options', async () => {
collection,
read: true,
};
const res = await mongoDBFind({ request, connection });
const res = await MongoDBFind({ request, connection });
expect(res).toEqual([
{
_id: 2,
@ -76,7 +75,7 @@ test('find mongodb error', async () => {
collection,
read: true,
};
await expect(mongoDBFind({ request, connection })).rejects.toThrow('unknown operator: $badOp');
await expect(MongoDBFind({ request, connection })).rejects.toThrow('unknown operator: $badOp');
});
test('checkRead should be true', async () => {

View File

@ -1,26 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - MongoDBFind",
"type": "object",
"required": ["query"],
"properties": {
"query": {
"type": "object",
"description": "A MongoDB query object",
"errorMessage": {
"type": "MongoDBFind request property \"query\" should be an object."
}
},
"options": {
"type": "object",
"description": "Optional settings.",
"errorMessage": {
"type": "MongoDBFind request property \"options\" should be an object."
}
}
},
"errorMessage": {
"type": "MongoDBFind request properties should be an object.",
"required": "MongoDBFind request should have required property \"query\"."
}
}

View File

@ -0,0 +1,42 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - MongoDBFind',
type: 'object',
required: ['query'],
properties: {
query: {
type: 'object',
description: 'A MongoDB query object',
errorMessage: {
type: 'MongoDBFind request property "query" should be an object.',
},
},
options: {
type: 'object',
description: 'Optional settings.',
errorMessage: {
type: 'MongoDBFind request property "options" should be an object.',
},
},
},
errorMessage: {
type: 'MongoDBFind request properties should be an object.',
required: 'MongoDBFind request should have required property "query".',
},
};

View File

@ -16,8 +16,9 @@
import getCollection from '../getCollection.js';
import { serialize, deserialize } from '../serialize.js';
import schema from './schema.js';
async function mongodbFindOne({ request, connection }) {
async function MongodbFindOne({ request, connection }) {
const deserializedRequest = deserialize(request);
const { query, options } = deserializedRequest;
const { collection, client } = await getCollection({ connection });
@ -32,4 +33,10 @@ async function mongodbFindOne({ request, connection }) {
return serialize(res);
}
export default mongodbFindOne;
MongodbFindOne.schema = schema;
MongodbFindOne.meta = {
checkRead: true,
checkWrite: false,
};
export default MongodbFindOne;

View File

@ -15,12 +15,11 @@
*/
import { validate } from '@lowdefy/ajv';
import mongoDBFindOne from './MongoDBFindOne.js';
import MongoDBFindOne from './MongoDBFindOne.js';
import populateTestMongoDb from '../../../../test/populateTestMongoDb.js';
import requestIndex from './index.js';
import schema from './MongoDBFindOneSchema.json';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = MongoDBFindOne.meta;
const schema = MongoDBFindOne.schema;
const databaseUri = process.env.MONGO_URL;
const databaseName = 'test';
@ -39,7 +38,7 @@ test('findOne', async () => {
collection,
read: true,
};
const res = await mongoDBFindOne({ request, connection });
const res = await MongoDBFindOne({ request, connection });
expect(res).toEqual({
_id: 1,
});
@ -55,7 +54,7 @@ test('findOne only find one', async () => {
collection,
read: true,
};
const res = await mongoDBFindOne({ request, connection });
const res = await MongoDBFindOne({ request, connection });
expect(res).toEqual({
_id: 2,
});
@ -72,7 +71,7 @@ test('find options', async () => {
collection,
read: true,
};
const res = await mongoDBFindOne({ request, connection });
const res = await MongoDBFindOne({ request, connection });
expect(res).toEqual({
_id: 2,
});
@ -86,7 +85,7 @@ test('findOne connection error', async () => {
collection,
read: true,
};
await expect(mongoDBFindOne({ request, connection })).rejects.toThrow(
await expect(MongoDBFindOne({ request, connection })).rejects.toThrow(
'Invalid connection string'
);
});
@ -99,7 +98,7 @@ test('findOne mongodb error', async () => {
collection,
read: true,
};
await expect(mongoDBFindOne({ request, connection })).rejects.toThrow('unknown operator: $badOp');
await expect(MongoDBFindOne({ request, connection })).rejects.toThrow('unknown operator: $badOp');
});
test('checkRead should be true', async () => {

View File

@ -1,26 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - MongoDBFindOne",
"type": "object",
"required": ["query"],
"properties": {
"query": {
"type": "object",
"description": "A MongoDB query object",
"errorMessage": {
"type": "MongoDBFindOne request property \"query\" should be an object."
}
},
"options": {
"type": "object",
"description": "Optional settings.",
"errorMessage": {
"type": "MongoDBFindOne request property \"options\" should be an object."
}
}
},
"errorMessage": {
"type": "MongoDBFindOne request properties should be an object.",
"required": "MongoDBFindOne request should have required property \"query\"."
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/MongoDBCollection/MongoDBFindOne/MongoDBFindOne.js',
schema: 'connections/MongoDBCollection/MongoDBFindOne/MongoDBFindOneSchema.json',
},
meta: {
checkRead: true,
checkWrite: false,
},
};

View File

@ -0,0 +1,42 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - MongoDBFindOne',
type: 'object',
required: ['query'],
properties: {
query: {
type: 'object',
description: 'A MongoDB query object',
errorMessage: {
type: 'MongoDBFindOne request property "query" should be an object.',
},
},
options: {
type: 'object',
description: 'Optional settings.',
errorMessage: {
type: 'MongoDBFindOne request property "options" should be an object.',
},
},
},
errorMessage: {
type: 'MongoDBFindOne request properties should be an object.',
required: 'MongoDBFindOne request should have required property "query".',
},
};

View File

@ -16,8 +16,9 @@
import getCollection from '../getCollection.js';
import { serialize, deserialize } from '../serialize.js';
import schema from './schema.js';
async function mongodbInsertMany({ request, connection }) {
async function MongodbInsertMany({ request, connection }) {
const deserializedRequest = deserialize(request);
const { docs, options } = deserializedRequest;
const { collection, client } = await getCollection({ connection });
@ -33,4 +34,10 @@ async function mongodbInsertMany({ request, connection }) {
return { insertedCount, ops };
}
export default mongodbInsertMany;
MongodbInsertMany.schema = schema;
MongodbInsertMany.meta = {
checkRead: false,
checkWrite: true,
};
export default MongodbInsertMany;

View File

@ -15,12 +15,11 @@
*/
import { validate } from '@lowdefy/ajv';
import mongoDBInsertMany from './MongoDBInsertMany.js';
import MongoDBInsertMany from './MongoDBInsertMany.js';
import clearTestMongoDb from '../../../../test/clearTestMongoDb.js';
import requestIndex from './index.js';
import schema from './MongoDBInsertManySchema.json';
const { checkRead, checkWrite } = requestIndex.meta;
const { checkRead, checkWrite } = MongoDBInsertMany.meta;
const schema = MongoDBInsertMany.schema;
const databaseUri = process.env.MONGO_URL;
const databaseName = 'test';
@ -40,7 +39,7 @@ test('insertMany', async () => {
collection,
write: true,
};
const res = await mongoDBInsertMany({ request, connection });
const res = await MongoDBInsertMany({ request, connection });
expect(res).toEqual({
insertedCount: 3,
ops: [
@ -68,7 +67,7 @@ test('insertMany options', async () => {
collection,
write: true,
};
const res = await mongoDBInsertMany({ request, connection });
const res = await MongoDBInsertMany({ request, connection });
expect(res).toEqual({
insertedCount: 2,
ops: [
@ -90,7 +89,7 @@ test('insertMany connection error', async () => {
collection,
write: true,
};
await expect(mongoDBInsertMany({ request, connection })).rejects.toThrow(
await expect(MongoDBInsertMany({ request, connection })).rejects.toThrow(
'Invalid connection string'
);
});
@ -103,8 +102,8 @@ test('insertMany mongodb error', async () => {
collection,
write: true,
};
await mongoDBInsertMany({ request, connection });
await expect(mongoDBInsertMany({ request, connection })).rejects.toThrow(
await MongoDBInsertMany({ request, connection });
await expect(MongoDBInsertMany({ request, connection })).rejects.toThrow(
'E11000 duplicate key error'
);
});

View File

@ -1,32 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Lowdefy Request Schema - MongoDBInsertMany",
"type": "object",
"required": ["docs"],
"properties": {
"docs": {
"type": "array",
"description": "The array of documents to be inserted.",
"errorMessage": {
"type": "MongoDBInsertMany request property \"docs\" should be an array."
},
"items": {
"type": "object",
"errorMessage": {
"type": "MongoDBInsertMany request property \"docs\" should be an array of documents to insert."
}
}
},
"options": {
"type": "object",
"description": "Optional settings.",
"errorMessage": {
"type": "MongoDBInsertMany request property \"options\" should be an object."
}
}
},
"errorMessage": {
"type": "MongoDBInsertMany request properties should be an object.",
"required": "MongoDBInsertMany request should have required property \"docs\"."
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
import: {
path: 'connections/MongoDBCollection/MongoDBInsertMany/MongoDBInsertMany.test.js',
schema: 'connections/MongoDBCollection/MongoDBInsertMany/MongoDBInsertManySchema.json',
},
meta: {
checkRead: false,
checkWrite: true,
},
};

View File

@ -0,0 +1,48 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export default {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Lowdefy Request Schema - MongoDBInsertMany',
type: 'object',
required: ['docs'],
properties: {
docs: {
type: 'array',
description: 'The array of documents to be inserted.',
errorMessage: {
type: 'MongoDBInsertMany request property "docs" should be an array.',
},
items: {
type: 'object',
errorMessage: {
type: 'MongoDBInsertMany request property "docs" should be an array of documents to insert.',
},
},
},
options: {
type: 'object',
description: 'Optional settings.',
errorMessage: {
type: 'MongoDBInsertMany request property "options" should be an object.',
},
},
},
errorMessage: {
type: 'MongoDBInsertMany request properties should be an object.',
required: 'MongoDBInsertMany request should have required property "docs".',
},
};

Some files were not shown because too many files have changed in this diff Show More