orchid-orm 1.77.0 → 1.77.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"bun.js","names":[],"sources":["../../src/migrations/adapters/bun.ts"],"sourcesContent":["import { patchRakeDb } from 'orchid-orm/migrations';\nexport * from '../patch-rake-db-types';\nexport * from 'rake-db/bun';\n\npatchRakeDb();\n"],"mappings":"mDAIa"}
1
+ {"version":3,"file":"bun.js","names":["patchRakeDb"],"sources":["../../src/migrations/adapters/bun.ts"],"sourcesContent":["import { patchRakeDb } from 'orchid-orm/migrations';\nexport * from '../patch-rake-db-types';\nexport * from 'rake-db/bun';\n\npatchRakeDb();\n"],"mappings":"CAIAA,kCAAAA,CAAAA,CAAAA,YAAAA,CAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"bun.mjs","names":[],"sources":["../../src/migrations/adapters/bun.ts"],"sourcesContent":["import { patchRakeDb } from 'orchid-orm/migrations';\nexport * from '../patch-rake-db-types';\nexport * from 'rake-db/bun';\n\npatchRakeDb();\n"],"mappings":";;AAIA,aAAa"}
1
+ {"version":3,"file":"bun.mjs","names":[],"sources":["../../src/migrations/adapters/bun.ts"],"sourcesContent":["import { patchRakeDb } from 'orchid-orm/migrations';\nexport * from '../patch-rake-db-types';\nexport * from 'rake-db/bun';\n\npatchRakeDb();\n"],"mappings":";;AAIA,YAAY"}
@@ -1,5 +1,6 @@
1
1
  import { ColumnSchemaConfig } from "pqb/internal";
2
2
  export * from "rake-db";
3
+ declare const patchRakeDb$1: () => void;
3
4
  declare module 'rake-db' {
4
5
  interface RakeDbConfig {
5
6
  dbPath?: string;
@@ -12,5 +13,5 @@ declare module 'rake-db' {
12
13
  generateTableTo?(tableName: string): string;
13
14
  }
14
15
  }
15
- declare const patchRakeDb: () => void;
16
+ declare const patchRakeDb: typeof patchRakeDb$1;
16
17
  export { patchRakeDb };
@@ -15,7 +15,7 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
19
  value: mod,
20
20
  enumerable: true
21
21
  }) : target, mod));
@@ -26,8 +26,6 @@ node_path = __toESM(node_path);
26
26
  let node_url = require("node:url");
27
27
  let node_fs_promises = require("node:fs/promises");
28
28
  node_fs_promises = __toESM(node_fs_promises);
29
- let typescript = require("typescript");
30
- typescript = __toESM(typescript);
31
29
  const viewDataToSql = (viewData, viewName) => {
32
30
  return (0, pqb_internal.sqlToRawSql)(viewDataToQuerySql(viewData, viewName));
33
31
  };
@@ -351,8 +349,9 @@ const compareColumns = async (adapter, domainsMap, ast, currentSchema, compareSq
351
349
  if (!typeCasts.get(dbBaseType)?.has(codeBaseType)) {
352
350
  if (!(dbColumn instanceof pqb_internal.EnumColumn) || !(codeColumn instanceof pqb_internal.EnumColumn) || !(0, pqb_internal.deepCompare)(dbColumn.options, codeColumn.options)) {
353
351
  if (verifying) throw new AbortSignal();
352
+ const tableName = (0, rake_db.concatSchemaAndName)(changeTableData.changeTableAst);
354
353
  if (await (0, rake_db.promptSelect)({
355
- message: `Cannot cast type of ${(0, rake_db.concatSchemaAndName)(changeTableData.changeTableAst)}'s column ${key} from ${dbType} to ${codeType}`,
354
+ message: `Cannot cast type of ${tableName}'s column ${key} from ${dbType} to ${codeType}`,
356
355
  options: [`${pqb_internal.colors.yellowBold(`-/+`)} recreate the column, existing data will be ${pqb_internal.colors.red("lost")}`, `write migration manually`]
357
356
  })) throw new AbortSignal();
358
357
  dbColumn.data.name = codeColumn.data.name;
@@ -432,7 +431,7 @@ JOIN pg_type AS t ON t.oid = casttarget`);
432
431
  for (const [source, target] of rows) {
433
432
  const set = directTypeCasts.get(source);
434
433
  if (set) set.add(target);
435
- else directTypeCasts.set(source, new Set([target]));
434
+ else directTypeCasts.set(source, /* @__PURE__ */ new Set([target]));
436
435
  }
437
436
  typeCasts = /* @__PURE__ */ new Map();
438
437
  for (const [type, directSet] of directTypeCasts.entries()) {
@@ -563,7 +562,8 @@ const makeComparableDomain = (currentSchema, schemaName, name, column) => {
563
562
  inner = inner.data.item;
564
563
  arrayDims++;
565
564
  }
566
- const [typeSchema = "pg_catalog", type] = (0, rake_db.getSchemaAndTableFromName)(currentSchema, getColumnDbType(inner, currentSchema));
565
+ const fullType = getColumnDbType(inner, currentSchema);
566
+ const [typeSchema = "pg_catalog", type] = (0, rake_db.getSchemaAndTableFromName)(currentSchema, fullType);
567
567
  return {
568
568
  schemaName,
569
569
  name,
@@ -802,7 +802,7 @@ const processPrimaryKey = (config, changeTableData) => {
802
802
  };
803
803
  const changePrimaryKey = (config, columnsPrimaryKey, { codeTable, dbTableData: { primaryKey: dbPrimaryKey }, changeTableAst: { shape, add, drop }, changingColumns }) => {
804
804
  const tablePrimaryKey = codeTable.internal.tableData.primaryKey;
805
- const primaryKey = [...new Set([...columnsPrimaryKey, ...(config.snakeCase ? tablePrimaryKey?.columns.map((key) => ({
805
+ const primaryKey = [.../* @__PURE__ */ new Set([...columnsPrimaryKey, ...(config.snakeCase ? tablePrimaryKey?.columns.map((key) => ({
806
806
  key,
807
807
  name: (0, pqb_internal.toSnakeCase)(key)
808
808
  })) : tablePrimaryKey?.columns.map((key) => ({
@@ -2210,7 +2210,7 @@ const processDefaultPrivileges = (ast, dbStructure, { internal: { roles } }) =>
2210
2210
  const codeObj = codePrivilege.objectConfigs.find((o) => o.object === objectType);
2211
2211
  const dbPrivs = dbObj?.privilegeConfigs ?? [];
2212
2212
  const codePrivs = codeObj?.privilegeConfigs ?? [];
2213
- const collapsedDbPrivs = collapsePrivilegesToAll({
2213
+ const collapsedDbPrivilege = {
2214
2214
  owner: dbPrivilege.owner,
2215
2215
  grantee: dbPrivilege.grantee,
2216
2216
  schema: dbPrivilege.schema,
@@ -2218,7 +2218,8 @@ const processDefaultPrivileges = (ast, dbStructure, { internal: { roles } }) =>
2218
2218
  object: objectType,
2219
2219
  privilegeConfigs: dbPrivs
2220
2220
  }]
2221
- }, objectTypeToAllPrivileges).objectConfigs[0]?.privilegeConfigs ?? [];
2221
+ };
2222
+ const collapsedDbPrivs = collapsePrivilegesToAll(collapsedDbPrivilege, objectTypeToAllPrivileges).objectConfigs[0]?.privilegeConfigs ?? [];
2222
2223
  const toGrant = codePrivs.filter((cp) => !collapsedDbPrivs.some((dp) => privilegeConfigsMatch(cp, dp, objectType, objectTypeToAllPrivileges)));
2223
2224
  const toRevoke = dbPrivs.filter((dp) => !codePrivs.some((cp) => privilegeConfigsMatch(cp, dp, objectType, objectTypeToAllPrivileges)));
2224
2225
  if (toGrant.length) {
@@ -2642,9 +2643,7 @@ const dbViewOptionsToAst = (view) => {
2642
2643
  case "security_barrier":
2643
2644
  options.securityBarrier = value === "true";
2644
2645
  break;
2645
- case "security_invoker":
2646
- options.securityInvoker = value === "true";
2647
- break;
2646
+ case "security_invoker": options.securityInvoker = value === "true";
2648
2647
  }
2649
2648
  }
2650
2649
  return options;
@@ -3069,10 +3068,11 @@ const report = (ast, config, currentSchema) => {
3069
3068
  break;
3070
3069
  }
3071
3070
  case "policy": {
3072
- const summary = formatPolicySummary(a, dbItemName({
3071
+ const table = dbItemName({
3073
3072
  schema: a.schema,
3074
3073
  name: a.table
3075
- }, currentSchema));
3074
+ }, currentSchema);
3075
+ const summary = formatPolicySummary(a, table);
3076
3076
  const message = a.action === "create" ? `${green("+ create policy")} ${a.name}: ${summary}` : `${red("- drop policy")} ${a.name}: ${summary}`;
3077
3077
  code.push(message);
3078
3078
  break;
@@ -3624,13 +3624,11 @@ const addTrailingSemicolon = (code) => {
3624
3624
  function importsToCode(imports) {
3625
3625
  return Object.entries(imports).map(([from, name]) => `import { ${name} } from '${from}';`).join("\n");
3626
3626
  }
3627
- const { createSourceFile, ScriptTarget, SyntaxKind } = typescript.default;
3628
3627
  const appCodeGenUpdateDbFile = async (dbPath, tables, extensions, domains, currentSchema) => {
3629
3628
  const content = await node_fs_promises.default.readFile(dbPath, "utf-8");
3630
- const statements = getTsStatements(content);
3631
- const importName = getOrchidOrmImportName(statements);
3632
- if (!importName) throw new Error(`Main file does not contain import of orchid-orm`);
3633
- const { config, tablesList } = getOrchidOrmArgs(importName, statements);
3629
+ const importInfo = getOrchidOrmImport(content);
3630
+ if (!importInfo) throw new Error(`Main file does not contain import of orchid-orm`);
3631
+ const { config, tablesList } = getOrchidOrmArgs(content, importInfo.importName);
3634
3632
  const changes = [];
3635
3633
  let replacedConfig;
3636
3634
  if (extensions.length || domains.length) {
@@ -3646,32 +3644,18 @@ const appCodeGenUpdateDbFile = async (dbPath, tables, extensions, domains, curre
3646
3644
  }, ast.baseType.data.name ?? "")},`).join("\n ")}\n },`;
3647
3645
  replacedConfig = code + "\n}";
3648
3646
  }
3649
- const tablesChanges = makeTablesListChanges(content, statements, tablesList, tables, dbPath);
3647
+ const tablesChanges = makeTablesListChanges(content, importInfo.lastImportEnd, tablesList, tables, dbPath);
3650
3648
  if (tablesChanges) addChange(content, changes, tablesChanges.imports.pos, tablesChanges.imports.text);
3651
3649
  if (replacedConfig) replaceContent(content, changes, config.pos, config.end, replacedConfig);
3652
3650
  if (tablesChanges) addChange(content, changes, tablesChanges.tablesList.pos, tablesChanges.tablesList.text);
3653
3651
  return applyChanges(content, changes);
3654
3652
  };
3655
- const getTsStatements = (content) => {
3656
- return createSourceFile("file.ts", content, ScriptTarget.Latest, true).statements;
3657
- };
3658
- const getOrchidOrmImportName = (statements) => {
3659
- for (const node of statements) {
3660
- if (node.kind !== SyntaxKind.ImportDeclaration) continue;
3661
- const imp = node;
3662
- if (imp.moduleSpecifier.getText().slice(1, -1) !== "orchid-orm") continue;
3663
- if (!imp.importClause) continue;
3664
- const elements = imp.importClause.namedBindings?.elements;
3665
- if (!elements);
3666
- for (const element of elements) if (element.name.escapedText === "orchidORM" || element.propertyName && "escapedText" in element.propertyName && element.propertyName.escapedText === "orchidORM") return element.name.escapedText.toString();
3667
- }
3668
- };
3669
- const makeTablesListChanges = (content, statements, object, tables, dbPath) => {
3653
+ const makeTablesListChanges = (content, importPos, object, tables, dbPath) => {
3670
3654
  const spaces = getTablesListSpaces(content, object);
3671
3655
  let imports = "";
3672
3656
  let tablesList = "";
3673
- const prependComma = object.properties.length && !object.properties.hasTrailingComma;
3674
- const tablesListNewLine = content.slice(object.properties.end, object.end).includes("\n");
3657
+ const prependComma = object.hasProperties && !object.hasTrailingComma;
3658
+ const tablesListNewLine = content.slice(object.propertiesEnd, object.end).includes("\n");
3675
3659
  const tablesArr = Object.values(tables);
3676
3660
  for (let i = 0; i < tablesArr.length; i++) {
3677
3661
  const { path, className, key } = tablesArr[i];
@@ -3681,15 +3665,13 @@ const makeTablesListChanges = (content, statements, object, tables, dbPath) => {
3681
3665
  if (i === tablesArr.length - 1 && !tablesListNewLine) tablesList += `\n${spaces}`;
3682
3666
  }
3683
3667
  if (!imports.length) return;
3684
- let importPos = 0;
3685
- for (const node of statements) if (node.kind === SyntaxKind.ImportDeclaration) importPos = node.end;
3686
3668
  return {
3687
3669
  imports: {
3688
3670
  pos: importPos,
3689
3671
  text: imports
3690
3672
  },
3691
3673
  tablesList: {
3692
- pos: object.properties.end,
3674
+ pos: object.propertiesEnd,
3693
3675
  text: tablesList
3694
3676
  }
3695
3677
  };
@@ -3698,24 +3680,165 @@ const getTablesListSpaces = (content, object) => {
3698
3680
  const lines = content.slice(0, object.end).split("\n");
3699
3681
  return lines[lines.length - 1].match(/^\s+/)?.[0] || "";
3700
3682
  };
3701
- const getOrchidOrmArgs = (importName, statements) => {
3702
- for (const v of statements) {
3703
- if (v.kind !== SyntaxKind.VariableStatement) continue;
3704
- for (const node of v.declarationList.declarations) {
3705
- const call = node.initializer;
3706
- if (call?.kind !== SyntaxKind.CallExpression) continue;
3707
- if (call.expression.getText() !== importName) continue;
3708
- if (call.arguments.length !== 2) throw new Error("Invalid number of arguments when initializing orchid orm");
3709
- const object = call.arguments[1];
3710
- if (object?.kind !== SyntaxKind.ObjectLiteralExpression) throw new Error("Second argument of orchidORM must be an object literal");
3711
- return {
3712
- config: call.arguments[0],
3713
- tablesList: object
3714
- };
3683
+ const getOrchidOrmArgs = (content, importName) => {
3684
+ const call = findCall(content, importName);
3685
+ if (!call) throw new Error("List of tables is not found in main file");
3686
+ const closeParen = findClosingBracket(content, call.openParen);
3687
+ if (closeParen === -1) throw new Error("List of tables is not found in main file");
3688
+ const firstComma = findTopLevelComma(content, call.openParen + 1, closeParen);
3689
+ if (firstComma === -1) throw new Error("Invalid number of arguments when initializing orchid orm");
3690
+ if (findTopLevelComma(content, firstComma + 1, closeParen) !== -1) throw new Error("Invalid number of arguments when initializing orchid orm");
3691
+ const config = makeTrimmedRange(content, call.openParen + 1, firstComma);
3692
+ const tablesList = getObjectRange(content, firstComma + 1, closeParen);
3693
+ if (!tablesList) throw new Error("Second argument of orchidORM must be an object literal");
3694
+ return {
3695
+ config,
3696
+ tablesList
3697
+ };
3698
+ };
3699
+ const getOrchidOrmImport = (content) => {
3700
+ let lastImportEnd = 0;
3701
+ let importName;
3702
+ const importRegex = /(^|\n)\s*import\s+([\s\S]*?)\s+from\s+['"]([^'"]+)['"]\s*;?/g;
3703
+ let match;
3704
+ while (match = importRegex.exec(content)) {
3705
+ lastImportEnd = importRegex.lastIndex;
3706
+ if (match[3] !== "orchid-orm") continue;
3707
+ const named = match[2].match(/\{([\s\S]*)\}/);
3708
+ if (!named) continue;
3709
+ for (const part of named[1].split(",")) {
3710
+ const item = part.trim();
3711
+ const alias = item.match(/^orchidORM\s+as\s+([A-Za-z_$][\w$]*)$/);
3712
+ if (alias) {
3713
+ importName = alias[1];
3714
+ continue;
3715
+ }
3716
+ if (item === "orchidORM") importName = "orchidORM";
3717
+ }
3718
+ }
3719
+ if (!importName) return;
3720
+ return {
3721
+ importName,
3722
+ lastImportEnd
3723
+ };
3724
+ };
3725
+ const findCall = (content, importName) => {
3726
+ let index = 0;
3727
+ while (index < content.length) {
3728
+ const found = content.indexOf(importName, index);
3729
+ if (found === -1) return;
3730
+ const before = content[found - 1];
3731
+ const after = content[found + importName.length];
3732
+ if ((!before || !isIdentifierChar(before)) && (!after || !isIdentifierChar(after))) {
3733
+ const openParen = skipWhitespace(content, found + importName.length);
3734
+ if (content[openParen] === "(") return { openParen };
3715
3735
  }
3736
+ index = found + importName.length;
3716
3737
  }
3717
3738
  throw new Error("List of tables is not found in main file");
3718
3739
  };
3740
+ const getObjectRange = (content, from, to) => {
3741
+ const pos = skipWhitespace(content, from);
3742
+ if (content[pos] !== "{") return;
3743
+ const end = findClosingBracket(content, pos);
3744
+ if (end === -1 || skipWhitespace(content, end + 1) < to) return;
3745
+ const lastBodyChar = findLastNonWhitespace(content, pos + 1, end);
3746
+ const hasProperties = lastBodyChar !== -1;
3747
+ const hasTrailingComma = hasProperties && content[lastBodyChar] === ",";
3748
+ const propertiesEnd = hasProperties ? lastBodyChar + 1 : pos + 1;
3749
+ return {
3750
+ pos,
3751
+ end: end + 1,
3752
+ propertiesEnd,
3753
+ hasProperties,
3754
+ hasTrailingComma
3755
+ };
3756
+ };
3757
+ const makeTrimmedRange = (content, from, to) => {
3758
+ return {
3759
+ pos: skipWhitespace(content, from),
3760
+ end: trimWhitespaceEnd(content, from, to)
3761
+ };
3762
+ };
3763
+ const findTopLevelComma = (content, from, to) => {
3764
+ let depth = 0;
3765
+ for (let i = from; i < to; i++) {
3766
+ const skipped = skipCodeFragment(content, i);
3767
+ if (skipped !== i) {
3768
+ i = skipped - 1;
3769
+ continue;
3770
+ }
3771
+ const char = content[i];
3772
+ if (char === "(" || char === "{" || char === "[") depth++;
3773
+ else if (char === ")" || char === "}" || char === "]") depth--;
3774
+ else if (char === "," && depth === 0) return i;
3775
+ }
3776
+ return -1;
3777
+ };
3778
+ const findClosingBracket = (content, open) => {
3779
+ const close = getClosingBracket(content[open]);
3780
+ if (!close) return -1;
3781
+ let depth = 1;
3782
+ for (let i = open + 1; i < content.length; i++) {
3783
+ const skipped = skipCodeFragment(content, i);
3784
+ if (skipped !== i) {
3785
+ i = skipped - 1;
3786
+ continue;
3787
+ }
3788
+ const char = content[i];
3789
+ if (char === content[open]) depth++;
3790
+ else if (char === close) {
3791
+ depth--;
3792
+ if (depth === 0) return i;
3793
+ }
3794
+ }
3795
+ return -1;
3796
+ };
3797
+ const getClosingBracket = (char) => {
3798
+ if (char === "(") return ")";
3799
+ if (char === "{") return "}";
3800
+ if (char === "[") return "]";
3801
+ };
3802
+ const skipCodeFragment = (content, i) => {
3803
+ const char = content[i];
3804
+ if (char === "'" || char === "\"" || char === "`") return skipQuoted(content, i, char);
3805
+ if (char === "/" && content[i + 1] === "/") {
3806
+ const nextLine = content.indexOf("\n", i + 2);
3807
+ return nextLine === -1 ? content.length : nextLine + 1;
3808
+ }
3809
+ if (char === "/" && content[i + 1] === "*") {
3810
+ const end = content.indexOf("*/", i + 2);
3811
+ return end === -1 ? content.length : end + 2;
3812
+ }
3813
+ return i;
3814
+ };
3815
+ const skipQuoted = (content, i, quote) => {
3816
+ for (let j = i + 1; j < content.length; j++) {
3817
+ if (content[j] === "\\") {
3818
+ j++;
3819
+ continue;
3820
+ }
3821
+ if (content[j] === quote) return j + 1;
3822
+ }
3823
+ return content.length;
3824
+ };
3825
+ const skipWhitespace = (content, from) => {
3826
+ let i = from;
3827
+ while (/\s/.test(content[i])) i++;
3828
+ return i;
3829
+ };
3830
+ const trimWhitespaceEnd = (content, from, to) => {
3831
+ let i = to;
3832
+ while (i > from && /\s/.test(content[i - 1])) i--;
3833
+ return i;
3834
+ };
3835
+ const findLastNonWhitespace = (content, from, to) => {
3836
+ for (let i = to - 1; i >= from; i--) if (!/\s/.test(content[i])) return i;
3837
+ return -1;
3838
+ };
3839
+ const isIdentifierChar = (char) => {
3840
+ return /[A-Za-z0-9_$]/.test(char);
3841
+ };
3719
3842
  const addChange = (content, changes, at, text, end = at) => {
3720
3843
  if (changes.length === 0) changes.push([0, at], text, [end, content.length]);
3721
3844
  else {
@@ -3743,7 +3866,8 @@ const pull = async (adapters, config) => {
3743
3866
  const [adapter] = adapters;
3744
3867
  const adapterSchema = adapter.getSchema();
3745
3868
  const currentSchema = (typeof adapterSchema === "function" ? adapterSchema() : adapterSchema) ?? "public";
3746
- const asts = await (0, rake_db.structureToAst)((0, rake_db.makeStructureToAstCtx)(config, currentSchema), adapter, config);
3869
+ const ctx = (0, rake_db.makeStructureToAstCtx)(config, currentSchema);
3870
+ const asts = await (0, rake_db.structureToAst)(ctx, adapter, config);
3747
3871
  const tableInfos = getTableInfos(asts, config);
3748
3872
  const exclusiveWriteOptions = { flag: "wx" };
3749
3873
  const pendingFileWrites = [];
@@ -3769,9 +3893,7 @@ const pull = async (adapters, config) => {
3769
3893
  version: ast.version
3770
3894
  });
3771
3895
  break;
3772
- case "domain":
3773
- domains.push(ast);
3774
- break;
3896
+ case "domain": domains.push(ast);
3775
3897
  }
3776
3898
  if (!firstTable && !extensions.length && !domains.length) {
3777
3899
  await adapter.close();