@supernova-studio/model 0.47.28 → 0.47.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supernova-studio/model",
3
- "version": "0.47.28",
3
+ "version": "0.47.29",
4
4
  "description": "Supernova Data Models",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,8 +22,8 @@ export const ExporterDestinationGithub = z.object({
22
22
  relativePath: nullishToOptional(z.string()),
23
23
 
24
24
  // Legacy deprecated fields. Use `credentialId` instead
25
- connectionId: z.string().optional(),
26
- userId: z.number().optional(),
25
+ connectionId: nullishToOptional(z.string()),
26
+ userId: nullishToOptional(z.number()),
27
27
  });
28
28
 
29
29
  export const ExporterDestinationAzure = z.object({
@@ -42,8 +42,8 @@ export const ExporterDestinationAzure = z.object({
42
42
  url: nullishToOptional(z.string()),
43
43
 
44
44
  // Legacy deprecated fields. Use `credentialId` instead
45
- connectionId: z.string().optional(),
46
- userId: z.number().optional(),
45
+ connectionId: nullishToOptional(z.string()),
46
+ userId: nullishToOptional(z.number()),
47
47
  });
48
48
 
49
49
  export const ExporterDestinationGitlab = z.object({
@@ -60,8 +60,8 @@ export const ExporterDestinationGitlab = z.object({
60
60
  url: nullishToOptional(z.string()),
61
61
 
62
62
  // Legacy deprecated fields. Use `credentialId` instead
63
- connectionId: z.string().optional(),
64
- userId: z.number().optional(),
63
+ connectionId: nullishToOptional(z.string()),
64
+ userId: nullishToOptional(z.number()),
65
65
  });
66
66
 
67
67
  export const ExporterDestinationBitbucket = z.object({
@@ -77,8 +77,8 @@ export const ExporterDestinationBitbucket = z.object({
77
77
  relativePath: nullishToOptional(z.string()),
78
78
 
79
79
  // Legacy deprecated fields. Use `credentialId` instead
80
- connectionId: z.string().optional(),
81
- userId: z.number().optional(),
80
+ connectionId: nullishToOptional(z.string()),
81
+ userId: nullishToOptional(z.number()),
82
82
  });
83
83
 
84
84
  export const ExportDestinationsMap = z.object({
@@ -57,6 +57,7 @@ export const ExportJobResult = z.object({
57
57
  gitlab: nullishToOptional(ExportJobPullRequestDestinationResult),
58
58
  bitbucket: nullishToOptional(ExportJobPullRequestDestinationResult),
59
59
  sndocs: nullishToOptional(ExportJobDocsDestinationResult),
60
+ logs: nullishToOptional(ExportJobLogEntry.array()),
60
61
  });
61
62
 
62
63
  export type ExportJobLogEntry = z.infer<typeof ExportJobLogEntry>;
@@ -71,8 +72,8 @@ export type ExportJobResult = z.infer<typeof ExportJobResult>;
71
72
 
72
73
  export const ExportJob = z.object({
73
74
  id: z.string(),
74
- createdAt: z.date(),
75
- finishedAt: z.date().optional(),
75
+ createdAt: z.coerce.date(),
76
+ finishedAt: z.coerce.date().optional(),
76
77
  designSystemId: z.string(),
77
78
  designSystemVersionId: z.string(),
78
79
  workspaceId: z.string(),
@@ -12,6 +12,7 @@ export const ExportJobContext = z.object({
12
12
  accessToken: z.string(),
13
13
 
14
14
  designSystemId: z.string(),
15
+ exporterId: z.string(),
15
16
  versionId: z.string(),
16
17
  brandId: z.string().optional(),
17
18
  themeId: z.string().optional(),
@@ -14,26 +14,36 @@ export const GitOrganization = z.object({
14
14
  id: z.string(),
15
15
  name: z.string(),
16
16
  url: z.string(),
17
+ slug: z.string(),
17
18
  });
18
- export type GitOrganization = z.infer<typeof GitOrganization>;
19
19
 
20
20
  export const GitProject = z.object({
21
21
  id: z.string(),
22
22
  name: z.string(),
23
23
  url: z.string(),
24
+ slug: z.string(),
24
25
  });
25
- export type GitProject = z.infer<typeof GitProject>;
26
26
 
27
27
  export const GitRepository = z.object({
28
28
  id: z.string(),
29
29
  name: z.string(),
30
30
  url: z.string(),
31
- defaultBranch: z.string(),
31
+ slug: z.string(),
32
+
33
+ /**
34
+ * Can be undefined when:
35
+ * - there are no branches in the repository yet
36
+ * - Git provider doesn't expose this information on a repository via their API
37
+ */
38
+ defaultBranch: z.string().optional(),
32
39
  });
33
- export type GitRepository = z.infer<typeof GitRepository>;
34
40
 
35
41
  export const GitBranch = z.object({
36
42
  name: z.string(),
37
43
  lastCommitId: z.string(),
38
44
  });
45
+
46
+ export type GitOrganization = z.infer<typeof GitOrganization>;
47
+ export type GitProject = z.infer<typeof GitProject>;
48
+ export type GitRepository = z.infer<typeof GitRepository>;
39
49
  export type GitBranch = z.infer<typeof GitBranch>;
@@ -15,6 +15,9 @@ export type IntegrationDesignSystem = z.infer<typeof IntegrationDesignSystem>;
15
15
  export const IntegrationCredentialsType = z.enum(["OAuth2", "PAT", "GithubApp"]);
16
16
  export type IntegrationCredentialsType = z.infer<typeof IntegrationCredentialsType>;
17
17
 
18
+ export const IntegrationCredentialsState = z.enum(["Active", "Inactive"]);
19
+ export type IntegrationCredentialsState = z.infer<typeof IntegrationCredentialsState>;
20
+
18
21
  export const IntegrationCredentialsProfile = z.object({
19
22
  id: nullishToOptional(z.string()),
20
23
  email: nullishToOptional(z.string()),
@@ -22,6 +25,7 @@ export const IntegrationCredentialsProfile = z.object({
22
25
  type: nullishToOptional(z.string()),
23
26
  avatarUrl: nullishToOptional(z.string()),
24
27
  organization: nullishToOptional(z.string()),
28
+ collection: nullishToOptional(z.string()),
25
29
  });
26
30
 
27
31
  export type IntegrationCredentialsProfile = z.infer<typeof IntegrationCredentialsProfile>;
@@ -41,6 +45,8 @@ export const IntegrationCredentials = z.object({
41
45
  appInstallationId: z.string().optional(),
42
46
  profile: IntegrationCredentialsProfile.optional(),
43
47
  customUrl: z.string().optional(),
48
+ state: IntegrationCredentialsState,
49
+
44
50
  user: UserMinified.optional(),
45
51
  });
46
52
 
@@ -76,9 +82,6 @@ export type ExtendedIntegration = Omit<Integration, "type"> & {
76
82
  integrationDesignSystems?: IntegrationDesignSystem[];
77
83
  };
78
84
 
79
- // Custom URL validation
80
- const forbiddenCustomUrldomainList = ["github.com", "gitlab.com", "bitbucket.org", "figma.com", "dev.azure.com"];
81
-
82
85
  export const IntegrationToken = z
83
86
  .object({
84
87
  access_token: z.string(),
@@ -86,16 +89,14 @@ export const IntegrationToken = z
86
89
  expires_in: z.union([z.number().optional(), z.string().optional()]),
87
90
  token_type: z.string().optional(),
88
91
  token_name: z.string().optional(),
89
- token_azure_organization_name: z.string().optional(), // Azure only
92
+ token_azure_organization_name: z.string().optional(), // Azure Cloud PAT only
93
+ token_azure_collection_name: z.string().optional(), // Azure Server PAT only
90
94
  token_bitbucket_username: z.string().optional(), // Bitbucket only
91
95
  custom_url: z
92
96
  .string()
97
+ .url()
93
98
  .optional()
94
- .refine(value => {
95
- if (!value) return true;
96
- if (forbiddenCustomUrldomainList.some(domain => value.includes(domain))) return false;
97
- return true;
98
- }, "Custom URL validation failed"),
99
+ .transform(value => value && formatCustomUrl(value)),
99
100
  })
100
101
  .refine(data => {
101
102
  if (data.custom_url && data.token_azure_organization_name) {
@@ -112,19 +113,25 @@ export const IntegrationToken = z
112
113
  tokenName: data.token_name,
113
114
  tokenBitbucketUsername: data.token_bitbucket_username,
114
115
  tokenAzureOrganizationName: data.token_azure_organization_name,
115
- customUrl: data.custom_url ? formatCustomUrl(data.custom_url) : undefined,
116
+ tokenAzureCollection: data.token_azure_collection_name,
117
+ customUrl: data.custom_url,
116
118
  };
117
-
118
- function formatCustomUrl(url: string): string {
119
- let formattedUrl = url.trim();
120
- if (!formattedUrl.startsWith("http://") && !formattedUrl.startsWith("https://")) {
121
- formattedUrl = "http://" + formattedUrl;
122
- }
123
- if (formattedUrl.endsWith("/")) {
124
- formattedUrl = formattedUrl.slice(0, -1);
125
- }
126
- return formattedUrl;
127
- }
128
119
  });
129
120
 
130
121
  export type IntegrationToken = z.infer<typeof IntegrationToken>;
122
+
123
+ // Custom URL validation
124
+ const forbiddenCustomUrlDomainList = ["github.com", "gitlab.com", "bitbucket.org", "figma.com", "dev.azure.com"];
125
+
126
+ function formatCustomUrl(url: string): string | undefined {
127
+ let formattedUrl = url.trim().toLowerCase();
128
+ if (!formattedUrl.startsWith("http://") && !formattedUrl.startsWith("https://")) {
129
+ formattedUrl = "https://" + formattedUrl;
130
+ }
131
+ if (formattedUrl.endsWith("/")) {
132
+ formattedUrl = formattedUrl.slice(0, -1);
133
+ }
134
+
135
+ // do not store default urls that we incorrectly provided as custom urls
136
+ return forbiddenCustomUrlDomainList.some(domain => formattedUrl.includes(domain)) ? undefined : formattedUrl;
137
+ }
@@ -115,6 +115,10 @@ export async function sleep(ms: number): Promise<void> {
115
115
  return new Promise(resolve => setTimeout(resolve, ms));
116
116
  }
117
117
 
118
+ export function uniqueBy<K, V>(items: V[], prop: (v: V) => K): V[] {
119
+ return Array.from(mapByUnique(items, prop).values());
120
+ }
121
+
118
122
  export type Pagination = {
119
123
  skip?: number;
120
124
  take?: number;
@@ -15,6 +15,7 @@ export type SupernovaExceptionType =
15
15
  | "MissingWorkspacePermission"
16
16
  | "MissingExporterPermission"
17
17
  | "MissingIntegration"
18
+ | "MissingIntegrationAccess"
18
19
  | "NoAccess"
19
20
  | "MissingCredentials"
20
21
  | "ValidationError"
@@ -85,6 +86,10 @@ export class SupernovaException extends Error {
85
86
  return new SupernovaException("MissingIntegration", message);
86
87
  }
87
88
 
89
+ static missingIntegrationAccess(message?: string): SupernovaException {
90
+ return new SupernovaException("MissingIntegrationAccess", message);
91
+ }
92
+
88
93
  static noAccess(message?: string): SupernovaException {
89
94
  return new SupernovaException("NoAccess", message);
90
95
  }