@tscircuit/fake-snippets 0.0.113 → 0.0.115

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.
@@ -18,35 +18,44 @@ export default withRouteSpec({
18
18
  description: z.string().optional(),
19
19
  is_private: z.boolean().optional().default(false),
20
20
  is_unlisted: z.boolean().optional().default(false),
21
+ org_id: z.string().optional(),
21
22
  }),
22
23
  jsonResponse: z.object({
23
24
  package: packageSchema.optional(),
24
25
  }),
25
26
  })(async (req, ctx) => {
26
- const { name, description, is_private, is_unlisted } = req.jsonBody
27
-
27
+ const { name, description, is_private, is_unlisted, org_id } = req.jsonBody
28
28
  let owner_segment = name?.split("/")[0]
29
29
  let unscoped_name = name?.split("/")[1]
30
30
 
31
31
  if (name && !unscoped_name) {
32
- throw ctx.error(400, {
32
+ return ctx.error(400, {
33
33
  error_code: "invalid_package_name",
34
34
  message:
35
35
  "Package name must include an author segment (e.g. author/package_name)",
36
36
  })
37
37
  }
38
+ const org = ctx.db.getOrg({ org_id })
39
+ if (Boolean(org_id) && !Boolean(org))
40
+ return ctx.error(404, {
41
+ error_code: "org_not_found",
42
+ message: "Organization not found",
43
+ })
38
44
 
39
45
  if (!unscoped_name) {
40
46
  const state = ctx.db.getState()
41
- const count = state.packages.filter(
42
- (pkg) => pkg.creator_account_id === ctx.auth.account_id,
43
- ).length
47
+
48
+ const count = org_id
49
+ ? state.packages.filter((pkg) => pkg.owner_org_id === org_id).length
50
+ : state.packages.filter(
51
+ (pkg) => pkg.creator_account_id === ctx.auth.account_id,
52
+ ).length
44
53
 
45
54
  unscoped_name = `untitled-package-${count}`
46
55
  }
47
56
 
48
57
  if (!owner_segment) {
49
- owner_segment = ctx.auth.github_username
58
+ owner_segment = org_id ? org!.org_name : ctx.auth.github_username
50
59
  }
51
60
 
52
61
  const final_name = name ?? `${owner_segment}/${unscoped_name}`
@@ -71,7 +80,7 @@ export default withRouteSpec({
71
80
  )
72
81
 
73
82
  if (!memberOrg) {
74
- throw ctx.error(403, {
83
+ return ctx.error(403, {
75
84
  error_code: "forbidden",
76
85
  message:
77
86
  "You must be a member of the organization to create a package under it",
@@ -87,7 +96,7 @@ export default withRouteSpec({
87
96
  .packages.find((pkg) => pkg.name === final_name)
88
97
 
89
98
  if (existingPackage) {
90
- throw ctx.error(400, {
99
+ return ctx.error(400, {
91
100
  error_code: "package_already_exists",
92
101
  message: "A package with this name already exists",
93
102
  })
@@ -10,6 +10,7 @@ export default withRouteSpec({
10
10
  owner_github_username: z.string().optional(),
11
11
  is_writable: z.boolean().optional(),
12
12
  name: z.string().optional(),
13
+ limit: z.number().int().min(1).optional(),
13
14
  }),
14
15
  jsonResponse: z.object({
15
16
  ok: z.boolean(),
@@ -25,8 +26,13 @@ export default withRouteSpec({
25
26
  ),
26
27
  }),
27
28
  })(async (req, ctx) => {
28
- const { creator_account_id, owner_github_username, name, is_writable } =
29
- req.commonParams
29
+ const {
30
+ creator_account_id,
31
+ owner_github_username,
32
+ name,
33
+ is_writable,
34
+ limit,
35
+ } = req.commonParams
30
36
 
31
37
  const auth = "auth" in ctx && ctx.auth ? ctx.auth : null
32
38
 
@@ -64,7 +70,9 @@ export default withRouteSpec({
64
70
  if (name) {
65
71
  packages = packages.filter((p) => p.name === name)
66
72
  }
67
-
73
+ if (limit) {
74
+ packages = packages.slice(0, limit)
75
+ }
68
76
  if (is_writable && auth) {
69
77
  packages = packages.filter(canManagePackage)
70
78
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/fake-snippets",
3
- "version": "0.0.113",
3
+ "version": "0.0.115",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -214,6 +214,7 @@ const CmdKMenu = () => {
214
214
  try {
215
215
  const response = await axios.post(`/packages/list`, {
216
216
  owner_github_username: currentUser,
217
+ limit: 5,
217
218
  })
218
219
  return response.data.packages || []
219
220
  } catch (error) {
@@ -19,6 +19,7 @@ import {
19
19
  import { createUseDialog } from "./create-use-dialog"
20
20
  import { useListUserOrgs } from "@/hooks/use-list-user-orgs"
21
21
  import { useGlobalStore } from "@/hooks/use-global-store"
22
+ import { ICreatePackageProps } from "@/hooks/useFileManagement"
22
23
 
23
24
  export const NewPackageSavePromptDialog = ({
24
25
  open,
@@ -31,27 +32,31 @@ export const NewPackageSavePromptDialog = ({
31
32
  onOpenChange: (open: boolean) => void
32
33
  initialIsPrivate?: boolean
33
34
  initialName?: string
34
- onSave: ({
35
- name,
36
- isPrivate,
37
- orgId,
38
- }: {
39
- name?: string
40
- isPrivate: boolean
41
- orgId: string
42
- }) => void
35
+ onSave: (props: ICreatePackageProps) => void
43
36
  }) => {
44
37
  const [packageName, setPackageName] = useState(initialName)
45
38
  const session = useGlobalStore((s) => s.session)
46
39
  const [isPrivate, setIsPrivate] = useState(initialIsPrivate)
47
40
  const [selectedOrgId, setSelectedOrgId] = useState<string>("")
48
41
  const { data: organizations, isLoading: orgsLoading } = useListUserOrgs()
42
+
43
+ const isOwnerPersonalOrg = useMemo(() => {
44
+ if (!selectedOrgId) return false
45
+ const selectedOrg = organizations?.find((x) => x.org_id === selectedOrgId)
46
+ return (
47
+ selectedOrg?.is_personal_org &&
48
+ selectedOrg?.owner_account_id == session?.account_id
49
+ )
50
+ }, [selectedOrgId, organizations, session?.github_username])
51
+
49
52
  const fullPackageName = useMemo(() => {
53
+ if (!Boolean(packageName)) return
50
54
  if (selectedOrgId) {
51
55
  return `${organizations?.find((x) => x.org_id === selectedOrgId)?.name}/${packageName}`
52
56
  }
53
57
  return `${session?.github_username}/${packageName}`
54
58
  }, [selectedOrgId, packageName, organizations, session?.github_username])
59
+
55
60
  useEffect(() => {
56
61
  if (organizations && organizations.length > 0 && !selectedOrgId) {
57
62
  setSelectedOrgId(
@@ -169,9 +174,13 @@ export const NewPackageSavePromptDialog = ({
169
174
  <Button
170
175
  onClick={() => {
171
176
  onSave({
172
- name: fullPackageName.trim(),
177
+ name: fullPackageName,
173
178
  isPrivate,
174
- orgId: selectedOrgId,
179
+ ...(isOwnerPersonalOrg
180
+ ? {}
181
+ : {
182
+ org_id: selectedOrgId,
183
+ }),
175
184
  })
176
185
  onOpenChange(false)
177
186
  }}
@@ -274,7 +274,7 @@ export const CodeEditorHeader: React.FC<CodeEditorHeaderProps> = ({
274
274
 
275
275
  return (
276
276
  <>
277
- <div className="flex items-center gap-2 px-2 border-b border-gray-200">
277
+ <div className="flex items-center gap-2 px-2 border-b md:py-2 border-gray-200">
278
278
  <button
279
279
  className={`text-gray-400 scale-90 p-0 transition-[width,opacity] duration-300 ease-in-out overflow-hidden ${
280
280
  sidebarOpen
@@ -45,6 +45,12 @@ export interface IRenameFileResult {
45
45
  fileRenamed: boolean
46
46
  }
47
47
 
48
+ export interface ICreatePackageProps {
49
+ isPrivate?: boolean
50
+ name?: string
51
+ org_id?: string
52
+ }
53
+
48
54
  export function useFileManagement({
49
55
  templateCode,
50
56
  currentPackage,
@@ -428,12 +434,8 @@ export function useFileManagement({
428
434
  const savePackage = async ({
429
435
  name,
430
436
  isPrivate,
431
- orgId,
432
- }: {
433
- name?: string
434
- isPrivate: boolean
435
- orgId: string
436
- }) => {
437
+ org_id,
438
+ }: ICreatePackageProps) => {
437
439
  if (!isLoggedIn) {
438
440
  toast({
439
441
  title: "Not Logged In",
@@ -443,9 +445,9 @@ export function useFileManagement({
443
445
  }
444
446
 
445
447
  await createPackageMutation.mutateAsync({
446
- is_private: isPrivate,
447
- org_id: orgId,
448
- ...(name ? { name } : {}),
448
+ is_private: Boolean(isPrivate),
449
+ ...(org_id ? { org_id: org_id } : {}),
450
+ ...(name ? { name: name?.trim() } : {}),
449
451
  })
450
452
  }
451
453