silgi 0.36.18 → 0.37.0

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.
package/dist/build.mjs CHANGED
@@ -26,6 +26,7 @@ import 'exsolve';
26
26
  import 'ufo';
27
27
  import 'node:fs/promises';
28
28
  import 'globby';
29
+ import 'oxc-parser';
29
30
  import 'ignore';
30
31
  import 'klona';
31
32
  import 'silgi/runtime';
@@ -16,8 +16,9 @@ import { fileURLToPath } from 'node:url';
16
16
  import { defu } from 'defu';
17
17
  import { resolveModuleURL } from 'exsolve';
18
18
  import { withTrailingSlash, isRelative } from 'ufo';
19
- import { readFile, readdir } from 'node:fs/promises';
19
+ import { readdir, readFile } from 'node:fs/promises';
20
20
  import { globby } from 'globby';
21
+ import { parseAsync } from 'oxc-parser';
21
22
  import ignore from 'ignore';
22
23
  import { klona } from 'klona';
23
24
  import { useSilgiRuntimeConfig, initRuntimeConfig } from 'silgi/runtime';
@@ -574,44 +575,22 @@ function resolveGroupSyntax(group) {
574
575
  return groups;
575
576
  }
576
577
 
577
- const TYPE_DECLARATION_EXPORT_REGEX = /\bexport\s+(?<declaration>(interface|type|declare (async function|function|let|const enum|const|enum|var|class)))\s+(?<name>[\w$]+)(?:\s+extends\s+(?<extends>[\w$, \t\n\r]+))?/g;
578
- const FUNCTION_VARIABLE_EXPORT_REGEX = /\bexport\s+(?:const|let|var)\s+(?<name>[\w$]+)\s*=\s*(?<funcName>\w+)\s*\(/g;
579
- function extractExportMatches(regex, fileContent, additionalMetadata = {}) {
580
- const matchedExports = [];
581
- for (const match of fileContent.matchAll(regex)) {
582
- const name = match.groups?.name || "";
583
- const declaration = match.groups?.declaration || "";
584
- const funcName = match.groups?.funcName || "";
585
- const extendsClause = match.groups?.extends || "";
586
- const codeSnippet = funcName ? `export const ${name} = ${funcName}(` : `export ${declaration} ${name}`;
587
- const extendedTypes = extendsClause ? extendsClause.split(",").map((typeName) => typeName.trim()) : [];
588
- matchedExports.push({
589
- ...additionalMetadata,
590
- name,
591
- declaration,
592
- funcName,
593
- code: codeSnippet,
594
- start: match.index,
595
- end: (match.index || 0) + match[0].length,
596
- extends: extendedTypes
597
- });
598
- }
599
- return matchedExports;
600
- }
601
578
  function generateUniqueIdentifier(filePath, exportName) {
602
579
  const fileBaseName = basename(filePath);
603
580
  const uniqueString = `${fileBaseName}${exportName}`;
604
581
  return hash(uniqueString);
605
582
  }
606
- function categorizeExports(exportedEntities, filePath) {
583
+ function categorizeExports(exportedEntities, filePath, functionExportCategories = {
584
+ createService: "service",
585
+ createSchema: "schema",
586
+ createShared: "shared",
587
+ createRoute: "route"
588
+ }, interfaceExportCategories = {
589
+ ExtendShared: "shared",
590
+ ExtendContext: "context"
591
+ }) {
607
592
  const runtimeExports = [];
608
593
  const typeExports = [];
609
- const functionExportCategories = {
610
- createService: "service",
611
- createSchema: "schema",
612
- createShared: "shared",
613
- createRoute: "route"
614
- };
615
594
  for (const [functionName, category] of Object.entries(functionExportCategories)) {
616
595
  const matchingExports = exportedEntities.filter((entity) => entity.funcName === functionName);
617
596
  for (const exportEntity of matchingExports) {
@@ -625,10 +604,6 @@ function categorizeExports(exportedEntities, filePath) {
625
604
  });
626
605
  }
627
606
  }
628
- const interfaceExportCategories = {
629
- ExtendShared: "shared",
630
- ExtendContext: "context"
631
- };
632
607
  for (const [extensionName, category] of Object.entries(interfaceExportCategories)) {
633
608
  const matchingExports = exportedEntities.filter(
634
609
  (entity) => entity.declaration === "interface" && entity.extends?.includes(extensionName)
@@ -725,13 +700,69 @@ async function verifyDirectoryCaseSensitivity(directoryPath, rootDirectory) {
725
700
  } catch {
726
701
  }
727
702
  }
728
- function stripCommentsAndStrings(code) {
729
- return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/"([^"\\]|\\.)*"/g, '""').replace(/'([^'\\]|\\.)*'/g, "''").replace(/`([^`\\]|\\.)*`/g, "``");
703
+ async function extractExportEntitiesFromFile(absoluteFilePath, functionExportNames = ["createSchema", "createService", "createRoute"], interfaceExtendsNames = ["ExtendShared", "ExtendContext"]) {
704
+ const exportEntities = [];
705
+ const fileContent = await readFile(absoluteFilePath, "utf-8");
706
+ const parsed = await parseAsync(absoluteFilePath, fileContent);
707
+ for (const node of parsed.program.body) {
708
+ if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "TSInterfaceDeclaration") {
709
+ const decl = node.declaration;
710
+ if (Array.isArray(decl.extends) && decl.extends.some(
711
+ (dec) => dec.type === "TSInterfaceHeritage" && dec.expression.type === "Identifier" && interfaceExtendsNames.includes(dec.expression.name)
712
+ )) {
713
+ exportEntities.push({
714
+ name: decl.id?.name,
715
+ type: "interface",
716
+ declaration: "interface",
717
+ extends: decl.extends.filter((e) => e.type === "TSInterfaceHeritage" && e.expression.type === "Identifier").map((e) => e.expression.type === "Identifier" ? e.expression.name : false).filter((name) => Boolean(name))
718
+ });
719
+ }
720
+ }
721
+ }
722
+ for (const node of parsed.program.body) {
723
+ if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") {
724
+ const decls = node.declaration.declarations;
725
+ if (Array.isArray(decls)) {
726
+ for (const decl of decls) {
727
+ if (decl.type === "VariableDeclarator" && decl.id.type === "Identifier" && decl.init && decl.init.type === "CallExpression" && decl.init.callee.type === "Identifier" && functionExportNames.includes(decl.init.callee.name)) {
728
+ exportEntities.push({
729
+ name: decl.id.name,
730
+ type: "function",
731
+ funcName: decl.init.callee.name
732
+ });
733
+ }
734
+ }
735
+ }
736
+ }
737
+ }
738
+ return exportEntities;
730
739
  }
731
- async function scanSilgiExports(path, packageName, silgiInstance = useSilgiCLI()) {
740
+ async function scanSilgiExports(path, packageName, silgiInstance = useSilgiCLI(), scanOptions = {}) {
732
741
  const processedFilePaths = /* @__PURE__ */ new Set();
733
742
  const alreadyScannedPaths = [];
734
743
  const serverDirectory = path || silgiInstance.options.serverDir;
744
+ const functionExportNames = scanOptions.functionExportNames ?? ["createSchema", "createService", "createRoute"];
745
+ const interfaceExtendsNames = scanOptions.interfaceExtendsNames ?? ["ExtendShared", "ExtendContext"];
746
+ const functionExportCategories = {};
747
+ functionExportNames.forEach((name) => {
748
+ if (name === "createService")
749
+ functionExportCategories[name] = "service";
750
+ else if (name === "createSchema")
751
+ functionExportCategories[name] = "schema";
752
+ else if (name === "createShared")
753
+ functionExportCategories[name] = "shared";
754
+ else if (name === "createRoute")
755
+ functionExportCategories[name] = "route";
756
+ else functionExportCategories[name] = name;
757
+ });
758
+ const interfaceExportCategories = {};
759
+ interfaceExtendsNames.forEach((name) => {
760
+ if (name === "ExtendShared")
761
+ interfaceExportCategories[name] = "shared";
762
+ else if (name === "ExtendContext")
763
+ interfaceExportCategories[name] = "context";
764
+ else interfaceExportCategories[name] = name;
765
+ });
735
766
  if (!serverDirectory) {
736
767
  consola.warn("No server directory specified for scanning");
737
768
  return;
@@ -758,22 +789,17 @@ async function scanSilgiExports(path, packageName, silgiInstance = useSilgiCLI()
758
789
  continue;
759
790
  }
760
791
  try {
761
- const fileContent = await readFile(absoluteFilePath, "utf-8");
762
- const cleanedContent = stripCommentsAndStrings(fileContent);
763
- const typeDeclarationExports = extractExportMatches(
764
- TYPE_DECLARATION_EXPORT_REGEX,
765
- cleanedContent,
766
- { type: "declaration" }
767
- );
768
- const functionVariableExports = extractExportMatches(
769
- FUNCTION_VARIABLE_EXPORT_REGEX,
770
- cleanedContent,
771
- { type: "variable" }
792
+ const exportEntities = await extractExportEntitiesFromFile(
793
+ absoluteFilePath,
794
+ functionExportNames,
795
+ interfaceExtendsNames
772
796
  );
773
- const allExportedEntities = [...typeDeclarationExports, ...functionVariableExports];
797
+ const allExportedEntities = exportEntities;
774
798
  const { runtimeExports, typeExports } = categorizeExports(
775
799
  allExportedEntities,
776
- absoluteFilePath
800
+ absoluteFilePath,
801
+ functionExportCategories,
802
+ interfaceExportCategories
777
803
  );
778
804
  registerExportsWithHooks(silgiInstance, runtimeExports, typeExports, packageName);
779
805
  } catch (error) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineCommand, runMain } from 'citty';
3
3
 
4
- const version = "0.36.18";
4
+ const version = "0.37.0";
5
5
  const packageJson = {
6
6
  version: version};
7
7
 
package/dist/cli/init.mjs CHANGED
@@ -23,6 +23,7 @@ import 'defu';
23
23
  import 'exsolve';
24
24
  import 'ufo';
25
25
  import 'globby';
26
+ import 'oxc-parser';
26
27
  import 'ignore';
27
28
  import 'klona';
28
29
  import 'silgi/runtime';
@@ -26,6 +26,7 @@ import 'exsolve';
26
26
  import 'ufo';
27
27
  import 'node:fs/promises';
28
28
  import 'globby';
29
+ import 'oxc-parser';
29
30
  import 'ignore';
30
31
  import 'klona';
31
32
  import 'silgi/runtime';
@@ -28,6 +28,7 @@ import 'exsolve';
28
28
  import 'ufo';
29
29
  import 'node:fs/promises';
30
30
  import 'globby';
31
+ import 'oxc-parser';
31
32
  import 'ignore';
32
33
  import 'klona';
33
34
  import 'silgi/runtime';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "silgi",
3
3
  "type": "module",
4
- "version": "0.36.18",
4
+ "version": "0.37.0",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {
@@ -117,6 +117,7 @@
117
117
  "mlly": "^1.7.4",
118
118
  "ofetch": "^1.4.1",
119
119
  "ohash": "^2.0.11",
120
+ "oxc-parser": "^0.68.1",
120
121
  "pathe": "^2.0.3",
121
122
  "perfect-debounce": "^1.0.0",
122
123
  "picocolors": "^1.1.1",