sapphiredev / shapeshift Goto Github PK
View Code? Open in Web Editor NEWBlazing fast input validation and transformation ⚡
Home Page: https://www.sapphirejs.dev
License: MIT License
Blazing fast input validation and transformation ⚡
Home Page: https://www.sapphirejs.dev
License: MIT License
TODO @kyranet: Implement something like zod's nativeenum
Originally posted by @vladfrangu in #44 (comment)
In a lot of cases we need to add type casts to our code because of the way it is set up. This makes development really annoying and it also removes a layer of type safety offered by TypeScript going forward. It is therefore prudent to remove the type casts and instead have TypeScript resolves types properly automatically.
Remove type casts such as shown at #40 (comment) and ensure code compiles successfully.
Continue to use type casts in the code.
Review comment from @vladfrangu #40 (comment)
Using DiscordJS and typescript, when I try to build using TSC, I get errors in sapphire/shapeshift
node_modules/@sapphire/shapeshift/dist/index.d.ts:590:44 - error TS2344: Type 'T' does not satisfy the constraint 'object'.
590 declare type SchemaOf<T> = ObjectValidator<T>;
~
node_modules/@sapphire/shapeshift/dist/index.d.ts:590:23
590 declare type SchemaOf<T> = ObjectValidator<T>;
~
This type parameter might need an `extends object` constraint.
node_modules/@sapphire/shapeshift/dist/index.d.ts:641:65 - error TS2344: Type 'T' does not satisfy the constraint 'object'.
641 object<T>(shape: MappedObjectValidator<T>): ObjectValidator<T, UndefinedToOptional<T>>;
~
node_modules/@sapphire/shapeshift/dist/index.d.ts:641:12
641 object<T>(shape: MappedObjectValidator<T>): ObjectValidator<T, UndefinedToOptional<T>>;
~
This type parameter might need an `extends object` constraint.
Found 2 errors in the same file, starting at: node_modules/@sapphire/shapeshift/dist/index.d.ts:590
Builds properly
No response
No response
Node v16, TypeScript, CommonJS, shapeshift 2.1.0
import { BaseError } from '@sapphire/shapeshift';
console.log(BaseError); // logs undefined
So the question is why BaseError is undefined?
And if this is normal behavior, then how can I check that the error was thrown by shapeshift? The original idea was to use instanceof BaseError
since all other errors inherits from it
BaseError should be exported correctly
OR
Tell me how to check that the error was thrown by shapeshift without instanceof BaseError
No response
Sorry if this is not a bug. I sent a such message to the Sapphire discord server but no response :(
With the new changes to the {}
type, sapphire is throwing errors when compiling.
Not throwing an error.
No response
Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import 'c:\Users\jpedr\Desktop\Visual Code\Node.js\Botter V4.1\node_modules\fast-deep-equal\es6' is not supported resolving ES modules imported from c:\Users\jpedr\Desktop\Visual Code\Node.js\Botter V4.1\node_modules\@sapphire\shapeshift\dist\index.mjs
Did you mean to import fast-deep-equal/es6/index.js?
at new NodeError (node:internal/errors:371:5)
at finalizeResolution (node:internal/modules/esm/resolve:390:17)
at moduleResolve (node:internal/modules/esm/resolve:915:10)
at defaultResolve (node:internal/modules/esm/resolve:1005:11)
at ESMLoader.resolve (node:internal/modules/esm/loader:530:30)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:251:18)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:79:40)
at link (node:internal/modules/esm/module_job:78:36) {
code: 'ERR_UNSUPPORTED_DIR_IMPORT',
url: 'file:///c:/Users/jpedr/Desktop/Visual%20Code/Node.js/Botter%20V4.1/node_modules/fast-deep-equal/es6'
}
at consoleBoth (file:///c:/Users/jpedr/Desktop/Visual%20Code/Node.js/Botter%20V4.1/src/Functions/Errors/catchHandlers.js:78:10)
at nullCatch (file:///c:/Users/jpedr/Desktop/Visual%20Code/Node.js/Botter%20V4.1/src/Functions/Errors/catchHandlers.js:3:2)
at async FileLoader.load (file:///c:/Users/jpedr/Desktop/Visual%20Code/Node.js/Botter%20V4.1/src/Structures/Utils/FileLoader.js:71:26)
at async loadCommands (file:///c:/Users/jpedr/Desktop/Visual%20Code/Node.js/Botter%20V4.1/src/Structures/Client/Client.js:190:15)
at async extendClient (file:///c:/Users/jpedr/Desktop/Visual%20Code/Node.js/Botter%20V4.1/src/Structures/Client/Client.js:123:3)
at async file:///c:/Users/jpedr/Desktop/Visual%20Code/Node.js/Botter%20V4.1/src/index.js:96:1
Using the tree:
[email protected]
└─┬ @discordjs/[email protected]
└── @sapphire/[email protected]
The error is throw
The #155 should be fixed this issue, but the compiled index.mjs
still throws the error
No response
No response
I'm not quite sure what's really going on. Sapphire is being called as a dependency by the discord.js package. This has been happening often and I'm not sure what I can do about it. I've tried getting support from the discord.js folks and they haven't been helpful. You can review the errors here.
I don't have any steps. I only know that when an interactionCreate
event is fired in my discord bot, the above error occurs.
No crashing? I'm not quite sure what sapphire is even for. Just know that it's a dependency for discord.js.
No response
I'm still new to making discord bots using discord.js. And still pretty new to javascript in general. So I'm not really sure what the next steps in diagnosing this issue. But my bot is highly unstable due to this issue and I need to figure out how to mitigate the crashing.
Originally discussed in the discord server. DefaultValidator's return type contains an extra undefined
.
const predicate = s.string.default("Hello");
predicated.parse("hello");
// string | undefined
It's return type should be string
.
Discord message link: https://discord.com/channels/737141877803057244/934614121687687179/947818834205741066
When trying to use s.string.reshape()
, TypeScript complains about that method not existing. A simple recursive grep
shows that the method is only in README.md, but it nowhere in the code.
grep reshape -r ./node_modules/@sapphire/shapeshift/dist/
(or rg reshape ./node_modules/@sapphire/shapeshift/dist/
)The method exists
No response
Found when disabling validation in @discordjs/builders
on EmbedBuilder#setDescription()
it would still throw a CombinedError
with ExpectedValidationError
in it.
import {s} from "@sapphire/shapeshift";
s.string
.lengthGreaterThanOrEqual(10)
.nullish
.setValidationEnabled(false).parse("test");
It should not throw any Error.
No response
No response
Using an object validator with a key that has a value with a default validator attached to it makes it be considered required
const obj = s.object({
limit: s.number.default(100)
});
It works
No response
CombinedPropertyError: Received one or more errors
at ObjectValidator.handleIgnoreStrategy (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:1105:72)
at ObjectValidator.handleStrategy (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:1004:47)
at ObjectValidator.handle (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:1079:17)
at ObjectValidator.parse (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:113:88)
at RequestQueueClient.listHead (/Users/vlad/Development/Apify/apify-ts/packages/memory-storage/dist/resource-clients/request-queue.js:135:12)
at file:///Users/vlad/Development/Apify/apify-ts/test/e2e/globs-vs-regexes-vs-pseudoUrls/test.mjs:90:52 {
errors: [
[
'limit',
MissingPropertyError: A required property is missing
at ObjectValidator.handleIgnoreStrategy (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:1101:27)
at ObjectValidator.handleStrategy (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:1004:47)
at ObjectValidator.handle (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:1079:17)
at ObjectValidator.parse (/Users/vlad/Development/Apify/apify-ts/node_modules/@sapphire/shapeshift/dist/index.js:113:88)
at RequestQueueClient.listHead (/Users/vlad/Development/Apify/apify-ts/packages/memory-storage/dist/resource-clients/request-queue.js:135:12)
at file:///Users/vlad/Development/Apify/apify-ts/test/e2e/globs-vs-regexes-vs-pseudoUrls/test.mjs:90:52 {
property: 'limit'
}
]
]
}
when you use type module in package.json
shapeshift imports fast-deep-equal as
import fastDeepEqual from "fast-deep-equal/es6";
breaking it
changing the code to
import fastDeepEqual from "fast-deep-equal";
fixes it.
set the type to module
it shouldnt crash
No response
One of the biggest issues with shapeshift right now is that when running a validator of the form s.string.parse(input)
, the error received is not really useful (it just says that the validator failed, not why or where or for what).
Other modules (notably ow uses callsites to infer the label from the callsite) either allow this or use some interesting mechanisms to detect/infer the label. Since we aim for speed ⚡ here, we should probably stick to letting users provide a label (or even a label factory?)
Support for adding labels on validators (mayhaps s.string.label('url')
instead of s.string('label')
as the latter is breaking which is not ideal).
Would be nice to also have something like s.string.label((input) => translate('bad-input', input))
to allow dynamic labels in one predicate (for instance for the 1 person planning on using shapeshift in an i18n context)
Not supporting this, which is a downside...so none :D
No response
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are awaiting their schedule. Click on a checkbox to get an update now.
These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.github/workflows/auto-deprecate.yml
actions/checkout v4
actions/setup-node v4
.github/workflows/ci-node-16.yml
actions/checkout v4
actions/setup-node v4
.github/workflows/codeql-analysis.yml
actions/checkout v4
github/codeql-action v3
github/codeql-action v3
.github/workflows/continuous-delivery.yml
actions/checkout v4
actions/setup-node v4
.github/workflows/continuous-integration.yml
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
codecov/codecov-action v4
.github/workflows/deprecate-on-merge.yml
actions/checkout v4
actions/setup-node v4
.github/workflows/documentation.yml
actions/checkout v4
actions/setup-node v4
actions/upload-artifact v4
actions/checkout v4
actions/setup-node v4
actions/download-artifact v4
actions/checkout v4
nick-fields/retry v3
.github/workflows/labelsync.yml
actions/checkout v4
crazy-max/ghaction-github-labeler v5
.github/workflows/publish.yml
actions/checkout v4
actions/setup-node v4
.github/workflows/release-crosspost.yml
kludge-cs/gitcord-release-changelogger v3.0.0
package.json
fast-deep-equal ^3.1.3
lodash ^4.17.21
@commitlint/cli ^19.3.0
@commitlint/config-conventional ^19.2.2
@favware/cliff-jumper ^4.0.3
@favware/npm-deprecate ^1.0.7
@sapphire/eslint-config ^5.0.5
@sapphire/prettier-config ^2.0.0
@sapphire/ts-config ^5.0.1
@types/jsdom ^21.1.7
@types/lodash ^4.17.7
@vitest/coverage-v8 ^2.0.5
cz-conventional-changelog ^3.3.0
esbuild-plugins-node-modules-polyfill ^1.6.4
eslint ^8.57.0
eslint-config-prettier ^9.1.0
eslint-plugin-prettier ^5.2.1
jsdom ^24.1.1
lint-staged ^15.2.8
prettier ^3.3.3
rimraf ^6.0.1
tsup ^8.2.4
vitest ^2.0.5
ansi-regex ^5.0.1
minimist ^1.2.8
yarn 4.4.0
not sure how to reproduce, after updating to latest version I run into this error, the package is not installed as a dependency on my project but seems being used by library I used which I'm not sure which one
should not throw an error
No response
No response
Right now, all validators have checks for whether or not they should run validations, as seen below:
shapeshift/src/validators/BaseValidator.ts
Lines 74 to 78 in e9a029a
This comes with a large performance impact, specially from those who desire to use the library without conditional validation. Also goes against Shapeshift's internal design of running the least amount of conditionals as possible.
Before we added conditional validation, Shapeshift was comfortably among the fastest libraries in our benchmarks.
A wrapper would solve the performance impact by making the validators always run the logic and constraints, where the PartialValidator<T>
would exclusively only run the handler and never the constraints (with no extra checks, of course).
For function (dynamic validation), we can also add a second class, or add a check in PartialValidator<T>
, invalidating the last sentence in the previous paragraph.
Unwrapping a PartialValidator<T>
should give back the underlying, fully-checked validator.
N/a.
No response
From #248 I could gather that cloudflare worker support is something that was being kept in mind. I recently tried to use @discordjs/builders which depends on sapphire and it gave me errors for needing to enable node_compat, something I could gather is heavily discouraged
Implement an alternative for the inspect function imports from util
Find another package which provides the same functionality as the inspect function
No response
when bundling with cloudflare workers, I get an error:
../../node_modules/@sapphire/shapeshift/dist/index.mjs:2:24:
2 │ import { inspect } from 'node:util';
╵ ~~~~~~~~~~~
The package "node:util" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that,
which will remove this error.
X [ERROR] Build failed with 1 error:
../../node_modules/@sapphire/shapeshift/dist/index.mjs:2:24: ERROR: Could not resolve "node:util"
all that's needed is to remove the node:
prefix, then the node_compat flag can actually work. Yeah it's really annoying.
using another library I guess
No response
Implement something like zod's nativeEnum
, so we can pass in a TS enum and validate using it (probably with handling transformation of string key -> numeric value too for numeric enums)
See above
N.A.
Originally posted by @vladfrangu in #44 (comment)
Add some method of parsing a schema that narrows the type down and doesn't throw an error
import { s } from '@sapphire/shapeshift'
const schema = s.object({
a: s.string,
b: s.number
})
// a value from an api, for example
const toCompare: any = {
a: 'Hello',
b: 1
}
if (!schema.is(toCompare)) {
return 'some error message'
}
toCompare // InferType<typeof schema>
import { s } from '@sapphire/shapeshift'
const schema = s.object({
a: s.string,
b: s.number
})
const obj: any = {
a: 'hello',
b: 1
}
const result = schema.run(obj)
// Note: checking result.isErr() does NOT
// limit the type correctly :(
if (!result.isOk()) {
return 'some error message'
}
result.value // InferType<typeof schema>
or closer to what I'd prefer built in
const isSchema = <T>(obj: unknown): obj is T =>schema.run(obj).isOk()
if (!isSchema<InferType<typeof schema>>(obj)) {
return 'some error message'
}
obj // InferType<typeof schema>
Thanks
We have s.string.email
and in forms it is often required to enter both an email and a phone number so lets also add s.string.phone
s.string.phone
Using s.string.regex
with the regex for a phone number, however this is not ideal because then end-users have to constantly look up the phone regex online
Refer to https://ihateregex.io/expr/phone/ for an example for a phone regex
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.