@upstart.gg/sdk 0.0.104 → 0.0.106

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.
Files changed (254) hide show
  1. package/dist/shared/ajv.d.ts +2 -0
  2. package/dist/shared/ajv.d.ts.map +1 -1
  3. package/dist/shared/ajv.js +1 -1
  4. package/dist/shared/attributes.js +1 -1
  5. package/dist/shared/brick-manifest.js +1 -1
  6. package/dist/shared/bricks/manifests/accordion.manifest.js +1 -1
  7. package/dist/shared/bricks/manifests/all-manifests.js +1 -1
  8. package/dist/shared/bricks/manifests/button.manifest.js +1 -1
  9. package/dist/shared/bricks/manifests/card.manifest.js +1 -1
  10. package/dist/shared/bricks/manifests/carousel.manifest.js +1 -1
  11. package/dist/shared/bricks/manifests/container.manifest.js +1 -1
  12. package/dist/shared/bricks/manifests/divider.manifest.js +1 -1
  13. package/dist/shared/bricks/manifests/footer.manifest.d.ts +1 -1
  14. package/dist/shared/bricks/manifests/footer.manifest.d.ts.map +1 -1
  15. package/dist/shared/bricks/manifests/footer.manifest.js +1 -1
  16. package/dist/shared/bricks/manifests/form.manifest.js +1 -1
  17. package/dist/shared/bricks/manifests/hero.manifest.js +1 -1
  18. package/dist/shared/bricks/manifests/icon.manifest.js +1 -1
  19. package/dist/shared/bricks/manifests/image.manifest.js +1 -1
  20. package/dist/shared/bricks/manifests/images-gallery.manifest.js +1 -1
  21. package/dist/shared/bricks/manifests/map.manifest.js +1 -1
  22. package/dist/shared/bricks/manifests/navbar.manifest.js +1 -1
  23. package/dist/shared/bricks/manifests/sidebar.manifest.js +1 -1
  24. package/dist/shared/bricks/manifests/social-links.manifest.js +1 -1
  25. package/dist/shared/bricks/manifests/testimonials.manifest.js +1 -1
  26. package/dist/shared/bricks/manifests/text.manifest.js +1 -1
  27. package/dist/shared/bricks/manifests/timeline.manifest.js +1 -1
  28. package/dist/shared/bricks/manifests/video.manifest.js +1 -1
  29. package/dist/shared/bricks/props/border.d.ts.map +1 -1
  30. package/dist/shared/bricks/props/border.js +1 -1
  31. package/dist/shared/bricks/props/container.js +1 -1
  32. package/dist/shared/bricks/props/effects.js +1 -1
  33. package/dist/shared/bricks.d.ts.map +1 -1
  34. package/dist/shared/bricks.js +1 -1
  35. package/dist/shared/{chunk-TCZBR3ZU.js → chunk-2DI5SIVV.js} +1 -1
  36. package/dist/shared/{chunk-O22VV7YR.js → chunk-33FU4KGU.js} +1 -1
  37. package/dist/shared/{chunk-WCNVFVDK.js → chunk-3ZGRY444.js} +1 -1
  38. package/dist/shared/{chunk-CUCUHPQ7.js → chunk-6OKXZL6R.js} +1 -1
  39. package/dist/shared/chunk-7E67XSKP.js +3 -0
  40. package/dist/shared/{chunk-LJQXN32B.js → chunk-AMGHA7QH.js} +1 -1
  41. package/dist/shared/{chunk-QALNFBY7.js → chunk-DC5DWF7B.js} +1 -1
  42. package/dist/shared/{chunk-I43NIQ2K.js → chunk-DY2YCYZ6.js} +1 -1
  43. package/dist/shared/{chunk-CEXHD4BO.js → chunk-E4UAVLKC.js} +2 -2
  44. package/dist/shared/{chunk-ZFTWLZ3G.js → chunk-EHH677K5.js} +1 -1
  45. package/dist/shared/{chunk-POYVTV5F.js → chunk-FD3KX2U7.js} +1 -1
  46. package/dist/shared/chunk-G3JO5DM5.js +3 -0
  47. package/dist/shared/{chunk-I5S2MPPR.js → chunk-H7OYUKBW.js} +1 -1
  48. package/dist/shared/{chunk-ATVHWZSA.js → chunk-HBM4DPIW.js} +1 -1
  49. package/dist/shared/chunk-HIBTEX2T.js +3 -0
  50. package/dist/shared/{chunk-E2EBTWJI.js → chunk-I3HSLGFA.js} +1 -1
  51. package/dist/shared/{chunk-UISES3HA.js → chunk-IXJX7EQ3.js} +1 -1
  52. package/dist/shared/{chunk-5IEGQ7YT.js → chunk-JAAPJQNK.js} +1 -1
  53. package/dist/shared/{chunk-UK6H3FDX.js → chunk-JDBVMPSI.js} +1 -1
  54. package/dist/shared/{chunk-F6MLW6DO.js → chunk-JH3NRO6M.js} +1 -1
  55. package/dist/shared/{chunk-ZNVRYEO7.js → chunk-L3TKLJKK.js} +1 -1
  56. package/dist/shared/{chunk-TEPFFY32.js → chunk-LOFXGDAK.js} +1 -1
  57. package/dist/shared/chunk-O3FJP65T.js +3 -0
  58. package/dist/shared/{chunk-7L3UOEMR.js → chunk-PX7QSNLO.js} +1 -1
  59. package/dist/shared/{chunk-22KRCQK5.js → chunk-U76JDFWJ.js} +1 -1
  60. package/dist/shared/{chunk-CW5FWW5W.js → chunk-UYZP24VV.js} +1 -1
  61. package/dist/shared/chunk-X42WBJTN.js +3 -0
  62. package/dist/shared/{chunk-OQIFFJ7I.js → chunk-XB3X4P3I.js} +1 -1
  63. package/dist/shared/chunk-XDCGA4WT.js +3 -0
  64. package/dist/shared/chunk-YGHBFXR6.js +3 -0
  65. package/dist/shared/{chunk-WEQRYCPD.js → chunk-ZWYLKIBI.js} +1 -1
  66. package/dist/shared/datasources/external/rss/fetcher.d.ts +1 -1
  67. package/dist/shared/datasources/external/rss/fetcher.d.ts.map +1 -1
  68. package/dist/shared/images.js +1 -1
  69. package/dist/shared/page.js +1 -1
  70. package/dist/shared/responsive.js +1 -1
  71. package/dist/shared/site.js +1 -1
  72. package/dist/shared/sitemap.js +1 -1
  73. package/dist/shared/theme.js +1 -1
  74. package/dist/shared/utils/schema.d.ts +6 -8
  75. package/dist/shared/utils/schema.d.ts.map +1 -1
  76. package/dist/shared/utils/schema.js +1 -1
  77. package/package.json +5 -9
  78. package/dist/shared/chunk-F63ANNAK.js +0 -3
  79. package/dist/shared/chunk-GPKRRX3D.js +0 -3
  80. package/dist/shared/chunk-HQQYIKTE.js +0 -3
  81. package/dist/shared/chunk-JFDOR3UH.js +0 -3
  82. package/dist/shared/chunk-OD2PRCLH.js +0 -3
  83. package/dist/shared/chunk-PK6UAFPW.js +0 -3
  84. package/dist/shared/chunk-VDHLON5R.js +0 -3
  85. package/src/node/cli/api.ts +0 -101
  86. package/src/node/cli/commands/cmd-build.ts +0 -64
  87. package/src/node/cli/commands/login/cmd-login.ts +0 -111
  88. package/src/node/cli/commands/logout/cmd-logout.ts +0 -11
  89. package/src/node/cli/commands/publish/cmd-publish.ts +0 -135
  90. package/src/node/cli/commands/publish/parse-gitignore.ts +0 -278
  91. package/src/node/cli/commands/publish/uploader.ts +0 -333
  92. package/src/node/cli/constants.ts +0 -14
  93. package/src/node/cli/is-logged-in.ts +0 -28
  94. package/src/node/cli/program.ts +0 -77
  95. package/src/node/cli/store.ts +0 -64
  96. package/src/node/cli/tests/api.test.ts +0 -161
  97. package/src/node/cli/types.ts +0 -34
  98. package/src/node/cli/utils.ts +0 -20
  99. package/src/node/shared/config.ts +0 -69
  100. package/src/node/shared/logger.ts +0 -44
  101. package/src/shared/ajv.ts +0 -103
  102. package/src/shared/analytics/init.ts +0 -14
  103. package/src/shared/analytics/track.ts +0 -21
  104. package/src/shared/analytics/types.ts +0 -13
  105. package/src/shared/attributes.ts +0 -211
  106. package/src/shared/brick-manifest.ts +0 -110
  107. package/src/shared/bricks/manifests/accordion.manifest.ts +0 -179
  108. package/src/shared/bricks/manifests/all-manifests.ts +0 -92
  109. package/src/shared/bricks/manifests/button.manifest.ts +0 -145
  110. package/src/shared/bricks/manifests/card.manifest.ts +0 -269
  111. package/src/shared/bricks/manifests/carousel.manifest.ts +0 -106
  112. package/src/shared/bricks/manifests/container.manifest.ts +0 -357
  113. package/src/shared/bricks/manifests/divider.manifest.ts +0 -121
  114. package/src/shared/bricks/manifests/footer.manifest.ts +0 -487
  115. package/src/shared/bricks/manifests/form.manifest.ts +0 -112
  116. package/src/shared/bricks/manifests/hero.manifest.ts +0 -132
  117. package/src/shared/bricks/manifests/icon.manifest.ts +0 -130
  118. package/src/shared/bricks/manifests/image.manifest.ts +0 -203
  119. package/src/shared/bricks/manifests/images-gallery.manifest.ts +0 -227
  120. package/src/shared/bricks/manifests/map.manifest.ts +0 -75
  121. package/src/shared/bricks/manifests/navbar.manifest.ts +0 -344
  122. package/src/shared/bricks/manifests/sidebar.manifest.ts +0 -90
  123. package/src/shared/bricks/manifests/social-links.manifest.ts +0 -370
  124. package/src/shared/bricks/manifests/testimonials.manifest.ts +0 -397
  125. package/src/shared/bricks/manifests/tests/header.manifest.test.ts +0 -10
  126. package/src/shared/bricks/manifests/text.manifest.ts +0 -164
  127. package/src/shared/bricks/manifests/timeline.manifest.ts +0 -456
  128. package/src/shared/bricks/manifests/video.manifest.ts +0 -59
  129. package/src/shared/bricks/props/_style-presets.ts +0 -352
  130. package/src/shared/bricks/props/align.ts +0 -59
  131. package/src/shared/bricks/props/background.ts +0 -118
  132. package/src/shared/bricks/props/boolean.ts +0 -11
  133. package/src/shared/bricks/props/border.ts +0 -84
  134. package/src/shared/bricks/props/color.ts +0 -24
  135. package/src/shared/bricks/props/common.ts +0 -37
  136. package/src/shared/bricks/props/container.ts +0 -356
  137. package/src/shared/bricks/props/css-length.ts +0 -25
  138. package/src/shared/bricks/props/datasource.ts +0 -60
  139. package/src/shared/bricks/props/date.ts +0 -24
  140. package/src/shared/bricks/props/effects.ts +0 -123
  141. package/src/shared/bricks/props/enum.ts +0 -42
  142. package/src/shared/bricks/props/file.ts +0 -12
  143. package/src/shared/bricks/props/geolocation.ts +0 -30
  144. package/src/shared/bricks/props/helpers.ts +0 -101
  145. package/src/shared/bricks/props/image.ts +0 -90
  146. package/src/shared/bricks/props/number.ts +0 -16
  147. package/src/shared/bricks/props/padding.ts +0 -21
  148. package/src/shared/bricks/props/position.ts +0 -27
  149. package/src/shared/bricks/props/preset.ts +0 -136
  150. package/src/shared/bricks/props/string.ts +0 -56
  151. package/src/shared/bricks/props/tests/align.test.ts +0 -37
  152. package/src/shared/bricks/props/tests/background.test.ts +0 -102
  153. package/src/shared/bricks/props/tests/border.test.ts +0 -38
  154. package/src/shared/bricks/props/tests/effects.test.ts +0 -37
  155. package/src/shared/bricks/props/tests/helpers.test.ts +0 -133
  156. package/src/shared/bricks/props/tests/image.test.ts +0 -71
  157. package/src/shared/bricks/props/tests/padding.ts +0 -12
  158. package/src/shared/bricks/props/tests/string.test.ts +0 -79
  159. package/src/shared/bricks/props/text.ts +0 -66
  160. package/src/shared/bricks/props/types.ts +0 -57
  161. package/src/shared/bricks.ts +0 -232
  162. package/src/shared/context.ts +0 -39
  163. package/src/shared/datarecords/external/airtable/handler.ts +0 -21
  164. package/src/shared/datarecords/external/airtable/options.ts +0 -22
  165. package/src/shared/datarecords/external/generic-webhook/handler.ts +0 -10
  166. package/src/shared/datarecords/external/generic-webhook/options.ts +0 -13
  167. package/src/shared/datarecords/external/google/oauth/config.ts +0 -30
  168. package/src/shared/datarecords/external/google/sheets/handler.ts +0 -26
  169. package/src/shared/datarecords/external/google/sheets/options.ts +0 -9
  170. package/src/shared/datarecords/types.ts +0 -120
  171. package/src/shared/datarecords.ts +0 -5
  172. package/src/shared/datasources/README.md +0 -3
  173. package/src/shared/datasources/external/facebook/posts/fetcher.ts +0 -52
  174. package/src/shared/datasources/external/facebook/posts/sample.ts +0 -35
  175. package/src/shared/datasources/external/facebook/posts/schema.ts +0 -33
  176. package/src/shared/datasources/external/facebook/posts/tests/fetcher.test.ts +0 -73
  177. package/src/shared/datasources/external/http-json/fetcher.ts +0 -28
  178. package/src/shared/datasources/external/http-json/options.ts +0 -12
  179. package/src/shared/datasources/external/http-json/schema.ts +0 -6
  180. package/src/shared/datasources/external/http-json/tests/fetcher.test.ts +0 -70
  181. package/src/shared/datasources/external/instagram/feed/fetcher.ts +0 -33
  182. package/src/shared/datasources/external/instagram/feed/sample.ts +0 -22
  183. package/src/shared/datasources/external/instagram/feed/schema.ts +0 -23
  184. package/src/shared/datasources/external/instagram/feed/tests/fetcher.test.ts +0 -64
  185. package/src/shared/datasources/external/mastodon/account/fetcher.ts +0 -24
  186. package/src/shared/datasources/external/mastodon/account/sample.ts +0 -33
  187. package/src/shared/datasources/external/mastodon/account/schema.ts +0 -45
  188. package/src/shared/datasources/external/mastodon/account/tests/fetcher.test.ts +0 -47
  189. package/src/shared/datasources/external/mastodon/options.ts +0 -11
  190. package/src/shared/datasources/external/mastodon/status/fetcher.ts +0 -35
  191. package/src/shared/datasources/external/mastodon/status/sample.array.ts +0 -59
  192. package/src/shared/datasources/external/mastodon/status/sample.single.ts +0 -55
  193. package/src/shared/datasources/external/mastodon/status/schema.ts +0 -130
  194. package/src/shared/datasources/external/mastodon/status/tests/fetcher.test.ts +0 -74
  195. package/src/shared/datasources/external/meta/oauth/config.ts +0 -16
  196. package/src/shared/datasources/external/meta/options.ts +0 -11
  197. package/src/shared/datasources/external/rss/fetcher.ts +0 -29
  198. package/src/shared/datasources/external/rss/options.ts +0 -11
  199. package/src/shared/datasources/external/rss/sample.ts +0 -22
  200. package/src/shared/datasources/external/rss/schema.ts +0 -42
  201. package/src/shared/datasources/external/threads/media/fetcher.ts +0 -53
  202. package/src/shared/datasources/external/threads/media/sample.ts +0 -44
  203. package/src/shared/datasources/external/threads/media/schema.ts +0 -37
  204. package/src/shared/datasources/external/tiktok/oauth/config.ts +0 -17
  205. package/src/shared/datasources/external/tiktok/video/fetcher.ts +0 -39
  206. package/src/shared/datasources/external/tiktok/video/options.ts +0 -12
  207. package/src/shared/datasources/external/tiktok/video/sample.ts +0 -26
  208. package/src/shared/datasources/external/tiktok/video/schema.ts +0 -27
  209. package/src/shared/datasources/external/youtube/list/fetcher.ts +0 -37
  210. package/src/shared/datasources/external/youtube/list/options.ts +0 -15
  211. package/src/shared/datasources/external/youtube/list/sample.ts +0 -33
  212. package/src/shared/datasources/external/youtube/list/schema.ts +0 -38
  213. package/src/shared/datasources/external/youtube/oauth/config.ts +0 -15
  214. package/src/shared/datasources/fetcher.ts +0 -17
  215. package/src/shared/datasources/internal/blog/schema.ts +0 -69
  216. package/src/shared/datasources/internal/changelog/schema.ts +0 -48
  217. package/src/shared/datasources/internal/contact-info/schema.ts +0 -20
  218. package/src/shared/datasources/internal/cv/schema.ts +0 -217
  219. package/src/shared/datasources/internal/faq/schema.ts +0 -27
  220. package/src/shared/datasources/internal/job-board/schema.ts +0 -228
  221. package/src/shared/datasources/internal/links/schema.ts +0 -15
  222. package/src/shared/datasources/internal/recipes/schema.ts +0 -42
  223. package/src/shared/datasources/internal/restaurant/schema.ts +0 -225
  224. package/src/shared/datasources/provider-options.ts +0 -7
  225. package/src/shared/datasources/samples.ts +0 -26
  226. package/src/shared/datasources/schemas.ts +0 -45
  227. package/src/shared/datasources/types.ts +0 -276
  228. package/src/shared/datasources/utils.ts +0 -16
  229. package/src/shared/datasources.ts +0 -42
  230. package/src/shared/env.ts +0 -23
  231. package/src/shared/errors.ts +0 -1
  232. package/src/shared/images.ts +0 -44
  233. package/src/shared/index.ts +0 -3
  234. package/src/shared/layout-constants.ts +0 -25
  235. package/src/shared/manifest.ts +0 -50
  236. package/src/shared/oauth.ts +0 -16
  237. package/src/shared/page.ts +0 -61
  238. package/src/shared/prompt.ts +0 -9
  239. package/src/shared/responsive.ts +0 -5
  240. package/src/shared/site.ts +0 -97
  241. package/src/shared/sitemap.ts +0 -66
  242. package/src/shared/social-icons.ts +0 -307
  243. package/src/shared/tests/attributes.test.ts +0 -37
  244. package/src/shared/theme.ts +0 -245
  245. package/src/shared/themes/README.md +0 -34
  246. package/src/shared/themes/color-system.ts +0 -127
  247. package/src/shared/utils/canvas-data-uri.ts +0 -2
  248. package/src/shared/utils/invariant.ts +0 -25
  249. package/src/shared/utils/json-date.ts +0 -8
  250. package/src/shared/utils/merge.ts +0 -12
  251. package/src/shared/utils/object-hash.ts +0 -7
  252. package/src/shared/utils/schema.ts +0 -35
  253. package/src/shared/utils/try-catch.ts +0 -12
  254. package/src/shared/utils/typed-ref.ts +0 -41
@@ -1,278 +0,0 @@
1
- /*!
2
- * parse-gitignore <https://github.com/jonschlinkert/parse-gitignore>
3
- * Copyright (c) 2015-present, Jon Schlinkert.
4
- * Released under the MIT License.
5
- *
6
- * Converted to typescript by Matthias E. <matthias@upstart.gg>
7
- */
8
-
9
- import * as fs from "node:fs";
10
-
11
- // eslint-disable-next-line no-control-regex
12
- const INVALID_PATH_CHARS_REGEX = /[<>"|?*\n\r\t\f\x00-\x1F]/;
13
- const GLOBSTAR_REGEX = /(?:^|\/)[*]{2}($|\/)/;
14
- const MAX_PATH_LENGTH = 260 - 12;
15
-
16
- interface ParseOptions {
17
- path?: string;
18
- dedupe?: boolean;
19
- unique?: boolean;
20
- ignore?: string[];
21
- unignore?: string[];
22
- format?: boolean;
23
- formatSection?: (section: Section) => string;
24
- }
25
-
26
- interface Section {
27
- name: string;
28
- comment?: string;
29
- patterns: string[];
30
- }
31
-
32
- interface ParsedGitignore {
33
- sections: Section[];
34
- patterns: string[];
35
- path?: string;
36
- input: Buffer;
37
- format: (opts?: ParseOptions) => string;
38
- dedupe: (opts?: ParseOptions) => ParsedGitignore;
39
- globs: (opts?: ParseOptions) => GlobResult[];
40
- }
41
-
42
- interface GlobResult {
43
- type: "ignore" | "unignore";
44
- path: string | null;
45
- patterns: string[];
46
- index: number;
47
- }
48
-
49
- const isObject = (v: unknown): v is Record<string, unknown> =>
50
- v !== null && typeof v === "object" && !Array.isArray(v);
51
-
52
- const isValidPath = (input: unknown): input is string =>
53
- typeof input === "string" && input.length <= MAX_PATH_LENGTH && !INVALID_PATH_CHARS_REGEX.test(input);
54
-
55
- const split = (str: string): string[] => str.split(/\r\n?|\n/);
56
- const isComment = (str: string): boolean => str.startsWith("#");
57
- const isParsed = (input: unknown): input is ParsedGitignore =>
58
- isObject(input) && Array.isArray(input.patterns) && Array.isArray(input.sections);
59
-
60
- const patterns = (input: string): string[] =>
61
- split(input)
62
- .map((l) => l.trim())
63
- .filter((line) => line !== "" && !isComment(line));
64
-
65
- const parse = (input: string | ParsedGitignore, options: ParseOptions = {}): ParsedGitignore => {
66
- let filepath = options.path;
67
-
68
- if (isParsed(input)) return input;
69
- if (isValidPath(input) && fs.existsSync(input)) {
70
- filepath = input;
71
- input = fs.readFileSync(input, "utf8");
72
- }
73
-
74
- const lines = split(input);
75
- const names = new Map<string, Section>();
76
-
77
- let parsed: ParsedGitignore = { sections: [], patterns: [] } as unknown as ParsedGitignore;
78
- let section: Section = { name: "default", patterns: [] };
79
- let prev: Section | null = null;
80
-
81
- for (const line of lines) {
82
- const value = line.trim();
83
-
84
- if (value.startsWith("#")) {
85
- const [, name] = /^#+\s*(.*)\s*$/.exec(value) || [];
86
-
87
- if (prev) {
88
- names.delete(prev.name);
89
- prev.comment = prev.comment ? `${prev.comment}\n${value}` : value;
90
- prev.name = name ? `${prev.name.trim()}\n${name.trim()}` : prev.name.trim();
91
- names.set(prev.name.toLowerCase().trim(), prev);
92
- continue;
93
- }
94
-
95
- section = { name: name?.trim() || "", comment: value, patterns: [] };
96
- names.set(section.name.toLowerCase(), section);
97
- parsed.sections.push(section);
98
- prev = section;
99
- continue;
100
- }
101
-
102
- if (value !== "") {
103
- section.patterns.push(value);
104
- parsed.patterns.push(value);
105
- }
106
-
107
- prev = null;
108
- }
109
-
110
- if (options.dedupe === true || options.unique === true) {
111
- parsed = dedupe(parsed, { ...options, format: false });
112
- }
113
-
114
- parsed.path = filepath;
115
- parsed.input = Buffer.from(input);
116
- parsed.format = (opts?: ParseOptions) => format(parsed, { ...options, ...opts });
117
- parsed.dedupe = (opts?: ParseOptions) => dedupe(parsed, { ...options, ...opts });
118
- parsed.globs = (opts?: ParseOptions) => globs(parsed, { path: filepath, ...options, ...opts });
119
- return parsed;
120
- };
121
-
122
- const parseFile = (filepath: string, options?: ParseOptions): ParsedGitignore =>
123
- parse(fs.readFileSync(filepath, "utf8"), options);
124
-
125
- const dedupe = (input: string | ParsedGitignore, options: ParseOptions): ParsedGitignore => {
126
- const parsed = parse(input, { ...options, dedupe: false });
127
-
128
- const names = new Map<string, Section>();
129
- const res: ParsedGitignore = { sections: [], patterns: [] } as unknown as ParsedGitignore;
130
- let current: Section;
131
-
132
- // first, combine duplicate sections
133
- for (const section of parsed.sections) {
134
- const { name = "", comment, patterns } = section;
135
- const key = name.trim().toLowerCase();
136
-
137
- for (const pattern of patterns) {
138
- if (!res.patterns.includes(pattern)) {
139
- res.patterns.push(pattern);
140
- }
141
- }
142
-
143
- if (name && names.has(key)) {
144
- current = names.get(key)!;
145
- current.patterns = [...current.patterns, ...patterns];
146
- } else {
147
- current = { name, comment, patterns };
148
- res.sections.push(current);
149
- names.set(key, current);
150
- }
151
- }
152
-
153
- // next, de-dupe patterns in each section
154
- for (const section of res.sections) {
155
- section.patterns = [...new Set(section.patterns)];
156
- }
157
-
158
- return res;
159
- };
160
-
161
- const glob = (pattern: string): string => {
162
- // Return if a glob pattern has already been specified for sub-directories
163
- if (GLOBSTAR_REGEX.test(pattern)) {
164
- return pattern;
165
- }
166
-
167
- // If there is a separator at the beginning or middle (or both) of the pattern,
168
- // then the pattern is relative to the directory level of the particular .gitignore
169
- // file itself. Otherwise the pattern may also match at any level below the
170
- // .gitignore level. relative paths only
171
- let relative = false;
172
- if (pattern.startsWith("/")) {
173
- pattern = pattern.slice(1);
174
- relative = true;
175
- } else if (pattern.slice(1, pattern.length - 1).includes("/")) {
176
- relative = true;
177
- }
178
-
179
- // If there is a separator at the end of the pattern then the pattern will only match directories.
180
- pattern += pattern.endsWith("/") ? "**/" : "/**";
181
-
182
- // If not relative, the pattern can match any files and directories.
183
- return relative ? pattern : `**/${pattern}`;
184
- };
185
-
186
- const globs = (input: string | ParsedGitignore, options: ParseOptions = {}): GlobResult[] => {
187
- const parsed = parse(input, options);
188
- const result: GlobResult[] = [];
189
- let index = 0;
190
-
191
- const globPatterns = parsed.patterns
192
- .concat(options.ignore || [])
193
- .concat((options.unignore || []).map((p) => (!p.startsWith("!") ? `!${p}` : p)));
194
-
195
- const push = (prefix: string, pattern: string) => {
196
- const prev = result[result.length - 1];
197
- const type = prefix ? "unignore" : "ignore";
198
-
199
- if (prev && prev.type === type) {
200
- if (!prev.patterns.includes(pattern)) {
201
- prev.patterns.push(pattern);
202
- }
203
- } else {
204
- result.push({ type, path: options.path || null, patterns: [pattern], index });
205
- index++;
206
- }
207
- };
208
-
209
- for (let pattern of globPatterns) {
210
- let prefix = "";
211
-
212
- // An optional prefix "!" which negates the pattern; any matching file excluded by
213
- // a previous pattern will become included again
214
- if (pattern.startsWith("!")) {
215
- pattern = pattern.slice(1);
216
- prefix = "!";
217
- }
218
-
219
- // add the raw pattern to the results
220
- push(prefix, pattern.startsWith("/") ? pattern.slice(1) : pattern);
221
-
222
- // add the glob pattern to the results
223
- push(prefix, glob(pattern));
224
- }
225
-
226
- return result;
227
- };
228
-
229
- /**
230
- * Formats a .gitignore section
231
- */
232
- const formatSection = (section: Section = { name: "", patterns: [] }): string => {
233
- const output = [section.comment || ""];
234
-
235
- if (section.patterns?.length) {
236
- output.push(section.patterns.join("\n"));
237
- output.push("");
238
- }
239
-
240
- return output.join("\n");
241
- };
242
-
243
- /**
244
- * Format a .gitignore file from the given input or object from `.parse()`.
245
- * @param {String | ParsedGitignore} input File path or contents.
246
- * @param {ParseOptions} options
247
- * @return {String} Returns formatted string.
248
- * @api public
249
- */
250
- const format = (input: string | ParsedGitignore, options: ParseOptions = {}): string => {
251
- const parsed = parse(input, options);
252
-
253
- const fn = options.formatSection || formatSection;
254
- const sections = parsed.sections || parsed;
255
- const output: string[] = [];
256
-
257
- for (const section of ([] as Section[]).concat(sections)) {
258
- output.push(fn(section));
259
- }
260
-
261
- return output.join("\n");
262
- };
263
-
264
- export {
265
- parse,
266
- parseFile,
267
- dedupe,
268
- format,
269
- globs,
270
- formatSection,
271
- patterns,
272
- type ParseOptions,
273
- type Section,
274
- type ParsedGitignore,
275
- type GlobResult,
276
- };
277
-
278
- export default parse;
@@ -1,333 +0,0 @@
1
- import path from "node:path";
2
- import fs from "node:fs";
3
- import crypto from "node:crypto";
4
- import fg from "fast-glob";
5
- import { API_BASE_URL, DEFAULT_UPLOAD_MAX_CONCURRENCY } from "../../constants";
6
- import http from "node:http";
7
- import https from "node:https";
8
- import { pipeline } from "node:stream";
9
- import type { GenericApiError } from "../../types";
10
- import { logger } from "~/node/shared/logger";
11
- import chalk from "chalk";
12
- import FormData from "form-data";
13
- import parseGitIgnore from "./parse-gitignore";
14
- import PQueue from "p-queue";
15
- import ora from "ora";
16
- import { customAlphabet } from "nanoid";
17
- import { post } from "../../api";
18
-
19
- interface UploadStats {
20
- fileName: string;
21
- fileSize: number;
22
- uploadDuration: number;
23
- statusCode: number;
24
- serverResponse: string;
25
- }
26
-
27
- class UploadError extends Error implements GenericApiError {
28
- constructor(
29
- public error: string,
30
- public error_description: string,
31
- public filename: string,
32
- ) {
33
- super(`${error}: ${error_description}`);
34
- this.name = "UploadError";
35
- }
36
- }
37
-
38
- interface UploadConfig {
39
- maxDataSize: number;
40
- retryAttempts: number;
41
- retryDelay: number;
42
- }
43
-
44
- const defaultConfig: UploadConfig = {
45
- maxDataSize: 12 * 1024 * 1024, // 12MB
46
- retryAttempts: 2,
47
- retryDelay: 1000,
48
- };
49
-
50
- const agent = new http.Agent({
51
- keepAlive: true,
52
- maxSockets: 10,
53
- keepAliveMsecs: 3000, // Keep connections open for 3 seconds
54
- });
55
-
56
- async function discoverFiles(templateDir: string): Promise<string[]> {
57
- const gitignore = path.join(templateDir, ".gitignore");
58
- const gitignoreExists = fs.existsSync(gitignore);
59
- const gitignored = gitignoreExists ? parseGitIgnore(fs.readFileSync(gitignore, "utf-8")).patterns : [];
60
-
61
- return fg("**/*", {
62
- cwd: templateDir,
63
- onlyFiles: true,
64
- dot: true,
65
- absolute: true,
66
- ignore: [
67
- "node_modules/**",
68
- ".cache/**",
69
- "**/.DS_Store",
70
- ".gitignore",
71
- ".env",
72
- ".env.*",
73
- ".git/**",
74
- "dist/**",
75
- ...gitignored,
76
- ],
77
- });
78
- }
79
-
80
- async function uploadFile(
81
- filePath: string,
82
- relativePath: string,
83
- uploadUrl: string,
84
- templateId: string,
85
- spinner: ReturnType<typeof ora>,
86
- token: string,
87
- config: UploadConfig,
88
- ): Promise<UploadStats> {
89
- const uploadWithRetry = async (attempt: number): Promise<UploadStats> => {
90
- try {
91
- return await performUpload(filePath, relativePath, uploadUrl, templateId, spinner, token, config);
92
- } catch (error) {
93
- if (attempt < config.retryAttempts) {
94
- logger.warn(`Retrying upload for ${relativePath} (attempt ${attempt + 1})`);
95
- await new Promise((resolve) => setTimeout(resolve, config.retryDelay));
96
- return uploadWithRetry(attempt + 1);
97
- }
98
- throw error;
99
- }
100
- };
101
-
102
- return uploadWithRetry(0);
103
- }
104
-
105
- async function performUpload(
106
- filePath: string,
107
- relativePath: string,
108
- uploadUrl: string,
109
- templateId: string,
110
- spinner: ReturnType<typeof ora>,
111
- token: string,
112
- config: UploadConfig,
113
- ): Promise<UploadStats> {
114
- return new Promise<UploadStats>((resolve, reject) => {
115
- const stats = fs.statSync(filePath);
116
- const fileName = path.basename(filePath);
117
- const startTime = Date.now();
118
-
119
- const form = new FormData({
120
- maxDataSize: config.maxDataSize,
121
- });
122
- const fileStream = fs.createReadStream(filePath);
123
- let totalUploaded = 0;
124
-
125
- const updateProgress = (chunk: Buffer | string) => {
126
- totalUploaded += chunk.length;
127
- };
128
-
129
- fileStream.on("data", updateProgress);
130
- form.append("file", fileStream, {
131
- filename: fileName,
132
- knownLength: stats.size,
133
- });
134
-
135
- const options: https.RequestOptions = {
136
- agent,
137
- method: "POST",
138
- headers: {
139
- authorization: `Bearer ${token}`,
140
- "x-upstart-template-file-path": relativePath,
141
- "x-upstart-template-id": templateId,
142
- ...form.getHeaders(),
143
- },
144
- };
145
-
146
- const protocol = uploadUrl.startsWith("https") ? https : http;
147
- const req = protocol.request(uploadUrl, options, (res) => {
148
- let responseBody = "";
149
- res.on("data", (chunk) => {
150
- responseBody += chunk;
151
- });
152
-
153
- res.on("end", () => {
154
- const endTime = Date.now();
155
- const uploadStats: UploadStats = {
156
- fileName,
157
- fileSize: stats.size,
158
- uploadDuration: endTime - startTime,
159
- statusCode: res.statusCode ?? 0,
160
- serverResponse: responseBody,
161
- };
162
-
163
- if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
164
- spinner.text = `Uploaded ${relativePath}`;
165
- resolve(uploadStats);
166
- } else {
167
- let errorObject: UploadError;
168
- if (res.headers["content-type"]?.startsWith("application/json")) {
169
- const parsedError = JSON.parse(responseBody);
170
- errorObject = new UploadError(
171
- parsedError.error || "unknown_error",
172
- parsedError.error_description || "Unknown error occurred",
173
- relativePath,
174
- );
175
- } else {
176
- errorObject = new UploadError(
177
- "unknown_error",
178
- responseBody || "Unknown error occurred",
179
- relativePath,
180
- );
181
- }
182
-
183
- spinner.fail(
184
- `Failed to upload ${relativePath} [${errorObject.error}] ${errorObject.error_description}`,
185
- );
186
-
187
- reject(errorObject);
188
- }
189
- });
190
- });
191
-
192
- req.on("error", (error) => {
193
- reject(new UploadError("request_error", error.message, relativePath));
194
- });
195
-
196
- pipeline(form, req, (err) => {
197
- if (err) {
198
- reject(
199
- new UploadError("pipeline_error", `Pipeline failed for ${fileName}: ${err.message}`, relativePath),
200
- );
201
- }
202
- });
203
- });
204
- }
205
-
206
- function reportUploadStatistics(
207
- templateId: string,
208
- uploadedFiles: UploadStats[],
209
- failedFiles: PromiseRejectedResult[],
210
- ) {
211
- if (failedFiles.length > 0) {
212
- logger.error(chalk.red(`Failed to upload ${failedFiles.length} files:`));
213
- failedFiles.forEach((failure) => {
214
- const error = failure.reason as UploadError;
215
- logger.error(`- ${error.filename}: ${error.error_description} (${error.error})`);
216
- });
217
- } else {
218
- logger.info(
219
- chalk.green(`Uploaded ${uploadedFiles.length} files successfully for template ${templateId}.\n`),
220
- );
221
- }
222
- }
223
-
224
- export async function uploadTemplate(
225
- templateId: string,
226
- templateDir: string,
227
- token: string,
228
- dryRun = false,
229
- config: Partial<UploadConfig> = {},
230
- ) {
231
- const fullConfig = { ...defaultConfig, ...config };
232
- const queue = new PQueue({ concurrency: DEFAULT_UPLOAD_MAX_CONCURRENCY });
233
- const files = await discoverFiles(templateDir);
234
- const filesCount = files.length;
235
- const signatures: Record<string, string> = {};
236
- // generate a upload id
237
- const uploadId = generateUploadId();
238
- let completedUploads = 0;
239
-
240
- // compute signatures
241
- for (const file of files) {
242
- const relativePath = path.relative(templateDir, file);
243
- const md5 = await sha1sum(file);
244
- signatures[relativePath] = md5;
245
- }
246
-
247
- if (dryRun) {
248
- logger.info("Dry run mode enabled. Skipping upload.\n");
249
- logger.info("The following files would have been uploaded:");
250
- files.forEach((file) => logger.info(`- ${file}`));
251
- process.exit(0);
252
- }
253
-
254
- const spinner = ora(`Uploading ${filesCount} files...`).start();
255
-
256
- // upload files
257
- const uploadPromises = files.map((file) => {
258
- const fullPath = path.resolve(templateDir, file);
259
- const relativePath = path.relative(templateDir, file);
260
- const url = `${API_BASE_URL}/v1/templates/${templateId}/upload/${uploadId}`;
261
- return queue.add(async () => {
262
- const result = await uploadFile(fullPath, relativePath, url, templateId, spinner, token, fullConfig);
263
- completedUploads++;
264
- return result;
265
- });
266
- });
267
-
268
- const results = await Promise.allSettled(uploadPromises);
269
- spinner.stop();
270
-
271
- const uploadedFiles = results.filter(
272
- (result): result is PromiseFulfilledResult<UploadStats> => result.status === "fulfilled",
273
- );
274
-
275
- const failedFiles = results.filter(
276
- (result): result is PromiseRejectedResult => result.status === "rejected",
277
- );
278
-
279
- reportUploadStatistics(
280
- templateId,
281
- uploadedFiles.map((r) => r.value),
282
- failedFiles,
283
- );
284
-
285
- // finalize upload
286
- if (!failedFiles.length && uploadedFiles.length) {
287
- const finalizeUrl = `${API_BASE_URL}/v1/templates/${templateId}/upload/${uploadId}/finalize`;
288
- const finalizePayload = {
289
- signatures,
290
- };
291
-
292
- const finalizeResponse = await post(finalizeUrl, finalizePayload);
293
-
294
- if (finalizeResponse.isError) {
295
- logger.error(
296
- `Failed to finalize upload: ${finalizeResponse.data.error_description} (${finalizeResponse.data.error})`,
297
- );
298
- return {
299
- filesCount,
300
- uploadedFiles: uploadedFiles.map((r) => r.value),
301
- failedFiles: [],
302
- success: false,
303
- };
304
- }
305
- }
306
-
307
- return {
308
- filesCount,
309
- uploadedFiles: uploadedFiles.map((r) => r.value),
310
- failedFiles,
311
- success: failedFiles.length === 0,
312
- };
313
- }
314
-
315
- async function sha1sum(filePath: string): Promise<string> {
316
- const hash = await crypto.subtle.digest("SHA-1", fs.readFileSync(filePath));
317
- // convert arrayBuffer to hex
318
- return Array.from(new Uint8Array(hash))
319
- .map((b) => b.toString(16).padStart(2, "0"))
320
- .join("");
321
- }
322
-
323
- function generateUploadId(): string {
324
- const randomId = customAlphabet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 5);
325
- const now = new Date();
326
- const year = now.getUTCFullYear();
327
- const month = (now.getUTCMonth() + 1).toString().padStart(2, "0");
328
- const day = now.getUTCDate().toString().padStart(2, "0");
329
- const hours = now.getUTCHours().toString().padStart(2, "0");
330
- const minutes = now.getUTCMinutes().toString().padStart(2, "0");
331
- const seconds = now.getUTCSeconds().toString().padStart(2, "0");
332
- return `${year}${month}${day}${hours}${minutes}${seconds}_${randomId()}`;
333
- }
@@ -1,14 +0,0 @@
1
- export const CLI_PROJECT_NAME = "upstart-cli";
2
- export const CLI_LOGIN_POLL_INTERVAL = 5000; // seconds
3
- export const CLI_LOGIN_CLIENT_ID =
4
- process.env.PUBLIC_UPSTART_OAUTH_CLIENT_ID ?? "50000000-0000-0000-0000-000000000001";
5
-
6
- export const API_BASE_URL = process.env.PUBLIC_UPSTART_API_BASE_URL ?? "https://api.upstart.gg";
7
- export const EDITOR_BASE_URL = process.env.PUBLIC_UPSTART_EDITOR_BASE_URL ?? "https://upstart.gg";
8
- export const DEFAULT_UPLOAD_MAX_CONCURRENCY = 10;
9
-
10
- export const OAUTH_ENDPOINT_DEVICE_CODE = "oauth/devicecode";
11
- export const OAUTH_ENDPOINT_TOKEN = "oauth/token";
12
- export const OAUTH_ENDPOINT_USER_INFO = "oauth/userinfo";
13
-
14
- export const API_ENDPOINT_REGISTER_TEMPLATE = "v1/templates";
@@ -1,28 +0,0 @@
1
- import { OAUTH_ENDPOINT_USER_INFO } from "./constants";
2
- import { accessStore } from "./store";
3
-
4
- export async function isLoggedIn(checkRemote = false): Promise<boolean> {
5
- const token = accessStore.get("access_token");
6
- const expiration = accessStore.get("expires_at");
7
-
8
- if (!token) {
9
- return false;
10
- }
11
-
12
- if (expiration && expiration < Date.now()) {
13
- console.log("Seems like your token expired...");
14
- return false;
15
- }
16
-
17
- if (!checkRemote) {
18
- return true;
19
- }
20
-
21
- // Check if token is valid
22
-
23
- // import dynamically "./api" to avoid circular dependency
24
- const { get } = await import("./api");
25
- const { isSuccess } = await get(OAUTH_ENDPOINT_USER_INFO);
26
-
27
- return isSuccess;
28
- }