@stryke/trpc-next 0.5.105 → 0.5.106
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/CHANGELOG.md +16 -0
- package/dist/action-handler.mjs.map +1 -1
- package/dist/client.mjs.map +1 -1
- package/dist/server.mjs.map +1 -1
- package/dist/shared.mjs.map +1 -1
- package/dist/shield/constructors.mjs.map +1 -1
- package/dist/shield/generator.mjs.map +1 -1
- package/dist/shield/rules.mjs.map +1 -1
- package/dist/shield/shield.mjs.map +1 -1
- package/dist/shield/utils.mjs.map +1 -1
- package/dist/shield/validation.mjs.map +1 -1
- package/dist/tanstack-query/client.mjs.map +1 -1
- package/dist/tanstack-query/server.mjs.map +1 -1
- package/package.json +16 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog for Stryke - TRPC Next
|
|
4
4
|
|
|
5
|
+
## [0.5.105](https://github.com/storm-software/stryke/releases/tag/trpc-next%400.5.105) (06/15/2026)
|
|
6
|
+
|
|
7
|
+
### Miscellaneous
|
|
8
|
+
|
|
9
|
+
- **monorepo:** Update asset references to the newly created `media` folder ([a3563a88](https://github.com/storm-software/stryke/commit/a3563a88))
|
|
10
|
+
|
|
11
|
+
### Updated Dependencies
|
|
12
|
+
|
|
13
|
+
- Updated **env** to **v0.20.103**
|
|
14
|
+
- Updated **fs** to **v0.33.86**
|
|
15
|
+
- Updated **path** to **v0.29.12**
|
|
16
|
+
- Updated **string-format** to **v0.17.27**
|
|
17
|
+
- Updated **type-checks** to **v0.6.18**
|
|
18
|
+
- Updated **types** to **v0.12.13**
|
|
19
|
+
- Updated **url** to **v0.4.36**
|
|
20
|
+
|
|
5
21
|
## [0.5.104](https://github.com/storm-software/stryke/releases/tag/trpc-next%400.5.104) (06/03/2026)
|
|
6
22
|
|
|
7
23
|
### Updated Dependencies
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-handler.mjs","names":[],"sources":["../src/action-handler.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"action-handler.mjs","names":[],"sources":["../src/action-handler.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { MaybePromise } from \"@stryke/types\";\nimport { experimental_createServerActionHandler } from \"@trpc/next/app-dir/server\";\nimport type {\n AnyRootTypes,\n RootConfig\n} from \"@trpc/server/unstable-core-do-not-import\";\nimport defu from \"defu\";\nimport type { ReadonlyRequestCookies } from \"next/dist/server/web/spec-extension/adapters/request-cookies\";\nimport type { BaseContext } from \"./types\";\n\n/**\n * This client invokes procedures directly on the server without fetching over HTTP.\n *\n * @param cookies - A function that returns the cookies to be passed to the API\n * @param t - The tRPC instance\n * @param createContext - An optional function to generate a context\n */\nexport function createTRPCServerActionHandler<\n TInstance extends {\n _config: RootConfig<AnyRootTypes>;\n },\n TContext extends BaseContext = BaseContext\n>(\n cookies: () => Promise<ReadonlyRequestCookies>,\n t: TInstance,\n createContext: () => MaybePromise<TContext> = async () => ({}) as TContext\n) {\n return experimental_createServerActionHandler(t, {\n createContext: async () => {\n const context = await Promise.resolve(createContext());\n\n return defu(context, {\n headers: {\n // Pass the cookie header to the API\n cookies: (await cookies()).toString() ?? \"\"\n }\n });\n }\n });\n}\n"],"mappings":";;;;;;;;;;;AAmCA,SAAgB,8BAMd,SACA,GACA,gBAA8C,aAAa,EAAE,GAC7D;AACA,QAAO,uCAAuC,GAAG,EAC/C,eAAe,YAAY;AAGzB,SAAO,KAAK,MAFU,QAAQ,QAAQ,eAAe,CAAC,EAEjC,EACnB,SAAS,EAEP,UAAU,MAAM,SAAS,EAAE,UAAU,IAAI,IAC1C,EACF,CAAC;IAEL,CAAC"}
|
package/dist/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\n\"use client\";\n\nimport { loggerLink } from \"@trpc/client\";\nimport type { UseTRPCActionResult } from \"@trpc/next/app-dir/client\";\nimport {\n experimental_createActionHook,\n experimental_createTRPCNextAppDirClient,\n experimental_serverActionLink\n} from \"@trpc/next/app-dir/client\";\nimport { experimental_nextHttpLink } from \"@trpc/next/app-dir/links/nextHttp\";\nimport type {\n ActionHandlerDef,\n TRPCActionHandler\n} from \"@trpc/next/app-dir/server\";\nimport type { AnyTRPCRouter } from \"@trpc/server\";\nimport { getTRPCServerUrl, transformer } from \"./shared\";\n\n/**\n * Creates a tRPC client for the Next.js app directory.\n *\n * @param baseUrl - The base URL for the tRPC server. This is typically the URL of the Next.js app.\n * @returns A tRPC client that can be used to make requests to the server.\n */\nexport function createTRPCClient<TRouter extends AnyTRPCRouter>(\n baseUrl: string\n) {\n return experimental_createTRPCNextAppDirClient<TRouter>({\n config() {\n return {\n links: [\n loggerLink({\n enabled: _op => true\n }),\n experimental_nextHttpLink({\n transformer,\n batch: true,\n url: getTRPCServerUrl(baseUrl),\n headers() {\n return {\n \"x-trpc-source\": \"client\"\n };\n }\n } as TRouter[\"_def\"][\"_config\"][\"$types\"])\n ]\n };\n }\n });\n}\n\n/**\n * Creates a tRPC action hook for the Next.js app directory.\n *\n * @returns A function that can be used to create a tRPC action hook.\n */\nexport function createUseAction<TRouter extends AnyTRPCRouter>() {\n return experimental_createActionHook<TRouter>({\n links: [\n loggerLink(),\n experimental_serverActionLink({\n transformer\n } as TRouter[\"_def\"][\"_config\"][\"$types\"])\n ]\n } as TRouter[\"_def\"][\"_config\"][\"$types\"]) as <TDef extends ActionHandlerDef>(\n handler: TRPCActionHandler<TDef>,\n useActionOpts?: any\n ) => UseTRPCActionResult<TDef>;\n}\n"],"mappings":";;;;;;;;;;;;;;AAyCA,SAAgB,iBACd,SACA;AACA,QAAO,wCAAiD,EACtD,SAAS;AACP,SAAO,EACL,OAAO,CACL,WAAW,EACT,UAAS,QAAO,MACjB,CAAC,EACF,0BAA0B;GACxB;GACA,OAAO;GACP,KAAK,iBAAiB,QAAQ;GAC9B,UAAU;AACR,WAAO,EACL,iBAAiB,UAClB;;GAEJ,CAAyC,CAC3C,EACF;IAEJ,CAAC;;;;;;;AAQJ,SAAgB,kBAAiD;AAC/D,QAAO,8BAAuC,EAC5C,OAAO,CACL,YAAY,EACZ,8BAA8B,EAC5B,aACD,CAAyC,CAC3C,EACF,CAAyC"}
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":[],"sources":["../src/server.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../src/server.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 License, and is\n free for commercial and private use. For more information, please visit\n our licensing page.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://stormsoftware.com/projects/stryke/docs\n Contact: https://stormsoftware.com/contact\n License: https://stormsoftware.com/projects/stryke/license\n\n ------------------------------------------------------------------- */\n\nimport type { MaybePromise } from \"@stryke/types\";\nimport type { Resolver } from \"@trpc/client\";\nimport { loggerLink } from \"@trpc/client\";\nimport { experimental_nextCacheLink } from \"@trpc/next/app-dir/links/nextCache\";\nimport { experimental_createTRPCNextAppDirServer } from \"@trpc/next/app-dir/server\";\nimport type { AnyTRPCRouter, inferRouterContext } from \"@trpc/server\";\nimport type {\n AnyProcedure,\n AnyRootTypes,\n inferProcedureInput,\n inferTransformedProcedureOutput,\n ProcedureType,\n RouterRecord\n} from \"@trpc/server/unstable-core-do-not-import\";\nimport type { FeatureFlags, ResolverDef } from \"@trpc/tanstack-react-query\";\nimport type { ReadonlyRequestCookies } from \"next/dist/server/web/spec-extension/adapters/request-cookies\";\nimport { transformer } from \"./shared\";\n\nexport type DecorateProcedureServer<\n TType extends ProcedureType,\n TDef extends ResolverDef\n> = TType extends \"query\"\n ? {\n query: Resolver<TDef>;\n revalidate: (\n input?: TDef[\"input\"]\n ) => Promise<\n { revalidated: false; error: string } | { revalidated: true }\n >;\n }\n : TType extends \"mutation\"\n ? {\n mutate: Resolver<TDef>;\n }\n : TType extends \"subscription\"\n ? {\n subscribe: Resolver<TDef>;\n }\n : never;\n\nexport type NextAppDirDecorateRouterRecord<\n TRoot extends AnyRootTypes,\n TRecord extends RouterRecord\n> = {\n [TKey in keyof TRecord]: TRecord[TKey] extends infer $Value\n ? $Value extends AnyProcedure\n ? DecorateProcedureServer<\n $Value[\"_def\"][\"type\"],\n {\n input: inferProcedureInput<$Value>;\n output: inferTransformedProcedureOutput<TRoot, $Value>;\n errorShape: TRoot[\"errorShape\"];\n transformer: TRoot[\"transformer\"];\n featureFlags: FeatureFlags;\n }\n >\n : $Value extends RouterRecord\n ? NextAppDirDecorateRouterRecord<TRoot, $Value>\n : never\n : never;\n};\n\n/**\n * This client invokes procedures directly on the server without fetching over HTTP.\n *\n * @param cookies - A function that returns the cookies\n * @param router - The router created by the user\n * @param createContext - An optional function to generate a context\n */\nexport function createTRPCServer<\n TRouter extends AnyTRPCRouter,\n TContext extends inferRouterContext<TRouter> = inferRouterContext<TRouter>\n>(\n cookies: () => Promise<ReadonlyRequestCookies>,\n router: TRouter,\n createContext: () => MaybePromise<TContext> = () => ({}) as TContext\n): NextAppDirDecorateRouterRecord<\n TRouter[\"_def\"][\"_config\"][\"$types\"],\n TRouter[\"_def\"][\"record\"]\n> {\n return experimental_createTRPCNextAppDirServer<TRouter>({\n config() {\n return {\n links: [\n loggerLink({\n enabled: _op => true\n }),\n experimental_nextCacheLink({\n // requests are cached for 5 seconds\n revalidate: 5,\n router,\n transformer,\n createContext: async () => {\n const context = await Promise.resolve(createContext());\n\n context.headers ??= {};\n context.headers[\"x-trpc-source\"] = \"rsc-invoke\";\n context.headers.cookie = (await cookies()).toString();\n\n return context;\n }\n })\n ]\n };\n }\n });\n}\n\nexport {\n experimental_notFound as notFound,\n experimental_redirect as redirect\n} from \"@trpc/server/adapters/next-app-dir\";\n"],"mappings":";;;;;;;;;;;;;;AAwGA,SAAgB,iBAId,SACA,QACA,uBAAqD,EAAE,GAIvD;AACA,QAAO,wCAAiD,EACtD,SAAS;AACP,SAAO,EACL,OAAO,CACL,WAAW,EACT,UAAS,QAAO,MACjB,CAAC,EACF,2BAA2B;GAEzB,YAAY;GACZ;GACA;GACA,eAAe,YAAY;IACzB,MAAM,UAAU,MAAM,QAAQ,QAAQ,eAAe,CAAC;AAEtD,YAAQ,YAAY,EAAE;AACtB,YAAQ,QAAQ,mBAAmB;AACnC,YAAQ,QAAQ,UAAU,MAAM,SAAS,EAAE,UAAU;AAErD,WAAO;;GAEV,CAAC,CACH,EACF;IAEJ,CAAC"}
|
package/dist/shared.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.mjs","names":[],"sources":["../src/shared.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"shared.mjs","names":[],"sources":["../src/shared.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { Temporal } from \"@js-temporal/polyfill\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport type { StormURLInterface } from \"@stryke/url/types\";\nimport type { QueryClientConfig } from \"@tanstack/react-query\";\nimport {\n defaultShouldDehydrateQuery,\n QueryClient\n} from \"@tanstack/react-query\";\nimport type { DataTransformer } from \"@trpc/server/unstable-core-do-not-import\";\nimport defu from \"defu\";\nimport superjson from \"superjson\";\n\nexport function getTRPCServerUrl(\n baseUrl: string | StormURLInterface,\n version: number | null = 1\n) {\n return joinPaths(\n typeof baseUrl === \"string\" ? baseUrl : baseUrl.host || \"\",\n \"api\",\n version ? `v${version}` : \"\",\n \"trpc\"\n );\n}\n\nsuperjson.registerCustom(\n {\n isApplicable: (v): v is Temporal.PlainDate =>\n v instanceof Temporal.PlainDate,\n serialize: v => v.toJSON(),\n deserialize: v => Temporal.PlainDate.from(v)\n },\n \"Temporal.PlainDate\"\n);\n\nsuperjson.registerCustom(\n {\n isApplicable: (v): v is Temporal.PlainDateTime =>\n v instanceof Temporal.PlainDateTime,\n serialize: v => v.toJSON(),\n deserialize: v => Temporal.PlainDateTime.from(v)\n },\n \"Temporal.PlainDateTime\"\n);\n\nexport const transformer = superjson as DataTransformer;\n\n/**\n * Create a TRPC Tanstack Query client.\n *\n * @param queryClientConfig - The query client config\n * @returns The TRPC Tanstack Query client\n */\nexport const createQueryClient = (\n queryClientConfig: Partial<QueryClientConfig> = {}\n) =>\n new QueryClient(\n defu(queryClientConfig, {\n defaultOptions: {\n queries: {\n // Since queries are prefetched on the server, we set a stale time so that\n // queries aren't immediately re-fetched on the client\n staleTime: 1000 * 30\n },\n dehydrate: {\n // include pending queries in dehydration\n // this allows us to prefetch in RSC and\n // send promises over the RSC boundary\n shouldDehydrateQuery: (query: any) =>\n defaultShouldDehydrateQuery(query) ||\n query.state.status === \"pending\",\n // eslint-disable-next-line ts/unbound-method\n serializeData: transformer.serialize\n },\n hydrate: {\n // eslint-disable-next-line ts/unbound-method\n deserializeData: transformer.deserialize\n }\n }\n })\n );\n"],"mappings":";;;;;;;AA8BA,SAAgB,iBACd,SACA,UAAyB,GACzB;AACA,QAAO,UACL,OAAO,YAAY,WAAW,UAAU,QAAQ,QAAQ,IACxD,OACA,UAAU,IAAI,YAAY,IAC1B,OACD;;AAGH,UAAU,eACR;CACE,eAAe,MACb,aAAa,SAAS;CACxB,YAAW,MAAK,EAAE,QAAQ;CAC1B,cAAa,MAAK,SAAS,UAAU,KAAK,EAAE;CAC7C,EACD,qBACD;AAED,UAAU,eACR;CACE,eAAe,MACb,aAAa,SAAS;CACxB,YAAW,MAAK,EAAE,QAAQ;CAC1B,cAAa,MAAK,SAAS,cAAc,KAAK,EAAE;CACjD,EACD,yBACD;AAED,MAAa,cAAc;;;;;;;AAQ3B,MAAa,qBACX,oBAAgD,EAAE,KAElD,IAAI,YACF,KAAK,mBAAmB,EACtB,gBAAgB;CACd,SAAS,EAGP,WAAW,MAAO,IACnB;CACD,WAAW;EAIT,uBAAuB,UACrB,4BAA4B,MAAM,IAClC,MAAM,MAAM,WAAW;EAEzB,eAAe,YAAY;EAC5B;CACD,SAAS,EAEP,iBAAiB,YAAY,aAC9B;CACF,EACF,CAAC,CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constructors.mjs","names":[],"sources":["../../src/shield/constructors.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"constructors.mjs","names":[],"sources":["../../src/shield/constructors.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport {\n Rule,\n RuleAnd,\n RuleChain,\n RuleFalse,\n RuleNot,\n RuleOr,\n RuleRace,\n RuleTrue\n} from \"./rules\";\nimport type {\n RuleConstructorOptionsInterface,\n RuleFunctionInterface,\n ShieldRule\n} from \"./types\";\n\n/**\n * Wraps a function into a Rule class. This way we can identify rules\n * once we start generating middleware from our ruleTree.\n *\n * ```\n * // 1.\n * const auth = rule()(async (ctx, type, path, input, rawInput, options) => {\n * return true\n * })\n *\n * // 2.\n * const auth = rule('name')(async (ctx, type, path, input, rawInput, options) => {\n * return true\n * })\n *\n * // 3.\n * const auth = rule({\n * name: 'name',\n * })(async (ctx, type, path, input, rawInput, options) => {\n * return true\n * })\n * ```\n */\nexport const rule =\n <TContext extends Record<string, any>>(\n name?: string,\n options?: RuleConstructorOptionsInterface\n ) =>\n (func: RuleFunctionInterface<TContext>): Rule<TContext> => {\n if (typeof name === \"object\") {\n options = name;\n name = Math.random().toString();\n } else if (typeof name === \"string\") {\n options = options ?? {};\n } else {\n name = Math.random().toString();\n options = {};\n }\n\n // @ts-ignore\n return new Rule(name, func, {});\n };\n\n/**\n * Logical operator and serves as a wrapper for and operation.\n */\nexport const and = <TContext extends Record<string, any>>(\n ...rules: ShieldRule<TContext>[]\n): RuleAnd<TContext> => {\n return new RuleAnd(rules);\n};\n\n/**\n * Logical operator and serves as a wrapper for and operation.\n */\nexport const chain = <TContext extends Record<string, any>>(\n ...rules: ShieldRule<TContext>[]\n): RuleChain<TContext> => {\n return new RuleChain(rules);\n};\n\n/**\n * Logical operator and serves as a wrapper for and operation.\n */\nexport const race = <TContext extends Record<string, any>>(\n ...rules: ShieldRule<TContext>[]\n): RuleRace<TContext> => {\n return new RuleRace(rules);\n};\n\n/**\n * Logical operator or serves as a wrapper for or operation.\n */\nexport const or = <TContext extends Record<string, any>>(\n ...rules: ShieldRule<TContext>[]\n): RuleOr<TContext> => {\n return new RuleOr(rules);\n};\n\n/**\n * Logical operator not serves as a wrapper for not operation.\n */\nexport const not = <TContext extends Record<string, any>>(\n rule: ShieldRule<TContext>,\n error?: string | Error\n): RuleNot<TContext> => {\n if (typeof error === \"string\") return new RuleNot(rule, new Error(error));\n return new RuleNot(rule, error);\n};\n\n/**\n * Allow queries.\n */\nexport const allow = new RuleTrue();\n\n/**\n * Deny queries.\n */\nexport const deny = new RuleFalse();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,MAAa,QAET,MACA,aAED,SAA0D;AACzD,KAAI,OAAO,SAAS,UAAU;AAC5B,YAAU;AACV,SAAO,KAAK,QAAQ,CAAC,UAAU;YACtB,OAAO,SAAS,SACzB,WAAU,WAAW,EAAE;MAClB;AACL,SAAO,KAAK,QAAQ,CAAC,UAAU;AAC/B,YAAU,EAAE;;AAId,QAAO,IAAI,KAAK,MAAM,MAAM,EAAE,CAAC;;;;;AAMnC,MAAa,OACX,GAAG,UACmB;AACtB,QAAO,IAAI,QAAQ,MAAM;;;;;AAM3B,MAAa,SACX,GAAG,UACqB;AACxB,QAAO,IAAI,UAAU,MAAM;;;;;AAM7B,MAAa,QACX,GAAG,UACoB;AACvB,QAAO,IAAI,SAAS,MAAM;;;;;AAM5B,MAAa,MACX,GAAG,UACkB;AACrB,QAAO,IAAI,OAAO,MAAM;;;;;AAM1B,MAAa,OACX,MACA,UACsB;AACtB,KAAI,OAAO,UAAU,SAAU,QAAO,IAAI,QAAQ,MAAM,IAAI,MAAM,MAAM,CAAC;AACzE,QAAO,IAAI,QAAQ,MAAM,MAAM;;;;;AAMjC,MAAa,QAAQ,IAAI,UAAU;;;;AAKnC,MAAa,OAAO,IAAI,WAAW"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.mjs","names":[],"sources":["../../src/shield/generator.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"generator.mjs","names":[],"sources":["../../src/shield/generator.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { IRules, OptionsInterface, ShieldRule } from \"./types\";\n\n/**\n * Generates middleware from given rules.\n */\nexport function generateMiddlewareFromRuleTree<\n TContext extends Record<string, unknown>\n>(ruleTree: IRules<TContext>, options: OptionsInterface<TContext>) {\n return async ({\n next,\n ctx,\n type,\n path,\n input,\n rawInput\n }: {\n next: () => Promise<any>;\n ctx: TContext;\n type: string;\n path: string;\n input: { [name: string]: any };\n rawInput: unknown;\n }) => {\n const opWithPath: Array<string> = path.split(\".\");\n const opName: string = opWithPath[opWithPath.length - 1]!;\n const keys = Object.keys(ruleTree);\n let rule: ShieldRule<TContext> | undefined;\n if (keys.includes(\"query\") || keys.includes(\"mutation\")) {\n // @ts-ignore\n rule = ruleTree?.[type]?.[opName];\n } else {\n const namespace = opWithPath[0];\n\n const tree = (ruleTree as Record<string, any>)[namespace!];\n if (tree?.[type]?.[opName]) {\n rule = tree?.[type]?.[opName];\n }\n }\n rule = rule ?? options.fallbackRule;\n\n if (rule) {\n return rule\n ?.resolve(ctx, type, path, input, rawInput, options)\n .then(async result => {\n if (result instanceof Error) {\n throw result;\n }\n if (!result) {\n throw options.fallbackError;\n }\n\n return next();\n });\n }\n\n return next();\n };\n}\n"],"mappings":";;;;AAuBA,SAAgB,+BAEd,UAA4B,SAAqC;AACjE,QAAO,OAAO,EACZ,MACA,KACA,MACA,MACA,OACA,eAQI;EACJ,MAAM,aAA4B,KAAK,MAAM,IAAI;EACjD,MAAM,SAAiB,WAAW,WAAW,SAAS;EACtD,MAAM,OAAO,OAAO,KAAK,SAAS;EAClC,IAAI;AACJ,MAAI,KAAK,SAAS,QAAQ,IAAI,KAAK,SAAS,WAAW,CAErD,QAAO,WAAW,QAAQ;OACrB;GAGL,MAAM,OAAQ,SAFI,WAAW;AAG7B,OAAI,OAAO,QAAQ,QACjB,QAAO,OAAO,QAAQ;;AAG1B,SAAO,QAAQ,QAAQ;AAEvB,MAAI,KACF,QAAO,MACH,QAAQ,KAAK,MAAM,MAAM,OAAO,UAAU,QAAQ,CACnD,KAAK,OAAM,WAAU;AACpB,OAAI,kBAAkB,MACpB,OAAM;AAER,OAAI,CAAC,OACH,OAAM,QAAQ;AAGhB,UAAO,MAAM;IACb;AAGN,SAAO,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.mjs","names":[],"sources":["../../src/shield/rules.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type {\n LogicRuleInterface,\n OptionsInterface,\n RuleFunctionInterface,\n RuleInterface,\n RuleResultInterface,\n ShieldRule\n} from \"./types\";\n\nexport class Rule<\n TContext extends Record<string, any>\n> implements RuleInterface<TContext> {\n readonly name: string;\n\n func?: RuleFunctionInterface<TContext>;\n\n constructor(name: string, func?: RuleFunctionInterface<TContext>) {\n this.name = name;\n this.func = func;\n }\n\n async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n try {\n /* Resolve */\n const res = await this.executeRule(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (res instanceof Error) {\n return res;\n } else if (typeof res === \"string\") {\n return new Error(res);\n } else if (res === true) {\n return true;\n } else {\n return false;\n }\n } catch (err) {\n if (options.debug) {\n throw err;\n } else {\n return false;\n }\n }\n }\n\n /**\n *\n * Compares a given rule with the current one\n * and checks whether their functions are equal.\n *\n */\n equals(rule: Rule<TContext>): boolean {\n return this.func === rule.func;\n }\n\n executeRule<TContext extends Record<string, any>>(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): string | boolean | Error | Promise<RuleResultInterface> {\n // @ts-ignore\n return this.func(ctx, type, path, input, rawInput, options);\n }\n}\n\nexport class LogicRule<TContext extends Record<string, any>>\n extends Rule<TContext>\n implements LogicRuleInterface<TContext>\n{\n private rules: ShieldRule<TContext>[];\n\n constructor(rules: ShieldRule<TContext>[]) {\n super(\"LogicRule\");\n\n this.rules = rules;\n }\n\n /**\n * By default logic rule resolves to false.\n */\n override async resolve(\n _ctx: TContext,\n _type: string,\n _path: string,\n _input: { [name: string]: any },\n _rawInput: unknown,\n _options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n return false;\n }\n\n /**\n * Evaluates all the rules.\n */\n async evaluate(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface[]> {\n const rules = this.getRules();\n const tasks = rules.map(async rule =>\n rule.resolve(ctx, type, path, input, rawInput, options)\n );\n\n return Promise.all(tasks);\n }\n\n /**\n * Returns rules in a logic rule.\n */\n getRules() {\n return this.rules;\n }\n}\n\n// Extended Types\n\nexport class RuleOr<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that at least one of them has evaluated to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.every(res => res !== true)) {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n } else {\n return true;\n }\n }\n}\n\nexport class RuleAnd<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that all of them have resolved to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.some(res => res !== true)) {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n } else {\n return true;\n }\n }\n}\n\nexport class RuleChain<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that all of them have resolved to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.some(res => res !== true)) {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n } else {\n return true;\n }\n }\n\n /**\n * Evaluates all the rules.\n */\n override async evaluate(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface[]> {\n const rules = this.getRules();\n\n return iterate(rules);\n\n async function iterate([\n rule,\n ...otherRules\n ]: ShieldRule<TContext>[]): Promise<RuleResultInterface[]> {\n if (rule === undefined) return [];\n return rule\n .resolve(ctx, type, path, input, rawInput, options)\n .then(async res => {\n if (res !== true) {\n return [res];\n } else {\n return iterate(otherRules).then(ress => ress.concat(res));\n }\n });\n }\n }\n}\n\nexport class RuleRace<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that at least one of them resolved to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.includes(true)) {\n return true;\n } else {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n }\n }\n\n /**\n * Evaluates all the rules.\n */\n override async evaluate(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface[]> {\n const rules = this.getRules();\n\n return iterate(rules);\n\n async function iterate([\n rule,\n ...otherRules\n ]: ShieldRule<TContext>[]): Promise<RuleResultInterface[]> {\n if (rule === undefined) return [];\n return rule\n .resolve(ctx, type, path, input, rawInput, options)\n .then(async res => {\n if (res === true) {\n return [res];\n } else {\n return iterate(otherRules).then(ress => ress.concat(res));\n }\n });\n }\n }\n}\n\nexport class RuleNot<TContext extends Record<string, any>>\n extends LogicRule<TContext>\n implements LogicRuleInterface<TContext>\n{\n error?: Error;\n\n override name: string = \"RuleNot\";\n\n override equals!: (rule: RuleInterface<TContext>) => boolean;\n\n constructor(rule: ShieldRule<TContext>, error?: Error) {\n super([rule]);\n this.error = error;\n }\n\n /**\n * Negates the result.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const [res] = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (res instanceof Error) {\n return true;\n } else if (res !== true) {\n return true;\n } else {\n if (this.error) return this.error;\n return false;\n }\n }\n}\n\nexport class RuleTrue<TContext extends Record<string, any>>\n extends LogicRule<TContext>\n implements LogicRuleInterface<TContext>\n{\n override name: string = \"RuleTrue\";\n\n override equals!: (rule: RuleInterface<TContext>) => boolean;\n\n constructor() {\n super([]);\n }\n\n /**\n *\n * Always true.\n *\n */\n override async resolve(): Promise<RuleResultInterface> {\n return true;\n }\n}\n\nexport class RuleFalse<TContext extends Record<string, any>>\n extends LogicRule<TContext>\n implements LogicRuleInterface<TContext>\n{\n override name: string = \"RuleTrue\";\n\n override equals!: (rule: RuleInterface<TContext>) => boolean;\n\n constructor() {\n super([]);\n }\n\n /**\n *\n * Always false.\n *\n */\n override async resolve(): Promise<RuleResultInterface> {\n return false;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rules.mjs","names":[],"sources":["../../src/shield/rules.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type {\n LogicRuleInterface,\n OptionsInterface,\n RuleFunctionInterface,\n RuleInterface,\n RuleResultInterface,\n ShieldRule\n} from \"./types\";\n\nexport class Rule<\n TContext extends Record<string, any>\n> implements RuleInterface<TContext> {\n readonly name: string;\n\n func?: RuleFunctionInterface<TContext>;\n\n constructor(name: string, func?: RuleFunctionInterface<TContext>) {\n this.name = name;\n this.func = func;\n }\n\n async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n try {\n /* Resolve */\n const res = await this.executeRule(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (res instanceof Error) {\n return res;\n } else if (typeof res === \"string\") {\n return new Error(res);\n } else if (res === true) {\n return true;\n } else {\n return false;\n }\n } catch (err) {\n if (options.debug) {\n throw err;\n } else {\n return false;\n }\n }\n }\n\n /**\n *\n * Compares a given rule with the current one\n * and checks whether their functions are equal.\n *\n */\n equals(rule: Rule<TContext>): boolean {\n return this.func === rule.func;\n }\n\n executeRule<TContext extends Record<string, any>>(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): string | boolean | Error | Promise<RuleResultInterface> {\n // @ts-ignore\n return this.func(ctx, type, path, input, rawInput, options);\n }\n}\n\nexport class LogicRule<TContext extends Record<string, any>>\n extends Rule<TContext>\n implements LogicRuleInterface<TContext>\n{\n private rules: ShieldRule<TContext>[];\n\n constructor(rules: ShieldRule<TContext>[]) {\n super(\"LogicRule\");\n\n this.rules = rules;\n }\n\n /**\n * By default logic rule resolves to false.\n */\n override async resolve(\n _ctx: TContext,\n _type: string,\n _path: string,\n _input: { [name: string]: any },\n _rawInput: unknown,\n _options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n return false;\n }\n\n /**\n * Evaluates all the rules.\n */\n async evaluate(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface[]> {\n const rules = this.getRules();\n const tasks = rules.map(async rule =>\n rule.resolve(ctx, type, path, input, rawInput, options)\n );\n\n return Promise.all(tasks);\n }\n\n /**\n * Returns rules in a logic rule.\n */\n getRules() {\n return this.rules;\n }\n}\n\n// Extended Types\n\nexport class RuleOr<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that at least one of them has evaluated to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.every(res => res !== true)) {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n } else {\n return true;\n }\n }\n}\n\nexport class RuleAnd<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that all of them have resolved to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.some(res => res !== true)) {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n } else {\n return true;\n }\n }\n}\n\nexport class RuleChain<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that all of them have resolved to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.some(res => res !== true)) {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n } else {\n return true;\n }\n }\n\n /**\n * Evaluates all the rules.\n */\n override async evaluate(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface[]> {\n const rules = this.getRules();\n\n return iterate(rules);\n\n async function iterate([\n rule,\n ...otherRules\n ]: ShieldRule<TContext>[]): Promise<RuleResultInterface[]> {\n if (rule === undefined) return [];\n return rule\n .resolve(ctx, type, path, input, rawInput, options)\n .then(async res => {\n if (res !== true) {\n return [res];\n } else {\n return iterate(otherRules).then(ress => ress.concat(res));\n }\n });\n }\n }\n}\n\nexport class RuleRace<\n TContext extends Record<string, any>\n> extends LogicRule<TContext> {\n constructor(rules: ShieldRule<TContext>[]) {\n super(rules);\n }\n\n /**\n * Makes sure that at least one of them resolved to true.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const result = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (result.includes(true)) {\n return true;\n } else {\n const customError = result.find(res => res instanceof Error);\n\n return customError ?? false;\n }\n }\n\n /**\n * Evaluates all the rules.\n */\n override async evaluate(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface[]> {\n const rules = this.getRules();\n\n return iterate(rules);\n\n async function iterate([\n rule,\n ...otherRules\n ]: ShieldRule<TContext>[]): Promise<RuleResultInterface[]> {\n if (rule === undefined) return [];\n return rule\n .resolve(ctx, type, path, input, rawInput, options)\n .then(async res => {\n if (res === true) {\n return [res];\n } else {\n return iterate(otherRules).then(ress => ress.concat(res));\n }\n });\n }\n }\n}\n\nexport class RuleNot<TContext extends Record<string, any>>\n extends LogicRule<TContext>\n implements LogicRuleInterface<TContext>\n{\n error?: Error;\n\n override name: string = \"RuleNot\";\n\n override equals!: (rule: RuleInterface<TContext>) => boolean;\n\n constructor(rule: ShieldRule<TContext>, error?: Error) {\n super([rule]);\n this.error = error;\n }\n\n /**\n * Negates the result.\n */\n override async resolve(\n ctx: TContext,\n type: string,\n path: string,\n input: { [name: string]: any },\n rawInput: unknown,\n options: OptionsInterface<TContext>\n ): Promise<RuleResultInterface> {\n const [res] = await this.evaluate(\n ctx,\n type,\n path,\n input,\n rawInput,\n options\n );\n\n if (res instanceof Error) {\n return true;\n } else if (res !== true) {\n return true;\n } else {\n if (this.error) return this.error;\n return false;\n }\n }\n}\n\nexport class RuleTrue<TContext extends Record<string, any>>\n extends LogicRule<TContext>\n implements LogicRuleInterface<TContext>\n{\n override name: string = \"RuleTrue\";\n\n override equals!: (rule: RuleInterface<TContext>) => boolean;\n\n constructor() {\n super([]);\n }\n\n /**\n *\n * Always true.\n *\n */\n override async resolve(): Promise<RuleResultInterface> {\n return true;\n }\n}\n\nexport class RuleFalse<TContext extends Record<string, any>>\n extends LogicRule<TContext>\n implements LogicRuleInterface<TContext>\n{\n override name: string = \"RuleTrue\";\n\n override equals!: (rule: RuleInterface<TContext>) => boolean;\n\n constructor() {\n super([]);\n }\n\n /**\n *\n * Always false.\n *\n */\n override async resolve(): Promise<RuleResultInterface> {\n return false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield.mjs","names":[],"sources":["../../src/shield/shield.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"shield.mjs","names":[],"sources":["../../src/shield/shield.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { MiddlewareFunction } from \"@trpc/server/unstable-core-do-not-import\";\nimport { allow } from \"./constructors\";\nimport { generateMiddlewareFromRuleTree } from \"./generator\";\nimport type {\n IFallbackErrorType,\n IRules,\n OptionsConstructorInterface,\n OptionsInterface,\n ShieldRule\n} from \"./types\";\nimport { withDefault } from \"./utils\";\nimport { ValidationError, validateRuleTree } from \"./validation\";\n\n/**\n * Makes sure all of defined rules are in accord with the options\n * shield can process.\n */\nfunction normalizeOptions<TContext extends Record<string, any>>(\n options: OptionsConstructorInterface<TContext>\n): OptionsInterface<TContext> {\n if (typeof options.fallbackError === \"string\") {\n options.fallbackError = new Error(options.fallbackError);\n }\n\n return {\n debug: options.debug ?? false,\n allowExternalErrors: withDefault(false)(options.allowExternalErrors),\n fallbackRule: withDefault<ShieldRule<TContext>>(\n allow as ShieldRule<TContext>\n )(options.fallbackRule),\n fallbackError: withDefault<IFallbackErrorType<TContext>>(\n new Error(\"Authorization error\")\n )(options.fallbackError)\n };\n}\n\n/**\n * Validates rules and generates middleware from defined rule tree.\n */\nexport function shield<\n TContext extends Record<string, any>,\n TMeta extends object = object\n>(\n ruleTree: IRules<TContext>,\n options: OptionsConstructorInterface<TContext> = {}\n): MiddlewareFunction<TContext, TMeta, TContext, TContext, unknown> {\n const normalizedOptions = normalizeOptions<TContext>(options);\n const ruleTreeValidity = validateRuleTree<TContext>(ruleTree);\n\n if (ruleTreeValidity.status === \"ok\") {\n return generateMiddlewareFromRuleTree<TContext>(\n ruleTree,\n normalizedOptions\n ) as any;\n } else {\n throw new ValidationError(ruleTreeValidity.message);\n }\n}\n"],"mappings":";;;;;;;;;;AAmCA,SAAS,iBACP,SAC4B;AAC5B,KAAI,OAAO,QAAQ,kBAAkB,SACnC,SAAQ,gBAAgB,IAAI,MAAM,QAAQ,cAAc;AAG1D,QAAO;EACL,OAAO,QAAQ,SAAS;EACxB,qBAAqB,YAAY,MAAM,CAAC,QAAQ,oBAAoB;EACpE,cAAc,YACZ,MACD,CAAC,QAAQ,aAAa;EACvB,eAAe,4BACb,IAAI,MAAM,sBAAsB,CACjC,CAAC,QAAQ,cAAc;EACzB;;;;;AAMH,SAAgB,OAId,UACA,UAAiD,EAAE,EACe;CAClE,MAAM,oBAAoB,iBAA2B,QAAQ;CAC7D,MAAM,mBAAmB,iBAA2B,SAAS;AAE7D,KAAI,iBAAiB,WAAW,KAC9B,QAAO,+BACL,UACA,kBACD;KAED,OAAM,IAAI,gBAAgB,iBAAiB,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":[],"sources":["../../src/shield/utils.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../../src/shield/utils.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { LogicRule, Rule } from \"./rules\";\nimport type {\n LogicRuleInterface,\n RuleFieldMapInterface,\n RuleInterface,\n ShieldRule\n} from \"./types\";\n\n/**\n * Makes sure that a certain field is a rule.\n */\nexport function isRule<TContext extends Record<string, any>>(\n x: any\n): x is RuleInterface<TContext> {\n return (\n x instanceof Rule || (x && x.constructor && x.constructor.name === \"Rule\")\n );\n}\n\n/**\n * Makes sure that a certain field is a logic rule.\n */\nexport function isLogicRule<TContext extends Record<string, any>>(\n x: any\n): x is LogicRuleInterface<TContext> {\n return (\n x instanceof LogicRule ||\n (x &&\n x.constructor &&\n (x.constructor.name === \"RuleOr\" ||\n x.constructor.name === \"RuleAnd\" ||\n x.constructor.name === \"RuleChain\" ||\n x.constructor.name === \"RuleRace\" ||\n x.constructor.name === \"RuleNot\" ||\n x.constructor.name === \"RuleTrue\" ||\n x.constructor.name === \"RuleFalse\"))\n );\n}\n\n/**\n * Makes sure that a certain field is a rule or a logic rule.\n */\nexport function isRuleFunction<TContext extends Record<string, any>>(\n x: any\n): x is ShieldRule<TContext> {\n return isRule(x) || isLogicRule(x);\n}\n\n/**\n * Determines whether a certain field is rule field map or not.\n */\nexport function isRuleFieldMap<TContext extends Record<string, any>>(\n x: any\n): x is RuleFieldMapInterface<TContext> {\n return (\n typeof x === \"object\" &&\n Object.values(x).every(rule => isRuleFunction(rule))\n );\n}\n\n/**\n * Flattens object of particular type by checking if the leaf\n * evaluates to true from particular function.\n */\nexport function flattenObjectOf<T>(\n obj: { [key: string]: any },\n f: (x: any) => boolean\n): T[] {\n const values = Object.keys(obj).reduce<T[]>((acc, key) => {\n const val = obj[key];\n if (f(val)) {\n return [...acc, val];\n } else if (typeof val === \"object\" && !f(val)) {\n return [...acc, ...flattenObjectOf(val, f)];\n } else {\n return acc;\n }\n }, []);\n\n return values;\n}\n\n/**\n * Returns fallback is provided value is undefined\n */\nexport function withDefault<T>(fallback: T): (value: T | undefined) => T {\n return value => {\n if (value === undefined) return fallback;\n return value;\n };\n}\n"],"mappings":";;;;;;AA6BA,SAAgB,OACd,GAC8B;AAC9B,QACE,aAAa,QAAS,KAAK,EAAE,eAAe,EAAE,YAAY,SAAS;;;;;AAOvE,SAAgB,YACd,GACmC;AACnC,QACE,aAAa,aACZ,KACC,EAAE,gBACD,EAAE,YAAY,SAAS,YACtB,EAAE,YAAY,SAAS,aACvB,EAAE,YAAY,SAAS,eACvB,EAAE,YAAY,SAAS,cACvB,EAAE,YAAY,SAAS,aACvB,EAAE,YAAY,SAAS,cACvB,EAAE,YAAY,SAAS;;;;;AAO/B,SAAgB,eACd,GAC2B;AAC3B,QAAO,OAAO,EAAE,IAAI,YAAY,EAAE;;;;;AAMpC,SAAgB,eACd,GACsC;AACtC,QACE,OAAO,MAAM,YACb,OAAO,OAAO,EAAE,CAAC,OAAM,SAAQ,eAAe,KAAK,CAAC;;;;;;AAQxD,SAAgB,gBACd,KACA,GACK;AAYL,QAXe,OAAO,KAAK,IAAI,CAAC,QAAa,KAAK,QAAQ;EACxD,MAAM,MAAM,IAAI;AAChB,MAAI,EAAE,IAAI,CACR,QAAO,CAAC,GAAG,KAAK,IAAI;WACX,OAAO,QAAQ,YAAY,CAAC,EAAE,IAAI,CAC3C,QAAO,CAAC,GAAG,KAAK,GAAG,gBAAgB,KAAK,EAAE,CAAC;MAE3C,QAAO;IAER,EAAE,CAEQ;;;;;AAMf,SAAgB,YAAe,UAA0C;AACvE,SAAO,UAAS;AACd,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.mjs","names":[],"sources":["../../src/shield/validation.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"validation.mjs","names":[],"sources":["../../src/shield/validation.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type {\n IRules,\n LogicRuleInterface,\n RuleInterface,\n ShieldRule\n} from \"./types\";\nimport { flattenObjectOf, isLogicRule, isRuleFunction } from \"./utils\";\n\n/**\n * Validates the rule tree declaration by checking references of rule\n * functions. We deem rule tree valid if no two rules with the same name point\n * to different rules.\n */\nexport function validateRuleTree<TContext extends Record<string, any>>(\n ruleTree: IRules<TContext>\n): { status: \"ok\" } | { status: \"err\"; message: string } {\n const rules = extractRules(ruleTree);\n\n const valid = rules.reduce<{\n map: Map<string, RuleInterface<TContext>>;\n duplicates: string[];\n }>(\n ({ map, duplicates }, rule) => {\n if (!map.has(rule.name)) {\n return { map: map.set(rule.name, rule), duplicates };\n } else if (\n !map.get(rule.name)!.equals(rule) &&\n !duplicates.includes(rule.name)\n ) {\n return {\n map: map.set(rule.name, rule),\n duplicates: [...duplicates, rule.name]\n };\n } else {\n return { map, duplicates };\n }\n },\n { map: new Map<string, RuleInterface<TContext>>(), duplicates: [] }\n );\n\n if (valid.duplicates.length === 0) {\n return { status: \"ok\" };\n } else {\n const duplicates = valid.duplicates.join(\", \");\n\n return {\n status: \"err\",\n message: `There seem to be multiple definitions of these rules: ${duplicates}`\n };\n }\n\n /**\n * Extracts rules from rule tree.\n */\n function extractRules<TContext extends Record<string, any>>(\n ruleTree: IRules<TContext>\n ): RuleInterface<TContext>[] {\n const resolvers = flattenObjectOf<ShieldRule<TContext>>(\n ruleTree,\n isRuleFunction\n );\n\n const rules = resolvers.reduce<RuleInterface<TContext>[]>((rules, rule) => {\n if (isLogicRule(rule)) {\n return [\n ...rules,\n ...extractLogicRules(rule)\n ] as RuleInterface<TContext>[];\n } else {\n return [...rules, rule] as RuleInterface<TContext>[];\n }\n }, []);\n\n return rules;\n }\n\n /**\n * Recursively extracts Rules from LogicRule\n */\n function extractLogicRules<TContext extends Record<string, any>>(\n rule: LogicRuleInterface<TContext>\n ): RuleInterface<TContext>[] {\n return rule\n .getRules()\n .reduce<RuleInterface<TContext>[]>((acc, shieldRule) => {\n if (isLogicRule(shieldRule)) {\n return [\n ...acc,\n ...extractLogicRules(shieldRule)\n ] as RuleInterface<TContext>[];\n } else {\n return [...acc, shieldRule] as RuleInterface<TContext>[];\n }\n }, []);\n }\n}\n\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n"],"mappings":";;;;;;;;AA+BA,SAAgB,iBACd,UACuD;CAGvD,MAAM,QAFQ,aAAa,SAER,CAAC,QAIjB,EAAE,KAAK,cAAc,SAAS;AAC7B,MAAI,CAAC,IAAI,IAAI,KAAK,KAAK,CACrB,QAAO;GAAE,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK;GAAE;GAAY;WAEpD,CAAC,IAAI,IAAI,KAAK,KAAK,CAAE,OAAO,KAAK,IACjC,CAAC,WAAW,SAAS,KAAK,KAAK,CAE/B,QAAO;GACL,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK;GAC7B,YAAY,CAAC,GAAG,YAAY,KAAK,KAAK;GACvC;MAED,QAAO;GAAE;GAAK;GAAY;IAG9B;EAAE,qBAAK,IAAI,KAAsC;EAAE,YAAY,EAAE;EAAE,CACpE;AAED,KAAI,MAAM,WAAW,WAAW,EAC9B,QAAO,EAAE,QAAQ,MAAM;KAIvB,QAAO;EACL,QAAQ;EACR,SAAS,yDAJQ,MAAM,WAAW,KAAK,KAIqC;EAC7E;;;;CAMH,SAAS,aACP,UAC2B;AAiB3B,SAhBkB,gBAChB,UACA,eAGqB,CAAC,QAAmC,OAAO,SAAS;AACzE,OAAI,YAAY,KAAK,CACnB,QAAO,CACL,GAAG,OACH,GAAG,kBAAkB,KAAK,CAC3B;OAED,QAAO,CAAC,GAAG,OAAO,KAAK;KAExB,EAAE,CAEO;;;;;CAMd,SAAS,kBACP,MAC2B;AAC3B,SAAO,KACJ,UAAU,CACV,QAAmC,KAAK,eAAe;AACtD,OAAI,YAAY,WAAW,CACzB,QAAO,CACL,GAAG,KACH,GAAG,kBAAkB,WAAW,CACjC;OAED,QAAO,CAAC,GAAG,KAAK,WAAW;KAE5B,EAAE,CAAC;;;AAIZ,IAAa,kBAAb,cAAqC,MAAM;CACzC,YAAY,SAAiB;AAC3B,QAAM,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../../src/tanstack-query/client.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../src/tanstack-query/client.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\n\"use client\";\n\nimport { isDevelopment } from \"@stryke/env\";\nimport type { StormURLInterface } from \"@stryke/url\";\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport { QueryClientProvider } from \"@tanstack/react-query\";\nimport {\n createTRPCClient,\n httpBatchStreamLink,\n loggerLink\n} from \"@trpc/client\";\nimport type { AnyTRPCRouter } from \"@trpc/server\";\nimport { createTRPCContext } from \"@trpc/tanstack-react-query\";\nimport { useState } from \"react\";\nimport { getTRPCServerUrl, transformer } from \"../shared\";\n\n/**\n * Create a TRPC Tanstack Query client.\n *\n * @returns The TRPC Tanstack Query client\n */\nexport function createTRPCTanstackQueryClient<TRouter extends AnyTRPCRouter>(\n baseUrl: string | StormURLInterface,\n queryClient: QueryClient\n) {\n const { TRPCProvider, useTRPC } = createTRPCContext<TRouter>();\n\n return {\n useTRPCTanstackQuery: useTRPC,\n TRPCTanstackQueryProvider: (props: { children: React.ReactNode }) => {\n const { children } = props;\n\n const [trpcClient] = useState(() =>\n createTRPCClient<TRouter>({\n links: [\n loggerLink({\n enabled: op =>\n isDevelopment ||\n (op.direction === \"down\" && op.result instanceof Error)\n }),\n httpBatchStreamLink<TRouter>({\n transformer,\n url: getTRPCServerUrl(baseUrl),\n headers: { \"x-trpc-source\": \"react-query\" }\n } as TRouter[\"_def\"][\"_config\"][\"$types\"])\n ]\n })\n );\n\n return (\n <TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n </TRPCProvider>\n );\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAuCA,SAAgB,8BACd,SACA,aACA;CACA,MAAM,EAAE,cAAc,YAAY,mBAA4B;AAE9D,QAAO;EACL,sBAAsB;EACtB,4BAA4B,UAAyC;GACnE,MAAM,EAAE,aAAa;GAErB,MAAM,CAAC,cAAc,eACnB,iBAA0B,EACxB,OAAO,CACL,WAAW,EACT,UAAS,OACP,iBACC,GAAG,cAAc,UAAU,GAAG,kBAAkB,OACpD,CAAC,EACF,oBAA6B;IAC3B;IACA,KAAK,iBAAiB,QAAQ;IAC9B,SAAS,EAAE,iBAAiB,eAAe;IAC5C,CAAyC,CAC3C,EACF,CAAC,CACH;AAED,UACE,oBAAC,cAAD;IAA0B;IAAyB;cACjD,oBAAC,qBAAD;KAAqB,QAAQ;KAC1B;KACmB;IACT;;EAGpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":[],"sources":["../../src/tanstack-query/server.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../../src/tanstack-query/server.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { MaybePromise } from \"@stryke/types\";\nimport type { QueryClientConfig } from \"@tanstack/react-query\";\nimport { dehydrate, HydrationBoundary } from \"@tanstack/react-query\";\nimport type { AnyTRPCRouter, inferRouterContext } from \"@trpc/server\";\nimport type { TRPCQueryOptions } from \"@trpc/tanstack-react-query\";\nimport { createTRPCOptionsProxy } from \"@trpc/tanstack-react-query\";\nimport defu from \"defu\";\nimport React, { cache } from \"react\";\nimport \"server-only\";\nimport { createQueryClient } from \"../shared\";\n\n/**\n * Create a TRPC Tanstack Query server.\n *\n * @example\n * ```tsx title=\"app/api/trpc/route.tsx\"\n * import { createTRPCTanstackQueryServer } from \"@trpc-next/tanstack-query/server\";\n * import { z } from \"zod\";\n * import { createRouter } from \"@trpc/server\";\n *\n * const router = createRouter().query(\"hello\", {\n * input: z.object({\n * name: z.string()\n * }),\n * resolve({ input }) {\n * return `Hello, ${input.name}!`;\n * }\n * });\n *\n * const { trpc, HydrateClient } = createTRPCTanstackQueryServer({\n * router,\n * headers: async () => new Headers()\n * });\n * ```\n *\n * @param headers - A function that returns the headers for the TRPC context.\n * @param router - The TRPC router to use for the server.\n * @param createContext - A function that creates the context for the TRPC server.\n * @param queryClientConfig - Optional configuration for the Tanstack Query client.\n * @returns An object containing the TRPC context and a component to hydrate the client state.\n */\nexport function createTRPCTanstackQueryServer<\n TRouter extends AnyTRPCRouter,\n TContext extends inferRouterContext<TRouter> = inferRouterContext<TRouter>\n>(\n headers: () => Promise<Headers>,\n router: TRouter,\n createContext: () => MaybePromise<TContext> = () => ({}) as TContext,\n queryClientConfig: Partial<QueryClientConfig> = {}\n) {\n const _createContext = cache(async (): Promise<TContext> => {\n const context = await Promise.resolve(createContext());\n\n const _headers = new Headers(await headers());\n _headers.set(\"x-trpc-source\", \"rsc\");\n\n return defu(\n {\n headers: Object.fromEntries(_headers)\n },\n context\n ) as TContext;\n });\n\n /**\n * Create a stable getter for the query client that\n * will return the same client during the same request.\n */\n const getQueryClient = cache(() => createQueryClient(queryClientConfig));\n\n const trpc = createTRPCOptionsProxy({\n router,\n queryClient: getQueryClient,\n ctx: _createContext\n });\n\n return {\n trpc,\n HydrateClient: (props: { children: React.ReactNode }) => {\n const dehydratedState = dehydrate(getQueryClient());\n\n return (\n <HydrationBoundary state={dehydratedState}>\n {props.children}\n </HydrationBoundary>\n );\n },\n prefetch: <T extends ReturnType<TRPCQueryOptions<any>>>(\n queryOptions: T\n ) => {\n const queryClient = getQueryClient();\n if (queryOptions.queryKey[1]?.type === \"infinite\") {\n void queryClient.prefetchInfiniteQuery(queryOptions as any);\n } else {\n void queryClient.prefetchQuery(queryOptions);\n }\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,SAAgB,8BAId,SACA,QACA,uBAAqD,EAAE,GACvD,oBAAgD,EAAE,EAClD;CACA,MAAM,iBAAiB,MAAM,YAA+B;EAC1D,MAAM,UAAU,MAAM,QAAQ,QAAQ,eAAe,CAAC;EAEtD,MAAM,WAAW,IAAI,QAAQ,MAAM,SAAS,CAAC;AAC7C,WAAS,IAAI,iBAAiB,MAAM;AAEpC,SAAO,KACL,EACE,SAAS,OAAO,YAAY,SAAS,EACtC,EACD,QACD;GACD;;;;;CAMF,MAAM,iBAAiB,YAAY,kBAAkB,kBAAkB,CAAC;AAQxE,QAAO;EACL,MAPW,uBAAuB;GAClC;GACA,aAAa;GACb,KAAK;GACN,CAGK;EACJ,gBAAgB,UAAyC;AAGvD,UACE,oBAAC,mBAAD;IAAmB,OAHG,UAAU,gBAAgB,CAGP;cACtC,MAAM;IACW;;EAGxB,WACE,iBACG;GACH,MAAM,cAAc,gBAAgB;AACpC,OAAI,aAAa,SAAS,IAAI,SAAS,WACrC,CAAK,YAAY,sBAAsB,aAAoB;OAE3D,CAAK,YAAY,cAAc,aAAa;;EAGjD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stryke/trpc-next",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.106",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A package to help in using tRPC in modern NextJs applications.",
|
|
6
6
|
"repository": {
|
|
@@ -75,18 +75,18 @@
|
|
|
75
75
|
"types": "./dist/index.d.cts",
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@js-temporal/polyfill": "^0.5.1",
|
|
78
|
-
"@stryke/env": "^0.20.
|
|
79
|
-
"@stryke/fs": "^0.33.
|
|
80
|
-
"@stryke/path": "^0.29.
|
|
81
|
-
"@stryke/string-format": "^0.17.
|
|
82
|
-
"@stryke/type-checks": "^0.6.
|
|
83
|
-
"@stryke/types": "^0.12.
|
|
84
|
-
"@stryke/url": "^0.4.
|
|
78
|
+
"@stryke/env": "^0.20.104",
|
|
79
|
+
"@stryke/fs": "^0.33.87",
|
|
80
|
+
"@stryke/path": "^0.29.13",
|
|
81
|
+
"@stryke/string-format": "^0.17.28",
|
|
82
|
+
"@stryke/type-checks": "^0.6.19",
|
|
83
|
+
"@stryke/types": "^0.12.14",
|
|
84
|
+
"@stryke/url": "^0.4.37",
|
|
85
85
|
"@tanstack/react-query": "^5.101.0",
|
|
86
|
-
"@trpc/client": "^11.
|
|
87
|
-
"@trpc/next": "^11.
|
|
88
|
-
"@trpc/server": "^11.
|
|
89
|
-
"@trpc/tanstack-react-query": "^11.
|
|
86
|
+
"@trpc/client": "^11.18.0",
|
|
87
|
+
"@trpc/next": "^11.18.0",
|
|
88
|
+
"@trpc/server": "^11.18.0",
|
|
89
|
+
"@trpc/tanstack-react-query": "^11.18.0",
|
|
90
90
|
"defu": "^6.1.7",
|
|
91
91
|
"server-only": "^0.0.1",
|
|
92
92
|
"superjson": "^2.2.6"
|
|
@@ -95,6 +95,9 @@
|
|
|
95
95
|
"@types/react": "^19.2.17",
|
|
96
96
|
"@types/react-dom": "^19.2.3",
|
|
97
97
|
"@types/react-native": "0.72.8",
|
|
98
|
+
"react": "^19.2.7",
|
|
99
|
+
"react-dom": "^19.2.7",
|
|
100
|
+
"react-native": "^0.77.3",
|
|
98
101
|
"tsdown": "^0.21.10"
|
|
99
102
|
},
|
|
100
103
|
"peerDependencies": {
|
|
@@ -108,5 +111,5 @@
|
|
|
108
111
|
"react-native": { "optional": true }
|
|
109
112
|
},
|
|
110
113
|
"publishConfig": { "access": "public" },
|
|
111
|
-
"gitHead": "
|
|
114
|
+
"gitHead": "d3f870d01085e6fa75e7bb1b82609476531953fe"
|
|
112
115
|
}
|