mirror of
https://github.com/zulip/zulip.git
synced 2025-11-11 01:16:19 +00:00
stream_data: Validate parameters with Zod.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
committed by
Anders Kaseorg
parent
9b511f5caa
commit
e28240a9ac
@@ -4,8 +4,8 @@ import {page_params} from "./base_page_params";
|
|||||||
import {$t, $t_html} from "./i18n";
|
import {$t, $t_html} from "./i18n";
|
||||||
import type {RealmDefaultSettings} from "./realm_user_settings_defaults";
|
import type {RealmDefaultSettings} from "./realm_user_settings_defaults";
|
||||||
import {realm} from "./state_data";
|
import {realm} from "./state_data";
|
||||||
|
import {StreamPostPolicy} from "./stream_types";
|
||||||
import type {StreamSpecificNotificationSettings} from "./sub_store";
|
import type {StreamSpecificNotificationSettings} from "./sub_store";
|
||||||
import {StreamPostPolicy} from "./sub_store";
|
|
||||||
import type {
|
import type {
|
||||||
FollowedTopicNotificationSettings,
|
FollowedTopicNotificationSettings,
|
||||||
PmNotificationSettings,
|
PmNotificationSettings,
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import {z} from "zod";
|
import {z} from "zod";
|
||||||
|
|
||||||
import {realm_default_settings_schema} from "./realm_user_settings_defaults";
|
import {realm_default_settings_schema} from "./realm_user_settings_defaults";
|
||||||
|
import {
|
||||||
|
never_subscribed_stream_schema,
|
||||||
|
stream_schema,
|
||||||
|
stream_subscription_schema,
|
||||||
|
} from "./stream_types";
|
||||||
import {user_settings_schema} from "./user_settings";
|
import {user_settings_schema} from "./user_settings";
|
||||||
|
|
||||||
const NOT_TYPED_YET = z.unknown();
|
const NOT_TYPED_YET = z.unknown();
|
||||||
@@ -368,10 +373,10 @@ export const state_data_schema = z
|
|||||||
.and(
|
.and(
|
||||||
z
|
z
|
||||||
.object({
|
.object({
|
||||||
subscriptions: NOT_TYPED_YET,
|
subscriptions: z.array(stream_subscription_schema),
|
||||||
unsubscribed: NOT_TYPED_YET,
|
unsubscribed: z.array(stream_subscription_schema),
|
||||||
never_subscribed: NOT_TYPED_YET,
|
never_subscribed: z.array(never_subscribed_stream_schema),
|
||||||
realm_default_streams: NOT_TYPED_YET,
|
realm_default_streams: z.array(stream_schema),
|
||||||
})
|
})
|
||||||
.transform((stream_data) => ({stream_data})),
|
.transform((stream_data) => ({stream_data})),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ import type {User} from "./people";
|
|||||||
import * as people from "./people";
|
import * as people from "./people";
|
||||||
import * as settings_config from "./settings_config";
|
import * as settings_config from "./settings_config";
|
||||||
import * as settings_data from "./settings_data";
|
import * as settings_data from "./settings_data";
|
||||||
|
import type {StateData} from "./state_data";
|
||||||
import {current_user, realm} from "./state_data";
|
import {current_user, realm} from "./state_data";
|
||||||
|
import type {StreamPostPolicy} from "./stream_types";
|
||||||
import * as sub_store from "./sub_store";
|
import * as sub_store from "./sub_store";
|
||||||
import type {
|
import type {
|
||||||
ApiStreamSubscription,
|
ApiStreamSubscription,
|
||||||
NeverSubscribedStream,
|
NeverSubscribedStream,
|
||||||
Stream,
|
Stream,
|
||||||
StreamPostPolicy,
|
|
||||||
StreamSpecificNotificationSettings,
|
StreamSpecificNotificationSettings,
|
||||||
StreamSubscription,
|
StreamSubscription,
|
||||||
} from "./sub_store";
|
} from "./sub_store";
|
||||||
@@ -21,13 +22,6 @@ import * as user_groups from "./user_groups";
|
|||||||
import {user_settings} from "./user_settings";
|
import {user_settings} from "./user_settings";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
|
||||||
type StreamInitParams = {
|
|
||||||
subscriptions: ApiStreamSubscription[];
|
|
||||||
unsubscribed: ApiStreamSubscription[];
|
|
||||||
never_subscribed: NeverSubscribedStream[];
|
|
||||||
realm_default_streams: Stream[];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Type for the parameter of `create_sub_from_server_data` function.
|
// Type for the parameter of `create_sub_from_server_data` function.
|
||||||
type ApiGenericStreamSubscription =
|
type ApiGenericStreamSubscription =
|
||||||
| NeverSubscribedStream
|
| NeverSubscribedStream
|
||||||
@@ -834,7 +828,7 @@ export function get_new_stream_announcements_stream(): string {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initialize(params: StreamInitParams): void {
|
export function initialize(params: StateData["stream_data"]): void {
|
||||||
/*
|
/*
|
||||||
We get `params` data, which is data that we "own"
|
We get `params` data, which is data that we "own"
|
||||||
and which has already been removed from `state_data`.
|
and which has already been removed from `state_data`.
|
||||||
|
|||||||
57
web/src/stream_types.ts
Normal file
57
web/src/stream_types.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import {z} from "zod";
|
||||||
|
|
||||||
|
export const enum StreamPostPolicy {
|
||||||
|
EVERYONE = 1,
|
||||||
|
ADMINS = 2,
|
||||||
|
RESTRICT_NEW_MEMBERS = 3,
|
||||||
|
MODERATORS = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
// These types are taken from the `zerver/lib/types.py`.
|
||||||
|
export const stream_schema = z.object({
|
||||||
|
creator_id: z.number().nullable(),
|
||||||
|
date_created: z.number(),
|
||||||
|
description: z.string(),
|
||||||
|
first_message_id: z.number().nullable(),
|
||||||
|
history_public_to_subscribers: z.boolean(),
|
||||||
|
invite_only: z.boolean(),
|
||||||
|
is_announcement_only: z.boolean(),
|
||||||
|
is_web_public: z.boolean(),
|
||||||
|
message_retention_days: z.number().nullable(),
|
||||||
|
name: z.string(),
|
||||||
|
rendered_description: z.string(),
|
||||||
|
stream_id: z.number(),
|
||||||
|
stream_post_policy: z.nativeEnum({
|
||||||
|
EVERYONE: StreamPostPolicy.EVERYONE,
|
||||||
|
ADMINS: StreamPostPolicy.ADMINS,
|
||||||
|
RESTRICT_NEW_MEMBERS: StreamPostPolicy.RESTRICT_NEW_MEMBERS,
|
||||||
|
MODERATORS: StreamPostPolicy.MODERATORS,
|
||||||
|
}),
|
||||||
|
can_remove_subscribers_group: z.number(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const stream_specific_notification_settings_schema = z.object({
|
||||||
|
audible_notifications: z.boolean().nullable(),
|
||||||
|
desktop_notifications: z.boolean().nullable(),
|
||||||
|
email_notifications: z.boolean().nullable(),
|
||||||
|
push_notifications: z.boolean().nullable(),
|
||||||
|
wildcard_mentions_notify: z.boolean().nullable(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const never_subscribed_stream_schema = stream_schema.extend({
|
||||||
|
stream_weekly_traffic: z.number().nullable(),
|
||||||
|
subscribers: z.array(z.number()).optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const stream_properties_schema = stream_specific_notification_settings_schema.extend({
|
||||||
|
color: z.string(),
|
||||||
|
is_muted: z.boolean(),
|
||||||
|
pin_to_top: z.boolean(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// This is the raw data we get from the server for a subscription.
|
||||||
|
export const stream_subscription_schema = stream_schema.merge(stream_properties_schema).extend({
|
||||||
|
email_address: z.string().optional(),
|
||||||
|
stream_weekly_traffic: z.number().nullable(),
|
||||||
|
subscribers: z.array(z.number()).optional(),
|
||||||
|
});
|
||||||
@@ -1,57 +1,23 @@
|
|||||||
|
import type {z} from "zod";
|
||||||
|
|
||||||
import * as blueslip from "./blueslip";
|
import * as blueslip from "./blueslip";
|
||||||
|
import type {
|
||||||
|
never_subscribed_stream_schema,
|
||||||
|
stream_properties_schema,
|
||||||
|
stream_schema,
|
||||||
|
stream_specific_notification_settings_schema,
|
||||||
|
stream_subscription_schema,
|
||||||
|
} from "./stream_types";
|
||||||
|
|
||||||
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<T>;
|
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<T>;
|
||||||
|
|
||||||
export const enum StreamPostPolicy {
|
export type Stream = z.infer<typeof stream_schema>;
|
||||||
EVERYONE = 1,
|
export type StreamSpecificNotificationSettings = z.infer<
|
||||||
ADMINS = 2,
|
typeof stream_specific_notification_settings_schema
|
||||||
RESTRICT_NEW_MEMBERS = 3,
|
>;
|
||||||
MODERATORS = 4,
|
export type NeverSubscribedStream = z.infer<typeof never_subscribed_stream_schema>;
|
||||||
}
|
export type StreamProperties = z.infer<typeof stream_properties_schema>;
|
||||||
|
export type ApiStreamSubscription = z.infer<typeof stream_subscription_schema>;
|
||||||
// These types are taken from the `zerver/lib/types.py`.
|
|
||||||
export type Stream = {
|
|
||||||
creator_id: number | null;
|
|
||||||
date_created: number;
|
|
||||||
description: string;
|
|
||||||
first_message_id: number | null;
|
|
||||||
history_public_to_subscribers: boolean;
|
|
||||||
invite_only: boolean;
|
|
||||||
is_announcement_only: boolean;
|
|
||||||
is_web_public: boolean;
|
|
||||||
message_retention_days: number | null;
|
|
||||||
name: string;
|
|
||||||
rendered_description: string;
|
|
||||||
stream_id: number;
|
|
||||||
stream_post_policy: StreamPostPolicy;
|
|
||||||
can_remove_subscribers_group: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type StreamSpecificNotificationSettings = {
|
|
||||||
audible_notifications: boolean | null;
|
|
||||||
desktop_notifications: boolean | null;
|
|
||||||
email_notifications: boolean | null;
|
|
||||||
push_notifications: boolean | null;
|
|
||||||
wildcard_mentions_notify: boolean | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NeverSubscribedStream = Stream & {
|
|
||||||
stream_weekly_traffic: number | null;
|
|
||||||
subscribers?: number[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type StreamProperties = StreamSpecificNotificationSettings & {
|
|
||||||
color: string;
|
|
||||||
is_muted: boolean;
|
|
||||||
pin_to_top: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is the raw data we get from the server for a subscription.
|
|
||||||
export type ApiStreamSubscription = (Stream & StreamProperties) & {
|
|
||||||
email_address?: string;
|
|
||||||
stream_weekly_traffic: number | null;
|
|
||||||
subscribers?: number[];
|
|
||||||
};
|
|
||||||
|
|
||||||
// These properties are added in `stream_data` when hydrating the streams and are not present in the data we get from the server.
|
// These properties are added in `stream_data` when hydrating the streams and are not present in the data we get from the server.
|
||||||
export type ExtraStreamAttrs = {
|
export type ExtraStreamAttrs = {
|
||||||
|
|||||||
Reference in New Issue
Block a user