Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Rewrite Schema #8479

Draft
wants to merge 19 commits into
base: v11
Choose a base branch
from
Draft

Draft: Rewrite Schema #8479

wants to merge 19 commits into from

Conversation

hsubox76
Copy link
Contributor

@hsubox76 hsubox76 commented Sep 4, 2024

See https://docs.google.com/document/d/1CXRbH7zmKqupD5LWUq8dh3spsGpozfRbOUa5MWi2tVY/edit?tab=t.wiordux8zots (internal)

Rewriting Schema as a class with static methods to enable easier building and some validation.

This is mostly backwards compatible - functionDeclaration.parameters takes an ObjectSchemaInterface which could be the ObjectSchema class or just a JS object that matches the interface. The only breaking change is the FunctionDeclarationSchemaType enum is now named SchemaType.

Keeping validation minimal as (1) TS should handle a lot of it and even if TS checking doesn't extend to JS-only developers, we don't really want to duplicate efforts with TS, (2) not a lot of rules have strong enough confirmation/guarantees from the backend for us to be sure enough to throw errors.

Copy link

changeset-bot bot commented Sep 4, 2024

⚠️ No Changeset found

Latest commit: 9d327c9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Sep 4, 2024

Size Report 1

Affected Products

  • @firebase/auth

    TypeBase (15c36cc)Merge (a21e56c)Diff
    browser182 kB182 kB+81 B (+0.0%)
    cordova209 kB209 kB+85 B (+0.0%)
    esm5236 kB236 kB+85 B (+0.0%)
    main179 kB179 kB+71 B (+0.0%)
    module182 kB182 kB+81 B (+0.0%)
    react-native199 kB199 kB+71 B (+0.0%)
  • @firebase/auth-cordova

    TypeBase (15c36cc)Merge (a21e56c)Diff
    browser209 kB209 kB+85 B (+0.0%)
    module209 kB209 kB+85 B (+0.0%)
  • @firebase/auth-web-extension

    TypeBase (15c36cc)Merge (a21e56c)Diff
    browser137 kB137 kB+81 B (+0.1%)
    main152 kB152 kB+69 B (+0.0%)
    module137 kB137 kB+81 B (+0.1%)
  • @firebase/auth/internal

    TypeBase (15c36cc)Merge (a21e56c)Diff
    browser193 kB193 kB+81 B (+0.0%)
    esm5249 kB249 kB+85 B (+0.0%)
    main214 kB214 kB+73 B (+0.0%)
    module193 kB193 kB+81 B (+0.0%)
  • @firebase/firestore

    TypeBase (15c36cc)Merge (a21e56c)Diff
    browser381 kB382 kB+48 B (+0.0%)
    esm5366 kB366 kB+50 B (+0.0%)
    main587 kB587 kB+120 B (+0.0%)
    module381 kB382 kB+48 B (+0.0%)
    react-native382 kB382 kB+48 B (+0.0%)
  • @firebase/util

    TypeBase (15c36cc)Merge (a21e56c)Diff
    browser23.2 kB23.4 kB+131 B (+0.6%)
    esm524.9 kB25.0 kB+131 B (+0.5%)
    main30.7 kB30.9 kB+233 B (+0.8%)
    module23.2 kB23.4 kB+131 B (+0.6%)
  • @firebase/vertexai-preview

    TypeBase (15c36cc)Merge (a21e56c)Diff
    browser25.4 kB28.0 kB+2.55 kB (+10.0%)
    main26.0 kB28.8 kB+2.77 kB (+10.6%)
    module25.4 kB28.0 kB+2.55 kB (+10.0%)
  • bundle

    16 size changes

    TypeBase (15c36cc)Merge (a21e56c)Diff
    auth (Anonymous)76.1 kB76.2 kB+119 B (+0.2%)
    auth (EmailAndPassword)84.4 kB84.5 kB+119 B (+0.1%)
    auth (GoogleFBTwitterGitHubPopup)103 kB103 kB+118 B (+0.1%)
    auth (GooglePopup)100 kB100 kB+119 B (+0.1%)
    auth (GoogleRedirect)100 kB100 kB+119 B (+0.1%)
    auth (Phone)86.8 kB86.9 kB+119 B (+0.1%)
    firestore (CSI Auto Indexing Disable and Delete)270 kB273 kB+2.56 kB (+0.9%)
    firestore (CSI Auto Indexing Enable)270 kB273 kB+2.56 kB (+0.9%)
    firestore (Persistence)305 kB308 kB+2.56 kB (+0.8%)
    firestore (Query Cursors)242 kB248 kB+6.22 kB (+2.6%)
    firestore (Query)240 kB246 kB+6.22 kB (+2.6%)
    firestore (Read data once)228 kB234 kB+6.22 kB (+2.7%)
    firestore (Read Write w Persistence)325 kB328 kB+2.55 kB (+0.8%)
    firestore (Realtime updates)230 kB236 kB+6.22 kB (+2.7%)
    firestore (Transaction)207 kB213 kB+6.50 kB (+3.1%)
    firestore (Write data)207 kB213 kB+6.24 kB (+3.0%)

  • firebase

    TypeBase (15c36cc)Merge (a21e56c)Diff
    firebase-app.js103 kB103 kB+2 B (+0.0%)
    firebase-auth-compat.js139 kB139 kB+88 B (+0.1%)
    firebase-auth-cordova.js177 kB177 kB+124 B (+0.1%)
    firebase-auth-web-extension.js117 kB117 kB+128 B (+0.1%)
    firebase-auth.js151 kB151 kB+128 B (+0.1%)
    firebase-compat.js788 kB791 kB+2.60 kB (+0.3%)
    firebase-firestore-compat.js344 kB346 kB+2.51 kB (+0.7%)
    firebase-firestore.js440 kB440 kB+48 B (+0.0%)
    firebase-vertexai-preview.js19.6 kB21.6 kB+1.99 kB (+10.2%)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/gSBaFszgqU.html

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Sep 4, 2024

Size Analysis Report 1

This report is too large (678,434 characters) to be displayed here in a GitHub comment. Please use the below link to see the full report on Google Cloud Storage.

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/HYD47Kn0Ry.html

/** Optional. The description of the property. */
description?: string;
/** Optional. Whether the property is nullable. Defaults to false. */
nullable: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullable means that the value can be undefined, not null, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI this isn't a JS concept of nullable, it's you giving a schema to the model to fill in (whether you're asking it to do function calling or give you a JSON response), and you're telling the model whether it's ok to return this field to you with a value of null. I don't think non JS languages have undefined so I think it's just null. So if you say "required: true" and "nullable: false" that means, you have to fill out this field when you send it back to me, and it can't be null. "required: true"/"nullable: true" I think means, "this field needs to be in the JSON and it needs to be filled with some actual value". Actually JSON is JS I guess, but the official spec says "undefined" isn't a valid JSON value, just null.

}

/** Converts class to a plain JSON object (not a string). */
toJSON(): Record<string, unknown> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we name this toJSON() if it returns a plain JS object? Is this an API requirement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the best name is - this is an intermediate object between the very abstract Schema, where all the children are Schemas, and a JSON string - it's a plain JS object or POJO, could call it toPOJO()? I have this instead of going straight to the stringified JSON because it's easier to inspect and debug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I was wrong, toJSON() actually should not return a JSON string, it should in fact return a JS symbol that is ready to pass to JSON.stringify(). Changing this back. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior

const obj: Record<string, unknown> = {};
for (const prop in this) {
if (this.hasOwnProperty(prop) && this[prop] !== undefined) {
if (prop !== 'required' || this.type === SchemaType.OBJECT) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we only include therequired property if this.type is SchemaType.OBJECT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been overhauled - the Schema proto actually sets "required" as an array on "object" type Schema only, and each member is the string name of a required property. Our initial design was to let the user set "required" as a boolean on each object property, as it's more user-friendly (that's where most people would naturally set it), but this causes a lot of implementation trickiness (how do you only let it be set on children of "object" Schema) and diverges a lot from the original spec. We compromised by removing "required" (both the array and the boolean) from the user-facing surface and providing an "optionalProperties" array on the ObjectSchema, assuming most users want most properties to be required by default, so they only have to do something actively if they want to make a property non-required.

toJSON(): Record<string, unknown> {
const obj: Record<string, unknown> = {};
for (const prop in this) {
if (this.hasOwnProperty(prop) && this[prop] !== undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think checking if this.hasOwnProperty(prop) is redundant in this case, since we are iterating over the properties of this (?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TS/ESlint yells about that, I think it's because classes have some built-in inherited native properties and hasOwnProperty skips them and focuses on the properties you explicitly put on it.

@hsubox76 hsubox76 changed the title Rewrite Schema Draft: Rewrite Schema Sep 4, 2024
@hsubox76 hsubox76 changed the base branch from main to v11 September 20, 2024 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants