silgi 0.3.12 → 0.3.13

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,5 +1,5 @@
1
1
  import { defineCommand } from 'citty';
2
- import { r as relativeWithDot, l as loadSilgiConfig } from '../shared/silgi.b9yhSIGd.mjs';
2
+ import { r as relativeWithDot, k as getDirectory, m as resolveSilgiModule, o as resolvePath$1, q as generateUris, v as generateSilgiStorageBaseType, l as loadSilgiConfig } from '../shared/silgi.D2yb1XAa.mjs';
3
3
  import { createHooks } from 'hookable';
4
4
  import ignore from 'ignore';
5
5
  import { isAbsolute, resolve, join, relative, dirname, basename, extname } from 'pathe';
@@ -8,7 +8,6 @@ import { readPackageJSON } from 'pkg-types';
8
8
  import { defu } from 'defu';
9
9
  import { withTrailingSlash } from 'ufo';
10
10
  import { resolvePath, resolve as resolve$1 } from 'mlly';
11
- import { i as getDirectory, r as resolveSilgiModule, j as resolvePath$1, k as generateUris, m as generateSilgiStorageBaseType } from '../shared/silgi.mBwNj1W0.mjs';
12
11
  import { readdir } from 'node:fs/promises';
13
12
  import { consola } from 'consola';
14
13
  import { globby } from 'globby';
@@ -16,14 +15,14 @@ import { parseSync } from '@oxc-parser/wasm';
16
15
  import { createJiti } from 'jiti';
17
16
  import { pathToFileURL, fileURLToPath } from 'node:url';
18
17
  import { pascalCase } from 'scule';
19
- import 'c12';
20
- import 'untyped';
21
- import 'std-env';
22
18
  import 'node:buffer';
23
19
  import 'klona';
24
20
  import 'unstorage';
25
21
  import 'unstorage/drivers/memory';
26
22
  import 'unctx';
23
+ import 'c12';
24
+ import 'untyped';
25
+ import 'std-env';
27
26
  import 'pathe/utils';
28
27
 
29
28
  async function _generateH3DTS(silgi) {
@@ -3,7 +3,7 @@ import consola from 'consola';
3
3
 
4
4
  const name = "silgi";
5
5
  const type = "module";
6
- const version = "0.3.12";
6
+ const version = "0.3.13";
7
7
  const packageManager = "pnpm@9.15.1";
8
8
  const sideEffects = false;
9
9
  const exports = {
@@ -149,6 +149,11 @@ const devDependencies = {
149
149
  vue: "^3.5.13",
150
150
  zod: "^3.24.1"
151
151
  };
152
+ const pnpm = {
153
+ patchedDependencies: {
154
+ "nitropack@2.10.4": "patches/nitropack@2.10.4.patch"
155
+ }
156
+ };
152
157
  const resolutions = {
153
158
  "@silgi/modules": "workspace:*",
154
159
  silgi: "workspace:*"
@@ -173,6 +178,7 @@ const packageJson = {
173
178
  peerDependenciesMeta: peerDependenciesMeta,
174
179
  dependencies: dependencies,
175
180
  devDependencies: devDependencies,
181
+ pnpm: pnpm,
176
182
  resolutions: resolutions,
177
183
  publishConfig: publishConfig
178
184
  };
@@ -1,9 +1,23 @@
1
1
  import { fileURLToPath } from 'node:url';
2
2
  import { resolve, dirname, join } from 'pathe';
3
- import { l as loadSilgiConfig, r as relativeWithDot } from '../../shared/silgi.b9yhSIGd.mjs';
4
- import 'c12';
3
+ import { types } from '../../index.mjs';
4
+ import { l as loadSilgiConfig, r as relativeWithDot } from '../../shared/silgi.D2yb1XAa.mjs';
5
+ import 'consola';
6
+ import 'defu';
7
+ import 'hookable';
5
8
  import 'untyped';
9
+ import 'semver/functions/satisfies.js';
10
+ import 'h3';
11
+ import 'node:fs';
12
+ import 'node:buffer';
13
+ import 'klona';
14
+ import 'unstorage';
15
+ import 'unstorage/drivers/memory';
16
+ import 'unctx';
17
+ import 'c12';
6
18
  import 'std-env';
19
+ import 'mlly';
20
+ import 'pathe/utils';
7
21
 
8
22
  const module = {
9
23
  name: "silgi",
@@ -35,6 +49,11 @@ const module = {
35
49
  from: "silgi",
36
50
  imports: ["silgi"]
37
51
  });
52
+ nitro.options.imports.presets.push({
53
+ from: "silgi",
54
+ imports: types.map((type) => type),
55
+ type: true
56
+ });
38
57
  }
39
58
  }
40
59
  };
@@ -1,10 +1,24 @@
1
1
  import { defineNuxtModule, createResolver, addImportsDir } from '@nuxt/kit';
2
2
  import { resolvePath } from 'mlly';
3
3
  import { join } from 'pathe';
4
- import { l as loadSilgiConfig, r as relativeWithDot } from '../../shared/silgi.b9yhSIGd.mjs';
5
- import 'c12';
4
+ import { types } from '../../index.mjs';
5
+ import { l as loadSilgiConfig, r as relativeWithDot } from '../../shared/silgi.D2yb1XAa.mjs';
6
+ import 'consola';
7
+ import 'defu';
8
+ import 'hookable';
6
9
  import 'untyped';
10
+ import 'semver/functions/satisfies.js';
11
+ import 'h3';
12
+ import 'node:fs';
13
+ import 'node:buffer';
14
+ import 'klona';
15
+ import 'unstorage';
16
+ import 'unstorage/drivers/memory';
17
+ import 'unctx';
18
+ import 'c12';
7
19
  import 'std-env';
20
+ import 'node:url';
21
+ import 'pathe/utils';
8
22
 
9
23
  const module = defineNuxtModule({
10
24
  meta: {
@@ -26,6 +40,11 @@ const module = defineNuxtModule({
26
40
  nuxt.hook("prepare:types", ({ references }) => {
27
41
  references.push({ path: relativeWithDot(nuxt.options.buildDir, join(silgi.buildDir, "silgi.d.ts")) });
28
42
  });
43
+ nuxt.options.imports.presets.push({
44
+ from: "silgi",
45
+ imports: types.map((type) => type),
46
+ type: true
47
+ });
29
48
  addImportsDir(composablesDir);
30
49
  }
31
50
  });
package/dist/index.d.mts CHANGED
@@ -193,4 +193,6 @@ declare function createSchema<T extends Partial<Record<keyof DefaultNamespaces,
193
193
  };
194
194
  };
195
195
 
196
- export { DefaultNamespaces, type ExtendContext, type FetchResponseData, type FilterMethods, MergedSilgiSchema, type MethodOption, type Namespaces, type ParamsOption, type RequestBodyOption, type RouterParams, ServiceType, Silgi, SilgiError, type SilgiFetchClient, SilgiHelper, type SilgiModuleContext, SilgiModuleShared, SilgiOptions, SilgiRouterTypes, SilgiSchema, createResolver, createSchema, createService, createShared, createSilgi, createSilgiFetch, defineSilgiModule, loadSilgiConfig, mergeSchemas, mergeServices, mergeShared, normalizeResult, parseURI, relativeWithDot, silgiCtx, silgiFetchRequestInterceptor, tryUseSilgi, useHook, useShared, useSilgi };
196
+ declare const types: string[];
197
+
198
+ export { DefaultNamespaces, type ExtendContext, type FetchResponseData, type FilterMethods, MergedSilgiSchema, type MethodOption, type Namespaces, type ParamsOption, type RequestBodyOption, type RouterParams, ServiceType, Silgi, SilgiError, type SilgiFetchClient, SilgiHelper, type SilgiModuleContext, SilgiModuleShared, SilgiOptions, SilgiRouterTypes, SilgiSchema, createResolver, createSchema, createService, createShared, createSilgi, createSilgiFetch, defineSilgiModule, loadSilgiConfig, mergeSchemas, mergeServices, mergeShared, normalizeResult, parseURI, relativeWithDot, silgiCtx, silgiFetchRequestInterceptor, tryUseSilgi, types, useHook, useShared, useSilgi };
package/dist/index.d.ts CHANGED
@@ -193,4 +193,6 @@ declare function createSchema<T extends Partial<Record<keyof DefaultNamespaces,
193
193
  };
194
194
  };
195
195
 
196
- export { DefaultNamespaces, type ExtendContext, type FetchResponseData, type FilterMethods, MergedSilgiSchema, type MethodOption, type Namespaces, type ParamsOption, type RequestBodyOption, type RouterParams, ServiceType, Silgi, SilgiError, type SilgiFetchClient, SilgiHelper, type SilgiModuleContext, SilgiModuleShared, SilgiOptions, SilgiRouterTypes, SilgiSchema, createResolver, createSchema, createService, createShared, createSilgi, createSilgiFetch, defineSilgiModule, loadSilgiConfig, mergeSchemas, mergeServices, mergeShared, normalizeResult, parseURI, relativeWithDot, silgiCtx, silgiFetchRequestInterceptor, tryUseSilgi, useHook, useShared, useSilgi };
196
+ declare const types: string[];
197
+
198
+ export { DefaultNamespaces, type ExtendContext, type FetchResponseData, type FilterMethods, MergedSilgiSchema, type MethodOption, type Namespaces, type ParamsOption, type RequestBodyOption, type RouterParams, ServiceType, Silgi, SilgiError, type SilgiFetchClient, SilgiHelper, type SilgiModuleContext, SilgiModuleShared, SilgiOptions, SilgiRouterTypes, SilgiSchema, createResolver, createSchema, createService, createShared, createSilgi, createSilgiFetch, defineSilgiModule, loadSilgiConfig, mergeSchemas, mergeServices, mergeShared, normalizeResult, parseURI, relativeWithDot, silgiCtx, silgiFetchRequestInterceptor, tryUseSilgi, types, useHook, useShared, useSilgi };
package/dist/index.mjs CHANGED
@@ -2,11 +2,9 @@ import { createConsola } from 'consola';
2
2
  import defu, { defu as defu$1 } from 'defu';
3
3
  import { createHooks } from 'hookable';
4
4
  import { applyDefaults } from 'untyped';
5
- import { u as useSilgi, l as loadSilgiModuleInstance, p as parseURI, S as SilgiError, a as useStorage, n as normalizeResult, b as SilgiErrorCode, g as generateStorageKey, s as scanAction, c as createStorage, d as silgiCtx, t as tryUseSilgi } from './shared/silgi.mBwNj1W0.mjs';
6
- export { e as createResolver, f as useHook, h as useShared } from './shared/silgi.mBwNj1W0.mjs';
5
+ import { u as useSilgi, a as loadSilgiModuleInstance, p as parseURI, S as SilgiError, b as useStorage, n as normalizeResult, c as SilgiErrorCode, g as generateStorageKey, d as SilgiConfigSchema, s as scanAction, e as createStorage, f as silgiCtx, t as tryUseSilgi } from './shared/silgi.D2yb1XAa.mjs';
6
+ export { h as createResolver, l as loadSilgiConfig, r as relativeWithDot, i as useHook, j as useShared } from './shared/silgi.D2yb1XAa.mjs';
7
7
  import satisfies from 'semver/functions/satisfies.js';
8
- import { S as SilgiConfigSchema } from './shared/silgi.b9yhSIGd.mjs';
9
- export { l as loadSilgiConfig, r as relativeWithDot } from './shared/silgi.b9yhSIGd.mjs';
10
8
  import { defineEventHandler, getQuery, readBody } from 'h3';
11
9
  import 'node:fs';
12
10
  import 'pathe';
@@ -15,11 +13,11 @@ import 'klona';
15
13
  import 'unstorage';
16
14
  import 'unstorage/drivers/memory';
17
15
  import 'unctx';
16
+ import 'c12';
17
+ import 'std-env';
18
18
  import 'node:url';
19
19
  import 'mlly';
20
20
  import 'pathe/utils';
21
- import 'c12';
22
- import 'std-env';
23
21
 
24
22
  const SEMANTIC_VERSION_RE = /-\d+\.[0-9a-f]+/;
25
23
  function normalizeSemanticVersion(version) {
@@ -496,4 +494,10 @@ function createSchema(silgiType) {
496
494
  return silgiType;
497
495
  }
498
496
 
499
- export { SilgiError, SilgiHelper, createSchema, createService, createShared, createSilgi, createSilgiFetch, defineSilgiModule, mergeSchemas, mergeServices, mergeShared, normalizeResult, parseURI, silgi, silgiCtx, silgiFetchRequestInterceptor, tryUseSilgi, useSilgi };
497
+ const types = [
498
+ "ExtractInputFromURI",
499
+ "ExtractOutputFromURI",
500
+ "ExtractRouterParamsFromURI"
501
+ ];
502
+
503
+ export { SilgiError, SilgiHelper, createSchema, createService, createShared, createSilgi, createSilgiFetch, defineSilgiModule, mergeSchemas, mergeServices, mergeShared, normalizeResult, parseURI, silgi, silgiCtx, silgiFetchRequestInterceptor, tryUseSilgi, types, useSilgi };
@@ -1,7 +1,71 @@
1
+ import { lstatSync, promises, existsSync } from 'node:fs';
2
+ import { isAbsolute, dirname, resolve, join, relative, basename, normalize } from 'pathe';
3
+ import { Buffer } from 'node:buffer';
4
+ import { klona } from 'klona';
5
+ import { createStorage as createStorage$1, builtinDrivers, prefixStorage } from 'unstorage';
6
+ import memoryDriver from 'unstorage/drivers/memory';
7
+ import { getContext } from 'unctx';
1
8
  import { loadConfig } from 'c12';
2
9
  import { defineUntypedSchema, applyDefaults } from 'untyped';
3
- import { resolve, join, relative, basename } from 'pathe';
4
10
  import { isDevelopment, isTest, isDebug } from 'std-env';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { resolvePath as resolvePath$1 } from 'mlly';
13
+ import { resolveAlias as resolveAlias$1 } from 'pathe/utils';
14
+
15
+ const silgiCtx = getContext("silgi");
16
+ function useShared() {
17
+ const instance = silgiCtx.tryUse();
18
+ if (!instance) {
19
+ throw new Error("Silgi instance is unavailable!");
20
+ }
21
+ return instance.options.shared;
22
+ }
23
+ function useSilgi() {
24
+ const instance = silgiCtx.tryUse();
25
+ if (!instance) {
26
+ throw new Error("Silgi instance is unavailable!");
27
+ }
28
+ return instance;
29
+ }
30
+ function useHook() {
31
+ const instance = silgiCtx.tryUse();
32
+ if (!instance) {
33
+ throw new Error("Silgi instance is unavailable!");
34
+ }
35
+ return instance.hooks.hook;
36
+ }
37
+ function normalizeResult(result) {
38
+ if (Array.isArray(result)) {
39
+ return [...result];
40
+ }
41
+ if (result && typeof result === "object") {
42
+ if (Object.keys(result).every((key) => !Number.isNaN(Number(key)))) {
43
+ return Object.values(result);
44
+ }
45
+ return { ...result };
46
+ }
47
+ return result;
48
+ }
49
+ function tryUseSilgi() {
50
+ return silgiCtx.tryUse();
51
+ }
52
+
53
+ function getDirectory(p) {
54
+ try {
55
+ return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
56
+ } catch {
57
+ }
58
+ return p;
59
+ }
60
+ async function loadSilgiModuleInstance(silgiModule) {
61
+ if (typeof silgiModule === "string") {
62
+ throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
63
+ }
64
+ if (typeof silgiModule !== "function") {
65
+ throw new TypeError(`Nuxt module should be a function: ${silgiModule}`);
66
+ }
67
+ return { silgiModule };
68
+ }
5
69
 
6
70
  const common = defineUntypedSchema({
7
71
  /**
@@ -431,6 +495,254 @@ const SilgiConfigSchema = {
431
495
  ...typescript
432
496
  };
433
497
 
498
+ var SilgiErrorCode = /* @__PURE__ */ ((SilgiErrorCode2) => {
499
+ SilgiErrorCode2["AUTH_UNAUTHORIZED"] = "AUTH_UNAUTHORIZED";
500
+ SilgiErrorCode2["AUTH_MISSING_CONTEXT"] = "AUTH_MISSING_CONTEXT";
501
+ SilgiErrorCode2["AUTH_INVALID_CONTEXT"] = "AUTH_INVALID_CONTEXT";
502
+ SilgiErrorCode2["AUTH_PERMISSION_DENIED"] = "AUTH_PERMISSION_DENIED";
503
+ SilgiErrorCode2["PLUGIN_ERROR"] = "PLUGIN_ERROR";
504
+ SilgiErrorCode2["METHOD_NOT_FOUND"] = "METHOD_NOT_FOUND";
505
+ SilgiErrorCode2["EXECUTION_ERROR"] = "EXECUTION_ERROR";
506
+ SilgiErrorCode2["CACHE_ERROR"] = "CACHE_ERROR";
507
+ SilgiErrorCode2["PLUGIN_ALREADY_EXISTS"] = "PLUGIN_ALREADY_EXISTS";
508
+ SilgiErrorCode2["PLUGIN_NOT_FOUND"] = "PLUGIN_NOT_FOUND";
509
+ SilgiErrorCode2["PLUGIN_INIT_ERROR"] = "PLUGIN_INIT_ERROR";
510
+ return SilgiErrorCode2;
511
+ })(SilgiErrorCode || {});
512
+ class SilgiError extends Error {
513
+ code;
514
+ details;
515
+ meta;
516
+ timestamp;
517
+ cause;
518
+ constructor(options) {
519
+ super(options.message);
520
+ this.name = "SilgiError";
521
+ this.code = options.code;
522
+ this.details = options.details;
523
+ this.meta = options.meta;
524
+ this.cause = options.cause;
525
+ this.timestamp = Date.now();
526
+ if (Error.captureStackTrace) {
527
+ Error.captureStackTrace(this, this.constructor);
528
+ }
529
+ }
530
+ // Improve error formatting
531
+ toString() {
532
+ let str = `${this.name} [${this.code}]: ${this.message}`;
533
+ if (this.details) {
534
+ str += `
535
+ Details: ${JSON.stringify(this.details, null, 2)}`;
536
+ }
537
+ if (this.meta) {
538
+ str += `
539
+ Meta: ${JSON.stringify(this.meta, null, 2)}`;
540
+ }
541
+ if (this.stack) {
542
+ str += `
543
+ ${this.stack}`;
544
+ }
545
+ return str;
546
+ }
547
+ toJSON() {
548
+ return {
549
+ name: this.name,
550
+ code: this.code,
551
+ message: this.message,
552
+ details: this.details,
553
+ meta: this.meta,
554
+ timestamp: this.timestamp,
555
+ stack: this.stack
556
+ };
557
+ }
558
+ static createFrom(error, code = "UNKNOWN_ERROR") {
559
+ if (error instanceof SilgiError) {
560
+ return error;
561
+ }
562
+ return new SilgiError({
563
+ code,
564
+ message: error instanceof Error ? error.message : String(error),
565
+ cause: error instanceof Error ? error : undefined
566
+ });
567
+ }
568
+ static isSilgiError(error) {
569
+ return error instanceof SilgiError;
570
+ }
571
+ }
572
+
573
+ function traverseObject(silgi, obj, currentPath = []) {
574
+ const uriMap = /* @__PURE__ */ new Map();
575
+ function traverse(node, path = []) {
576
+ if (!node || typeof node !== "object")
577
+ return;
578
+ if (path.length === 4) {
579
+ const basePath = path.join("/");
580
+ let paramString = "";
581
+ if (node.router) {
582
+ let params = null;
583
+ if (node.router?._def?.typeName !== undefined) {
584
+ try {
585
+ const shape = node.router?.shape?.params?.shape;
586
+ params = shape ? Object.keys(shape) : null;
587
+ } catch {
588
+ params = null;
589
+ }
590
+ }
591
+ if (params?.length) {
592
+ paramString = params.map((p) => `:${p}`).join("/");
593
+ }
594
+ }
595
+ uriMap.set(basePath, paramString);
596
+ return;
597
+ }
598
+ for (const key in node) {
599
+ if (!["_type", "fields"].includes(key)) {
600
+ traverse(node[key], [...path, key]);
601
+ }
602
+ }
603
+ }
604
+ traverse(obj, currentPath);
605
+ return uriMap;
606
+ }
607
+ function parseURI(uri, uris) {
608
+ if (!uris) {
609
+ const silgiCtx = useSilgi();
610
+ uris = silgiCtx.uris;
611
+ }
612
+ uri = uri.replace("/srn", "");
613
+ const [cleanPath, queryString] = uri.split("?");
614
+ const query = new URLSearchParams(queryString);
615
+ const methodQuery = query.get("method")?.toLowerCase();
616
+ const parts = cleanPath.split("/").filter(Boolean);
617
+ const [namespace, service, methodOrAction, action, ...routerParams] = parts;
618
+ let uriKey = `${namespace}/${service}/${methodOrAction}/${action}`;
619
+ if (methodQuery) {
620
+ uriKey = `${namespace}/${service}/${methodQuery}/${methodOrAction}`;
621
+ routerParams.unshift(action);
622
+ }
623
+ const paramTemplate = uris[uriKey];
624
+ const routerParamsData = {};
625
+ if (paramTemplate && routerParams.length > 0) {
626
+ const paramNames = paramTemplate.split("/").map((p) => p.replace(":", ""));
627
+ routerParams.forEach((value, index) => {
628
+ if (paramNames[index]) {
629
+ routerParamsData[paramNames[index]] = value;
630
+ }
631
+ });
632
+ }
633
+ return {
634
+ namespaceName: namespace,
635
+ serviceName: service,
636
+ methodName: methodQuery || methodOrAction,
637
+ actionName: methodQuery ? methodOrAction : action,
638
+ raw: uri,
639
+ parts: [namespace, service, methodQuery || methodOrAction, action],
640
+ routerParams: routerParamsData,
641
+ query: query.toString() ? Object.fromEntries(query) : undefined,
642
+ uri: uriKey
643
+ };
644
+ }
645
+
646
+ async function createStorage(silgi) {
647
+ const storage = createStorage$1();
648
+ const mounts = klona({
649
+ ...silgi.options.storage,
650
+ ...silgi.options.devStorage
651
+ });
652
+ for (const [path, opts] of Object.entries(mounts)) {
653
+ if (opts.driver) {
654
+ const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
655
+ storage.mount("/memory:cache", memoryDriver());
656
+ storage.mount(path, driver(opts));
657
+ } else {
658
+ silgi.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
659
+ }
660
+ }
661
+ return storage;
662
+ }
663
+ function useStorage(base = "/memory:cache") {
664
+ const silgi = useSilgi();
665
+ return base ? prefixStorage(silgi.storage, base) : silgi.storage;
666
+ }
667
+ async function generateStorageKey(params) {
668
+ const {
669
+ operation,
670
+ input,
671
+ keyGenerator,
672
+ requestId,
673
+ storageOptions
674
+ } = params;
675
+ const cacheScopePrefix = storageOptions?.scope === "request" ? "req" : "global";
676
+ const parts = [
677
+ cacheScopePrefix,
678
+ // Always include scope prefix first
679
+ operation.namespaceName,
680
+ operation.serviceName,
681
+ operation.methodName
682
+ ].filter(Boolean);
683
+ if (storageOptions?.scope === "request") {
684
+ if (!requestId) {
685
+ throw new SilgiError({
686
+ code: "CACHE_ERROR",
687
+ message: "Request ID is required for request-scoped cache"
688
+ });
689
+ }
690
+ parts.push(requestId);
691
+ }
692
+ if (keyGenerator) {
693
+ const customKey = await Promise.resolve(keyGenerator(input));
694
+ parts.push(customKey);
695
+ } else {
696
+ parts.push(typeof input === "object" ? JSON.stringify(input) : String(input));
697
+ }
698
+ return Buffer.from(parts.join(":")).toString("base64");
699
+ }
700
+ async function generateSilgiStorageBaseType(silgi) {
701
+ silgi.hook("prepare:schema.ts", async (options) => {
702
+ if (silgi.options.storage) {
703
+ for (const [key, _value] of Object.entries(silgi.options.storage)) {
704
+ options.storeBase.push(key);
705
+ }
706
+ }
707
+ });
708
+ }
709
+
710
+ async function generateUris(silgi) {
711
+ silgi.hook("read:core.ts", async (data) => {
712
+ const { context, object, path } = await data();
713
+ const uriMap = traverseObject(silgi, object.schemas, []);
714
+ if (uriMap.size > 0) {
715
+ const uriContent = Array.from(uriMap.entries()).map(([uri, params]) => ` '${uri}': '${params}',`).join("\n");
716
+ const newContext = context.replace(
717
+ /export const uris = \{[^}]*\}/,
718
+ `export const uris = {
719
+ ${uriContent}
720
+ }`
721
+ );
722
+ await promises.writeFile(path, newContext);
723
+ }
724
+ });
725
+ }
726
+ async function findAction(silgi, uri) {
727
+ const { parts } = parseURI(uri, silgi);
728
+ let result = silgi.services;
729
+ for (const part of parts) {
730
+ if (result && Object.prototype.hasOwnProperty.call(result, part)) {
731
+ result = Object.assign({}, result[part]);
732
+ } else {
733
+ console.error("Property not found:", part);
734
+ break;
735
+ }
736
+ }
737
+ return result;
738
+ }
739
+ async function scanAction(silgi) {
740
+ for (const [key, _value] of Object.entries(silgi.uris)) {
741
+ const handler = await findAction(silgi, key);
742
+ silgi.scannedHandlers.set(key, handler);
743
+ }
744
+ }
745
+
434
746
  async function loadSilgiConfig(opts) {
435
747
  globalThis.defineSilgiConfig = (c) => c;
436
748
  const result = await loadConfig({
@@ -451,9 +763,80 @@ async function loadSilgiConfig(opts) {
451
763
  return await applyDefaults(SilgiConfigSchema, silgiConfig);
452
764
  }
453
765
 
766
+ async function resolvePath(path, opts = {}) {
767
+ const _path = path;
768
+ path = normalize(path);
769
+ if (isAbsolute(path)) {
770
+ if (existsSync(path) && !await isDirectory(path)) {
771
+ return path;
772
+ }
773
+ }
774
+ const cwd = opts.cwd || process.cwd();
775
+ const extensions = opts.extensions || [".ts", ".mjs", ".cjs", ".json"];
776
+ const modulesDir = opts.modulesDir || [];
777
+ path = resolveAlias(path);
778
+ if (!isAbsolute(path)) {
779
+ path = resolve(cwd, path);
780
+ }
781
+ let _isDir = false;
782
+ if (existsSync(path)) {
783
+ _isDir = await isDirectory(path);
784
+ if (!_isDir) {
785
+ return path;
786
+ }
787
+ }
788
+ for (const ext of extensions) {
789
+ const pathWithExt = path + ext;
790
+ if (existsSync(pathWithExt)) {
791
+ return pathWithExt;
792
+ }
793
+ const pathWithIndex = join(path, `index${ext}`);
794
+ if (_isDir && existsSync(pathWithIndex)) {
795
+ return pathWithIndex;
796
+ }
797
+ }
798
+ const resolveModulePath = await resolvePath$1(_path, { url: [cwd, ...modulesDir] }).catch(() => null);
799
+ if (resolveModulePath) {
800
+ return resolveModulePath;
801
+ }
802
+ return opts.fallbackToOriginal ? _path : path;
803
+ }
804
+ async function isDirectory(path) {
805
+ return (await promises.lstat(path)).isDirectory();
806
+ }
807
+ function resolveAlias(path, alias) {
808
+ return resolveAlias$1(path, {});
809
+ }
810
+ function createResolver(base) {
811
+ if (!base) {
812
+ throw new Error("`base` argument is missing for createResolver(base)!");
813
+ }
814
+ base = base.toString();
815
+ if (base.startsWith("file://")) {
816
+ base = dirname(fileURLToPath(base));
817
+ }
818
+ return {
819
+ resolve: (...path) => resolve(base, ...path),
820
+ resolvePath: (path, opts) => resolvePath(path, { cwd: base, ...opts })
821
+ };
822
+ }
823
+ async function resolveSilgiModule(base, paths) {
824
+ const resolved = [];
825
+ const resolver = createResolver(base);
826
+ for (const path of paths) {
827
+ if (path.startsWith(base)) {
828
+ resolved.push(path.split("/index.ts")[0]);
829
+ } else {
830
+ const resolvedPath = await resolver.resolvePath(path);
831
+ resolved.push(resolvedPath.slice(0, resolvedPath.lastIndexOf(path) + path.length));
832
+ }
833
+ }
834
+ return resolved;
835
+ }
836
+
454
837
  const RELATIVE_RE = /^([^.])/;
455
838
  function relativeWithDot(from, to) {
456
839
  return relative(from, to).replace(RELATIVE_RE, "./$1") || ".";
457
840
  }
458
841
 
459
- export { SilgiConfigSchema as S, loadSilgiConfig as l, relativeWithDot as r };
842
+ export { SilgiError as S, loadSilgiModuleInstance as a, useStorage as b, SilgiErrorCode as c, SilgiConfigSchema as d, createStorage as e, silgiCtx as f, generateStorageKey as g, createResolver as h, useHook as i, useShared as j, getDirectory as k, loadSilgiConfig as l, resolveSilgiModule as m, normalizeResult as n, resolvePath as o, parseURI as p, generateUris as q, relativeWithDot as r, scanAction as s, tryUseSilgi as t, useSilgi as u, generateSilgiStorageBaseType as v };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "silgi",
3
3
  "type": "module",
4
- "version": "0.3.12",
4
+ "version": "0.3.13",
5
5
  "sideEffects": false,
6
6
  "exports": {
7
7
  ".": {
@@ -1,386 +0,0 @@
1
- import { lstatSync, promises, existsSync } from 'node:fs';
2
- import { isAbsolute, dirname, resolve, normalize, join } from 'pathe';
3
- import { Buffer } from 'node:buffer';
4
- import { klona } from 'klona';
5
- import { createStorage as createStorage$1, builtinDrivers, prefixStorage } from 'unstorage';
6
- import memoryDriver from 'unstorage/drivers/memory';
7
- import { getContext } from 'unctx';
8
- import { fileURLToPath } from 'node:url';
9
- import { resolvePath as resolvePath$1 } from 'mlly';
10
- import { resolveAlias as resolveAlias$1 } from 'pathe/utils';
11
-
12
- const silgiCtx = getContext("silgi");
13
- function useShared() {
14
- const instance = silgiCtx.tryUse();
15
- if (!instance) {
16
- throw new Error("Silgi instance is unavailable!");
17
- }
18
- return instance.options.shared;
19
- }
20
- function useSilgi() {
21
- const instance = silgiCtx.tryUse();
22
- if (!instance) {
23
- throw new Error("Silgi instance is unavailable!");
24
- }
25
- return instance;
26
- }
27
- function useHook() {
28
- const instance = silgiCtx.tryUse();
29
- if (!instance) {
30
- throw new Error("Silgi instance is unavailable!");
31
- }
32
- return instance.hooks.hook;
33
- }
34
- function normalizeResult(result) {
35
- if (Array.isArray(result)) {
36
- return [...result];
37
- }
38
- if (result && typeof result === "object") {
39
- if (Object.keys(result).every((key) => !Number.isNaN(Number(key)))) {
40
- return Object.values(result);
41
- }
42
- return { ...result };
43
- }
44
- return result;
45
- }
46
- function tryUseSilgi() {
47
- return silgiCtx.tryUse();
48
- }
49
-
50
- function getDirectory(p) {
51
- try {
52
- return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
53
- } catch {
54
- }
55
- return p;
56
- }
57
- async function loadSilgiModuleInstance(silgiModule) {
58
- if (typeof silgiModule === "string") {
59
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
60
- }
61
- if (typeof silgiModule !== "function") {
62
- throw new TypeError(`Nuxt module should be a function: ${silgiModule}`);
63
- }
64
- return { silgiModule };
65
- }
66
-
67
- var SilgiErrorCode = /* @__PURE__ */ ((SilgiErrorCode2) => {
68
- SilgiErrorCode2["AUTH_UNAUTHORIZED"] = "AUTH_UNAUTHORIZED";
69
- SilgiErrorCode2["AUTH_MISSING_CONTEXT"] = "AUTH_MISSING_CONTEXT";
70
- SilgiErrorCode2["AUTH_INVALID_CONTEXT"] = "AUTH_INVALID_CONTEXT";
71
- SilgiErrorCode2["AUTH_PERMISSION_DENIED"] = "AUTH_PERMISSION_DENIED";
72
- SilgiErrorCode2["PLUGIN_ERROR"] = "PLUGIN_ERROR";
73
- SilgiErrorCode2["METHOD_NOT_FOUND"] = "METHOD_NOT_FOUND";
74
- SilgiErrorCode2["EXECUTION_ERROR"] = "EXECUTION_ERROR";
75
- SilgiErrorCode2["CACHE_ERROR"] = "CACHE_ERROR";
76
- SilgiErrorCode2["PLUGIN_ALREADY_EXISTS"] = "PLUGIN_ALREADY_EXISTS";
77
- SilgiErrorCode2["PLUGIN_NOT_FOUND"] = "PLUGIN_NOT_FOUND";
78
- SilgiErrorCode2["PLUGIN_INIT_ERROR"] = "PLUGIN_INIT_ERROR";
79
- return SilgiErrorCode2;
80
- })(SilgiErrorCode || {});
81
- class SilgiError extends Error {
82
- code;
83
- details;
84
- meta;
85
- timestamp;
86
- cause;
87
- constructor(options) {
88
- super(options.message);
89
- this.name = "SilgiError";
90
- this.code = options.code;
91
- this.details = options.details;
92
- this.meta = options.meta;
93
- this.cause = options.cause;
94
- this.timestamp = Date.now();
95
- if (Error.captureStackTrace) {
96
- Error.captureStackTrace(this, this.constructor);
97
- }
98
- }
99
- // Improve error formatting
100
- toString() {
101
- let str = `${this.name} [${this.code}]: ${this.message}`;
102
- if (this.details) {
103
- str += `
104
- Details: ${JSON.stringify(this.details, null, 2)}`;
105
- }
106
- if (this.meta) {
107
- str += `
108
- Meta: ${JSON.stringify(this.meta, null, 2)}`;
109
- }
110
- if (this.stack) {
111
- str += `
112
- ${this.stack}`;
113
- }
114
- return str;
115
- }
116
- toJSON() {
117
- return {
118
- name: this.name,
119
- code: this.code,
120
- message: this.message,
121
- details: this.details,
122
- meta: this.meta,
123
- timestamp: this.timestamp,
124
- stack: this.stack
125
- };
126
- }
127
- static createFrom(error, code = "UNKNOWN_ERROR") {
128
- if (error instanceof SilgiError) {
129
- return error;
130
- }
131
- return new SilgiError({
132
- code,
133
- message: error instanceof Error ? error.message : String(error),
134
- cause: error instanceof Error ? error : undefined
135
- });
136
- }
137
- static isSilgiError(error) {
138
- return error instanceof SilgiError;
139
- }
140
- }
141
-
142
- function traverseObject(silgi, obj, currentPath = []) {
143
- const uriMap = /* @__PURE__ */ new Map();
144
- function traverse(node, path = []) {
145
- if (!node || typeof node !== "object")
146
- return;
147
- if (path.length === 4) {
148
- const basePath = path.join("/");
149
- let paramString = "";
150
- if (node.router) {
151
- let params = null;
152
- if (node.router?._def?.typeName !== undefined) {
153
- try {
154
- const shape = node.router?.shape?.params?.shape;
155
- params = shape ? Object.keys(shape) : null;
156
- } catch {
157
- params = null;
158
- }
159
- }
160
- if (params?.length) {
161
- paramString = params.map((p) => `:${p}`).join("/");
162
- }
163
- }
164
- uriMap.set(basePath, paramString);
165
- return;
166
- }
167
- for (const key in node) {
168
- if (!["_type", "fields"].includes(key)) {
169
- traverse(node[key], [...path, key]);
170
- }
171
- }
172
- }
173
- traverse(obj, currentPath);
174
- return uriMap;
175
- }
176
- function parseURI(uri, uris) {
177
- if (!uris) {
178
- const silgiCtx = useSilgi();
179
- uris = silgiCtx.uris;
180
- }
181
- uri = uri.replace("/srn", "");
182
- const [cleanPath, queryString] = uri.split("?");
183
- const query = new URLSearchParams(queryString);
184
- const methodQuery = query.get("method")?.toLowerCase();
185
- const parts = cleanPath.split("/").filter(Boolean);
186
- const [namespace, service, methodOrAction, action, ...routerParams] = parts;
187
- let uriKey = `${namespace}/${service}/${methodOrAction}/${action}`;
188
- if (methodQuery) {
189
- uriKey = `${namespace}/${service}/${methodQuery}/${methodOrAction}`;
190
- routerParams.unshift(action);
191
- }
192
- const paramTemplate = uris[uriKey];
193
- const routerParamsData = {};
194
- if (paramTemplate && routerParams.length > 0) {
195
- const paramNames = paramTemplate.split("/").map((p) => p.replace(":", ""));
196
- routerParams.forEach((value, index) => {
197
- if (paramNames[index]) {
198
- routerParamsData[paramNames[index]] = value;
199
- }
200
- });
201
- }
202
- return {
203
- namespaceName: namespace,
204
- serviceName: service,
205
- methodName: methodQuery || methodOrAction,
206
- actionName: methodQuery ? methodOrAction : action,
207
- raw: uri,
208
- parts: [namespace, service, methodQuery || methodOrAction, action],
209
- routerParams: routerParamsData,
210
- query: query.toString() ? Object.fromEntries(query) : undefined,
211
- uri: uriKey
212
- };
213
- }
214
-
215
- async function createStorage(silgi) {
216
- const storage = createStorage$1();
217
- const mounts = klona({
218
- ...silgi.options.storage,
219
- ...silgi.options.devStorage
220
- });
221
- for (const [path, opts] of Object.entries(mounts)) {
222
- if (opts.driver) {
223
- const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
224
- storage.mount("/memory:cache", memoryDriver());
225
- storage.mount(path, driver(opts));
226
- } else {
227
- silgi.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
228
- }
229
- }
230
- return storage;
231
- }
232
- function useStorage(base = "/memory:cache") {
233
- const silgi = useSilgi();
234
- return base ? prefixStorage(silgi.storage, base) : silgi.storage;
235
- }
236
- async function generateStorageKey(params) {
237
- const {
238
- operation,
239
- input,
240
- keyGenerator,
241
- requestId,
242
- storageOptions
243
- } = params;
244
- const cacheScopePrefix = storageOptions?.scope === "request" ? "req" : "global";
245
- const parts = [
246
- cacheScopePrefix,
247
- // Always include scope prefix first
248
- operation.namespaceName,
249
- operation.serviceName,
250
- operation.methodName
251
- ].filter(Boolean);
252
- if (storageOptions?.scope === "request") {
253
- if (!requestId) {
254
- throw new SilgiError({
255
- code: "CACHE_ERROR",
256
- message: "Request ID is required for request-scoped cache"
257
- });
258
- }
259
- parts.push(requestId);
260
- }
261
- if (keyGenerator) {
262
- const customKey = await Promise.resolve(keyGenerator(input));
263
- parts.push(customKey);
264
- } else {
265
- parts.push(typeof input === "object" ? JSON.stringify(input) : String(input));
266
- }
267
- return Buffer.from(parts.join(":")).toString("base64");
268
- }
269
- async function generateSilgiStorageBaseType(silgi) {
270
- silgi.hook("prepare:schema.ts", async (options) => {
271
- if (silgi.options.storage) {
272
- for (const [key, _value] of Object.entries(silgi.options.storage)) {
273
- options.storeBase.push(key);
274
- }
275
- }
276
- });
277
- }
278
-
279
- async function generateUris(silgi) {
280
- silgi.hook("read:core.ts", async (data) => {
281
- const { context, object, path } = await data();
282
- const uriMap = traverseObject(silgi, object.schemas, []);
283
- if (uriMap.size > 0) {
284
- const uriContent = Array.from(uriMap.entries()).map(([uri, params]) => ` '${uri}': '${params}',`).join("\n");
285
- const newContext = context.replace(
286
- /export const uris = \{[^}]*\}/,
287
- `export const uris = {
288
- ${uriContent}
289
- }`
290
- );
291
- await promises.writeFile(path, newContext);
292
- }
293
- });
294
- }
295
- async function findAction(silgi, uri) {
296
- const { parts } = parseURI(uri, silgi);
297
- let result = silgi.services;
298
- for (const part of parts) {
299
- if (result && Object.prototype.hasOwnProperty.call(result, part)) {
300
- result = Object.assign({}, result[part]);
301
- } else {
302
- console.error("Property not found:", part);
303
- break;
304
- }
305
- }
306
- return result;
307
- }
308
- async function scanAction(silgi) {
309
- for (const [key, _value] of Object.entries(silgi.uris)) {
310
- const handler = await findAction(silgi, key);
311
- silgi.scannedHandlers.set(key, handler);
312
- }
313
- }
314
-
315
- async function resolvePath(path, opts = {}) {
316
- const _path = path;
317
- path = normalize(path);
318
- if (isAbsolute(path)) {
319
- if (existsSync(path) && !await isDirectory(path)) {
320
- return path;
321
- }
322
- }
323
- const cwd = opts.cwd || process.cwd();
324
- const extensions = opts.extensions || [".ts", ".mjs", ".cjs", ".json"];
325
- const modulesDir = opts.modulesDir || [];
326
- path = resolveAlias(path);
327
- if (!isAbsolute(path)) {
328
- path = resolve(cwd, path);
329
- }
330
- let _isDir = false;
331
- if (existsSync(path)) {
332
- _isDir = await isDirectory(path);
333
- if (!_isDir) {
334
- return path;
335
- }
336
- }
337
- for (const ext of extensions) {
338
- const pathWithExt = path + ext;
339
- if (existsSync(pathWithExt)) {
340
- return pathWithExt;
341
- }
342
- const pathWithIndex = join(path, `index${ext}`);
343
- if (_isDir && existsSync(pathWithIndex)) {
344
- return pathWithIndex;
345
- }
346
- }
347
- const resolveModulePath = await resolvePath$1(_path, { url: [cwd, ...modulesDir] }).catch(() => null);
348
- if (resolveModulePath) {
349
- return resolveModulePath;
350
- }
351
- return opts.fallbackToOriginal ? _path : path;
352
- }
353
- async function isDirectory(path) {
354
- return (await promises.lstat(path)).isDirectory();
355
- }
356
- function resolveAlias(path, alias) {
357
- return resolveAlias$1(path, {});
358
- }
359
- function createResolver(base) {
360
- if (!base) {
361
- throw new Error("`base` argument is missing for createResolver(base)!");
362
- }
363
- base = base.toString();
364
- if (base.startsWith("file://")) {
365
- base = dirname(fileURLToPath(base));
366
- }
367
- return {
368
- resolve: (...path) => resolve(base, ...path),
369
- resolvePath: (path, opts) => resolvePath(path, { cwd: base, ...opts })
370
- };
371
- }
372
- async function resolveSilgiModule(base, paths) {
373
- const resolved = [];
374
- const resolver = createResolver(base);
375
- for (const path of paths) {
376
- if (path.startsWith(base)) {
377
- resolved.push(path.split("/index.ts")[0]);
378
- } else {
379
- const resolvedPath = await resolver.resolvePath(path);
380
- resolved.push(resolvedPath.slice(0, resolvedPath.lastIndexOf(path) + path.length));
381
- }
382
- }
383
- return resolved;
384
- }
385
-
386
- export { SilgiError as S, useStorage as a, SilgiErrorCode as b, createStorage as c, silgiCtx as d, createResolver as e, useHook as f, generateStorageKey as g, useShared as h, getDirectory as i, resolvePath as j, generateUris as k, loadSilgiModuleInstance as l, generateSilgiStorageBaseType as m, normalizeResult as n, parseURI as p, resolveSilgiModule as r, scanAction as s, tryUseSilgi as t, useSilgi as u };