@stackframe/stack-shared 2.8.65 → 2.8.67
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/dist/config/db-sync-mappings.d.mts +17 -0
- package/dist/config/db-sync-mappings.d.ts +17 -0
- package/dist/config/db-sync-mappings.js +195 -0
- package/dist/config/db-sync-mappings.js.map +1 -0
- package/dist/config/schema-fuzzer.test.js +11 -0
- package/dist/config/schema-fuzzer.test.js.map +1 -1
- package/dist/config/schema.d.mts +95 -24
- package/dist/config/schema.d.ts +95 -24
- package/dist/config/schema.js +15 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/esm/config/db-sync-mappings.js +170 -0
- package/dist/esm/config/db-sync-mappings.js.map +1 -0
- package/dist/esm/config/schema-fuzzer.test.js +11 -0
- package/dist/esm/config/schema-fuzzer.test.js.map +1 -1
- package/dist/esm/config/schema.js +15 -0
- package/dist/esm/config/schema.js.map +1 -1
- package/dist/esm/interface/admin-interface.js.map +1 -1
- package/dist/esm/interface/client-interface.js +17 -2
- package/dist/esm/interface/client-interface.js.map +1 -1
- package/dist/esm/interface/crud/users.js +1 -3
- package/dist/esm/interface/crud/users.js.map +1 -1
- package/dist/esm/interface/server-interface.js.map +1 -1
- package/dist/esm/known-errors.js.map +1 -1
- package/dist/esm/schema-fields.js +5 -3
- package/dist/esm/schema-fields.js.map +1 -1
- package/dist/interface/admin-interface.d.mts +3 -5
- package/dist/interface/admin-interface.d.ts +3 -5
- package/dist/interface/admin-interface.js.map +1 -1
- package/dist/interface/client-interface.d.mts +1 -1
- package/dist/interface/client-interface.d.ts +1 -1
- package/dist/interface/client-interface.js +17 -2
- package/dist/interface/client-interface.js.map +1 -1
- package/dist/interface/crud/project-api-keys.d.mts +2 -2
- package/dist/interface/crud/project-api-keys.d.ts +2 -2
- package/dist/interface/crud/users.js +1 -3
- package/dist/interface/crud/users.js.map +1 -1
- package/dist/interface/server-interface.d.mts +1 -1
- package/dist/interface/server-interface.d.ts +1 -1
- package/dist/interface/server-interface.js.map +1 -1
- package/dist/known-errors.d.mts +1 -1
- package/dist/known-errors.d.ts +1 -1
- package/dist/known-errors.js.map +1 -1
- package/dist/schema-fields.d.mts +7 -1
- package/dist/schema-fields.d.ts +7 -1
- package/dist/schema-fields.js +6 -3
- package/dist/schema-fields.js.map +1 -1
- package/dist/sessions.d.mts +1 -1
- package/dist/sessions.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const DEFAULT_DB_SYNC_MAPPINGS: {
|
|
2
|
+
readonly users: {
|
|
3
|
+
readonly sourceTables: {
|
|
4
|
+
readonly ProjectUser: "ProjectUser";
|
|
5
|
+
};
|
|
6
|
+
readonly targetTable: "users";
|
|
7
|
+
readonly targetTableSchemas: {
|
|
8
|
+
readonly postgres: string;
|
|
9
|
+
};
|
|
10
|
+
readonly internalDbFetchQuery: string;
|
|
11
|
+
readonly externalDbUpdateQueries: {
|
|
12
|
+
readonly postgres: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { DEFAULT_DB_SYNC_MAPPINGS };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const DEFAULT_DB_SYNC_MAPPINGS: {
|
|
2
|
+
readonly users: {
|
|
3
|
+
readonly sourceTables: {
|
|
4
|
+
readonly ProjectUser: "ProjectUser";
|
|
5
|
+
};
|
|
6
|
+
readonly targetTable: "users";
|
|
7
|
+
readonly targetTableSchemas: {
|
|
8
|
+
readonly postgres: string;
|
|
9
|
+
};
|
|
10
|
+
readonly internalDbFetchQuery: string;
|
|
11
|
+
readonly externalDbUpdateQueries: {
|
|
12
|
+
readonly postgres: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { DEFAULT_DB_SYNC_MAPPINGS };
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/config/db-sync-mappings.ts
|
|
21
|
+
var db_sync_mappings_exports = {};
|
|
22
|
+
__export(db_sync_mappings_exports, {
|
|
23
|
+
DEFAULT_DB_SYNC_MAPPINGS: () => DEFAULT_DB_SYNC_MAPPINGS
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(db_sync_mappings_exports);
|
|
26
|
+
var DEFAULT_DB_SYNC_MAPPINGS = {
|
|
27
|
+
"users": {
|
|
28
|
+
sourceTables: { "ProjectUser": "ProjectUser" },
|
|
29
|
+
targetTable: "users",
|
|
30
|
+
targetTableSchemas: {
|
|
31
|
+
postgres: `
|
|
32
|
+
CREATE TABLE IF NOT EXISTS "users" (
|
|
33
|
+
"id" uuid PRIMARY KEY NOT NULL,
|
|
34
|
+
"display_name" text,
|
|
35
|
+
"profile_image_url" text,
|
|
36
|
+
"primary_email" text,
|
|
37
|
+
"primary_email_verified" boolean NOT NULL DEFAULT false,
|
|
38
|
+
"signed_up_at" timestamp without time zone NOT NULL,
|
|
39
|
+
"client_metadata" jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
40
|
+
"client_read_only_metadata" jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
41
|
+
"server_metadata" jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
42
|
+
"is_anonymous" boolean NOT NULL DEFAULT false
|
|
43
|
+
);
|
|
44
|
+
REVOKE ALL ON "users" FROM PUBLIC;
|
|
45
|
+
GRANT SELECT ON "users" TO PUBLIC;
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS "_stack_sync_metadata" (
|
|
48
|
+
"mapping_name" text PRIMARY KEY NOT NULL,
|
|
49
|
+
"last_synced_sequence_id" bigint NOT NULL DEFAULT -1,
|
|
50
|
+
"updated_at" timestamp without time zone NOT NULL DEFAULT now()
|
|
51
|
+
);
|
|
52
|
+
`.trim()
|
|
53
|
+
},
|
|
54
|
+
internalDbFetchQuery: `
|
|
55
|
+
SELECT *
|
|
56
|
+
FROM (
|
|
57
|
+
SELECT
|
|
58
|
+
"ProjectUser"."projectUserId" AS "id",
|
|
59
|
+
"ProjectUser"."displayName" AS "display_name",
|
|
60
|
+
"ProjectUser"."profileImageUrl" AS "profile_image_url",
|
|
61
|
+
(
|
|
62
|
+
SELECT "ContactChannel"."value"
|
|
63
|
+
FROM "ContactChannel"
|
|
64
|
+
WHERE "ContactChannel"."projectUserId" = "ProjectUser"."projectUserId"
|
|
65
|
+
AND "ContactChannel"."tenancyId" = "ProjectUser"."tenancyId"
|
|
66
|
+
AND "ContactChannel"."type" = 'EMAIL'
|
|
67
|
+
AND "ContactChannel"."isPrimary" = 'TRUE'
|
|
68
|
+
LIMIT 1
|
|
69
|
+
) AS "primary_email",
|
|
70
|
+
COALESCE(
|
|
71
|
+
(
|
|
72
|
+
SELECT "ContactChannel"."isVerified"
|
|
73
|
+
FROM "ContactChannel"
|
|
74
|
+
WHERE "ContactChannel"."projectUserId" = "ProjectUser"."projectUserId"
|
|
75
|
+
AND "ContactChannel"."tenancyId" = "ProjectUser"."tenancyId"
|
|
76
|
+
AND "ContactChannel"."type" = 'EMAIL'
|
|
77
|
+
AND "ContactChannel"."isPrimary" = 'TRUE'
|
|
78
|
+
LIMIT 1
|
|
79
|
+
),
|
|
80
|
+
false
|
|
81
|
+
) AS "primary_email_verified",
|
|
82
|
+
"ProjectUser"."createdAt" AS "signed_up_at",
|
|
83
|
+
COALESCE("ProjectUser"."clientMetadata", '{}'::jsonb) AS "client_metadata",
|
|
84
|
+
COALESCE("ProjectUser"."clientReadOnlyMetadata", '{}'::jsonb) AS "client_read_only_metadata",
|
|
85
|
+
COALESCE("ProjectUser"."serverMetadata", '{}'::jsonb) AS "server_metadata",
|
|
86
|
+
"ProjectUser"."isAnonymous" AS "is_anonymous",
|
|
87
|
+
"ProjectUser"."sequenceId" AS "sequence_id",
|
|
88
|
+
"ProjectUser"."tenancyId",
|
|
89
|
+
false AS "is_deleted"
|
|
90
|
+
FROM "ProjectUser"
|
|
91
|
+
WHERE "ProjectUser"."tenancyId" = $1::uuid
|
|
92
|
+
|
|
93
|
+
UNION ALL
|
|
94
|
+
|
|
95
|
+
SELECT
|
|
96
|
+
("DeletedRow"."primaryKey"->>'projectUserId')::uuid AS "id",
|
|
97
|
+
NULL::text AS "display_name",
|
|
98
|
+
NULL::text AS "profile_image_url",
|
|
99
|
+
NULL::text AS "primary_email",
|
|
100
|
+
false AS "primary_email_verified",
|
|
101
|
+
"DeletedRow"."deletedAt"::timestamp without time zone AS "signed_up_at",
|
|
102
|
+
'{}'::jsonb AS "client_metadata",
|
|
103
|
+
'{}'::jsonb AS "client_read_only_metadata",
|
|
104
|
+
'{}'::jsonb AS "server_metadata",
|
|
105
|
+
false AS "is_anonymous",
|
|
106
|
+
"DeletedRow"."sequenceId" AS "sequence_id",
|
|
107
|
+
"DeletedRow"."tenancyId",
|
|
108
|
+
true AS "is_deleted"
|
|
109
|
+
FROM "DeletedRow"
|
|
110
|
+
WHERE
|
|
111
|
+
"DeletedRow"."tenancyId" = $1::uuid
|
|
112
|
+
AND "DeletedRow"."tableName" = 'ProjectUser'
|
|
113
|
+
) AS "_src"
|
|
114
|
+
WHERE "sequence_id" IS NOT NULL
|
|
115
|
+
AND "sequence_id" > $2::bigint
|
|
116
|
+
ORDER BY "sequence_id" ASC
|
|
117
|
+
LIMIT 1000
|
|
118
|
+
`.trim(),
|
|
119
|
+
// Last parameter = mapping_name (for metadata tracking)
|
|
120
|
+
externalDbUpdateQueries: {
|
|
121
|
+
postgres: `
|
|
122
|
+
WITH params AS (
|
|
123
|
+
SELECT
|
|
124
|
+
$1::uuid AS "id",
|
|
125
|
+
$2::text AS "display_name",
|
|
126
|
+
$3::text AS "profile_image_url",
|
|
127
|
+
$4::text AS "primary_email",
|
|
128
|
+
$5::boolean AS "primary_email_verified",
|
|
129
|
+
$6::timestamp without time zone AS "signed_up_at",
|
|
130
|
+
$7::jsonb AS "client_metadata",
|
|
131
|
+
$8::jsonb AS "client_read_only_metadata",
|
|
132
|
+
$9::jsonb AS "server_metadata",
|
|
133
|
+
$10::boolean AS "is_anonymous",
|
|
134
|
+
$11::bigint AS "sequence_id",
|
|
135
|
+
$12::boolean AS "is_deleted",
|
|
136
|
+
$13::text AS "mapping_name"
|
|
137
|
+
),
|
|
138
|
+
deleted AS (
|
|
139
|
+
DELETE FROM "users" u
|
|
140
|
+
USING params p
|
|
141
|
+
WHERE p."is_deleted" = true AND u."id" = p."id"
|
|
142
|
+
RETURNING 1
|
|
143
|
+
),
|
|
144
|
+
upserted AS (
|
|
145
|
+
INSERT INTO "users" (
|
|
146
|
+
"id",
|
|
147
|
+
"display_name",
|
|
148
|
+
"profile_image_url",
|
|
149
|
+
"primary_email",
|
|
150
|
+
"primary_email_verified",
|
|
151
|
+
"signed_up_at",
|
|
152
|
+
"client_metadata",
|
|
153
|
+
"client_read_only_metadata",
|
|
154
|
+
"server_metadata",
|
|
155
|
+
"is_anonymous"
|
|
156
|
+
)
|
|
157
|
+
SELECT
|
|
158
|
+
p."id",
|
|
159
|
+
p."display_name",
|
|
160
|
+
p."profile_image_url",
|
|
161
|
+
p."primary_email",
|
|
162
|
+
p."primary_email_verified",
|
|
163
|
+
p."signed_up_at",
|
|
164
|
+
p."client_metadata",
|
|
165
|
+
p."client_read_only_metadata",
|
|
166
|
+
p."server_metadata",
|
|
167
|
+
p."is_anonymous"
|
|
168
|
+
FROM params p
|
|
169
|
+
WHERE p."is_deleted" = false
|
|
170
|
+
ON CONFLICT ("id") DO UPDATE SET
|
|
171
|
+
"display_name" = EXCLUDED."display_name",
|
|
172
|
+
"profile_image_url" = EXCLUDED."profile_image_url",
|
|
173
|
+
"primary_email" = EXCLUDED."primary_email",
|
|
174
|
+
"primary_email_verified" = EXCLUDED."primary_email_verified",
|
|
175
|
+
"signed_up_at" = EXCLUDED."signed_up_at",
|
|
176
|
+
"client_metadata" = EXCLUDED."client_metadata",
|
|
177
|
+
"client_read_only_metadata" = EXCLUDED."client_read_only_metadata",
|
|
178
|
+
"server_metadata" = EXCLUDED."server_metadata",
|
|
179
|
+
"is_anonymous" = EXCLUDED."is_anonymous"
|
|
180
|
+
RETURNING 1
|
|
181
|
+
)
|
|
182
|
+
INSERT INTO "_stack_sync_metadata" ("mapping_name", "last_synced_sequence_id", "updated_at")
|
|
183
|
+
SELECT p."mapping_name", p."sequence_id", now() FROM params p
|
|
184
|
+
ON CONFLICT ("mapping_name") DO UPDATE SET
|
|
185
|
+
"last_synced_sequence_id" = GREATEST("_stack_sync_metadata"."last_synced_sequence_id", EXCLUDED."last_synced_sequence_id"),
|
|
186
|
+
"updated_at" = now();
|
|
187
|
+
`.trim()
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
192
|
+
0 && (module.exports = {
|
|
193
|
+
DEFAULT_DB_SYNC_MAPPINGS
|
|
194
|
+
});
|
|
195
|
+
//# sourceMappingURL=db-sync-mappings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/config/db-sync-mappings.ts"],"sourcesContent":["export const DEFAULT_DB_SYNC_MAPPINGS = {\n \"users\": {\n sourceTables: { \"ProjectUser\": \"ProjectUser\" },\n targetTable: \"users\",\n targetTableSchemas: {\n postgres: `\n CREATE TABLE IF NOT EXISTS \"users\" (\n \"id\" uuid PRIMARY KEY NOT NULL,\n \"display_name\" text,\n \"profile_image_url\" text,\n \"primary_email\" text,\n \"primary_email_verified\" boolean NOT NULL DEFAULT false,\n \"signed_up_at\" timestamp without time zone NOT NULL,\n \"client_metadata\" jsonb NOT NULL DEFAULT '{}'::jsonb,\n \"client_read_only_metadata\" jsonb NOT NULL DEFAULT '{}'::jsonb,\n \"server_metadata\" jsonb NOT NULL DEFAULT '{}'::jsonb,\n \"is_anonymous\" boolean NOT NULL DEFAULT false\n );\n REVOKE ALL ON \"users\" FROM PUBLIC;\n GRANT SELECT ON \"users\" TO PUBLIC;\n\n CREATE TABLE IF NOT EXISTS \"_stack_sync_metadata\" (\n \"mapping_name\" text PRIMARY KEY NOT NULL,\n \"last_synced_sequence_id\" bigint NOT NULL DEFAULT -1,\n \"updated_at\" timestamp without time zone NOT NULL DEFAULT now()\n );\n `.trim(),\n },\n internalDbFetchQuery: `\n SELECT *\n FROM (\n SELECT\n \"ProjectUser\".\"projectUserId\" AS \"id\",\n \"ProjectUser\".\"displayName\" AS \"display_name\",\n \"ProjectUser\".\"profileImageUrl\" AS \"profile_image_url\",\n (\n SELECT \"ContactChannel\".\"value\"\n FROM \"ContactChannel\"\n WHERE \"ContactChannel\".\"projectUserId\" = \"ProjectUser\".\"projectUserId\"\n AND \"ContactChannel\".\"tenancyId\" = \"ProjectUser\".\"tenancyId\"\n AND \"ContactChannel\".\"type\" = 'EMAIL'\n AND \"ContactChannel\".\"isPrimary\" = 'TRUE'\n LIMIT 1\n ) AS \"primary_email\",\n COALESCE(\n (\n SELECT \"ContactChannel\".\"isVerified\"\n FROM \"ContactChannel\"\n WHERE \"ContactChannel\".\"projectUserId\" = \"ProjectUser\".\"projectUserId\"\n AND \"ContactChannel\".\"tenancyId\" = \"ProjectUser\".\"tenancyId\"\n AND \"ContactChannel\".\"type\" = 'EMAIL'\n AND \"ContactChannel\".\"isPrimary\" = 'TRUE'\n LIMIT 1\n ),\n false\n ) AS \"primary_email_verified\",\n \"ProjectUser\".\"createdAt\" AS \"signed_up_at\",\n COALESCE(\"ProjectUser\".\"clientMetadata\", '{}'::jsonb) AS \"client_metadata\",\n COALESCE(\"ProjectUser\".\"clientReadOnlyMetadata\", '{}'::jsonb) AS \"client_read_only_metadata\",\n COALESCE(\"ProjectUser\".\"serverMetadata\", '{}'::jsonb) AS \"server_metadata\",\n \"ProjectUser\".\"isAnonymous\" AS \"is_anonymous\",\n \"ProjectUser\".\"sequenceId\" AS \"sequence_id\",\n \"ProjectUser\".\"tenancyId\",\n false AS \"is_deleted\"\n FROM \"ProjectUser\"\n WHERE \"ProjectUser\".\"tenancyId\" = $1::uuid\n\n UNION ALL\n\n SELECT\n (\"DeletedRow\".\"primaryKey\"->>'projectUserId')::uuid AS \"id\",\n NULL::text AS \"display_name\",\n NULL::text AS \"profile_image_url\",\n NULL::text AS \"primary_email\",\n false AS \"primary_email_verified\",\n \"DeletedRow\".\"deletedAt\"::timestamp without time zone AS \"signed_up_at\",\n '{}'::jsonb AS \"client_metadata\",\n '{}'::jsonb AS \"client_read_only_metadata\",\n '{}'::jsonb AS \"server_metadata\",\n false AS \"is_anonymous\",\n \"DeletedRow\".\"sequenceId\" AS \"sequence_id\",\n \"DeletedRow\".\"tenancyId\",\n true AS \"is_deleted\"\n FROM \"DeletedRow\"\n WHERE\n \"DeletedRow\".\"tenancyId\" = $1::uuid\n AND \"DeletedRow\".\"tableName\" = 'ProjectUser'\n ) AS \"_src\"\n WHERE \"sequence_id\" IS NOT NULL\n AND \"sequence_id\" > $2::bigint\n ORDER BY \"sequence_id\" ASC\n LIMIT 1000\n `.trim(),\n // Last parameter = mapping_name (for metadata tracking)\n externalDbUpdateQueries: {\n postgres: `\n WITH params AS (\n SELECT\n $1::uuid AS \"id\",\n $2::text AS \"display_name\",\n $3::text AS \"profile_image_url\",\n $4::text AS \"primary_email\",\n $5::boolean AS \"primary_email_verified\",\n $6::timestamp without time zone AS \"signed_up_at\",\n $7::jsonb AS \"client_metadata\",\n $8::jsonb AS \"client_read_only_metadata\",\n $9::jsonb AS \"server_metadata\",\n $10::boolean AS \"is_anonymous\",\n $11::bigint AS \"sequence_id\",\n $12::boolean AS \"is_deleted\",\n $13::text AS \"mapping_name\"\n ),\n deleted AS (\n DELETE FROM \"users\" u\n USING params p\n WHERE p.\"is_deleted\" = true AND u.\"id\" = p.\"id\"\n RETURNING 1\n ),\n upserted AS (\n INSERT INTO \"users\" (\n \"id\",\n \"display_name\",\n \"profile_image_url\",\n \"primary_email\",\n \"primary_email_verified\",\n \"signed_up_at\",\n \"client_metadata\",\n \"client_read_only_metadata\",\n \"server_metadata\",\n \"is_anonymous\"\n )\n SELECT\n p.\"id\",\n p.\"display_name\",\n p.\"profile_image_url\",\n p.\"primary_email\",\n p.\"primary_email_verified\",\n p.\"signed_up_at\",\n p.\"client_metadata\",\n p.\"client_read_only_metadata\",\n p.\"server_metadata\",\n p.\"is_anonymous\"\n FROM params p\n WHERE p.\"is_deleted\" = false\n ON CONFLICT (\"id\") DO UPDATE SET\n \"display_name\" = EXCLUDED.\"display_name\",\n \"profile_image_url\" = EXCLUDED.\"profile_image_url\",\n \"primary_email\" = EXCLUDED.\"primary_email\",\n \"primary_email_verified\" = EXCLUDED.\"primary_email_verified\",\n \"signed_up_at\" = EXCLUDED.\"signed_up_at\",\n \"client_metadata\" = EXCLUDED.\"client_metadata\",\n \"client_read_only_metadata\" = EXCLUDED.\"client_read_only_metadata\",\n \"server_metadata\" = EXCLUDED.\"server_metadata\",\n \"is_anonymous\" = EXCLUDED.\"is_anonymous\"\n RETURNING 1\n )\n INSERT INTO \"_stack_sync_metadata\" (\"mapping_name\", \"last_synced_sequence_id\", \"updated_at\")\n SELECT p.\"mapping_name\", p.\"sequence_id\", now() FROM params p\n ON CONFLICT (\"mapping_name\") DO UPDATE SET\n \"last_synced_sequence_id\" = GREATEST(\"_stack_sync_metadata\".\"last_synced_sequence_id\", EXCLUDED.\"last_synced_sequence_id\"),\n \"updated_at\" = now();\n `.trim(),\n },\n },\n} as const;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,2BAA2B;AAAA,EACtC,SAAS;AAAA,IACP,cAAc,EAAE,eAAe,cAAc;AAAA,IAC7C,aAAa;AAAA,IACb,oBAAoB;AAAA,MAClB,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAqBR,KAAK;AAAA,IACT;AAAA,IACA,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgEpB,KAAK;AAAA;AAAA,IAEP,yBAAyB;AAAA,MACvB,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAkER,KAAK;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
|
|
@@ -50,6 +50,17 @@ var branchSchemaFuzzerConfig = [{
|
|
|
50
50
|
}],
|
|
51
51
|
signUpRulesDefaultAction: ["allow", "reject"]
|
|
52
52
|
}],
|
|
53
|
+
dbSync: [{
|
|
54
|
+
externalDatabases: [{
|
|
55
|
+
"some-external-db-id": [{
|
|
56
|
+
type: ["postgres"],
|
|
57
|
+
connectionString: [
|
|
58
|
+
"postgres://user:password@host:port/database",
|
|
59
|
+
"some-connection-string"
|
|
60
|
+
]
|
|
61
|
+
}]
|
|
62
|
+
}]
|
|
63
|
+
}],
|
|
53
64
|
dataVault: [{
|
|
54
65
|
stores: [{
|
|
55
66
|
"some-store-id": [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/schema-fuzzer.test.ts"],"sourcesContent":["import { ALL_APPS } from \"../apps/apps-config\";\nimport { SUPPORTED_CURRENCIES } from \"../utils/currency-constants\";\nimport { StackAssertionError } from \"../utils/errors\";\nimport { getOrUndefined, isObjectLike, set, typedEntries, typedFromEntries } from \"../utils/objects\";\nimport { nicify } from \"../utils/strings\";\nimport { normalize, override } from \"./format\";\nimport { BranchConfigNormalizedOverride, EnvironmentConfigNormalizedOverride, OrganizationConfigNormalizedOverride, ProjectConfigNormalizedOverride, applyBranchDefaults, applyEnvironmentDefaults, applyOrganizationDefaults, applyProjectDefaults, assertNoConfigOverrideErrors, branchConfigSchema, environmentConfigSchema, migrateConfigOverride, organizationConfigSchema, projectConfigSchema, sanitizeBranchConfig, sanitizeEnvironmentConfig, sanitizeOrganizationConfig, sanitizeProjectConfig } from \"./schema\";\n\ntype FuzzerConfig<T> = ReadonlyArray<T extends object ? ([T] extends [any[]] ? { readonly [K in keyof T]: FuzzerConfig<T[K]> } : Required<{\n [K in keyof T]: FuzzerConfig<T[K]>;\n}> & Record<string, FuzzerConfig<any>>) : T>;\n\nconst projectSchemaFuzzerConfig = [{\n sourceOfTruth: [{\n type: [\"hosted\", \"neon\", \"postgres\"],\n connectionString: [\"\", \"postgres://user:password@host:port/database\", \"THIS IS A STRING LOLOL\"],\n connectionStrings: [{\n \"123-some-branch-id\": [\"\", \"THIS IS A CONNECTION STRING OR SO\"],\n }],\n }],\n}] satisfies FuzzerConfig<ProjectConfigNormalizedOverride>;\n\nconst branchSchemaFuzzerConfig = [{\n apiKeys: [{\n enabled: [{\n team: [true, false],\n user: [true, false],\n }],\n }],\n auth: [{\n allowSignUp: [true, false],\n password: [{\n allowSignIn: [true, false],\n }],\n otp: [{\n allowSignIn: [true, false],\n }],\n passkey: [{\n allowSignIn: [true, false],\n }],\n oauth: [{\n accountMergeStrategy: [\"link_method\", \"raise_error\", \"allow_duplicates\"],\n providers: [{\n \"google\": [{\n type: [\"google\", \"github\", \"x\"] as const,\n allowSignIn: [true, false],\n allowConnectedAccounts: [true, false],\n }],\n }],\n }],\n signUpRules: [{\n \"some-rule-id\": [{\n enabled: [true, false],\n displayName: [\"Block Test Emails\", \"Allow Only Company Domain\"],\n priority: [0, 1, 100],\n condition: ['email.endsWith(\"@test.com\")', 'emailDomain == \"company.com\"'],\n action: [{\n type: [\"allow\", \"reject\", \"restrict\", \"log\"] as const,\n message: [\"\", \"Sign up is not allowed for this email\"],\n }],\n }],\n }],\n signUpRulesDefaultAction: [\"allow\", \"reject\"],\n }],\n dataVault: [{\n stores: [{\n \"some-store-id\": [{\n displayName: [\"Some Store\", \"Some Other Store\"],\n }],\n \"some-other-store-id\": [{\n displayName: [\"Some Store\", \"Some Other Store\"],\n }],\n }],\n }],\n payments: [{\n blockNewPurchases: [false, true],\n autoPay: [{\n interval: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n }],\n productLines: [{\n \"some-product-line-id\": [{\n displayName: [\"Some Product Line\", \"Some Other Product Line\"],\n customerType: [\"user\", \"team\", \"custom\"] as const,\n }],\n }],\n catalogs: [{ // ensure migration works\n \"some-product-line-id\": [{\n displayName: [\"Some Product Line\", \"Some Other Product Line\"],\n }],\n }],\n groups: [{ // ensure migration works\n \"some-product-line-id\": [{\n displayName: [\"Some Product Line\", \"Some Other Product Line\"],\n }],\n }],\n items: [{\n \"some-item-id\": [{\n customerType: [\"user\", \"team\", \"custom\"] as const,\n displayName: [\"Some Item\", \"Some Other Item\"],\n }],\n }],\n products: [{\n \"some-product-id\": [{\n displayName: [\"Some Product\", \"Some Other Product\"],\n customerType: [\"user\", \"team\", \"custom\"] as const,\n freeTrial: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n serverOnly: [true, false],\n stackable: [true, false],\n productLineId: [\"some-product-line-id\", \"some-other-product-line-id\"],\n catalogId: [\"some-product-line-id\", \"some-other-product-line-id\"], // ensure migration works\n groupId: [\"some-product-line-id\", \"some-other-product-line-id\"], // ensure migration works\n isAddOnTo: [false, { \"some-product-id\": [true], \"some-other-product-id\": [true] }] as const,\n prices: [\"include-by-default\" as \"include-by-default\", {\n \"some-price-id\": [{\n ...typedFromEntries(SUPPORTED_CURRENCIES.map(currency => [currency.code, [\"100_00\", \"not a number\", \"Infinity\", \"0\"]])),\n interval: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n serverOnly: [true, false],\n freeTrial: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n }],\n }],\n includedItems: [{\n \"some-item-id\": [{\n quantity: [0, 1, -3, 100, 0.333, Infinity],\n repeat: [\"never\", [[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n expires: [\"never\", \"when-purchase-expires\", \"when-repeated\"] as const,\n }],\n }],\n }],\n }],\n }],\n emails: [{\n themes: [{\n \"12345678-1234-4234-9234-123456789012\": [{\n displayName: [\"Some Theme\", \"Some Other Theme\"],\n tsxSource: [\"\", \"some typescript source code\"],\n }],\n }],\n selectedThemeId: [\"some-theme-id\", \"some-other-theme-id\"],\n templates: [{\n \"12345678-1234-4234-9234-123456789012\": [{\n themeId: [\"some-theme-id\", \"some-other-theme-id\"],\n displayName: [\"Some Template\", \"Some Other Template\"],\n tsxSource: [\"\", \"some typescript source code\"],\n }],\n }],\n }],\n teams: [{\n createPersonalTeamOnSignUp: [true, false],\n allowClientTeamCreation: [true, false],\n }],\n users: [{\n allowClientUserDeletion: [true, false],\n }],\n rbac: [{\n permissions: [{\n \"some_permission_id\": [{\n containedPermissionIds: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n description: [\"Some Permission\", \"Some Other Permission\"],\n scope: [\"team\", \"project\"] as const,\n }],\n }],\n defaultPermissions: [{\n teamCreator: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n teamMember: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n signUp: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n }],\n }],\n domains: [{}],\n apps: [{\n installed: [typedFromEntries(typedEntries(ALL_APPS).map(([key, value]) => [key, [{\n enabled: [true, false],\n }]]))],\n }],\n onboarding: [{\n requireEmailVerification: [true, false],\n }],\n}] satisfies FuzzerConfig<BranchConfigNormalizedOverride>;\n\nconst environmentSchemaFuzzerConfig = [{\n ...branchSchemaFuzzerConfig[0],\n auth: [{\n ...branchSchemaFuzzerConfig[0].auth[0],\n oauth: [{\n ...branchSchemaFuzzerConfig[0].auth[0].oauth[0],\n providers: [typedFromEntries(typedEntries(branchSchemaFuzzerConfig[0].auth[0].oauth[0].providers[0]).map(([key, value]) => [key, [{\n ...value[0],\n isShared: [true, false],\n clientId: [\"some-client-id\"],\n clientSecret: [\"some-client-secret\"],\n facebookConfigId: [\"some-facebook-config-id\"],\n microsoftTenantId: [\"some-microsoft-tenant-id\"],\n appleBundles: [{ \"some-bundle-id\": [{ bundleId: [\"com.example.app\"] }] }],\n }]]))] as const,\n }],\n }],\n domains: [{\n allowLocalhost: [true, false],\n trustedDomains: [{\n \"some-domain-id\": [{\n baseUrl: [\"https://example.com/something-here\"],\n handlerPath: [\"/something-here\"],\n }],\n }],\n }],\n emails: [{\n ...branchSchemaFuzzerConfig[0].emails[0],\n server: [{\n isShared: [true, false],\n provider: [\"resend\", \"smtp\"] as const,\n host: [\"example.com\", \"://super weird host that's not valid\"],\n port: [1234, 0.12543, -100, Infinity],\n username: [\"some-username\", \"some username with a space\"],\n password: [\"some-password\", \"some password with a space\"],\n senderName: [\"Some Sender\"],\n senderEmail: [\"some-sender@example.com\", \"some invalid email\"],\n }],\n }],\n payments: [{\n ...branchSchemaFuzzerConfig[0].payments[0],\n testMode: [false, true],\n }],\n}] satisfies FuzzerConfig<EnvironmentConfigNormalizedOverride>;\n\nconst organizationSchemaFuzzerConfig = environmentSchemaFuzzerConfig satisfies FuzzerConfig<OrganizationConfigNormalizedOverride>;\n\nfunction setDeep<T>(obj: T, path: string[], value: any) {\n if (!isObjectLike(obj)) return obj;\n\n if (path.length === 0) {\n throw new Error(\"Path is empty\");\n } else if (path.length === 1) {\n set(obj as any, path[0], value);\n } else {\n const [key, ...rest] = path;\n setDeep(getOrUndefined(obj as any, key), rest, value);\n }\n}\n\nfunction createFuzzerInput<T>(config: FuzzerConfig<T>, progress: number): T {\n progress = Math.min(1, 2 * progress);\n const createShouldRandom = (strength: number) => {\n const chance = Math.random() * strength * 1.2 - 0.1;\n return () => Math.random() < chance;\n };\n const createShouldObjectDependent = (strength: number) => {\n const objectChance = Math.random() * strength * 1.2 - 0.1;\n const primitiveChance = Math.random() * strength * 1.2 - 0.1;\n return (v: any) => Math.random() * Math.random() < (isObjectLike(v) ? objectChance : primitiveChance);\n };\n\n const shouldKeep = createShouldObjectDependent(progress * 1);\n const shouldMakeNested = createShouldObjectDependent(1.25);\n const shouldNull = createShouldRandom(0.25);\n\n let res: any;\n const recurse = <U>(outputPath: string[], config: FuzzerConfig<U>, forceNested: boolean, forceNonNull: boolean) => {\n let subConfig: any = config[Math.floor(Math.random() * config.length)];\n const originalValue = isObjectLike(subConfig) ? (Array.isArray(subConfig) ? [] : {}) : subConfig;\n\n const newValue = forceNonNull || !shouldNull() ? originalValue : null;\n const newOutputPath = forceNested || shouldMakeNested(originalValue) || outputPath.length === 0 ? outputPath : [outputPath.join(\".\")];\n if (outputPath.length === 0) {\n res = newValue;\n } else {\n if (forceNested || shouldKeep(originalValue)) {\n setDeep(res, newOutputPath, newValue);\n }\n }\n if (isObjectLike(subConfig)) {\n for (const [key, newValue] of typedEntries(subConfig)) {\n recurse([...newOutputPath, key], newValue, Array.isArray(subConfig), Array.isArray(subConfig));\n }\n }\n };\n recurse<T>([], config, false, true);\n return res;\n}\n\nundefined?.test(\"fuzz schemas\", async ({ expect }) => {\n const totalIterations = process.env.CI ? 1000 : 200;\n for (let i = 0; i < totalIterations; i++) {\n const projectInput = createFuzzerInput<ProjectConfigNormalizedOverride>(projectSchemaFuzzerConfig, i / totalIterations);\n const branchInput = createFuzzerInput<BranchConfigNormalizedOverride>(branchSchemaFuzzerConfig, i / totalIterations);\n const environmentInput = createFuzzerInput<EnvironmentConfigNormalizedOverride>(environmentSchemaFuzzerConfig, i / totalIterations);\n const organizationInput = createFuzzerInput<OrganizationConfigNormalizedOverride>(organizationSchemaFuzzerConfig, i / totalIterations);\n\n try {\n const projectMigrated = migrateConfigOverride(\"project\", projectInput);\n await assertNoConfigOverrideErrors(projectConfigSchema, projectMigrated);\n const projectOverridden = override({}, projectMigrated);\n await sanitizeProjectConfig(normalize(applyProjectDefaults(projectOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n const branchMigrated = migrateConfigOverride(\"branch\", branchInput);\n await assertNoConfigOverrideErrors(branchConfigSchema, branchMigrated);\n const branchOverridden = override(projectOverridden, branchMigrated);\n await sanitizeBranchConfig(normalize(applyBranchDefaults(branchOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n const environmentMigrated = migrateConfigOverride(\"environment\", environmentInput);\n await assertNoConfigOverrideErrors(environmentConfigSchema, environmentMigrated);\n const environmentOverridden = override(branchOverridden, environmentMigrated);\n await sanitizeEnvironmentConfig(normalize(applyEnvironmentDefaults(environmentOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n const organizationMigrated = migrateConfigOverride(\"organization\", organizationInput);\n await assertNoConfigOverrideErrors(organizationConfigSchema, organizationMigrated);\n const organizationOverridden = override(environmentOverridden, organizationMigrated);\n await sanitizeOrganizationConfig(normalize(applyOrganizationDefaults(organizationOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n } catch (e) {\n const data = {\n cause: e,\n inputs: {\n projectInput,\n branchInput,\n environmentInput,\n organizationInput,\n },\n } as const;\n console.error(\"Failed to fuzz schema in iteration ${i}/${totalIterations}!\", nicify(data));\n throw new StackAssertionError(`Error in iteration ${i}/${totalIterations} of schema fuzz: ${e}`, { cause: e });\n }\n }\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/config/schema-fuzzer.test.ts"],"sourcesContent":["import { ALL_APPS } from \"../apps/apps-config\";\nimport { SUPPORTED_CURRENCIES } from \"../utils/currency-constants\";\nimport { StackAssertionError } from \"../utils/errors\";\nimport { getOrUndefined, isObjectLike, set, typedEntries, typedFromEntries } from \"../utils/objects\";\nimport { nicify } from \"../utils/strings\";\nimport { normalize, override } from \"./format\";\nimport { BranchConfigNormalizedOverride, EnvironmentConfigNormalizedOverride, OrganizationConfigNormalizedOverride, ProjectConfigNormalizedOverride, applyBranchDefaults, applyEnvironmentDefaults, applyOrganizationDefaults, applyProjectDefaults, assertNoConfigOverrideErrors, branchConfigSchema, environmentConfigSchema, migrateConfigOverride, organizationConfigSchema, projectConfigSchema, sanitizeBranchConfig, sanitizeEnvironmentConfig, sanitizeOrganizationConfig, sanitizeProjectConfig } from \"./schema\";\n\ntype FuzzerConfig<T> = ReadonlyArray<T extends object ? ([T] extends [any[]] ? { readonly [K in keyof T]: FuzzerConfig<T[K]> } : Required<{\n [K in keyof T]: FuzzerConfig<T[K]>;\n}> & Record<string, FuzzerConfig<any>>) : T>;\n\nconst projectSchemaFuzzerConfig = [{\n sourceOfTruth: [{\n type: [\"hosted\", \"neon\", \"postgres\"],\n connectionString: [\"\", \"postgres://user:password@host:port/database\", \"THIS IS A STRING LOLOL\"],\n connectionStrings: [{\n \"123-some-branch-id\": [\"\", \"THIS IS A CONNECTION STRING OR SO\"],\n }],\n }],\n}] satisfies FuzzerConfig<ProjectConfigNormalizedOverride>;\n\nconst branchSchemaFuzzerConfig = [{\n apiKeys: [{\n enabled: [{\n team: [true, false],\n user: [true, false],\n }],\n }],\n auth: [{\n allowSignUp: [true, false],\n password: [{\n allowSignIn: [true, false],\n }],\n otp: [{\n allowSignIn: [true, false],\n }],\n passkey: [{\n allowSignIn: [true, false],\n }],\n oauth: [{\n accountMergeStrategy: [\"link_method\", \"raise_error\", \"allow_duplicates\"],\n providers: [{\n \"google\": [{\n type: [\"google\", \"github\", \"x\"] as const,\n allowSignIn: [true, false],\n allowConnectedAccounts: [true, false],\n }],\n }],\n }],\n signUpRules: [{\n \"some-rule-id\": [{\n enabled: [true, false],\n displayName: [\"Block Test Emails\", \"Allow Only Company Domain\"],\n priority: [0, 1, 100],\n condition: ['email.endsWith(\"@test.com\")', 'emailDomain == \"company.com\"'],\n action: [{\n type: [\"allow\", \"reject\", \"restrict\", \"log\"] as const,\n message: [\"\", \"Sign up is not allowed for this email\"],\n }],\n }],\n }],\n signUpRulesDefaultAction: [\"allow\", \"reject\"],\n }],\n dbSync: [{\n externalDatabases: [{\n \"some-external-db-id\": [{\n type: [\"postgres\"] as const,\n connectionString: [\n \"postgres://user:password@host:port/database\",\n \"some-connection-string\",\n ],\n }],\n }],\n }],\n dataVault: [{\n stores: [{\n \"some-store-id\": [{\n displayName: [\"Some Store\", \"Some Other Store\"],\n }],\n \"some-other-store-id\": [{\n displayName: [\"Some Store\", \"Some Other Store\"],\n }],\n }],\n }],\n payments: [{\n blockNewPurchases: [false, true],\n autoPay: [{\n interval: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n }],\n productLines: [{\n \"some-product-line-id\": [{\n displayName: [\"Some Product Line\", \"Some Other Product Line\"],\n customerType: [\"user\", \"team\", \"custom\"] as const,\n }],\n }],\n catalogs: [{ // ensure migration works\n \"some-product-line-id\": [{\n displayName: [\"Some Product Line\", \"Some Other Product Line\"],\n }],\n }],\n groups: [{ // ensure migration works\n \"some-product-line-id\": [{\n displayName: [\"Some Product Line\", \"Some Other Product Line\"],\n }],\n }],\n items: [{\n \"some-item-id\": [{\n customerType: [\"user\", \"team\", \"custom\"] as const,\n displayName: [\"Some Item\", \"Some Other Item\"],\n }],\n }],\n products: [{\n \"some-product-id\": [{\n displayName: [\"Some Product\", \"Some Other Product\"],\n customerType: [\"user\", \"team\", \"custom\"] as const,\n freeTrial: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n serverOnly: [true, false],\n stackable: [true, false],\n productLineId: [\"some-product-line-id\", \"some-other-product-line-id\"],\n catalogId: [\"some-product-line-id\", \"some-other-product-line-id\"], // ensure migration works\n groupId: [\"some-product-line-id\", \"some-other-product-line-id\"], // ensure migration works\n isAddOnTo: [false, { \"some-product-id\": [true], \"some-other-product-id\": [true] }] as const,\n prices: [\"include-by-default\" as \"include-by-default\", {\n \"some-price-id\": [{\n ...typedFromEntries(SUPPORTED_CURRENCIES.map(currency => [currency.code, [\"100_00\", \"not a number\", \"Infinity\", \"0\"]])),\n interval: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n serverOnly: [true, false],\n freeTrial: [[[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n }],\n }],\n includedItems: [{\n \"some-item-id\": [{\n quantity: [0, 1, -3, 100, 0.333, Infinity],\n repeat: [\"never\", [[0, 1, -3, 100, 0.333, Infinity], [\"day\", \"week\", \"month\", \"year\"]]] as const,\n expires: [\"never\", \"when-purchase-expires\", \"when-repeated\"] as const,\n }],\n }],\n }],\n }],\n }],\n emails: [{\n themes: [{\n \"12345678-1234-4234-9234-123456789012\": [{\n displayName: [\"Some Theme\", \"Some Other Theme\"],\n tsxSource: [\"\", \"some typescript source code\"],\n }],\n }],\n selectedThemeId: [\"some-theme-id\", \"some-other-theme-id\"],\n templates: [{\n \"12345678-1234-4234-9234-123456789012\": [{\n themeId: [\"some-theme-id\", \"some-other-theme-id\"],\n displayName: [\"Some Template\", \"Some Other Template\"],\n tsxSource: [\"\", \"some typescript source code\"],\n }],\n }],\n }],\n teams: [{\n createPersonalTeamOnSignUp: [true, false],\n allowClientTeamCreation: [true, false],\n }],\n users: [{\n allowClientUserDeletion: [true, false],\n }],\n rbac: [{\n permissions: [{\n \"some_permission_id\": [{\n containedPermissionIds: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n description: [\"Some Permission\", \"Some Other Permission\"],\n scope: [\"team\", \"project\"] as const,\n }],\n }],\n defaultPermissions: [{\n teamCreator: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n teamMember: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n signUp: [{\n \"some_permission_id\": [true],\n \"$some_other_permission_id\": [true],\n }] as const,\n }],\n }],\n domains: [{}],\n apps: [{\n installed: [typedFromEntries(typedEntries(ALL_APPS).map(([key, value]) => [key, [{\n enabled: [true, false],\n }]]))],\n }],\n onboarding: [{\n requireEmailVerification: [true, false],\n }],\n}] satisfies FuzzerConfig<BranchConfigNormalizedOverride>;\n\nconst environmentSchemaFuzzerConfig = [{\n ...branchSchemaFuzzerConfig[0],\n auth: [{\n ...branchSchemaFuzzerConfig[0].auth[0],\n oauth: [{\n ...branchSchemaFuzzerConfig[0].auth[0].oauth[0],\n providers: [typedFromEntries(typedEntries(branchSchemaFuzzerConfig[0].auth[0].oauth[0].providers[0]).map(([key, value]) => [key, [{\n ...value[0],\n isShared: [true, false],\n clientId: [\"some-client-id\"],\n clientSecret: [\"some-client-secret\"],\n facebookConfigId: [\"some-facebook-config-id\"],\n microsoftTenantId: [\"some-microsoft-tenant-id\"],\n appleBundles: [{ \"some-bundle-id\": [{ bundleId: [\"com.example.app\"] }] }],\n }]]))] as const,\n }],\n }],\n domains: [{\n allowLocalhost: [true, false],\n trustedDomains: [{\n \"some-domain-id\": [{\n baseUrl: [\"https://example.com/something-here\"],\n handlerPath: [\"/something-here\"],\n }],\n }],\n }],\n emails: [{\n ...branchSchemaFuzzerConfig[0].emails[0],\n server: [{\n isShared: [true, false],\n provider: [\"resend\", \"smtp\"] as const,\n host: [\"example.com\", \"://super weird host that's not valid\"],\n port: [1234, 0.12543, -100, Infinity],\n username: [\"some-username\", \"some username with a space\"],\n password: [\"some-password\", \"some password with a space\"],\n senderName: [\"Some Sender\"],\n senderEmail: [\"some-sender@example.com\", \"some invalid email\"],\n }],\n }],\n payments: [{\n ...branchSchemaFuzzerConfig[0].payments[0],\n testMode: [false, true],\n }],\n}] satisfies FuzzerConfig<EnvironmentConfigNormalizedOverride>;\n\nconst organizationSchemaFuzzerConfig = environmentSchemaFuzzerConfig satisfies FuzzerConfig<OrganizationConfigNormalizedOverride>;\n\nfunction setDeep<T>(obj: T, path: string[], value: any) {\n if (!isObjectLike(obj)) return obj;\n\n if (path.length === 0) {\n throw new Error(\"Path is empty\");\n } else if (path.length === 1) {\n set(obj as any, path[0], value);\n } else {\n const [key, ...rest] = path;\n setDeep(getOrUndefined(obj as any, key), rest, value);\n }\n}\n\nfunction createFuzzerInput<T>(config: FuzzerConfig<T>, progress: number): T {\n progress = Math.min(1, 2 * progress);\n const createShouldRandom = (strength: number) => {\n const chance = Math.random() * strength * 1.2 - 0.1;\n return () => Math.random() < chance;\n };\n const createShouldObjectDependent = (strength: number) => {\n const objectChance = Math.random() * strength * 1.2 - 0.1;\n const primitiveChance = Math.random() * strength * 1.2 - 0.1;\n return (v: any) => Math.random() * Math.random() < (isObjectLike(v) ? objectChance : primitiveChance);\n };\n\n const shouldKeep = createShouldObjectDependent(progress * 1);\n const shouldMakeNested = createShouldObjectDependent(1.25);\n const shouldNull = createShouldRandom(0.25);\n\n let res: any;\n const recurse = <U>(outputPath: string[], config: FuzzerConfig<U>, forceNested: boolean, forceNonNull: boolean) => {\n let subConfig: any = config[Math.floor(Math.random() * config.length)];\n const originalValue = isObjectLike(subConfig) ? (Array.isArray(subConfig) ? [] : {}) : subConfig;\n\n const newValue = forceNonNull || !shouldNull() ? originalValue : null;\n const newOutputPath = forceNested || shouldMakeNested(originalValue) || outputPath.length === 0 ? outputPath : [outputPath.join(\".\")];\n if (outputPath.length === 0) {\n res = newValue;\n } else {\n if (forceNested || shouldKeep(originalValue)) {\n setDeep(res, newOutputPath, newValue);\n }\n }\n if (isObjectLike(subConfig)) {\n for (const [key, newValue] of typedEntries(subConfig)) {\n recurse([...newOutputPath, key], newValue, Array.isArray(subConfig), Array.isArray(subConfig));\n }\n }\n };\n recurse<T>([], config, false, true);\n return res;\n}\n\nundefined?.test(\"fuzz schemas\", async ({ expect }) => {\n const totalIterations = process.env.CI ? 1000 : 200;\n for (let i = 0; i < totalIterations; i++) {\n const projectInput = createFuzzerInput<ProjectConfigNormalizedOverride>(projectSchemaFuzzerConfig, i / totalIterations);\n const branchInput = createFuzzerInput<BranchConfigNormalizedOverride>(branchSchemaFuzzerConfig, i / totalIterations);\n const environmentInput = createFuzzerInput<EnvironmentConfigNormalizedOverride>(environmentSchemaFuzzerConfig, i / totalIterations);\n const organizationInput = createFuzzerInput<OrganizationConfigNormalizedOverride>(organizationSchemaFuzzerConfig, i / totalIterations);\n\n try {\n const projectMigrated = migrateConfigOverride(\"project\", projectInput);\n await assertNoConfigOverrideErrors(projectConfigSchema, projectMigrated);\n const projectOverridden = override({}, projectMigrated);\n await sanitizeProjectConfig(normalize(applyProjectDefaults(projectOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n const branchMigrated = migrateConfigOverride(\"branch\", branchInput);\n await assertNoConfigOverrideErrors(branchConfigSchema, branchMigrated);\n const branchOverridden = override(projectOverridden, branchMigrated);\n await sanitizeBranchConfig(normalize(applyBranchDefaults(branchOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n const environmentMigrated = migrateConfigOverride(\"environment\", environmentInput);\n await assertNoConfigOverrideErrors(environmentConfigSchema, environmentMigrated);\n const environmentOverridden = override(branchOverridden, environmentMigrated);\n await sanitizeEnvironmentConfig(normalize(applyEnvironmentDefaults(environmentOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n const organizationMigrated = migrateConfigOverride(\"organization\", organizationInput);\n await assertNoConfigOverrideErrors(organizationConfigSchema, organizationMigrated);\n const organizationOverridden = override(environmentOverridden, organizationMigrated);\n await sanitizeOrganizationConfig(normalize(applyOrganizationDefaults(organizationOverridden), { onDotIntoNonObject: \"ignore\" }) as any);\n\n } catch (e) {\n const data = {\n cause: e,\n inputs: {\n projectInput,\n branchInput,\n environmentInput,\n organizationInput,\n },\n } as const;\n console.error(\"Failed to fuzz schema in iteration ${i}/${totalIterations}!\", nicify(data));\n throw new StackAssertionError(`Error in iteration ${i}/${totalIterations} of schema fuzz: ${e}`, { cause: e });\n }\n }\n});\n"],"mappings":"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","names":[]}
|