@workos/oagen 0.19.1 → 0.19.3

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.
@@ -4794,14 +4794,75 @@ function collectFromImports(lines) {
4794
4794
  return byModule;
4795
4795
  }
4796
4796
  /**
4797
+ * Collect TypeScript imports, grouped by form. Handles single-line and
4798
+ * multi-line `{ … }` named imports. Disjoint from Python's `from X import Y`
4799
+ * syntax so this can be called in parallel with `collectFromImports`.
4800
+ */
4801
+ function collectTsImports(lines) {
4802
+ const out = {
4803
+ named: /* @__PURE__ */ new Map(),
4804
+ typeOnly: /* @__PURE__ */ new Map(),
4805
+ defaults: /* @__PURE__ */ new Map(),
4806
+ namespaces: /* @__PURE__ */ new Map(),
4807
+ sideEffects: /* @__PURE__ */ new Set()
4808
+ };
4809
+ for (let i = 0; i < lines.length; i++) {
4810
+ const trimmed = lines[i].trim();
4811
+ if (!/^import(\s|$)/.test(trimmed)) continue;
4812
+ let fullText = lines[i];
4813
+ if (fullText.includes("{") && !fullText.includes("}")) while (i + 1 < lines.length) {
4814
+ i++;
4815
+ fullText += " " + lines[i].trim();
4816
+ if (lines[i].includes("}")) break;
4817
+ }
4818
+ const normalized = fullText.replace(/\s+/g, " ").trim().replace(/;\s*$/, "");
4819
+ let m = normalized.match(/^import\s+['"]([^'"]+)['"]$/);
4820
+ if (m) {
4821
+ out.sideEffects.add(m[1]);
4822
+ continue;
4823
+ }
4824
+ m = normalized.match(/^import\s+\*\s+as\s+(\w+)\s+from\s+['"]([^'"]+)['"]$/);
4825
+ if (m) {
4826
+ out.namespaces.set(m[2], m[1]);
4827
+ continue;
4828
+ }
4829
+ m = normalized.match(/^import\s+(type\s+)?(?:(\w+)\s*,\s*)?\{\s*([^}]*)\s*\}\s+from\s+['"]([^'"]+)['"]$/);
4830
+ if (m) {
4831
+ const isTypeOnly = !!m[1];
4832
+ const defaultName = m[2];
4833
+ const namesRaw = m[3];
4834
+ const mod = m[4];
4835
+ if (defaultName) out.defaults.set(mod, defaultName);
4836
+ const names = namesRaw.split(",").map((s) => s.trim().replace(/\s+as\s+\w+$/, "")).filter(Boolean);
4837
+ const target = isTypeOnly ? out.typeOnly : out.named;
4838
+ if (!target.has(mod)) target.set(mod, /* @__PURE__ */ new Set());
4839
+ for (const n of names) target.get(mod).add(n);
4840
+ continue;
4841
+ }
4842
+ m = normalized.match(/^import\s+(?:type\s+)?(\w+)\s+from\s+['"]([^'"]+)['"]$/);
4843
+ if (m) {
4844
+ out.defaults.set(m[2], m[1]);
4845
+ continue;
4846
+ }
4847
+ }
4848
+ return out;
4849
+ }
4850
+ /**
4797
4851
  * Add imports from the existing file that are absent from the generated
4798
- * result. Handles both `import X` and `from X import Y` forms.
4852
+ * result. Handles:
4853
+ *
4854
+ * - Python: `import X` and `from X import Y`
4855
+ * - TypeScript: `import { X } from 'module'`, `import type { X } from 'module'`,
4856
+ * `import X from 'module'`, `import * as X from 'module'`, `import 'module'`
4857
+ * - PHP: `use Foo\Bar;` and `use Foo\Bar as Baz;` (namespace-qualified only)
4858
+ * - Ruby: `require '…'` and `require_relative '…'`
4859
+ *
4799
4860
  * Mutates `resultLines` in place.
4800
4861
  */
4801
4862
  function spliceExtraImports(existingLines, resultLines) {
4802
- const isSimpleImport = (l) => /^import\s+\w/.test(l);
4803
- const existingSimple = new Set(existingLines.filter(isSimpleImport).map((l) => l.trim()));
4804
- const generatedSimple = new Set(resultLines.filter(isSimpleImport).map((l) => l.trim()));
4863
+ const isPythonSimpleImport = (l) => /^import\s+\w/.test(l) && !/\sfrom\s/.test(l);
4864
+ const existingSimple = new Set(existingLines.filter(isPythonSimpleImport).map((l) => l.trim()));
4865
+ const generatedSimple = new Set(resultLines.filter(isPythonSimpleImport).map((l) => l.trim()));
4805
4866
  const extraSimple = [...existingSimple].filter((l) => !generatedSimple.has(l));
4806
4867
  const existingFrom = collectFromImports(existingLines);
4807
4868
  const generatedFrom = collectFromImports(resultLines);
@@ -4818,15 +4879,52 @@ function spliceExtraImports(existingLines, resultLines) {
4818
4879
  if (extra.length > 0) extraFromLines.push(`from ${mod} import ${extra.join(", ")}`);
4819
4880
  }
4820
4881
  }
4821
- const allExtra = [...extraSimple, ...extraFromLines];
4882
+ const existingTs = collectTsImports(existingLines);
4883
+ const generatedTs = collectTsImports(resultLines);
4884
+ const extraTsLines = [];
4885
+ for (const mod of existingTs.sideEffects) if (!generatedTs.sideEffects.has(mod)) extraTsLines.push(`import '${mod}';`);
4886
+ for (const [mod, name] of existingTs.defaults) {
4887
+ if (generatedTs.defaults.has(mod)) continue;
4888
+ extraTsLines.push(`import ${name} from '${mod}';`);
4889
+ }
4890
+ for (const [mod, name] of existingTs.namespaces) if (!generatedTs.namespaces.has(mod)) extraTsLines.push(`import * as ${name} from '${mod}';`);
4891
+ for (const [mod, existIds] of existingTs.named) {
4892
+ const genIds = generatedTs.named.get(mod) ?? /* @__PURE__ */ new Set();
4893
+ const genTypeIds = generatedTs.typeOnly.get(mod) ?? /* @__PURE__ */ new Set();
4894
+ const extra = [...existIds].filter((id) => !genIds.has(id) && !genTypeIds.has(id));
4895
+ if (extra.length > 0) extraTsLines.push(`import { ${extra.join(", ")} } from '${mod}';`);
4896
+ }
4897
+ for (const [mod, existIds] of existingTs.typeOnly) {
4898
+ const genIds = generatedTs.typeOnly.get(mod) ?? /* @__PURE__ */ new Set();
4899
+ const genNamedIds = generatedTs.named.get(mod) ?? /* @__PURE__ */ new Set();
4900
+ const extra = [...existIds].filter((id) => !genIds.has(id) && !genNamedIds.has(id));
4901
+ if (extra.length > 0) extraTsLines.push(`import type { ${extra.join(", ")} } from '${mod}';`);
4902
+ }
4903
+ const isPhpUseImport = (l) => /^use\s+[\w\\]+\\[\w\\]*(\s+as\s+\w+)?\s*;?$/.test(l);
4904
+ const existingPhpUse = new Set(existingLines.filter(isPhpUseImport).map((l) => l.trim()));
4905
+ const generatedPhpUse = new Set(resultLines.filter(isPhpUseImport).map((l) => l.trim()));
4906
+ const extraPhpUse = [...existingPhpUse].filter((l) => !generatedPhpUse.has(l));
4907
+ const isRubyRequire = (l) => /^require(_relative)?\s+['"][^'"]+['"]\s*$/.test(l);
4908
+ const existingRubyRequire = new Set(existingLines.filter(isRubyRequire).map((l) => l.trim()));
4909
+ const generatedRubyRequire = new Set(resultLines.filter(isRubyRequire).map((l) => l.trim()));
4910
+ const extraRubyRequire = [...existingRubyRequire].filter((l) => !generatedRubyRequire.has(l));
4911
+ const allExtra = [
4912
+ ...extraSimple,
4913
+ ...extraFromLines,
4914
+ ...extraTsLines,
4915
+ ...extraPhpUse,
4916
+ ...extraRubyRequire
4917
+ ];
4822
4918
  if (allExtra.length === 0) return;
4919
+ const isImportStart = (l) => /^\s*import(\s|$)/.test(l) || /^from\s+/.test(l) || /^\s*use\s+[\w\\]/.test(l) || /^\s*require(_relative)?\s+['"]/.test(l);
4823
4920
  let lastImportIdx = -1;
4824
- for (let i = 0; i < resultLines.length; i++) if (isSimpleImport(resultLines[i]) || /^from\s+/.test(resultLines[i])) {
4921
+ for (let i = 0; i < resultLines.length; i++) {
4922
+ if (!isImportStart(resultLines[i])) continue;
4825
4923
  lastImportIdx = i;
4826
- if (resultLines[i].includes("(") && !resultLines[i].includes(")")) while (i + 1 < resultLines.length) {
4924
+ if ((resultLines[i].match(/[({]/g) ?? []).length > (resultLines[i].match(/[)}]/g) ?? []).length) while (i + 1 < resultLines.length) {
4827
4925
  i++;
4828
4926
  lastImportIdx = i;
4829
- if (resultLines[i].includes(")")) break;
4927
+ if ((resultLines[i].match(/[)}]/g) ?? []).length > 0) break;
4830
4928
  }
4831
4929
  }
4832
4930
  if (lastImportIdx >= 0) resultLines.splice(lastImportIdx + 1, 0, ...allExtra);