New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@lbu/store

Package Overview
Dependencies
Maintainers
2
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lbu/store - npm Package Compare versions

Comparing version 0.0.45 to 0.0.46

index.d.ts

2

index.js

@@ -41,3 +41,3 @@ import { dirnameForModule } from "@lbu/stdlib";

export const migrations = dirnameForModule(import.meta) + "/migrations";
export const migrations = `${dirnameForModule(import.meta)}/migrations`;
export { structure as storeStructure } from "./src/generated/structure.js";
{
"name": "@lbu/store",
"version": "0.0.45",
"version": "0.0.46",
"description": "Postgres & S3-compatible wrappers for common things",
"main": "./index.js",
"exports": "./index.js",
"types": "./index.d.ts",
"type": "module",

@@ -17,4 +18,5 @@ "keywords": [

"dependencies": {
"@lbu/insight": "0.0.45",
"@lbu/stdlib": "0.0.45",
"@lbu/insight": "0.0.46",
"@lbu/stdlib": "0.0.46",
"@types/minio": "7.0.6",
"mime-types": "2.1.27",

@@ -24,9 +26,15 @@ "minio": "7.0.16",

},
"author": {
"name": "Dirk de Visser",
"email": "dirkdev98@gmail.com"
},
"maintainers": [
{
"name": "Dirk de Visser",
"email": "dirkdev98@gmail.com"
},
{
"name": "Daniël Hansen"
}
],
"homepage": "https://lbu.lightbase.nl",
"repository": {
"type": "git",
"url": "ssh://git@github.com/lightbasenl/lbu.git",
"url": "https://github.com/lightbasenl/lbu.git",
"directory": "packages/store"

@@ -40,3 +48,3 @@ },

},
"gitHead": "2a7bd7e726fc2f6b5709d5b4f3edfc676bb36407"
"gitHead": "6b9827983e55ade8f018d8d0c306a2fdbe6b94cb"
}

@@ -14,4 +14,4 @@ # @lbu/store

- Script runner, can watch & reload almost anything (via nodemon)
- Flexible code generators supporting routers, validators, api clients, mocks,
CRUD queries and more in the future.
- Flexible code generators supporting routers, validators, api clients, CRUD
queries and more in the future.
- Opinionated structured logging

@@ -91,3 +91,2 @@ - Common Koa middleware wrapped in a single function

- Typescript or JSDoc types
- Generated mocks
- An extendable set of types:

@@ -112,4 +111,14 @@ - boolean, number, string;

## Development
## New features
See [CONTRIBUTING.md](/contributing.md).
New features added should fall under the following categories:
- It improves the interface between api and client in some way. An example may
be to support websockets in @lbu/code-gen
- It improves the developer experience one way or another while developing an
api For example the `lbu docker` commands or various utilities provided by
@lbu/stdlib
Although some parts heavily rely on conventions set by the packages, we
currently aim not to be a framework. However, the idea of being a bit more of
framework is not completely out of the door yet.

@@ -10,25 +10,2 @@ import { once } from "events";

/**
* @name FileCacheOptions
*
* @typedef {object}
* @property {number} inMemoryThreshold Maximum byte size of a file to be stored in
* memory
* @property {string} cacheControlHeader Customize default Cache-Control header to give
* back
*/
/**
* @name FileCache
*
* @class
* A relatively simple local file cache implementation.
* Supports saving files in memory and on local disk
* Files#contentLength smaller than the provided threshold will be stored in memory.
* A file will always be cached in full, and then the range requests will be evaluated
* after The FileCache#clear does not remove files from disk, but will overwrite the
* file when added to the cache again
*
* FileCache#getFileStream is compatible with `sendFile` in @lbu/server
*/
export class FileCache {

@@ -38,4 +15,2 @@ static fileCachePath = "/tmp";

/**
* Create a new file cache
*
* @param {FileStoreContext} fileStore

@@ -62,8 +37,2 @@ * @param {FileCacheOptions} [options]

/**
* Get a file(part) from the cache.
* If the file(part) does not exist, it will try to fetch it from the FileStore
* If the file store throws an error / it doesn't exist, the error is propagated to the
* caller
*
* @public
* @param {StoreFileStore} file

@@ -89,11 +58,7 @@ * @param {number} [start]

return this.cacheFileOnDisk(cacheKey, file.id, start, end);
} else {
return this.cacheFileInMemory(cacheKey, file.id, start, end);
}
return this.cacheFileInMemory(cacheKey, file.id, start, end);
}
/**
* Remove a file from cache, but not from local disk
*
* @public
* @param {string} fileId

@@ -100,0 +65,0 @@ */

@@ -21,11 +21,2 @@ import { createReadStream } from "fs";

/**
* @name FileStoreContext
*
* @typedef {object}
* @property sql
* @property {minio.Client} minio
* @property {string} bucketName
*/
/**
* @param sql

@@ -44,6 +35,2 @@ * @param {minio.Client} minio

/**
* Create or update a file.
* If you pass in a non-existent id, the function will not error, but also not update the
* file
*
* @param {FileStoreContext} fc

@@ -116,5 +103,4 @@ * @param {StoreFileStoreInsertPartial_Input & { id?: string }} props

return fc.minio.getPartialObject(fc.bucketName, id, start, size);
} else {
return fc.minio.getObject(fc.bucketName, id);
}
return fc.minio.getObject(fc.bucketName, id);
}

@@ -121,0 +107,0 @@

@@ -28,3 +28,3 @@ // Generated by @lbu/code-gen

where.bucketNameLike ?? null
}, NULL) IS NULL OR fs."bucketName" LIKE ${"%" + where.bucketNameLike + "%"})
}, NULL) IS NULL OR fs."bucketName" LIKE ${`%${where.bucketNameLike}%`})
`,

@@ -51,5 +51,3 @@

where.bucketNameLike ?? null
}, NULL) IS NULL OR fs."bucketName" LIKE ${
"%" + where.bucketNameLike + "%"
})
}, NULL) IS NULL OR fs."bucketName" LIKE ${`%${where.bucketNameLike}%`})
`;

@@ -77,3 +75,3 @@ return result?.[0]?.genCount ?? 0;

where.bucketNameLike ?? null
}, NULL) IS NULL OR fs."bucketName" LIKE ${"%" + where.bucketNameLike + "%"})
}, NULL) IS NULL OR fs."bucketName" LIKE ${`%${where.bucketNameLike}%`})
`,

@@ -132,5 +130,3 @@

where.bucketNameLike ?? null
}, NULL) IS NULL OR fs."bucketName" LIKE ${
"%" + where.bucketNameLike + "%"
})
}, NULL) IS NULL OR fs."bucketName" LIKE ${`%${where.bucketNameLike}%`})
`;

@@ -172,3 +168,13 @@ let query = `UPDATE "fileStore" fs SET `;

query += `fs."id" `;
query += `= ANY (ARRAY['${where.idIn.join("', '")}']::uuid[])`;
query += `= ANY (ARRAY[`;
let addOne = false;
for (const value of where.idIn || []) {
addOne = true;
query += `$${idx++},`;
argList.push(value);
}
query = `${query.substring(
0,
query.length - (addOne ? 1 : 0),
)}]::uuid[])`;
query += " AND ";

@@ -214,3 +220,3 @@ }

where.bucketNameLike ?? null
}, NULL) IS NULL OR fs."bucketName" LIKE ${"%" + where.bucketNameLike + "%"})
}, NULL) IS NULL OR fs."bucketName" LIKE ${`%${where.bucketNameLike}%`})
GROUP BY fs.id`,

@@ -357,3 +363,13 @@

query += `ss."id" `;
query += `= ANY (ARRAY['${where.idIn.join("', '")}']::uuid[])`;
query += `= ANY (ARRAY[`;
let addOne = false;
for (const value of where.idIn || []) {
addOne = true;
query += `$${idx++},`;
argList.push(value);
}
query = `${query.substring(
0,
query.length - (addOne ? 1 : 0),
)}]::uuid[])`;
query += " AND ";

@@ -439,5 +455,5 @@ }

where.name ?? null
}) AND (COALESCE(${where.nameLike ?? null}, NULL) IS NULL OR jq."name" LIKE ${
"%" + where.nameLike + "%"
})
}) AND (COALESCE(${
where.nameLike ?? null
}, NULL) IS NULL OR jq."name" LIKE ${`%${where.nameLike}%`})
`,

@@ -464,3 +480,3 @@

where.nameLike ?? null
}, NULL) IS NULL OR jq."name" LIKE ${"%" + where.nameLike + "%"})
}, NULL) IS NULL OR jq."name" LIKE ${`%${where.nameLike}%`})
`;

@@ -484,5 +500,5 @@ return result?.[0]?.genCount ?? 0;

where.name ?? null
}) AND (COALESCE(${where.nameLike ?? null}, NULL) IS NULL OR jq."name" LIKE ${
"%" + where.nameLike + "%"
})
}) AND (COALESCE(${
where.nameLike ?? null
}, NULL) IS NULL OR jq."name" LIKE ${`%${where.nameLike}%`})
`,

@@ -489,0 +505,0 @@

export const structureString =
'{"store":{"fileStore":{"type":"object","group":"store","name":"fileStore","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"strict":false},"enableQueries":true,"queryOptions":{"withHistory":true},"keys":{"id":{"type":"uuid","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"sql":{"searchable":true,"primary":true}},"bucketName":{"type":"string","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false},"sql":{"searchable":true}},"contentLength":{"type":"number","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"convert":false,"integer":true}},"contentType":{"type":"string","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false}},"filename":{"type":"string","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false}}},"uniqueName":"StoreFileStore"},"sessionStore":{"type":"object","group":"store","name":"sessionStore","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"strict":false},"enableQueries":true,"queryOptions":{"withDates":true},"keys":{"id":{"type":"uuid","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"sql":{"searchable":true,"primary":true}},"expires":{"type":"date","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"sql":{"searchable":true}},"data":{"type":"any","docString":"","isOptional":true,"defaultValue":"{}","disabled":{"validator":false,"mock":false}}},"uniqueName":"StoreSessionStore"},"jobQueue":{"type":"object","group":"store","name":"jobQueue","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"strict":false},"enableQueries":true,"queryOptions":{"withDates":true},"keys":{"id":{"type":"number","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"convert":false,"integer":true},"sql":{"searchable":true,"primary":true}},"isComplete":{"type":"boolean","docString":"","isOptional":true,"defaultValue":"false","disabled":{"validator":false,"mock":false},"validator":{"convert":false},"sql":{"searchable":true}},"priority":{"type":"number","docString":"","isOptional":true,"defaultValue":"0","disabled":{"validator":false,"mock":false},"validator":{"convert":false,"integer":true}},"scheduledAt":{"type":"date","docString":"","isOptional":true,"defaultValue":"(new Date())","disabled":{"validator":false,"mock":false},"sql":{"searchable":true}},"name":{"type":"string","docString":"","isOptional":false,"disabled":{"validator":false,"mock":false},"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false},"sql":{"searchable":true}},"data":{"type":"any","docString":"","isOptional":true,"defaultValue":"{}","disabled":{"validator":false,"mock":false}}},"uniqueName":"StoreJobQueue"}}}';
'{"store":{"fileStore":{"type":"object","group":"store","name":"fileStore","docString":"","isOptional":false,"validator":{"strict":false},"enableQueries":true,"queryOptions":{"withHistory":true},"keys":{"id":{"type":"uuid","docString":"","isOptional":false,"sql":{"searchable":true,"primary":true}},"bucketName":{"type":"string","docString":"","isOptional":false,"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false},"sql":{"searchable":true}},"contentLength":{"type":"number","docString":"","isOptional":false,"validator":{"convert":false,"integer":true}},"contentType":{"type":"string","docString":"","isOptional":false,"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false}},"filename":{"type":"string","docString":"","isOptional":false,"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false}}},"uniqueName":"StoreFileStore"},"sessionStore":{"type":"object","group":"store","name":"sessionStore","docString":"","isOptional":false,"validator":{"strict":false},"enableQueries":true,"queryOptions":{"withDates":true},"keys":{"id":{"type":"uuid","docString":"","isOptional":false,"sql":{"searchable":true,"primary":true}},"expires":{"type":"date","docString":"","isOptional":false,"sql":{"searchable":true}},"data":{"type":"any","docString":"","isOptional":true,"defaultValue":"{}"}},"uniqueName":"StoreSessionStore"},"jobQueue":{"type":"object","group":"store","name":"jobQueue","docString":"","isOptional":false,"validator":{"strict":false},"enableQueries":true,"queryOptions":{"withDates":true},"keys":{"id":{"type":"number","docString":"","isOptional":false,"validator":{"convert":false,"integer":true},"sql":{"searchable":true,"primary":true}},"isComplete":{"type":"boolean","docString":"","isOptional":true,"defaultValue":"false","validator":{"convert":false},"sql":{"searchable":true}},"priority":{"type":"number","docString":"","isOptional":true,"defaultValue":"0","validator":{"convert":false,"integer":true}},"scheduledAt":{"type":"date","docString":"","isOptional":true,"defaultValue":"(new Date())","sql":{"searchable":true}},"name":{"type":"string","docString":"","isOptional":false,"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false},"sql":{"searchable":true}},"data":{"type":"any","docString":"","isOptional":true,"defaultValue":"{}"}},"uniqueName":"StoreJobQueue"}}}';
export const structure = JSON.parse(structureString);

@@ -7,26 +7,2 @@ import { createHash } from "crypto";

/**
* @name MigrateContext
*
* @typedef {object}
* @property {MigrateFile[]} files
* @property {string[]} namespaces
* @property {object<string, string>} storedHashes
* @property {Postgres} sql
*/
/**
* @name MigrateFile
*
* @typedef {object}
* @property {string} namespace
* @property {number} number
* @property {boolean} repeatable
* @property {string} name
* @property {string} fullPath
* @property {boolean} isMigrated
* @property {string} source
* @property {string} hash
*/
/**
* @param sql

@@ -41,32 +17,44 @@ * @param migrationDirectory

) {
const migrations = await readMigrationsDir(migrationDirectory);
try {
const migrations = await readMigrationsDir(migrationDirectory);
// Automatically add this package to the migrations
if (migrations.namespaces.indexOf("@lbu/store") === -1) {
migrations.namespaces.unshift("@lbu/store");
// Automatically add this package to the migrations
if (migrations.namespaces.indexOf("@lbu/store") === -1) {
migrations.namespaces.unshift("@lbu/store");
const { migrationFiles } = await readMigrationsDir(
dirnameForModule(import.meta) + "/../migrations",
"@lbu/store",
migrations.namespaces,
);
const { migrationFiles } = await readMigrationsDir(
`${dirnameForModule(import.meta)}/../migrations`,
"@lbu/store",
migrations.namespaces,
);
migrations.migrationFiles.push(...migrationFiles);
}
migrations.migrationFiles.push(...migrationFiles);
}
const mc = {
files: sortMigrations(migrations.namespaces, migrations.migrationFiles),
namespaces: migrations.namespaces,
sql,
storedHashes: {},
};
const mc = {
files: sortMigrations(migrations.namespaces, migrations.migrationFiles),
namespaces: migrations.namespaces,
sql,
storedHashes: {},
};
await acquireLock(sql);
await syncWithSchemaState(mc);
return mc;
await Promise.race([
acquireLock(sql),
new Promise((_, reject) => {
setTimeout(
() => reject(new Error("Could not acquire advisory lock")),
2500,
);
}),
]);
await syncWithSchemaState(mc);
return mc;
} catch (error) {
// Help user by dropping the sql connection so the application will exit
sql?.end();
throw error;
}
}
/**
* Get a list of migrations to be applied
*
* @param {MigrateContext} mc

@@ -92,6 +80,12 @@ * @returns {({name: string, number: number, repeatable: boolean}[])|boolean}

export async function runMigrations(mc) {
const migrationFiles = filterMigrationsToBeApplied(mc);
try {
const migrationFiles = filterMigrationsToBeApplied(mc);
for (const migration of migrationFiles) {
await runMigration(mc.sql, migration);
for (const migration of migrationFiles) {
await runMigration(mc.sql, migration);
}
} catch (error) {
// Help user by dropping the sql connection so the application will exit
mc?.sql?.end();
throw error;
}

@@ -98,0 +92,0 @@ }

@@ -0,1 +1,2 @@

import { log } from "@lbu/insight";
import { storeQueries } from "./generated/queries.js";

@@ -57,45 +58,4 @@

/**
* @name JobData
*
* Row data for a specific job
*
* @typedef {object}
* @property {number} id
* @property {Date} createdAt
* @property {Date} scheduledAt
* @property {string} name
* @property {object} data
*/
/**
* @name JobInput
*
* @typedef {object}
* @property {number} [priority=0]
* @property {object} [data={}]
* @property {Date} [scheduledAt]
* @property {string} [name]
*/
/**
* @name JobQueueWorkerOptions
*
* @typedef {object}
* @property {function(sql: *, data: JobData): (void|Promise<void>)} handler
* @property {number} [pollInterval] Determine the poll interval in milliseconds if the
* queue was empty. Defaults to 1500 ms
* @property {number} [parallelCount] Set the amount of parallel jobs to process.
* Defaults to 1. Make sure it is not higher than the amount of Postgres connections in
* the pool
*/
/**
* @class
*
*/
export class JobQueueWorker {
/**
* Create a new JobQueueWorker
*
* @param sql

@@ -131,7 +91,2 @@ * @param {string|JobQueueWorkerOptions} nameOrOptions

/**
* Start the JobQueueWorker
*
* @public
*/
start() {

@@ -152,8 +107,2 @@ if (this.isStarted) {

/**
* Stop the JobQueueWorker
* Running jobs will continue to run, but no new jobs are fetched
*
* @public
*/
stop() {

@@ -170,5 +119,2 @@ if (!this.isStarted) {

/**
* Get the number of jobs that need to run
*
* @public
* @returns {Promise<{pendingCount: number, scheduledCount: number}|undefined>}

@@ -184,6 +130,2 @@ */

/**
* Return the average time between scheduled and completed for jobs completed in the
* provided time range in milliseconds
*
* @public
* @param {Date} startDate

@@ -289,3 +231,3 @@ * @param {Date} endDate

.catch((e) => {
console.error(e);
log.error(e);
}); // user should have handled error already, so ignore it

@@ -292,0 +234,0 @@ }

@@ -6,12 +6,3 @@ import { storeQueries } from "./generated/queries.js";

/**
* @name SessionStore
*
* @typedef {object}
* @property {function(string): Promise<object|boolean>} get
* @property {function(string, object, number): Promise<void>} set
* @property {function(string): Promise<void>} destroy
*/
/**
*
* @param sql

@@ -18,0 +9,0 @@ * @param {object} [options]

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc