drizzle-kit 0.30.1-7db411e → 0.30.1-86fcd29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/api.js +64 -17
  2. package/api.mjs +64 -17
  3. package/bin.cjs +1 -1
  4. package/package.json +1 -1
package/api.js CHANGED
@@ -24837,24 +24837,40 @@ var init_primary_keys = __esm({
24837
24837
  function getOrderByOperators() {
24838
24838
  return orderByOperators;
24839
24839
  }
24840
- function mapRelationalRow(row, buildQueryResultSelection, mapColumnValue = (value) => value, parseJson = false) {
24840
+ function mapRelationalRow(row, buildQueryResultSelection, mapColumnValue = (value) => value, parseJson = false, path2) {
24841
24841
  for (const selectionItem of buildQueryResultSelection) {
24842
24842
  const field = selectionItem.field;
24843
24843
  if (is(field, Table2)) {
24844
- if (row[selectionItem.key] === null)
24844
+ const currentPath = `${path2 ? `${path2}.` : ""}${selectionItem.key}`;
24845
+ if (row[selectionItem.key] === null) {
24846
+ if (!selectionItem.isOptional) {
24847
+ throw new DrizzleError({
24848
+ message: `Unexpected null in relational query result on field "${currentPath}".
24849
+ Did you forget to mark relation as optional?`
24850
+ });
24851
+ }
24845
24852
  continue;
24853
+ }
24846
24854
  if (parseJson)
24847
24855
  row[selectionItem.key] = JSON.parse(row[selectionItem.key]);
24848
24856
  if (selectionItem.isArray) {
24849
24857
  for (const item of row[selectionItem.key]) {
24850
- mapRelationalRow(item, selectionItem.selection, mapColumnValue);
24858
+ mapRelationalRow(
24859
+ item,
24860
+ selectionItem.selection,
24861
+ mapColumnValue,
24862
+ false,
24863
+ currentPath
24864
+ );
24851
24865
  }
24852
24866
  continue;
24853
24867
  }
24854
24868
  mapRelationalRow(
24855
24869
  row[selectionItem.key],
24856
24870
  selectionItem.selection,
24857
- mapColumnValue
24871
+ mapColumnValue,
24872
+ false,
24873
+ currentPath
24858
24874
  );
24859
24875
  continue;
24860
24876
  }
@@ -24905,7 +24921,7 @@ function defineRelations(schema5, relations) {
24905
24921
  );
24906
24922
  }
24907
24923
  function relationsFieldFilterToSQL(column5, filter2) {
24908
- if (typeof filter2 !== "object" || is(filter2, Placeholder))
24924
+ if (typeof filter2 !== "object")
24909
24925
  return eq(column5, filter2);
24910
24926
  const entries = Object.entries(filter2);
24911
24927
  if (!entries.length)
@@ -24932,6 +24948,21 @@ function relationsFieldFilterToSQL(column5, filter2) {
24932
24948
  );
24933
24949
  continue;
24934
24950
  }
24951
+ case "isNotNull":
24952
+ case "isNull": {
24953
+ if (!value)
24954
+ continue;
24955
+ parts.push(operators[target](column5));
24956
+ continue;
24957
+ }
24958
+ case "in": {
24959
+ parts.push(operators.inArray(column5, value));
24960
+ continue;
24961
+ }
24962
+ case "notIn": {
24963
+ parts.push(operators.notInArray(column5, value));
24964
+ continue;
24965
+ }
24935
24966
  default: {
24936
24967
  parts.push(
24937
24968
  operators[target](
@@ -25048,6 +25079,7 @@ var init_relations = __esm({
25048
25079
  init_table();
25049
25080
  init_column();
25050
25081
  init_entity();
25082
+ init_errors();
25051
25083
  init_primary_keys();
25052
25084
  init_expressions();
25053
25085
  init_sql();
@@ -25247,7 +25279,8 @@ Hint: you can specify "alias" on both sides of the relation with the same value`
25247
25279
  if (!this.query) {
25248
25280
  if (!this.table)
25249
25281
  throw new Error("Table must be set before building aggregate field");
25250
- this.query = sql`select count(*) as ${sql.identifier("r")} from ${this.table}`.mapWith(Number);
25282
+ const table5 = this.table;
25283
+ this.query = sql`select count(*) as ${sql.identifier("r")} from ${table5[IsAlias] ? sql`${sql`${sql.identifier(table5[Schema] ?? "")}.`.if(table5[Schema])}${sql.identifier(table5[OriginalName])} as ${table5}` : table5}`.mapWith(Number);
25251
25284
  }
25252
25285
  return this.query;
25253
25286
  }
@@ -25308,7 +25341,7 @@ Hint: you can specify "alias" on both sides of the relation with the same value`
25308
25341
  }
25309
25342
  through(column5) {
25310
25343
  this._.through = column5;
25311
- return this;
25344
+ throw new Error("Not implemented");
25312
25345
  }
25313
25346
  getSQL() {
25314
25347
  return this._.column.getSQL();
@@ -26071,7 +26104,7 @@ var init_dialect = __esm({
26071
26104
  sql`, `
26072
26105
  );
26073
26106
  });
26074
- __publicField(this, "buildColumns", (table5, tableConfig, selection, config) => config?.columns ? (() => {
26107
+ __publicField(this, "buildColumns", (table5, selection, config) => config?.columns ? (() => {
26075
26108
  const entries = Object.entries(config.columns);
26076
26109
  const columnIdentifiers = [];
26077
26110
  let colSelectionMode;
@@ -26729,7 +26762,7 @@ var init_dialect = __esm({
26729
26762
  const offset = params?.offset;
26730
26763
  const where = params?.where && relationWhere ? and(relationsFilterToSQL(table5, params.where), relationWhere) : params?.where ? relationsFilterToSQL(table5, params.where) : relationWhere;
26731
26764
  const order = params?.orderBy ? relationsOrderToSQL(table5, params.orderBy) : void 0;
26732
- const columns = this.buildColumns(table5, tableConfig, selection, params);
26765
+ const columns = this.buildColumns(table5, selection, params);
26733
26766
  const extras = params?.extras ? relationExtrasToSQL(table5, params.extras) : void 0;
26734
26767
  if (extras)
26735
26768
  selection.push(...extras.selection);
@@ -26777,7 +26810,8 @@ var init_dialect = __esm({
26777
26810
  field: targetTable,
26778
26811
  key: k,
26779
26812
  selection: innerQuery.selection,
26780
- isArray: !isSingle2
26813
+ isArray: !isSingle2,
26814
+ isOptional: (relation.optional ?? false) || join !== true && !!join.where
26781
26815
  });
26782
26816
  return sql`left join lateral(select ${isSingle2 ? sql`row_to_json(${sql.identifier("t")}.*) ${sql.identifier("r")}` : sql`json_agg(row_to_json(${sql.identifier("t")}.*)) ${sql.identifier("r")}`} from (${innerQuery.sql}) as ${sql.identifier("t")}) as ${sql.identifier(k)} on true`;
26783
26817
  }),
@@ -32833,7 +32867,7 @@ var init_dialect2 = __esm({
32833
32867
  }
32834
32868
  const relation = tableConfig.relations[k];
32835
32869
  const isSingle2 = is(relation, One);
32836
- const targetTable = relation.targetTable;
32870
+ const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
32837
32871
  const relationFilter = relationToSQL(relation, table5, targetTable);
32838
32872
  const innerQuery = this.buildRelationalQuery({
32839
32873
  table: targetTable,
@@ -32852,7 +32886,8 @@ var init_dialect2 = __esm({
32852
32886
  field: targetTable,
32853
32887
  key: k,
32854
32888
  selection: innerQuery.selection,
32855
- isArray: !isSingle2
32889
+ isArray: !isSingle2,
32890
+ isOptional: (relation.optional ?? false) || join !== true && !!join.where
32856
32891
  });
32857
32892
  const jsonColumns = sql.join(
32858
32893
  innerQuery.selection.map((s) => {
@@ -37744,6 +37779,12 @@ var init_dialect3 = __esm({
37744
37779
  columnIdentifiers.push(
37745
37780
  sql`${table5[column5.tsName]} as ${sql.identifier(column5.tsName)}`
37746
37781
  );
37782
+ selection.push(
37783
+ {
37784
+ key: column5.tsName,
37785
+ field: column5.column
37786
+ }
37787
+ );
37747
37788
  }
37748
37789
  return columnIdentifiers.length ? sql.join(columnIdentifiers, sql`, `) : void 0;
37749
37790
  })() : this.unwrapAllColumns(table5, selection));
@@ -38565,7 +38606,8 @@ var init_dialect3 = __esm({
38565
38606
  relationWhere,
38566
38607
  mode,
38567
38608
  errorPath,
38568
- depth
38609
+ depth,
38610
+ isNested
38569
38611
  }) {
38570
38612
  const selection = [];
38571
38613
  const isSingle = mode === "first";
@@ -38599,7 +38641,7 @@ var init_dialect3 = __esm({
38599
38641
  key: k,
38600
38642
  field: relation2
38601
38643
  });
38602
- return sql`, lateral(${query2}) as ${sql.identifier(k)}`;
38644
+ return sql` left join lateral (${query2}) as ${sql.identifier(k)} on true`;
38603
38645
  }
38604
38646
  const relation = tableConfig.relations[k];
38605
38647
  const isSingle2 = is(relation, One);
@@ -38615,19 +38657,21 @@ var init_dialect3 = __esm({
38615
38657
  tables,
38616
38658
  relationWhere: relationFilter,
38617
38659
  errorPath: `${currentPath.length ? `${currentPath}.` : ""}${k}`,
38618
- depth: currentDepth + 1
38660
+ depth: currentDepth + 1,
38661
+ isNested: true
38619
38662
  });
38620
38663
  selection.push({
38621
38664
  field: targetTable,
38622
38665
  key: k,
38623
38666
  selection: innerQuery.selection,
38624
- isArray: !isSingle2
38667
+ isArray: !isSingle2,
38668
+ isOptional: (relation.optional ?? false) || join !== true && !!join.where
38625
38669
  });
38626
38670
  const jsonColumns = sql.join(
38627
38671
  innerQuery.selection.map((s) => sql`${sql.raw(this.escapeString(s.key))}, ${sql.identifier(s.key)}`),
38628
38672
  sql`, `
38629
38673
  );
38630
- return sql`, lateral(select ${isSingle2 ? sql`json_object(${jsonColumns}) as ${sql.identifier("r")}` : sql`coalesce(json_arrayagg(json_object(${jsonColumns})), json_array()) as ${sql.identifier("r")}`} from (${innerQuery.sql}) as ${sql.identifier("t")}) as ${sql.identifier(k)}`;
38674
+ return sql` left join lateral(select ${sql`${isSingle2 ? sql`json_object(${jsonColumns})` : sql`coalesce(json_arrayagg(json_object(${jsonColumns})), json_array())`} as ${sql.identifier("r")}`} from (${innerQuery.sql}) as ${sql.identifier("t")}) as ${sql.identifier(k)} on true`;
38631
38675
  })
38632
38676
  );
38633
38677
  })() : void 0;
@@ -38638,6 +38682,9 @@ var init_dialect3 = __esm({
38638
38682
  message: `No fields selected for table "${tableConfig.tsName}"${currentPath ? ` ("${currentPath}")` : ""}`
38639
38683
  });
38640
38684
  }
38685
+ if (isNested && order) {
38686
+ selectionArr.push(sql`row_number() over (order by ${order})`);
38687
+ }
38641
38688
  const selectionSet = sql.join(selectionArr, sql`, `);
38642
38689
  const query = sql`select ${selectionSet} from ${table5[IsAlias] ? sql`${sql`${sql.identifier(table5[Schema] ?? "")}.`.if(table5[Schema])}${sql.identifier(table5[OriginalName])} as ${table5}` : table5}${sql`${joins}`.if(joins)}${sql` where ${where}`.if(where)}${sql` order by ${order}`.if(order)}${sql` limit ${limit}`.if(limit !== void 0)}${sql` offset ${offset}`.if(offset !== void 0)}`;
38643
38690
  return {
package/api.mjs CHANGED
@@ -24842,24 +24842,40 @@ var init_primary_keys = __esm({
24842
24842
  function getOrderByOperators() {
24843
24843
  return orderByOperators;
24844
24844
  }
24845
- function mapRelationalRow(row, buildQueryResultSelection, mapColumnValue = (value) => value, parseJson = false) {
24845
+ function mapRelationalRow(row, buildQueryResultSelection, mapColumnValue = (value) => value, parseJson = false, path2) {
24846
24846
  for (const selectionItem of buildQueryResultSelection) {
24847
24847
  const field = selectionItem.field;
24848
24848
  if (is(field, Table2)) {
24849
- if (row[selectionItem.key] === null)
24849
+ const currentPath = `${path2 ? `${path2}.` : ""}${selectionItem.key}`;
24850
+ if (row[selectionItem.key] === null) {
24851
+ if (!selectionItem.isOptional) {
24852
+ throw new DrizzleError({
24853
+ message: `Unexpected null in relational query result on field "${currentPath}".
24854
+ Did you forget to mark relation as optional?`
24855
+ });
24856
+ }
24850
24857
  continue;
24858
+ }
24851
24859
  if (parseJson)
24852
24860
  row[selectionItem.key] = JSON.parse(row[selectionItem.key]);
24853
24861
  if (selectionItem.isArray) {
24854
24862
  for (const item of row[selectionItem.key]) {
24855
- mapRelationalRow(item, selectionItem.selection, mapColumnValue);
24863
+ mapRelationalRow(
24864
+ item,
24865
+ selectionItem.selection,
24866
+ mapColumnValue,
24867
+ false,
24868
+ currentPath
24869
+ );
24856
24870
  }
24857
24871
  continue;
24858
24872
  }
24859
24873
  mapRelationalRow(
24860
24874
  row[selectionItem.key],
24861
24875
  selectionItem.selection,
24862
- mapColumnValue
24876
+ mapColumnValue,
24877
+ false,
24878
+ currentPath
24863
24879
  );
24864
24880
  continue;
24865
24881
  }
@@ -24910,7 +24926,7 @@ function defineRelations(schema5, relations) {
24910
24926
  );
24911
24927
  }
24912
24928
  function relationsFieldFilterToSQL(column5, filter2) {
24913
- if (typeof filter2 !== "object" || is(filter2, Placeholder))
24929
+ if (typeof filter2 !== "object")
24914
24930
  return eq(column5, filter2);
24915
24931
  const entries = Object.entries(filter2);
24916
24932
  if (!entries.length)
@@ -24937,6 +24953,21 @@ function relationsFieldFilterToSQL(column5, filter2) {
24937
24953
  );
24938
24954
  continue;
24939
24955
  }
24956
+ case "isNotNull":
24957
+ case "isNull": {
24958
+ if (!value)
24959
+ continue;
24960
+ parts.push(operators[target](column5));
24961
+ continue;
24962
+ }
24963
+ case "in": {
24964
+ parts.push(operators.inArray(column5, value));
24965
+ continue;
24966
+ }
24967
+ case "notIn": {
24968
+ parts.push(operators.notInArray(column5, value));
24969
+ continue;
24970
+ }
24940
24971
  default: {
24941
24972
  parts.push(
24942
24973
  operators[target](
@@ -25053,6 +25084,7 @@ var init_relations = __esm({
25053
25084
  init_table();
25054
25085
  init_column();
25055
25086
  init_entity();
25087
+ init_errors();
25056
25088
  init_primary_keys();
25057
25089
  init_expressions();
25058
25090
  init_sql();
@@ -25252,7 +25284,8 @@ Hint: you can specify "alias" on both sides of the relation with the same value`
25252
25284
  if (!this.query) {
25253
25285
  if (!this.table)
25254
25286
  throw new Error("Table must be set before building aggregate field");
25255
- this.query = sql`select count(*) as ${sql.identifier("r")} from ${this.table}`.mapWith(Number);
25287
+ const table5 = this.table;
25288
+ this.query = sql`select count(*) as ${sql.identifier("r")} from ${table5[IsAlias] ? sql`${sql`${sql.identifier(table5[Schema] ?? "")}.`.if(table5[Schema])}${sql.identifier(table5[OriginalName])} as ${table5}` : table5}`.mapWith(Number);
25256
25289
  }
25257
25290
  return this.query;
25258
25291
  }
@@ -25313,7 +25346,7 @@ Hint: you can specify "alias" on both sides of the relation with the same value`
25313
25346
  }
25314
25347
  through(column5) {
25315
25348
  this._.through = column5;
25316
- return this;
25349
+ throw new Error("Not implemented");
25317
25350
  }
25318
25351
  getSQL() {
25319
25352
  return this._.column.getSQL();
@@ -26076,7 +26109,7 @@ var init_dialect = __esm({
26076
26109
  sql`, `
26077
26110
  );
26078
26111
  });
26079
- __publicField(this, "buildColumns", (table5, tableConfig, selection, config) => config?.columns ? (() => {
26112
+ __publicField(this, "buildColumns", (table5, selection, config) => config?.columns ? (() => {
26080
26113
  const entries = Object.entries(config.columns);
26081
26114
  const columnIdentifiers = [];
26082
26115
  let colSelectionMode;
@@ -26734,7 +26767,7 @@ var init_dialect = __esm({
26734
26767
  const offset = params?.offset;
26735
26768
  const where = params?.where && relationWhere ? and(relationsFilterToSQL(table5, params.where), relationWhere) : params?.where ? relationsFilterToSQL(table5, params.where) : relationWhere;
26736
26769
  const order = params?.orderBy ? relationsOrderToSQL(table5, params.orderBy) : void 0;
26737
- const columns = this.buildColumns(table5, tableConfig, selection, params);
26770
+ const columns = this.buildColumns(table5, selection, params);
26738
26771
  const extras = params?.extras ? relationExtrasToSQL(table5, params.extras) : void 0;
26739
26772
  if (extras)
26740
26773
  selection.push(...extras.selection);
@@ -26782,7 +26815,8 @@ var init_dialect = __esm({
26782
26815
  field: targetTable,
26783
26816
  key: k,
26784
26817
  selection: innerQuery.selection,
26785
- isArray: !isSingle2
26818
+ isArray: !isSingle2,
26819
+ isOptional: (relation.optional ?? false) || join !== true && !!join.where
26786
26820
  });
26787
26821
  return sql`left join lateral(select ${isSingle2 ? sql`row_to_json(${sql.identifier("t")}.*) ${sql.identifier("r")}` : sql`json_agg(row_to_json(${sql.identifier("t")}.*)) ${sql.identifier("r")}`} from (${innerQuery.sql}) as ${sql.identifier("t")}) as ${sql.identifier(k)} on true`;
26788
26822
  }),
@@ -32838,7 +32872,7 @@ var init_dialect2 = __esm({
32838
32872
  }
32839
32873
  const relation = tableConfig.relations[k];
32840
32874
  const isSingle2 = is(relation, One);
32841
- const targetTable = relation.targetTable;
32875
+ const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
32842
32876
  const relationFilter = relationToSQL(relation, table5, targetTable);
32843
32877
  const innerQuery = this.buildRelationalQuery({
32844
32878
  table: targetTable,
@@ -32857,7 +32891,8 @@ var init_dialect2 = __esm({
32857
32891
  field: targetTable,
32858
32892
  key: k,
32859
32893
  selection: innerQuery.selection,
32860
- isArray: !isSingle2
32894
+ isArray: !isSingle2,
32895
+ isOptional: (relation.optional ?? false) || join !== true && !!join.where
32861
32896
  });
32862
32897
  const jsonColumns = sql.join(
32863
32898
  innerQuery.selection.map((s) => {
@@ -37749,6 +37784,12 @@ var init_dialect3 = __esm({
37749
37784
  columnIdentifiers.push(
37750
37785
  sql`${table5[column5.tsName]} as ${sql.identifier(column5.tsName)}`
37751
37786
  );
37787
+ selection.push(
37788
+ {
37789
+ key: column5.tsName,
37790
+ field: column5.column
37791
+ }
37792
+ );
37752
37793
  }
37753
37794
  return columnIdentifiers.length ? sql.join(columnIdentifiers, sql`, `) : void 0;
37754
37795
  })() : this.unwrapAllColumns(table5, selection));
@@ -38570,7 +38611,8 @@ var init_dialect3 = __esm({
38570
38611
  relationWhere,
38571
38612
  mode,
38572
38613
  errorPath,
38573
- depth
38614
+ depth,
38615
+ isNested
38574
38616
  }) {
38575
38617
  const selection = [];
38576
38618
  const isSingle = mode === "first";
@@ -38604,7 +38646,7 @@ var init_dialect3 = __esm({
38604
38646
  key: k,
38605
38647
  field: relation2
38606
38648
  });
38607
- return sql`, lateral(${query2}) as ${sql.identifier(k)}`;
38649
+ return sql` left join lateral (${query2}) as ${sql.identifier(k)} on true`;
38608
38650
  }
38609
38651
  const relation = tableConfig.relations[k];
38610
38652
  const isSingle2 = is(relation, One);
@@ -38620,19 +38662,21 @@ var init_dialect3 = __esm({
38620
38662
  tables,
38621
38663
  relationWhere: relationFilter,
38622
38664
  errorPath: `${currentPath.length ? `${currentPath}.` : ""}${k}`,
38623
- depth: currentDepth + 1
38665
+ depth: currentDepth + 1,
38666
+ isNested: true
38624
38667
  });
38625
38668
  selection.push({
38626
38669
  field: targetTable,
38627
38670
  key: k,
38628
38671
  selection: innerQuery.selection,
38629
- isArray: !isSingle2
38672
+ isArray: !isSingle2,
38673
+ isOptional: (relation.optional ?? false) || join !== true && !!join.where
38630
38674
  });
38631
38675
  const jsonColumns = sql.join(
38632
38676
  innerQuery.selection.map((s) => sql`${sql.raw(this.escapeString(s.key))}, ${sql.identifier(s.key)}`),
38633
38677
  sql`, `
38634
38678
  );
38635
- return sql`, lateral(select ${isSingle2 ? sql`json_object(${jsonColumns}) as ${sql.identifier("r")}` : sql`coalesce(json_arrayagg(json_object(${jsonColumns})), json_array()) as ${sql.identifier("r")}`} from (${innerQuery.sql}) as ${sql.identifier("t")}) as ${sql.identifier(k)}`;
38679
+ return sql` left join lateral(select ${sql`${isSingle2 ? sql`json_object(${jsonColumns})` : sql`coalesce(json_arrayagg(json_object(${jsonColumns})), json_array())`} as ${sql.identifier("r")}`} from (${innerQuery.sql}) as ${sql.identifier("t")}) as ${sql.identifier(k)} on true`;
38636
38680
  })
38637
38681
  );
38638
38682
  })() : void 0;
@@ -38643,6 +38687,9 @@ var init_dialect3 = __esm({
38643
38687
  message: `No fields selected for table "${tableConfig.tsName}"${currentPath ? ` ("${currentPath}")` : ""}`
38644
38688
  });
38645
38689
  }
38690
+ if (isNested && order) {
38691
+ selectionArr.push(sql`row_number() over (order by ${order})`);
38692
+ }
38646
38693
  const selectionSet = sql.join(selectionArr, sql`, `);
38647
38694
  const query = sql`select ${selectionSet} from ${table5[IsAlias] ? sql`${sql`${sql.identifier(table5[Schema] ?? "")}.`.if(table5[Schema])}${sql.identifier(table5[OriginalName])} as ${table5}` : table5}${sql`${joins}`.if(joins)}${sql` where ${where}`.if(where)}${sql` order by ${order}`.if(order)}${sql` limit ${limit}`.if(limit !== void 0)}${sql` offset ${offset}`.if(offset !== void 0)}`;
38648
38695
  return {
package/bin.cjs CHANGED
@@ -92611,7 +92611,7 @@ init_utils5();
92611
92611
  var version2 = async () => {
92612
92612
  const { npmVersion } = await ormCoreVersions();
92613
92613
  const ormVersion = npmVersion ? `drizzle-orm: v${npmVersion}` : "";
92614
- const envVersion = "0.30.1-7db411e";
92614
+ const envVersion = "0.30.1-86fcd29";
92615
92615
  const kitVersion = envVersion ? `v${envVersion}` : "--";
92616
92616
  const versions = `drizzle-kit: ${kitVersion}
92617
92617
  ${ormVersion}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-kit",
3
- "version": "0.30.1-7db411e",
3
+ "version": "0.30.1-86fcd29",
4
4
  "homepage": "https://orm.drizzle.team",
5
5
  "keywords": [
6
6
  "drizzle",