@tscircuit/fake-snippets 0.0.71 → 0.0.73
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/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +26 -0
- package/bun.lock +58 -58
- package/dist/bundle.js +56 -5
- package/dist/index.d.ts +15 -2
- package/dist/index.js +47 -1
- package/dist/schema.d.ts +8 -0
- package/dist/schema.js +1 -0
- package/fake-snippets-api/lib/db/db-client.ts +47 -0
- package/fake-snippets-api/lib/db/schema.ts +1 -0
- package/fake-snippets-api/lib/package_file/generate-fs-sha.ts +20 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package.ts +1 -0
- package/fake-snippets-api/routes/api/package_files/create.ts +3 -0
- package/fake-snippets-api/routes/api/package_files/create_or_update.ts +9 -3
- package/fake-snippets-api/routes/api/package_files/delete.ts +3 -0
- package/fake-snippets-api/routes/api/packages/create.ts +1 -0
- package/package.json +11 -11
- package/src/App.tsx +5 -0
- package/src/components/FileSidebar.tsx +111 -37
- package/src/components/JLCPCBImportDialog.tsx +1 -1
- package/src/components/PackageBuildsPage/DeploymentDetailsPage.tsx +56 -0
- package/src/components/PackageBuildsPage/build-preview-content.tsx +11 -0
- package/src/components/PackageBuildsPage/collapsible-section.tsx +70 -0
- package/src/components/PackageBuildsPage/deployment-details-panel.tsx +84 -0
- package/src/components/PackageBuildsPage/deployment-header.tsx +75 -0
- package/src/components/PackageCard.tsx +1 -10
- package/src/components/TrendingPackagesCarousel.tsx +5 -16
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -1
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +2 -6
- package/src/components/package-port/CodeAndPreview.tsx +78 -267
- package/src/components/package-port/CodeEditor.tsx +30 -19
- package/src/components/package-port/CodeEditorHeader.tsx +7 -6
- package/src/components/package-port/EditorNav.tsx +17 -13
- package/src/components/ui/tree-view.tsx +3 -3
- package/src/hooks/use-current-package-id.ts +2 -8
- package/src/hooks/use-preview-images.ts +3 -15
- package/src/hooks/useFileManagement.ts +257 -38
- package/src/hooks/usePackageFilesLoader.ts +2 -2
- package/src/hooks/useUpdatePackageFilesMutation.ts +50 -24
- package/src/lib/utils/checkIfManualEditsImported.ts +9 -0
- package/src/pages/editor.tsx +2 -10
- package/src/pages/package-builds.tsx +33 -0
- package/src/pages/package-editor.tsx +2 -14
- package/src/hooks/use-get-fsmap-hash-for-package.ts +0 -19
package/dist/index.d.ts
CHANGED
|
@@ -508,6 +508,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
508
508
|
ai_description: z.ZodNullable<z.ZodString>;
|
|
509
509
|
latest_license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
510
510
|
ai_usage_instructions: z.ZodNullable<z.ZodString>;
|
|
511
|
+
latest_package_release_fs_sha: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
511
512
|
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
512
513
|
}, "strip", z.ZodTypeAny, {
|
|
513
514
|
name: string;
|
|
@@ -535,6 +536,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
535
536
|
website: string | null;
|
|
536
537
|
ai_description: string | null;
|
|
537
538
|
ai_usage_instructions: string | null;
|
|
539
|
+
latest_package_release_fs_sha: string | null;
|
|
538
540
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
539
541
|
latest_license?: string | null | undefined;
|
|
540
542
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -566,6 +568,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
566
568
|
is_source_from_github?: boolean | undefined;
|
|
567
569
|
website?: string | null | undefined;
|
|
568
570
|
latest_license?: string | null | undefined;
|
|
571
|
+
latest_package_release_fs_sha?: string | null | undefined;
|
|
569
572
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
570
573
|
}>;
|
|
571
574
|
type Package = z.infer<typeof packageSchema>;
|
|
@@ -779,6 +782,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
779
782
|
website: string | null;
|
|
780
783
|
ai_description: string | null;
|
|
781
784
|
ai_usage_instructions: string | null;
|
|
785
|
+
latest_package_release_fs_sha: string | null;
|
|
782
786
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
783
787
|
latest_license?: string | null | undefined;
|
|
784
788
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -889,7 +893,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
889
893
|
}[];
|
|
890
894
|
total_cost_without_shipping: number;
|
|
891
895
|
}[];
|
|
892
|
-
}, "addOrder" | "getOrderById" | "getOrderFilesByOrderId" | "addOrderQuote" | "getOrderQuoteById" | "getJlcpcbOrderStatesByOrderId" | "getJlcpcbOrderStepRunsByJlcpcbOrderStateId" | "updateOrder" | "addJlcpcbOrderState" | "updateJlcpcbOrderState" | "addOrderFile" | "getOrderFileById" | "addAccount" | "addAccountPackage" | "getAccountPackageById" | "updateAccountPackage" | "deleteAccountPackage" | "addSnippet" | "getLatestSnippets" | "getTrendingSnippets" | "getPackagesByAuthor" | "getSnippetByAuthorAndName" | "updateSnippet" | "getSnippetById" | "searchSnippets" | "searchPackages" | "deleteSnippet" | "addSession" | "getSessions" | "createLoginPage" | "getLoginPage" | "updateLoginPage" | "getAccount" | "updateAccount" | "createSession" | "addStar" | "removeStar" | "hasStarred" | "addPackage" | "updatePackage" | "getPackageById" | "getPackageReleaseById" | "addPackageRelease" | "updatePackageRelease" | "deletePackageFile" | "addPackageFile" | "updatePackageFile" | "getStarCount" | "getPackageFilesByReleaseId"> & {
|
|
896
|
+
}, "addOrder" | "getOrderById" | "getOrderFilesByOrderId" | "addOrderQuote" | "getOrderQuoteById" | "getJlcpcbOrderStatesByOrderId" | "getJlcpcbOrderStepRunsByJlcpcbOrderStateId" | "updateOrder" | "addJlcpcbOrderState" | "updateJlcpcbOrderState" | "addOrderFile" | "getOrderFileById" | "addAccount" | "addAccountPackage" | "getAccountPackageById" | "updateAccountPackage" | "deleteAccountPackage" | "addSnippet" | "getLatestSnippets" | "getTrendingSnippets" | "getPackagesByAuthor" | "getSnippetByAuthorAndName" | "updateSnippet" | "getSnippetById" | "searchSnippets" | "searchPackages" | "deleteSnippet" | "addSession" | "getSessions" | "createLoginPage" | "getLoginPage" | "updateLoginPage" | "getAccount" | "updateAccount" | "createSession" | "addStar" | "removeStar" | "hasStarred" | "addPackage" | "updatePackage" | "getPackageById" | "getPackageReleaseById" | "addPackageRelease" | "updatePackageRelease" | "deletePackageFile" | "addPackageFile" | "updatePackageFile" | "getStarCount" | "getPackageFilesByReleaseId" | "updatePackageReleaseFsSha"> & {
|
|
893
897
|
addOrder: (order: Omit<Order, "order_id">) => Order;
|
|
894
898
|
getOrderById: (orderId: string) => Order | undefined;
|
|
895
899
|
getOrderFilesByOrderId: (orderId: string) => OrderFile[];
|
|
@@ -963,6 +967,10 @@ declare const createDatabase: ({ seed }?: {
|
|
|
963
967
|
updatePackageFile: (packageFileId: string, updates: Partial<Omit<PackageFile, "package_file_id">>) => PackageFile;
|
|
964
968
|
getStarCount: (packageId: string) => number;
|
|
965
969
|
getPackageFilesByReleaseId: (packageReleaseId: string) => PackageFile[];
|
|
970
|
+
/**
|
|
971
|
+
* Update fs_sha for a package release based on its files
|
|
972
|
+
*/
|
|
973
|
+
updatePackageReleaseFsSha: (packageReleaseId: string) => void;
|
|
966
974
|
}> & Omit<{
|
|
967
975
|
idCounter: number;
|
|
968
976
|
snippets: {
|
|
@@ -1070,6 +1078,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
1070
1078
|
website: string | null;
|
|
1071
1079
|
ai_description: string | null;
|
|
1072
1080
|
ai_usage_instructions: string | null;
|
|
1081
|
+
latest_package_release_fs_sha: string | null;
|
|
1073
1082
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1074
1083
|
latest_license?: string | null | undefined;
|
|
1075
1084
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -1180,7 +1189,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
1180
1189
|
}[];
|
|
1181
1190
|
total_cost_without_shipping: number;
|
|
1182
1191
|
}[];
|
|
1183
|
-
}, "addOrder" | "getOrderById" | "getOrderFilesByOrderId" | "addOrderQuote" | "getOrderQuoteById" | "getJlcpcbOrderStatesByOrderId" | "getJlcpcbOrderStepRunsByJlcpcbOrderStateId" | "updateOrder" | "addJlcpcbOrderState" | "updateJlcpcbOrderState" | "addOrderFile" | "getOrderFileById" | "addAccount" | "addAccountPackage" | "getAccountPackageById" | "updateAccountPackage" | "deleteAccountPackage" | "addSnippet" | "getLatestSnippets" | "getTrendingSnippets" | "getPackagesByAuthor" | "getSnippetByAuthorAndName" | "updateSnippet" | "getSnippetById" | "searchSnippets" | "searchPackages" | "deleteSnippet" | "addSession" | "getSessions" | "createLoginPage" | "getLoginPage" | "updateLoginPage" | "getAccount" | "updateAccount" | "createSession" | "addStar" | "removeStar" | "hasStarred" | "addPackage" | "updatePackage" | "getPackageById" | "getPackageReleaseById" | "addPackageRelease" | "updatePackageRelease" | "deletePackageFile" | "addPackageFile" | "updatePackageFile" | "getStarCount" | "getPackageFilesByReleaseId"> & {
|
|
1192
|
+
}, "addOrder" | "getOrderById" | "getOrderFilesByOrderId" | "addOrderQuote" | "getOrderQuoteById" | "getJlcpcbOrderStatesByOrderId" | "getJlcpcbOrderStepRunsByJlcpcbOrderStateId" | "updateOrder" | "addJlcpcbOrderState" | "updateJlcpcbOrderState" | "addOrderFile" | "getOrderFileById" | "addAccount" | "addAccountPackage" | "getAccountPackageById" | "updateAccountPackage" | "deleteAccountPackage" | "addSnippet" | "getLatestSnippets" | "getTrendingSnippets" | "getPackagesByAuthor" | "getSnippetByAuthorAndName" | "updateSnippet" | "getSnippetById" | "searchSnippets" | "searchPackages" | "deleteSnippet" | "addSession" | "getSessions" | "createLoginPage" | "getLoginPage" | "updateLoginPage" | "getAccount" | "updateAccount" | "createSession" | "addStar" | "removeStar" | "hasStarred" | "addPackage" | "updatePackage" | "getPackageById" | "getPackageReleaseById" | "addPackageRelease" | "updatePackageRelease" | "deletePackageFile" | "addPackageFile" | "updatePackageFile" | "getStarCount" | "getPackageFilesByReleaseId" | "updatePackageReleaseFsSha"> & {
|
|
1184
1193
|
addOrder: (order: Omit<Order, "order_id">) => Order;
|
|
1185
1194
|
getOrderById: (orderId: string) => Order | undefined;
|
|
1186
1195
|
getOrderFilesByOrderId: (orderId: string) => OrderFile[];
|
|
@@ -1254,6 +1263,10 @@ declare const createDatabase: ({ seed }?: {
|
|
|
1254
1263
|
updatePackageFile: (packageFileId: string, updates: Partial<Omit<PackageFile, "package_file_id">>) => PackageFile;
|
|
1255
1264
|
getStarCount: (packageId: string) => number;
|
|
1256
1265
|
getPackageFilesByReleaseId: (packageReleaseId: string) => PackageFile[];
|
|
1266
|
+
/**
|
|
1267
|
+
* Update fs_sha for a package release based on its files
|
|
1268
|
+
*/
|
|
1269
|
+
updatePackageReleaseFsSha: (packageReleaseId: string) => void;
|
|
1257
1270
|
};
|
|
1258
1271
|
type DbClient = ReturnType<typeof createDatabase>;
|
|
1259
1272
|
|
package/dist/index.js
CHANGED
|
@@ -188,6 +188,7 @@ var packageSchema = z.object({
|
|
|
188
188
|
ai_description: z.string().nullable(),
|
|
189
189
|
latest_license: z.string().nullable().optional(),
|
|
190
190
|
ai_usage_instructions: z.string().nullable(),
|
|
191
|
+
latest_package_release_fs_sha: z.string().nullable().default(null),
|
|
191
192
|
default_view: z.enum(["files", "3d", "pcb", "schematic"]).default("files").optional()
|
|
192
193
|
});
|
|
193
194
|
var jlcpcbOrderStateSchema = z.object({
|
|
@@ -2001,6 +2002,17 @@ export const SquareWaveModule = () => (
|
|
|
2001
2002
|
});
|
|
2002
2003
|
};
|
|
2003
2004
|
|
|
2005
|
+
// fake-snippets-api/lib/package_file/generate-fs-sha.ts
|
|
2006
|
+
import md5 from "md5";
|
|
2007
|
+
function generateFsSha(packageFiles) {
|
|
2008
|
+
const fsMap = {};
|
|
2009
|
+
packageFiles.filter((file) => file.content_text).forEach((file) => {
|
|
2010
|
+
fsMap[file.file_path] = file.content_text || "";
|
|
2011
|
+
});
|
|
2012
|
+
const hash = md5(JSON.stringify(fsMap));
|
|
2013
|
+
return `md5-${hash}`;
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2004
2016
|
// fake-snippets-api/lib/db/db-client.ts
|
|
2005
2017
|
var createDatabase = ({ seed: seed2 } = {}) => {
|
|
2006
2018
|
const db = hoist(createStore(initializer));
|
|
@@ -2209,7 +2221,8 @@ var initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
2209
2221
|
is_private: false,
|
|
2210
2222
|
is_public: true,
|
|
2211
2223
|
is_unlisted: false,
|
|
2212
|
-
latest_package_release_id: `package_release_${nextId}
|
|
2224
|
+
latest_package_release_id: `package_release_${nextId}`,
|
|
2225
|
+
latest_package_release_fs_sha: null
|
|
2213
2226
|
};
|
|
2214
2227
|
const newPackageRelease = {
|
|
2215
2228
|
package_release_id: `package_release_${nextId}`,
|
|
@@ -2265,6 +2278,20 @@ var initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
2265
2278
|
packageFiles: [...state.packageFiles, ...packageFiles],
|
|
2266
2279
|
idCounter: fileIdCounter
|
|
2267
2280
|
}));
|
|
2281
|
+
const dbState = get();
|
|
2282
|
+
const releaseFiles = dbState.packageFiles.filter(
|
|
2283
|
+
(pf) => pf.package_release_id === newPackageRelease.package_release_id
|
|
2284
|
+
);
|
|
2285
|
+
const fsSha = generateFsSha(releaseFiles);
|
|
2286
|
+
set((state) => ({
|
|
2287
|
+
...state,
|
|
2288
|
+
packageReleases: state.packageReleases.map(
|
|
2289
|
+
(pr) => pr.package_release_id === newPackageRelease.package_release_id ? { ...pr, fs_sha: fsSha } : pr
|
|
2290
|
+
),
|
|
2291
|
+
packages: state.packages.map(
|
|
2292
|
+
(pkg) => pkg.latest_package_release_id === newPackageRelease.package_release_id ? { ...pkg, latest_package_release_fs_sha: fsSha } : pkg
|
|
2293
|
+
)
|
|
2294
|
+
}));
|
|
2268
2295
|
return {
|
|
2269
2296
|
snippet_id: newPackage.package_id,
|
|
2270
2297
|
package_release_id: newPackageRelease.package_release_id,
|
|
@@ -2976,6 +3003,25 @@ var initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
2976
3003
|
return state.packageFiles.filter(
|
|
2977
3004
|
(pf) => pf.package_release_id === packageReleaseId
|
|
2978
3005
|
);
|
|
3006
|
+
},
|
|
3007
|
+
/**
|
|
3008
|
+
* Update fs_sha for a package release based on its files
|
|
3009
|
+
*/
|
|
3010
|
+
updatePackageReleaseFsSha: (packageReleaseId) => {
|
|
3011
|
+
const state = get();
|
|
3012
|
+
const packageFiles = state.packageFiles.filter(
|
|
3013
|
+
(pf) => pf.package_release_id === packageReleaseId
|
|
3014
|
+
);
|
|
3015
|
+
const fsSha = generateFsSha(packageFiles);
|
|
3016
|
+
set((currentState) => ({
|
|
3017
|
+
...currentState,
|
|
3018
|
+
packageReleases: currentState.packageReleases.map(
|
|
3019
|
+
(pr) => pr.package_release_id === packageReleaseId ? { ...pr, fs_sha: fsSha } : pr
|
|
3020
|
+
),
|
|
3021
|
+
packages: currentState.packages.map(
|
|
3022
|
+
(pkg) => pkg.latest_package_release_id === packageReleaseId ? { ...pkg, latest_package_release_fs_sha: fsSha } : pkg
|
|
3023
|
+
)
|
|
3024
|
+
}));
|
|
2979
3025
|
}
|
|
2980
3026
|
}));
|
|
2981
3027
|
|
package/dist/schema.d.ts
CHANGED
|
@@ -633,6 +633,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
633
633
|
ai_description: z.ZodNullable<z.ZodString>;
|
|
634
634
|
latest_license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
635
635
|
ai_usage_instructions: z.ZodNullable<z.ZodString>;
|
|
636
|
+
latest_package_release_fs_sha: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
636
637
|
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
637
638
|
}, "strip", z.ZodTypeAny, {
|
|
638
639
|
name: string;
|
|
@@ -660,6 +661,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
660
661
|
website: string | null;
|
|
661
662
|
ai_description: string | null;
|
|
662
663
|
ai_usage_instructions: string | null;
|
|
664
|
+
latest_package_release_fs_sha: string | null;
|
|
663
665
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
664
666
|
latest_license?: string | null | undefined;
|
|
665
667
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -691,6 +693,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
691
693
|
is_source_from_github?: boolean | undefined;
|
|
692
694
|
website?: string | null | undefined;
|
|
693
695
|
latest_license?: string | null | undefined;
|
|
696
|
+
latest_package_release_fs_sha?: string | null | undefined;
|
|
694
697
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
695
698
|
}>;
|
|
696
699
|
type Package = z.infer<typeof packageSchema>;
|
|
@@ -1071,6 +1074,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1071
1074
|
ai_description: z.ZodNullable<z.ZodString>;
|
|
1072
1075
|
latest_license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1073
1076
|
ai_usage_instructions: z.ZodNullable<z.ZodString>;
|
|
1077
|
+
latest_package_release_fs_sha: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
1074
1078
|
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
1075
1079
|
}, "strip", z.ZodTypeAny, {
|
|
1076
1080
|
name: string;
|
|
@@ -1098,6 +1102,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1098
1102
|
website: string | null;
|
|
1099
1103
|
ai_description: string | null;
|
|
1100
1104
|
ai_usage_instructions: string | null;
|
|
1105
|
+
latest_package_release_fs_sha: string | null;
|
|
1101
1106
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1102
1107
|
latest_license?: string | null | undefined;
|
|
1103
1108
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -1129,6 +1134,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1129
1134
|
is_source_from_github?: boolean | undefined;
|
|
1130
1135
|
website?: string | null | undefined;
|
|
1131
1136
|
latest_license?: string | null | undefined;
|
|
1137
|
+
latest_package_release_fs_sha?: string | null | undefined;
|
|
1132
1138
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
1133
1139
|
}>, "many">>;
|
|
1134
1140
|
orders: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -1576,6 +1582,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1576
1582
|
website: string | null;
|
|
1577
1583
|
ai_description: string | null;
|
|
1578
1584
|
ai_usage_instructions: string | null;
|
|
1585
|
+
latest_package_release_fs_sha: string | null;
|
|
1579
1586
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1580
1587
|
latest_license?: string | null | undefined;
|
|
1581
1588
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -1795,6 +1802,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1795
1802
|
is_source_from_github?: boolean | undefined;
|
|
1796
1803
|
website?: string | null | undefined;
|
|
1797
1804
|
latest_license?: string | null | undefined;
|
|
1805
|
+
latest_package_release_fs_sha?: string | null | undefined;
|
|
1798
1806
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
1799
1807
|
}[] | undefined;
|
|
1800
1808
|
orders?: {
|
package/dist/schema.js
CHANGED
|
@@ -183,6 +183,7 @@ var packageSchema = z.object({
|
|
|
183
183
|
ai_description: z.string().nullable(),
|
|
184
184
|
latest_license: z.string().nullable().optional(),
|
|
185
185
|
ai_usage_instructions: z.string().nullable(),
|
|
186
|
+
latest_package_release_fs_sha: z.string().nullable().default(null),
|
|
186
187
|
default_view: z.enum(["files", "3d", "pcb", "schematic"]).default("files").optional()
|
|
187
188
|
});
|
|
188
189
|
var jlcpcbOrderStateSchema = z.object({
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type snippetSchema,
|
|
23
23
|
} from "./schema.ts"
|
|
24
24
|
import { seed as seedFn } from "./seed"
|
|
25
|
+
import { generateFsSha } from "../package_file/generate-fs-sha"
|
|
25
26
|
|
|
26
27
|
export const createDatabase = ({ seed }: { seed?: boolean } = {}) => {
|
|
27
28
|
const db = hoist(createStore(initializer))
|
|
@@ -271,6 +272,7 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
271
272
|
is_public: true,
|
|
272
273
|
is_unlisted: false,
|
|
273
274
|
latest_package_release_id: `package_release_${nextId}`,
|
|
275
|
+
latest_package_release_fs_sha: null,
|
|
274
276
|
}
|
|
275
277
|
|
|
276
278
|
// Create package release
|
|
@@ -341,6 +343,27 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
341
343
|
idCounter: fileIdCounter,
|
|
342
344
|
}))
|
|
343
345
|
|
|
346
|
+
// Update fs_sha for the new package release
|
|
347
|
+
const dbState = get()
|
|
348
|
+
const releaseFiles = dbState.packageFiles.filter(
|
|
349
|
+
(pf) => pf.package_release_id === newPackageRelease.package_release_id,
|
|
350
|
+
)
|
|
351
|
+
const fsSha = generateFsSha(releaseFiles)
|
|
352
|
+
|
|
353
|
+
set((state) => ({
|
|
354
|
+
...state,
|
|
355
|
+
packageReleases: state.packageReleases.map((pr) =>
|
|
356
|
+
pr.package_release_id === newPackageRelease.package_release_id
|
|
357
|
+
? { ...pr, fs_sha: fsSha }
|
|
358
|
+
: pr,
|
|
359
|
+
),
|
|
360
|
+
packages: state.packages.map((pkg) =>
|
|
361
|
+
pkg.latest_package_release_id === newPackageRelease.package_release_id
|
|
362
|
+
? { ...pkg, latest_package_release_fs_sha: fsSha }
|
|
363
|
+
: pkg,
|
|
364
|
+
),
|
|
365
|
+
}))
|
|
366
|
+
|
|
344
367
|
// Return in the same format as create endpoint
|
|
345
368
|
return {
|
|
346
369
|
snippet_id: newPackage.package_id,
|
|
@@ -1287,4 +1310,28 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
1287
1310
|
(pf) => pf.package_release_id === packageReleaseId,
|
|
1288
1311
|
)
|
|
1289
1312
|
},
|
|
1313
|
+
/**
|
|
1314
|
+
* Update fs_sha for a package release based on its files
|
|
1315
|
+
*/
|
|
1316
|
+
updatePackageReleaseFsSha: (packageReleaseId: string): void => {
|
|
1317
|
+
const state = get()
|
|
1318
|
+
const packageFiles = state.packageFiles.filter(
|
|
1319
|
+
(pf) => pf.package_release_id === packageReleaseId,
|
|
1320
|
+
)
|
|
1321
|
+
const fsSha = generateFsSha(packageFiles)
|
|
1322
|
+
|
|
1323
|
+
set((currentState) => ({
|
|
1324
|
+
...currentState,
|
|
1325
|
+
packageReleases: currentState.packageReleases.map((pr) =>
|
|
1326
|
+
pr.package_release_id === packageReleaseId
|
|
1327
|
+
? { ...pr, fs_sha: fsSha }
|
|
1328
|
+
: pr,
|
|
1329
|
+
),
|
|
1330
|
+
packages: currentState.packages.map((pkg) =>
|
|
1331
|
+
pkg.latest_package_release_id === packageReleaseId
|
|
1332
|
+
? { ...pkg, latest_package_release_fs_sha: fsSha }
|
|
1333
|
+
: pkg,
|
|
1334
|
+
),
|
|
1335
|
+
}))
|
|
1336
|
+
},
|
|
1290
1337
|
}))
|
|
@@ -219,6 +219,7 @@ export const packageSchema = z.object({
|
|
|
219
219
|
ai_description: z.string().nullable(),
|
|
220
220
|
latest_license: z.string().nullable().optional(),
|
|
221
221
|
ai_usage_instructions: z.string().nullable(),
|
|
222
|
+
latest_package_release_fs_sha: z.string().nullable().default(null),
|
|
222
223
|
default_view: z
|
|
223
224
|
.enum(["files", "3d", "pcb", "schematic"])
|
|
224
225
|
.default("files")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import md5 from "md5"
|
|
2
|
+
import type { PackageFile } from "../db/schema"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generate an MD5 hash from package files content
|
|
6
|
+
* Uses the same format as existing tests: creates a map of file_path -> content_text
|
|
7
|
+
* and generates an MD5 hash of the JSON stringified map
|
|
8
|
+
*/
|
|
9
|
+
export function generateFsSha(packageFiles: PackageFile[]): string {
|
|
10
|
+
const fsMap: Record<string, string> = {}
|
|
11
|
+
|
|
12
|
+
packageFiles
|
|
13
|
+
.filter((file) => file.content_text) // Only include files with content
|
|
14
|
+
.forEach((file) => {
|
|
15
|
+
fsMap[file.file_path] = file.content_text || ""
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const hash = md5(JSON.stringify(fsMap))
|
|
19
|
+
return `md5-${hash}`
|
|
20
|
+
}
|
|
@@ -125,6 +125,9 @@ export default withRouteSpec(routeSpec)(async (req, ctx) => {
|
|
|
125
125
|
// Add to the test database
|
|
126
126
|
ctx.db.addPackageFile(newPackageFile)
|
|
127
127
|
|
|
128
|
+
// Update fs_sha for the package release
|
|
129
|
+
ctx.db.updatePackageReleaseFsSha(packageReleaseId)
|
|
130
|
+
|
|
128
131
|
return ctx.json({
|
|
129
132
|
ok: true,
|
|
130
133
|
package_file: newPackageFile,
|
|
@@ -28,7 +28,7 @@ const routeSpec = {
|
|
|
28
28
|
}, "Cannot specify both package_release_id and package_name_with_version")
|
|
29
29
|
.refine((v) => {
|
|
30
30
|
if (v.content_base64 && v.content_text) return false
|
|
31
|
-
if (!v.content_base64 &&
|
|
31
|
+
if (!v.content_base64 && v.content_text === undefined) return false
|
|
32
32
|
return true
|
|
33
33
|
}, "Either content_base64 or content_text is required"),
|
|
34
34
|
jsonResponse: z.object({
|
|
@@ -136,7 +136,7 @@ export default withRouteSpec(routeSpec)(async (req, ctx) => {
|
|
|
136
136
|
exisitingFile.package_file_id,
|
|
137
137
|
{
|
|
138
138
|
content_text:
|
|
139
|
-
content_text
|
|
139
|
+
content_text ??
|
|
140
140
|
(content_base64
|
|
141
141
|
? Buffer.from(content_base64, "base64").toString()
|
|
142
142
|
: null),
|
|
@@ -146,6 +146,9 @@ export default withRouteSpec(routeSpec)(async (req, ctx) => {
|
|
|
146
146
|
},
|
|
147
147
|
)
|
|
148
148
|
|
|
149
|
+
// Update fs_sha for the package release
|
|
150
|
+
ctx.db.updatePackageReleaseFsSha(packageReleaseId)
|
|
151
|
+
|
|
149
152
|
return ctx.json({
|
|
150
153
|
ok: true,
|
|
151
154
|
package_file,
|
|
@@ -167,7 +170,7 @@ export default withRouteSpec(routeSpec)(async (req, ctx) => {
|
|
|
167
170
|
package_release_id: packageReleaseId,
|
|
168
171
|
file_path,
|
|
169
172
|
content_text:
|
|
170
|
-
content_text
|
|
173
|
+
content_text ??
|
|
171
174
|
(content_base64
|
|
172
175
|
? Buffer.from(content_base64, "base64").toString()
|
|
173
176
|
: null),
|
|
@@ -181,6 +184,9 @@ export default withRouteSpec(routeSpec)(async (req, ctx) => {
|
|
|
181
184
|
// Add to the test database
|
|
182
185
|
ctx.db.addPackageFile(newPackageFile)
|
|
183
186
|
|
|
187
|
+
// Update fs_sha for the package release
|
|
188
|
+
ctx.db.updatePackageReleaseFsSha(packageReleaseId)
|
|
189
|
+
|
|
184
190
|
return ctx.json({
|
|
185
191
|
ok: true,
|
|
186
192
|
package_file: newPackageFile,
|
|
@@ -42,6 +42,7 @@ export default withRouteSpec({
|
|
|
42
42
|
owner_org_id: ctx.auth.personal_org_id,
|
|
43
43
|
owner_github_username: ctx.auth.github_username,
|
|
44
44
|
latest_package_release_id: null,
|
|
45
|
+
latest_package_release_fs_sha: null,
|
|
45
46
|
latest_version: null,
|
|
46
47
|
license: null,
|
|
47
48
|
website: null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/fake-snippets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.73",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"lint": "biome format .",
|
|
27
27
|
"build:vite:analyze": "VITE_BUNDLE_ANALYZE=true vite build",
|
|
28
28
|
"build:fake-api:tsup": "tsup-node ./fake-snippets-api/lib/index.ts --format esm --dts",
|
|
29
|
-
"build:fake-api:bundle": "
|
|
29
|
+
"build:fake-api:bundle": "winterspec2 bundle -o dist/bundle.js",
|
|
30
30
|
"build:fake-api": "bun run build:fake-api:tsup && bun run build:fake-api:bundle && bun run build:fake-api:schema",
|
|
31
31
|
"build:fake-api:schema": "tsup-node ./fake-snippets-api/lib/db/schema.ts --format esm --dts",
|
|
32
32
|
"generate-images": "bun run scripts/generate-image-sizes.ts",
|
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
"@radix-ui/react-toggle-group": "^1.1.0",
|
|
72
72
|
"@radix-ui/react-tooltip": "^1.1.2",
|
|
73
73
|
"@tscircuit/eval": "^0.0.198",
|
|
74
|
-
"@tscircuit/footprinter": "^0.0.
|
|
74
|
+
"@tscircuit/footprinter": "^0.0.169",
|
|
75
75
|
"@tscircuit/layout": "^0.0.29",
|
|
76
76
|
"@tscircuit/math-utils": "^0.0.10",
|
|
77
77
|
"@tscircuit/mm": "^0.0.8",
|
|
78
|
-
"@tscircuit/props": "^0.0.
|
|
78
|
+
"@tscircuit/props": "^0.0.194",
|
|
79
79
|
"@types/file-saver": "^2.0.7",
|
|
80
80
|
"@types/ms": "^0.7.34",
|
|
81
81
|
"@typescript/ata": "^0.9.7",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@valtown/codemirror-ts": "^2.2.0",
|
|
84
84
|
"@vercel/analytics": "^1.4.1",
|
|
85
85
|
"change-case": "^5.4.4",
|
|
86
|
-
"circuit-json": "^0.0.
|
|
86
|
+
"circuit-json": "^0.0.190",
|
|
87
87
|
"circuit-json-to-bom-csv": "^0.0.6",
|
|
88
88
|
"circuit-json-to-gerber": "^0.0.21",
|
|
89
89
|
"circuit-json-to-pnp-csv": "^0.0.6",
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"recharts": "^2.12.7",
|
|
128
128
|
"remark-gfm": "^4.0.1",
|
|
129
129
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
130
|
-
"schematic-symbols": "^0.0.
|
|
130
|
+
"schematic-symbols": "^0.0.140",
|
|
131
131
|
"sitemap": "^8.0.0",
|
|
132
132
|
"sonner": "^1.5.0",
|
|
133
133
|
"states-us": "^1.1.1",
|
|
@@ -145,9 +145,9 @@
|
|
|
145
145
|
"@biomejs/biome": "^1.9.2",
|
|
146
146
|
"@playwright/test": "^1.48.0",
|
|
147
147
|
"@tailwindcss/typography": "^0.5.16",
|
|
148
|
-
"@tscircuit/core": "^0.0.
|
|
148
|
+
"@tscircuit/core": "^0.0.433",
|
|
149
149
|
"@tscircuit/prompt-benchmarks": "^0.0.28",
|
|
150
|
-
"@tscircuit/runframe": "^0.0.
|
|
150
|
+
"@tscircuit/runframe": "^0.0.507",
|
|
151
151
|
"@types/babel__standalone": "^7.1.7",
|
|
152
152
|
"@types/bun": "^1.1.10",
|
|
153
153
|
"@types/country-list": "^2.1.4",
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
"@typescript/vfs": "^1.6.0",
|
|
162
162
|
"@vitejs/plugin-react": "^4.3.1",
|
|
163
163
|
"autoprefixer": "^10.4.20",
|
|
164
|
-
"circuit-to-svg": "^0.0.
|
|
164
|
+
"circuit-to-svg": "^0.0.136",
|
|
165
165
|
"get-port": "^7.1.0",
|
|
166
166
|
"globals": "^15.9.0",
|
|
167
167
|
"he": "^1.2.0",
|
|
@@ -175,11 +175,11 @@
|
|
|
175
175
|
"shiki": "^3.2.1",
|
|
176
176
|
"tailwindcss": "^3.4.13",
|
|
177
177
|
"terser": "^5.27.0",
|
|
178
|
-
"tsup": "^8.
|
|
178
|
+
"tsup": "^8.5.0",
|
|
179
179
|
"typescript": "^5.6.3",
|
|
180
180
|
"vite": "^6.3.4",
|
|
181
181
|
"vite-plugin-image-optimizer": "^1.1.8",
|
|
182
|
-
"winterspec": "^0.0.
|
|
182
|
+
"winterspec": "^0.0.107",
|
|
183
183
|
"zod": "^3.23.8",
|
|
184
184
|
"zustand": "^4.5.5",
|
|
185
185
|
"zustand-hoist": "^2.0.1"
|
package/src/App.tsx
CHANGED
|
@@ -68,6 +68,7 @@ const UserProfilePage = lazyImport(() => import("@/pages/user-profile"))
|
|
|
68
68
|
const DevLoginPage = lazyImport(() => import("@/pages/dev-login"))
|
|
69
69
|
const BetaPage = lazyImport(() => import("@/pages/beta"))
|
|
70
70
|
const ViewPackagePage = lazyImport(() => import("@/pages/view-package"))
|
|
71
|
+
const PackageBuildsPage = lazyImport(() => import("@/pages/package-builds"))
|
|
71
72
|
const TrendingPage = lazyImport(() => import("@/pages/trending"))
|
|
72
73
|
const PackageEditorPage = lazyImport(async () => {
|
|
73
74
|
const [editorModule] = await Promise.all([
|
|
@@ -124,6 +125,10 @@ function App() {
|
|
|
124
125
|
<Route path="/dev-login" component={DevLoginPage} />
|
|
125
126
|
<Route path="/:username" component={UserProfilePage} />
|
|
126
127
|
<Route path="/:author/:packageName" component={ViewPackagePage} />
|
|
128
|
+
<Route
|
|
129
|
+
path="/:author/:packageName/builds"
|
|
130
|
+
component={PackageBuildsPage}
|
|
131
|
+
/>
|
|
127
132
|
<Route component={lazyImport(() => import("@/pages/404"))} />
|
|
128
133
|
</Switch>
|
|
129
134
|
</Suspense>
|