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

@ginger.io/beyonce

Package Overview
Dependencies
Maintainers
24
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ginger.io/beyonce - npm Package Compare versions

Comparing version 0.0.50 to 0.0.51

59

dist/codegen/generateCode.js

@@ -21,13 +21,2 @@ "use strict";

};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -89,3 +78,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

parser: "typescript",
semi: false,
semi: false
});

@@ -96,3 +85,3 @@ }

const tables = [];
Object.entries(config.Tables).forEach(([name, { Partitions, GSIs }]) => {
Object.entries(config.tables).forEach(([name, { models, partitions, gsis }]) => {
const table = {

@@ -102,7 +91,7 @@ name,

sortKeyName: "sk",
partitions: toPartitions(name, Partitions),
gsis: [],
partitions: buildPartitions(name, models, partitions),
gsis: []
};
if (GSIs !== undefined) {
Object.entries(GSIs).forEach(([name, { partitionKey, sortKey }]) => {
if (gsis !== undefined) {
Object.entries(gsis).forEach(([name, { partitionKey, sortKey }]) => {
table.gsis.push({ name, partitionKey, sortKey });

@@ -115,21 +104,27 @@ });

}
function toPartitions(tableName, partitionDefs) {
const partitions = Object.entries(partitionDefs).map(([partitionName, partition]) => {
const models = Object.entries(partition).map(([modelName, model]) => {
const { partitionKey, sortKey } = model, fields = __rest(model, ["partitionKey", "sortKey"]);
return {
tableName,
partitionName,
name: modelName,
keys: { partitionKey, sortKey },
fields,
};
});
function buildPartitions(tableName, modelDefinitions, partitionDefinitions) {
return Object.entries(partitionDefinitions).map(([partitionName, partition]) => ({
tableName,
name: partitionName,
models: buildModels(tableName, partitionName, partition, modelDefinitions)
}));
}
function buildModels(tableName, partitionName, partition, modelDefinitions) {
return Object.entries(partition.models).map(([modelName, { partitionKey, sortKey }]) => {
const partitionKeyWithPrefix = [
partition.partitionKeyPrefix,
...partitionKey
];
const fields = modelDefinitions[modelName];
if (!fields) {
throw new Error(`${modelName} is defined in a YAML partition, but does not appear in your models list`);
}
return {
tableName,
name: partitionName,
models,
partitionName,
name: modelName,
keys: { partitionKey: partitionKeyWithPrefix, sortKey },
fields
};
});
return partitions;
}

@@ -136,0 +131,0 @@ function parseYaml(yamlData) {

@@ -10,3 +10,3 @@ "use strict";

const fieldToModels = {
model: [],
model: []
};

@@ -16,3 +16,3 @@ const fieldsAllModelsHave = {

[table.sortKeyName]: "string",
model: "string",
model: "string"
};

@@ -19,0 +19,0 @@ table.partitions.forEach((partition) => {

export declare type YAMLFile = {
Tables: {
tables: {
[tableName: string]: TableDefinition;

@@ -7,6 +7,9 @@ };

export declare type TableDefinition = {
Partitions: {
models: {
[modelName: string]: ModelDefinition;
};
partitions: {
[partitionName: string]: PartitionDefinition;
};
GSIs?: {
gsis?: {
[indexName: string]: GSIDefinition;

@@ -16,10 +19,12 @@ };

export declare type PartitionDefinition = {
[modelName: string]: ModelDefinition;
partitionKeyPrefix: string;
models: {
[modelName: string]: ModelKeys;
};
};
export declare type ModelDefinition = Keys & Fields;
export declare type Keys = {
export declare type ModelKeys = {
partitionKey: string[];
sortKey: string[];
};
export declare type Fields = {
export declare type ModelDefinition = {
[fieldName: string]: string;

@@ -52,5 +57,5 @@ };

name: string;
keys: Keys;
fields: Fields;
keys: ModelKeys;
fields: ModelDefinition;
};
//# sourceMappingURL=types.d.ts.map
{
"name": "@ginger.io/beyonce",
"version": "0.0.50",
"version": "0.0.51",
"description": "Type-safe DynamoDB query builder for TypeScript. Designed with single-table architecture in mind.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -26,22 +26,45 @@ # Beyonce

Define your `tables`, `partitions` and `models` in YAML:
Define your `tables`, `models` and `partitions` in YAML:
```YAML
Tables:
tables:
# We have a single DynamoDB Table named "Library".
Library:
Partitions: # A "partition" is a set of models with the same partition key
Authors: # e.g. this one contains Authors + Books
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: string
# Let's add two models to our Library table: Author and Book.
models:
Author:
id: string
name: string
Book:
partitionKey: [Author, $authorId]
sortKey: [Book, $id]
id: string
authorId: string
name: string
Book:
id: string
authorId: string
name: string
# Now, imagine we want to be able to retrieve an Author + all their Books
# in a single DynamoDB Query operation.
# To do that, we need a specific Author and all their Books to live under the same partition key.
# How about we use "Author-$id" as the partition key? Great, let's go with that.
# Beyonce calls a group of models that share the same partition key a "patition".
# Let's define one now, and name it "Authors"
partitions:
Authors:
# All Beyonce partition keys are prefixed (to help you avoid collisions)
# We said above we want our final partition key to be "Author-$id",
# so we set: "Author" as our prefix here
partitionKeyPrefix: Author
# And, now we can put a given Author and all their Books into the same partition
models:
Author:
partitionKey: [$id] # "Author-$id"
sortKey: [Author, $id]
Book:
partitionKey: [$authorId] # "Author-$authorId"
sortKey: [Book, $id]
```

@@ -51,6 +74,8 @@

Beyonce expects you to specify your partition and sort keys as arrays, e.g. `[Author, $id]`. The first element is a "key prefix" and all subsequent items must be field names on your model. For example we set the primary key of the `Author` model above to: `[Author, $id]`, would result in the key: `Author-$id`, where `$id` is the value of a specific Author's id. And if we wanted a compound key we could do `[Author, $id, $name]`. You can specify compound keys for both partition and sort keys.
Beyonce expects you to specify your partition and sort keys using arrays, e.g. `[Author, $id]`. The first element in this example is interpreted as a string literal, while the second substitutes the value of a specific model instance's `id` field. In addition, Beyonce prefixes partition keys with the `partitionKeyPrefix` set on the Beyonce "partition" configured your the YAML file.
Using the example above, if we wanted to place `Books` under the same partition key, then we'd need to set the `Book` model's `partitionKey` to `[Author, $authorId]`.
In our example above, we set the `Author` partiion's `partitionKeyPrefix` to `"Author"` and the `Author` model's `partitionKey` field to `[$id]`. Thus the full partition key at runtime is `Author-$id` (Beyonce uses `-` as a delimiter).
If you'd like to form a composite partition or sort key using multiple model fields, that is supported as well, e.g. `[$id, $name]`.
#### Global secondary indexes

@@ -61,8 +86,10 @@

```YAML
Tables:
tables:
Library:
Partitions:
models:
...
partitions:
...
GSIs:
gsis:
byName: # must match your GSI's name

@@ -69,0 +96,0 @@ partitionKey: $name # name field must exist on at least one model

@@ -11,3 +11,10 @@ import yaml from "js-yaml"

import { generateTaggedUnion } from "./generateTaggedUnion"
import { Model, Partition, Table, TableDefinition, YAMLFile } from "./types"
import {
Model,
Partition,
PartitionDefinition,
Table,
TableDefinition,
YAMLFile
} from "./types"

@@ -61,3 +68,3 @@ export function generateCode(yamlData: string): string {

parser: "typescript",
semi: false,
semi: false
})

@@ -69,49 +76,68 @@ }

Object.entries(config.Tables).forEach(([name, { Partitions, GSIs }]) => {
const table: Table = {
name,
partitionKeyName: "pk",
sortKeyName: "sk",
partitions: toPartitions(name, Partitions),
gsis: [],
}
Object.entries(config.tables).forEach(
([name, { models, partitions, gsis }]) => {
const table: Table = {
name,
partitionKeyName: "pk",
sortKeyName: "sk",
partitions: buildPartitions(name, models, partitions),
gsis: []
}
if (GSIs !== undefined) {
Object.entries(GSIs).forEach(([name, { partitionKey, sortKey }]) => {
table.gsis.push({ name, partitionKey, sortKey })
})
if (gsis !== undefined) {
Object.entries(gsis).forEach(([name, { partitionKey, sortKey }]) => {
table.gsis.push({ name, partitionKey, sortKey })
})
}
tables.push(table)
}
)
tables.push(table)
})
return tables
}
function toPartitions(
function buildPartitions(
tableName: string,
partitionDefs: TableDefinition["Partitions"]
modelDefinitions: TableDefinition["models"],
partitionDefinitions: TableDefinition["partitions"]
): Partition[] {
const partitions = Object.entries(partitionDefs).map(
([partitionName, partition]) => {
const models = Object.entries(partition).map(([modelName, model]) => {
const { partitionKey, sortKey, ...fields } = model
return {
tableName,
partitionName,
name: modelName,
keys: { partitionKey, sortKey },
fields,
}
})
return Object.entries(partitionDefinitions).map(
([partitionName, partition]) => ({
tableName,
name: partitionName,
models: buildModels(tableName, partitionName, partition, modelDefinitions)
})
)
}
function buildModels(
tableName: string,
partitionName: string,
partition: PartitionDefinition,
modelDefinitions: TableDefinition["models"]
): Model[] {
return Object.entries(partition.models).map(
([modelName, { partitionKey, sortKey }]) => {
const partitionKeyWithPrefix = [
partition.partitionKeyPrefix,
...partitionKey
]
const fields = modelDefinitions[modelName]
if (!fields) {
throw new Error(
`${modelName} is defined in a YAML partition, but does not appear in your models list`
)
}
return {
tableName,
name: partitionName,
models,
partitionName,
name: modelName,
keys: { partitionKey: partitionKeyWithPrefix, sortKey },
fields
}
}
)
return partitions
}

@@ -118,0 +144,0 @@

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

import { Fields, Table } from "./types"
import { ModelDefinition, Table } from "./types"

@@ -9,9 +9,9 @@ export function generateGSIs(tables: Table[]): string {

const fieldToModels: { [fieldName: string]: string[] } = {
model: [],
model: []
}
const fieldsAllModelsHave: Fields = {
const fieldsAllModelsHave: ModelDefinition = {
[table.partitionKeyName]: "string",
[table.sortKeyName]: "string",
model: "string",
model: "string"
}

@@ -18,0 +18,0 @@

export type YAMLFile = {
Tables: {
tables: {
[tableName: string]: TableDefinition

@@ -8,16 +8,22 @@ }

export type TableDefinition = {
Partitions: {
models: {
[modelName: string]: ModelDefinition
}
partitions: {
[partitionName: string]: PartitionDefinition
}
GSIs?: { [indexName: string]: GSIDefinition }
gsis?: { [indexName: string]: GSIDefinition }
}
export type PartitionDefinition = {
[modelName: string]: ModelDefinition
partitionKeyPrefix: string
models: {
[modelName: string]: ModelKeys
}
}
export type ModelDefinition = Keys & Fields
export type Keys = { partitionKey: string[]; sortKey: string[] }
export type Fields = { [fieldName: string]: string }
export type ModelKeys = { partitionKey: string[]; sortKey: string[] }
export type ModelDefinition = { [fieldName: string]: string }

@@ -53,4 +59,4 @@ export type GSIDefinition = {

name: string
keys: Keys
fields: Fields
keys: ModelKeys
fields: ModelDefinition
}

@@ -5,11 +5,15 @@ import { generateCode } from "../../main/codegen/generateCode"

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: string
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: string
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $id]
`)

@@ -48,18 +52,25 @@

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: string
Book:
id: string
authorId: string
name: string
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: string
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $id]
Book:
partitionKey: [Author, $authorId]
sortKey: [Book, $id]
id: string
authorId: string
name: string
Book:
partitionKey: [$authorId]
sortKey: [Book, $id]
`)

@@ -110,21 +121,32 @@

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: string
userId: string
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $userId]
id: string
name: string
userId: string
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $userId]
Music:
Partitions:
models:
Musician:
id: string
name: string
musicianId: string
partitions:
Musicians:
Musician:
partitionKey: [Musician, $id]
sortKey: [Musician, $musicianId]
id: string
name: string
musicianId: string
partitionKeyPrefix: Musician
models:
Musician:
partitionKey: [$id]
sortKey: [Musician, $musicianId]
`)

@@ -184,19 +206,26 @@

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: string
Book:
id: string
name: string
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: string
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $id]
Book:
partitionKey: [Author, $id]
sortKey: [Book, $id]
id: string
name: string
Book:
partitionKey: [$id]
sortKey: [Book, $id]
GSIs:
gsis:
modelById:

@@ -218,19 +247,26 @@ partitionKey: $model

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: string
Book:
id: string
name: string
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: string
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $id]
Book:
partitionKey: [Author, $id]
sortKey: [Book, $id]
id: string
name: string
Book:
partitionKey: [$id]
sortKey: [Book, $id]
GSIs:
gsis:
modelById:

@@ -251,19 +287,26 @@ partitionKey: $model

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: string
Book:
id: string
name: string
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: string
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $id]
Book:
partitionKey: [Author, $id]
sortKey: [Book, $id]
id: string
name: string
Book:
partitionKey: [$id]
sortKey: [Book, $id]
GSIs:
gsis:
byNameAndId:

@@ -283,19 +326,25 @@ partitionKey: $name

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: string
Book:
id: string
name: string
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: string
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $id]
Book:
partitionKey: [Author, $id]
sortKey: [Book, $id]
id: string
name: string
GSIs:
Book:
partitionKey: [$id]
sortKey: [Book, $id]
gsis:
byNameAndId:

@@ -315,11 +364,16 @@ partitionKey: $sk

const result = generateCode(`
Tables:
tables:
Library:
Partitions:
models:
Author:
id: string
name: BestNameEvah from @cool.io/some/sweet/package
partitions:
Authors:
Author:
partitionKey: [Author, $id]
sortKey: [Author, $id]
id: string
name: BestNameEvah from @cool.io/some/sweet/package
partitionKeyPrefix: Author
models:
Author:
partitionKey: [$id]
sortKey: [Author, $id]
`)

@@ -337,11 +391,16 @@

const result = generateCode(`
Tables:
tables:
ComplexLibrary:
Partitions:
models:
ComplexAuthor:
id: string
name: string
partitions:
ComplexAuthors:
ComplexAuthor:
partitionKey: [Author, $id]
sortKey: [Author, $id, $name]
id: string
name: string
partitionKeyPrefix: Author
models:
ComplexAuthor:
partitionKey: [$id]
sortKey: [Author, $id, $name]
`)

@@ -348,0 +407,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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