@datum-cloud/strapi-revalidate 0.1.0

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 (80) hide show
  1. package/.env.example +5 -0
  2. package/LICENSE +121 -0
  3. package/README.md +227 -0
  4. package/dist/cache/drivers/file.d.ts +37 -0
  5. package/dist/cache/drivers/file.d.ts.map +1 -0
  6. package/dist/cache/drivers/file.js +151 -0
  7. package/dist/cache/drivers/file.js.map +1 -0
  8. package/dist/cache/drivers/memory.d.ts +20 -0
  9. package/dist/cache/drivers/memory.d.ts.map +1 -0
  10. package/dist/cache/drivers/memory.js +76 -0
  11. package/dist/cache/drivers/memory.js.map +1 -0
  12. package/dist/cache/drivers/redis.d.ts +25 -0
  13. package/dist/cache/drivers/redis.d.ts.map +1 -0
  14. package/dist/cache/drivers/redis.js +36 -0
  15. package/dist/cache/drivers/redis.js.map +1 -0
  16. package/dist/cache/index.d.ts +28 -0
  17. package/dist/cache/index.d.ts.map +1 -0
  18. package/dist/cache/index.js +54 -0
  19. package/dist/cache/index.js.map +1 -0
  20. package/dist/cache/manager.d.ts +55 -0
  21. package/dist/cache/manager.d.ts.map +1 -0
  22. package/dist/cache/manager.js +73 -0
  23. package/dist/cache/manager.js.map +1 -0
  24. package/dist/cache/types.d.ts +33 -0
  25. package/dist/cache/types.d.ts.map +1 -0
  26. package/dist/cache/types.js +9 -0
  27. package/dist/cache/types.js.map +1 -0
  28. package/dist/client/graphql.d.ts +46 -0
  29. package/dist/client/graphql.d.ts.map +1 -0
  30. package/dist/client/graphql.js +97 -0
  31. package/dist/client/graphql.js.map +1 -0
  32. package/dist/client/index.d.ts +28 -0
  33. package/dist/client/index.d.ts.map +1 -0
  34. package/dist/client/index.js +38 -0
  35. package/dist/client/index.js.map +1 -0
  36. package/dist/client/rest.d.ts +23 -0
  37. package/dist/client/rest.d.ts.map +1 -0
  38. package/dist/client/rest.js +25 -0
  39. package/dist/client/rest.js.map +1 -0
  40. package/dist/content/articles.d.ts +36 -0
  41. package/dist/content/articles.d.ts.map +1 -0
  42. package/dist/content/articles.js +157 -0
  43. package/dist/content/articles.js.map +1 -0
  44. package/dist/content/authors.d.ts +28 -0
  45. package/dist/content/authors.d.ts.map +1 -0
  46. package/dist/content/authors.js +115 -0
  47. package/dist/content/authors.js.map +1 -0
  48. package/dist/content/index.d.ts +11 -0
  49. package/dist/content/index.d.ts.map +1 -0
  50. package/dist/content/index.js +10 -0
  51. package/dist/content/index.js.map +1 -0
  52. package/dist/index.d.ts +37 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +35 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/types/config.d.ts +108 -0
  57. package/dist/types/config.d.ts.map +1 -0
  58. package/dist/types/config.js +49 -0
  59. package/dist/types/config.js.map +1 -0
  60. package/dist/types/strapi.d.ts +103 -0
  61. package/dist/types/strapi.d.ts.map +1 -0
  62. package/dist/types/strapi.js +11 -0
  63. package/dist/types/strapi.js.map +1 -0
  64. package/dist/webhook/handler.d.ts +38 -0
  65. package/dist/webhook/handler.d.ts.map +1 -0
  66. package/dist/webhook/handler.js +156 -0
  67. package/dist/webhook/handler.js.map +1 -0
  68. package/dist/webhook/index.d.ts +9 -0
  69. package/dist/webhook/index.d.ts.map +1 -0
  70. package/dist/webhook/index.js +7 -0
  71. package/dist/webhook/index.js.map +1 -0
  72. package/dist/webhook/tags.d.ts +22 -0
  73. package/dist/webhook/tags.d.ts.map +1 -0
  74. package/dist/webhook/tags.js +39 -0
  75. package/dist/webhook/tags.js.map +1 -0
  76. package/dist/webhook/types.d.ts +60 -0
  77. package/dist/webhook/types.d.ts.map +1 -0
  78. package/dist/webhook/types.js +6 -0
  79. package/dist/webhook/types.js.map +1 -0
  80. package/package.json +90 -0
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Article fetchers.
3
+ *
4
+ * Refactored from datum.net's `articles.ts`: same GraphQL queries and same
5
+ * primary-then-fallback read pattern, but the client and cache are injected
6
+ * rather than module-level singletons. Datum-specific transforms (block
7
+ * stripping, top-3 cover preservation, reading-time calculation) are
8
+ * intentionally not ported — those belong in application code.
9
+ */
10
+ import type { CacheManager } from '../cache/manager.js';
11
+ import type { StrapiClient } from '../client/index.js';
12
+ import type { StrapiArticle } from '../types/strapi.js';
13
+ /** GraphQL query: every published article, newest first. */
14
+ export declare const ARTICLES_QUERY = "\n query GetArticles {\n articles(pagination: { limit: 100 }, sort: [\"originalPublishedAt:desc\"]) {\n documentId\n title\n slug\n description\n originalPublishedAt\n blocks {\n __typename\n ... on ComponentSharedRichText {\n id\n body\n }\n }\n cover {\n url\n alternativeText\n width\n height\n formats\n }\n author {\n documentId\n slug\n name\n isTeam\n avatar {\n url\n alternativeText\n }\n }\n category {\n name\n slug\n }\n }\n }\n";
15
+ /** GraphQL query: a single article by slug, including SEO and quote blocks. */
16
+ export declare const ARTICLE_BY_SLUG_QUERY = "\n query GetArticleBySlug($slug: String!) {\n articles(filters: { slug: { eq: $slug } }) {\n documentId\n title\n slug\n description\n originalPublishedAt\n blocks {\n __typename\n ... on ComponentSharedQuote {\n body\n title\n }\n ... on ComponentSharedRichText {\n id\n body\n }\n }\n cover {\n url\n alternativeText\n width\n height\n formats\n }\n author {\n documentId\n slug\n name\n isTeam\n avatar {\n url\n alternativeText\n }\n }\n category {\n name\n slug\n }\n seo {\n metaTitle\n metaDescription\n ogTitle\n ogDescription\n shareImage {\n url\n }\n }\n }\n }\n";
17
+ /** Dependencies threaded into every content fetcher. */
18
+ export interface ContentDeps {
19
+ client: StrapiClient;
20
+ cache: CacheManager;
21
+ }
22
+ /**
23
+ * Fetch every article from Strapi. Reads from cache first; on Strapi failure,
24
+ * serves stale data from the persistent fallback cache instead of throwing.
25
+ *
26
+ * Cache key: `strapi-articles`. Tags: `["articles"]`.
27
+ */
28
+ export declare function fetchArticles({ client, cache }: ContentDeps): Promise<StrapiArticle[]>;
29
+ /**
30
+ * Fetch a single article by slug. Cached per slug; falls back to stale
31
+ * data when Strapi is unreachable.
32
+ *
33
+ * Cache key: `strapi-article-<slug>`. Tags: `["articles", "article:<slug>"]`.
34
+ */
35
+ export declare function fetchArticle(slug: string, { client, cache }: ContentDeps): Promise<StrapiArticle | null>;
36
+ //# sourceMappingURL=articles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"articles.d.ts","sourceRoot":"","sources":["../../src/content/articles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAA0B,MAAM,oBAAoB,CAAC;AAOhF,4DAA4D;AAC5D,eAAO,MAAM,cAAc,0pBAsC1B,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,43BAmDjC,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAmB5F;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,WAAW,GAC7B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAqB/B"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Article fetchers.
3
+ *
4
+ * Refactored from datum.net's `articles.ts`: same GraphQL queries and same
5
+ * primary-then-fallback read pattern, but the client and cache are injected
6
+ * rather than module-level singletons. Datum-specific transforms (block
7
+ * stripping, top-3 cover preservation, reading-time calculation) are
8
+ * intentionally not ported — those belong in application code.
9
+ */
10
+ const LIST_CACHE_KEY = 'strapi-articles';
11
+ const DETAIL_CACHE_PREFIX = 'strapi-article-';
12
+ const FALLBACK_LIST_KEY = 'articles';
13
+ const FALLBACK_DETAIL_PREFIX = 'article-';
14
+ /** GraphQL query: every published article, newest first. */
15
+ export const ARTICLES_QUERY = `
16
+ query GetArticles {
17
+ articles(pagination: { limit: 100 }, sort: ["originalPublishedAt:desc"]) {
18
+ documentId
19
+ title
20
+ slug
21
+ description
22
+ originalPublishedAt
23
+ blocks {
24
+ __typename
25
+ ... on ComponentSharedRichText {
26
+ id
27
+ body
28
+ }
29
+ }
30
+ cover {
31
+ url
32
+ alternativeText
33
+ width
34
+ height
35
+ formats
36
+ }
37
+ author {
38
+ documentId
39
+ slug
40
+ name
41
+ isTeam
42
+ avatar {
43
+ url
44
+ alternativeText
45
+ }
46
+ }
47
+ category {
48
+ name
49
+ slug
50
+ }
51
+ }
52
+ }
53
+ `;
54
+ /** GraphQL query: a single article by slug, including SEO and quote blocks. */
55
+ export const ARTICLE_BY_SLUG_QUERY = `
56
+ query GetArticleBySlug($slug: String!) {
57
+ articles(filters: { slug: { eq: $slug } }) {
58
+ documentId
59
+ title
60
+ slug
61
+ description
62
+ originalPublishedAt
63
+ blocks {
64
+ __typename
65
+ ... on ComponentSharedQuote {
66
+ body
67
+ title
68
+ }
69
+ ... on ComponentSharedRichText {
70
+ id
71
+ body
72
+ }
73
+ }
74
+ cover {
75
+ url
76
+ alternativeText
77
+ width
78
+ height
79
+ formats
80
+ }
81
+ author {
82
+ documentId
83
+ slug
84
+ name
85
+ isTeam
86
+ avatar {
87
+ url
88
+ alternativeText
89
+ }
90
+ }
91
+ category {
92
+ name
93
+ slug
94
+ }
95
+ seo {
96
+ metaTitle
97
+ metaDescription
98
+ ogTitle
99
+ ogDescription
100
+ shareImage {
101
+ url
102
+ }
103
+ }
104
+ }
105
+ }
106
+ `;
107
+ /**
108
+ * Fetch every article from Strapi. Reads from cache first; on Strapi failure,
109
+ * serves stale data from the persistent fallback cache instead of throwing.
110
+ *
111
+ * Cache key: `strapi-articles`. Tags: `["articles"]`.
112
+ */
113
+ export async function fetchArticles({ client, cache }) {
114
+ const cached = await cache.get(LIST_CACHE_KEY);
115
+ if (cached)
116
+ return cached;
117
+ const response = await client.query(ARTICLES_QUERY);
118
+ if (!response?.articles) {
119
+ const fallback = await cache.getFallback(FALLBACK_LIST_KEY);
120
+ if (fallback) {
121
+ console.warn(`Strapi unreachable — serving ${fallback.length} articles from fallback`);
122
+ return fallback;
123
+ }
124
+ return [];
125
+ }
126
+ await cache.set(LIST_CACHE_KEY, response.articles, { tags: ['articles'] });
127
+ // Mirror to fallback under the legacy datum.net key so manual recovery is straightforward.
128
+ await cache.set(FALLBACK_LIST_KEY, response.articles, { tags: ['articles'] });
129
+ return response.articles;
130
+ }
131
+ /**
132
+ * Fetch a single article by slug. Cached per slug; falls back to stale
133
+ * data when Strapi is unreachable.
134
+ *
135
+ * Cache key: `strapi-article-<slug>`. Tags: `["articles", "article:<slug>"]`.
136
+ */
137
+ export async function fetchArticle(slug, { client, cache }) {
138
+ const cacheKey = `${DETAIL_CACHE_PREFIX}${slug}`;
139
+ const cached = await cache.get(cacheKey);
140
+ if (cached)
141
+ return cached;
142
+ const response = await client.query(ARTICLE_BY_SLUG_QUERY, { slug });
143
+ if (!response?.articles || response.articles.length === 0) {
144
+ const fallback = await cache.getFallback(`${FALLBACK_DETAIL_PREFIX}${slug}`);
145
+ if (fallback) {
146
+ console.warn(`Strapi unreachable — serving article "${slug}" from fallback`);
147
+ return fallback;
148
+ }
149
+ return null;
150
+ }
151
+ const article = response.articles[0];
152
+ const tags = ['articles', `article:${slug}`];
153
+ await cache.set(cacheKey, article, { tags });
154
+ await cache.set(`${FALLBACK_DETAIL_PREFIX}${slug}`, article, { tags });
155
+ return article;
156
+ }
157
+ //# sourceMappingURL=articles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"articles.js","sourceRoot":"","sources":["../../src/content/articles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,cAAc,GAAG,iBAAiB,CAAC;AACzC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAC9C,MAAM,iBAAiB,GAAG,UAAU,CAAC;AACrC,MAAM,sBAAsB,GAAG,UAAU,CAAC;AAE1C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsC7B,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDpC,CAAC;AAQF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,EAAe;IAChE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAkB,cAAc,CAAC,CAAC;IAChE,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAyB,cAAc,CAAC,CAAC;IAE5E,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,CAAkB,iBAAiB,CAAC,CAAC;QAC7E,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,gCAAgC,QAAQ,CAAC,MAAM,yBAAyB,CAAC,CAAC;YACvF,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC3E,2FAA2F;IAC3F,MAAM,KAAK,CAAC,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9E,OAAO,QAAQ,CAAC,QAAQ,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,EAAE,MAAM,EAAE,KAAK,EAAe;IAE9B,MAAM,QAAQ,GAAG,GAAG,mBAAmB,GAAG,IAAI,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAgB,QAAQ,CAAC,CAAC;IACxD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAyB,qBAAqB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7F,IAAI,CAAC,QAAQ,EAAE,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,CAAgB,GAAG,sBAAsB,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5F,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,yCAAyC,IAAI,iBAAiB,CAAC,CAAC;YAC7E,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,sBAAsB,GAAG,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Author fetchers.
3
+ *
4
+ * Refactored from datum.net's `authors.ts`. Datum-specific concerns (team
5
+ * sorting, cardCategories normalization, color helpers) are intentionally
6
+ * out of scope — this module returns Strapi authors as-is.
7
+ */
8
+ import type { StrapiAuthorFull } from '../types/strapi.js';
9
+ import type { ContentDeps } from './articles.js';
10
+ /** GraphQL query: every author. */
11
+ export declare const AUTHORS_QUERY = "\n query GetAuthors {\n authors(pagination: { limit: 100 }) {\n documentId\n slug\n name\n title\n bio\n isTeam\n team\n location\n timezone\n avatar {\n url\n alternativeText\n }\n social {\n twitter\n linkedin\n github\n discord\n email\n }\n }\n }\n";
12
+ /** GraphQL query: a single author by slug. */
13
+ export declare const AUTHOR_BY_SLUG_QUERY = "\n query GetAuthorBySlug($slug: String!) {\n authors(filters: { slug: { eq: $slug } }) {\n documentId\n slug\n name\n title\n bio\n isTeam\n team\n location\n timezone\n avatar {\n url\n alternativeText\n }\n social {\n twitter\n linkedin\n github\n discord\n email\n }\n }\n }\n";
14
+ /**
15
+ * Fetch every author from Strapi. Caches the list; falls back to stale data
16
+ * on Strapi failure.
17
+ *
18
+ * Cache key: `strapi-authors`. Tags: `["authors"]`.
19
+ */
20
+ export declare function fetchAuthors({ client, cache }: ContentDeps): Promise<StrapiAuthorFull[]>;
21
+ /**
22
+ * Fetch a single author by slug. Cached per slug; falls back to stale data
23
+ * on Strapi failure.
24
+ *
25
+ * Cache key: `strapi-author-<slug>`. Tags: `["authors", "author:<slug>"]`.
26
+ */
27
+ export declare function fetchAuthor(slug: string, { client, cache }: ContentDeps): Promise<StrapiAuthorFull | null>;
28
+ //# sourceMappingURL=authors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authors.d.ts","sourceRoot":"","sources":["../../src/content/authors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAOjD,mCAAmC;AACnC,eAAO,MAAM,aAAa,2XAyBzB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,oBAAoB,sZAyBhC,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkB9F;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,WAAW,GAC7B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAqBlC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Author fetchers.
3
+ *
4
+ * Refactored from datum.net's `authors.ts`. Datum-specific concerns (team
5
+ * sorting, cardCategories normalization, color helpers) are intentionally
6
+ * out of scope — this module returns Strapi authors as-is.
7
+ */
8
+ const LIST_CACHE_KEY = 'strapi-authors';
9
+ const DETAIL_CACHE_PREFIX = 'strapi-author-';
10
+ const FALLBACK_LIST_KEY = 'authors';
11
+ const FALLBACK_DETAIL_PREFIX = 'author-';
12
+ /** GraphQL query: every author. */
13
+ export const AUTHORS_QUERY = `
14
+ query GetAuthors {
15
+ authors(pagination: { limit: 100 }) {
16
+ documentId
17
+ slug
18
+ name
19
+ title
20
+ bio
21
+ isTeam
22
+ team
23
+ location
24
+ timezone
25
+ avatar {
26
+ url
27
+ alternativeText
28
+ }
29
+ social {
30
+ twitter
31
+ linkedin
32
+ github
33
+ discord
34
+ email
35
+ }
36
+ }
37
+ }
38
+ `;
39
+ /** GraphQL query: a single author by slug. */
40
+ export const AUTHOR_BY_SLUG_QUERY = `
41
+ query GetAuthorBySlug($slug: String!) {
42
+ authors(filters: { slug: { eq: $slug } }) {
43
+ documentId
44
+ slug
45
+ name
46
+ title
47
+ bio
48
+ isTeam
49
+ team
50
+ location
51
+ timezone
52
+ avatar {
53
+ url
54
+ alternativeText
55
+ }
56
+ social {
57
+ twitter
58
+ linkedin
59
+ github
60
+ discord
61
+ email
62
+ }
63
+ }
64
+ }
65
+ `;
66
+ /**
67
+ * Fetch every author from Strapi. Caches the list; falls back to stale data
68
+ * on Strapi failure.
69
+ *
70
+ * Cache key: `strapi-authors`. Tags: `["authors"]`.
71
+ */
72
+ export async function fetchAuthors({ client, cache }) {
73
+ const cached = await cache.get(LIST_CACHE_KEY);
74
+ if (cached)
75
+ return cached;
76
+ const response = await client.query(AUTHORS_QUERY);
77
+ if (!response?.authors) {
78
+ const fallback = await cache.getFallback(FALLBACK_LIST_KEY);
79
+ if (fallback) {
80
+ console.warn(`Strapi unreachable — serving ${fallback.length} authors from fallback`);
81
+ return fallback;
82
+ }
83
+ return [];
84
+ }
85
+ await cache.set(LIST_CACHE_KEY, response.authors, { tags: ['authors'] });
86
+ await cache.set(FALLBACK_LIST_KEY, response.authors, { tags: ['authors'] });
87
+ return response.authors;
88
+ }
89
+ /**
90
+ * Fetch a single author by slug. Cached per slug; falls back to stale data
91
+ * on Strapi failure.
92
+ *
93
+ * Cache key: `strapi-author-<slug>`. Tags: `["authors", "author:<slug>"]`.
94
+ */
95
+ export async function fetchAuthor(slug, { client, cache }) {
96
+ const cacheKey = `${DETAIL_CACHE_PREFIX}${slug}`;
97
+ const cached = await cache.get(cacheKey);
98
+ if (cached)
99
+ return cached;
100
+ const response = await client.query(AUTHOR_BY_SLUG_QUERY, { slug });
101
+ if (!response?.authors || response.authors.length === 0) {
102
+ const fallback = await cache.getFallback(`${FALLBACK_DETAIL_PREFIX}${slug}`);
103
+ if (fallback) {
104
+ console.warn(`Strapi unreachable — serving author "${slug}" from fallback`);
105
+ return fallback;
106
+ }
107
+ return null;
108
+ }
109
+ const author = response.authors[0];
110
+ const tags = ['authors', `author:${slug}`];
111
+ await cache.set(cacheKey, author, { tags });
112
+ await cache.set(`${FALLBACK_DETAIL_PREFIX}${slug}`, author, { tags });
113
+ return author;
114
+ }
115
+ //# sourceMappingURL=authors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authors.js","sourceRoot":"","sources":["../../src/content/authors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Public content surface.
3
+ *
4
+ * Re-exports every built-in fetcher and their GraphQL queries. Queries are
5
+ * exported as `const` strings so consumers can extend them with additional
6
+ * fields by composing their own query and passing it to the client directly.
7
+ */
8
+ export type { ContentDeps } from './articles.js';
9
+ export { fetchArticles, fetchArticle, ARTICLES_QUERY, ARTICLE_BY_SLUG_QUERY, } from './articles.js';
10
+ export { fetchAuthors, fetchAuthor, AUTHORS_QUERY, AUTHOR_BY_SLUG_QUERY } from './authors.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EACd,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public content surface.
3
+ *
4
+ * Re-exports every built-in fetcher and their GraphQL queries. Queries are
5
+ * exported as `const` strings so consumers can extend them with additional
6
+ * fields by composing their own query and passing it to the client directly.
7
+ */
8
+ export { fetchArticles, fetchArticle, ARTICLES_QUERY, ARTICLE_BY_SLUG_QUERY, } from './articles.js';
9
+ export { fetchAuthors, fetchAuthor, AUTHORS_QUERY, AUTHOR_BY_SLUG_QUERY } from './authors.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EACd,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Package root — re-exports the most commonly used API surface so most
3
+ * consumers can `import { createStrapiRevalidate } from 'strapi-revalidate'`
4
+ * and never touch the subpath imports.
5
+ */
6
+ import type { CacheManager } from './cache/manager.js';
7
+ import type { StrapiClient } from './client/index.js';
8
+ import type { RevalidateConfig, RevalidateConfigInput } from './types/config.js';
9
+ import type { WebhookHandler } from './webhook/handler.js';
10
+ export * from './cache/index.js';
11
+ export * from './client/index.js';
12
+ export * from './content/index.js';
13
+ export * from './webhook/index.js';
14
+ export * from './types/strapi.js';
15
+ export { revalidateConfigSchema } from './types/config.js';
16
+ export type { RevalidateConfig, RevalidateConfigInput, CacheDriverName, TransportName, } from './types/config.js';
17
+ /** Bundle of objects returned by `createStrapiRevalidate`. */
18
+ export interface StrapiRevalidate {
19
+ config: RevalidateConfig;
20
+ client: StrapiClient;
21
+ cache: CacheManager;
22
+ /** Pre-built webhook handler bound to this `client`/`cache` pair. */
23
+ webhook: WebhookHandler;
24
+ }
25
+ /**
26
+ * One-call factory that validates config, builds the client, cache manager,
27
+ * and webhook handler, and returns them as a single object.
28
+ *
29
+ * @example
30
+ * const { cache, client, webhook } = createStrapiRevalidate({
31
+ * url: process.env.STRAPI_URL!,
32
+ * token: process.env.STRAPI_TOKEN!,
33
+ * webhook: { secret: process.env.STRAPI_WEBHOOK_SECRET },
34
+ * });
35
+ */
36
+ export declare function createStrapiRevalidate(input: RevalidateConfigInput): StrapiRevalidate;
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,qEAAqE;IACrE,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,CAMrF"}
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Package root — re-exports the most commonly used API surface so most
3
+ * consumers can `import { createStrapiRevalidate } from 'strapi-revalidate'`
4
+ * and never touch the subpath imports.
5
+ */
6
+ import { createCache } from './cache/index.js';
7
+ import { createStrapiClient } from './client/index.js';
8
+ import { revalidateConfigSchema } from './types/config.js';
9
+ import { createWebhookHandler } from './webhook/handler.js';
10
+ // Subpath re-exports (mirrors the package.json exports map).
11
+ export * from './cache/index.js';
12
+ export * from './client/index.js';
13
+ export * from './content/index.js';
14
+ export * from './webhook/index.js';
15
+ export * from './types/strapi.js';
16
+ export { revalidateConfigSchema } from './types/config.js';
17
+ /**
18
+ * One-call factory that validates config, builds the client, cache manager,
19
+ * and webhook handler, and returns them as a single object.
20
+ *
21
+ * @example
22
+ * const { cache, client, webhook } = createStrapiRevalidate({
23
+ * url: process.env.STRAPI_URL!,
24
+ * token: process.env.STRAPI_TOKEN!,
25
+ * webhook: { secret: process.env.STRAPI_WEBHOOK_SECRET },
26
+ * });
27
+ */
28
+ export function createStrapiRevalidate(input) {
29
+ const config = revalidateConfigSchema.parse(input);
30
+ const cache = createCache(config);
31
+ const client = createStrapiClient(config);
32
+ const webhook = createWebhookHandler({ config, cache });
33
+ return { config, client, cache, webhook };
34
+ }
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,6DAA6D;AAC7D,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAiB3D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAA4B;IACjE,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,oBAAoB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Runtime configuration schema for strapi-revalidate.
3
+ *
4
+ * Validated with zod so misconfigurations surface at startup rather than
5
+ * at the first cache miss or webhook delivery.
6
+ */
7
+ import { z } from 'zod';
8
+ import type { WebhookEvent } from '../webhook/types.js';
9
+ /** Supported cache driver identifiers. */
10
+ export declare const cacheDriverNameSchema: z.ZodEnum<["file", "memory", "redis"]>;
11
+ export type CacheDriverName = z.infer<typeof cacheDriverNameSchema>;
12
+ /** Supported transport identifiers for the Strapi client. */
13
+ export declare const transportNameSchema: z.ZodEnum<["graphql", "rest"]>;
14
+ export type TransportName = z.infer<typeof transportNameSchema>;
15
+ /**
16
+ * Full runtime configuration schema.
17
+ *
18
+ * Use `revalidateConfigSchema.parse(input)` to validate user input and
19
+ * apply defaults in one step.
20
+ */
21
+ export declare const revalidateConfigSchema: z.ZodObject<{
22
+ url: z.ZodString;
23
+ token: z.ZodString;
24
+ webhook: z.ZodOptional<z.ZodObject<{
25
+ secret: z.ZodOptional<z.ZodString>;
26
+ tagMap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
27
+ onRevalidate: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodType<WebhookEvent, z.ZodTypeDef, WebhookEvent>], z.ZodUnknown>, z.ZodUnion<[z.ZodVoid, z.ZodPromise<z.ZodVoid>]>>>;
28
+ }, "strip", z.ZodTypeAny, {
29
+ secret?: string | undefined;
30
+ tagMap?: Record<string, string[]> | undefined;
31
+ onRevalidate?: ((args_0: WebhookEvent, ...args: unknown[]) => void | Promise<void>) | undefined;
32
+ }, {
33
+ secret?: string | undefined;
34
+ tagMap?: Record<string, string[]> | undefined;
35
+ onRevalidate?: ((args_0: WebhookEvent, ...args: unknown[]) => void | Promise<void>) | undefined;
36
+ }>>;
37
+ cache: z.ZodDefault<z.ZodObject<{
38
+ driver: z.ZodDefault<z.ZodEnum<["file", "memory", "redis"]>>;
39
+ ttl: z.ZodDefault<z.ZodNumber>;
40
+ dir: z.ZodDefault<z.ZodString>;
41
+ fallbackDir: z.ZodDefault<z.ZodString>;
42
+ redisUrl: z.ZodOptional<z.ZodString>;
43
+ keyPrefix: z.ZodOptional<z.ZodString>;
44
+ }, "strip", z.ZodTypeAny, {
45
+ driver: "file" | "memory" | "redis";
46
+ ttl: number;
47
+ dir: string;
48
+ fallbackDir: string;
49
+ redisUrl?: string | undefined;
50
+ keyPrefix?: string | undefined;
51
+ }, {
52
+ driver?: "file" | "memory" | "redis" | undefined;
53
+ ttl?: number | undefined;
54
+ dir?: string | undefined;
55
+ fallbackDir?: string | undefined;
56
+ redisUrl?: string | undefined;
57
+ keyPrefix?: string | undefined;
58
+ }>>;
59
+ transport: z.ZodDefault<z.ZodEnum<["graphql", "rest"]>>;
60
+ timeout: z.ZodDefault<z.ZodNumber>;
61
+ retry: z.ZodDefault<z.ZodNumber>;
62
+ debug: z.ZodDefault<z.ZodBoolean>;
63
+ }, "strip", z.ZodTypeAny, {
64
+ url: string;
65
+ token: string;
66
+ cache: {
67
+ driver: "file" | "memory" | "redis";
68
+ ttl: number;
69
+ dir: string;
70
+ fallbackDir: string;
71
+ redisUrl?: string | undefined;
72
+ keyPrefix?: string | undefined;
73
+ };
74
+ transport: "graphql" | "rest";
75
+ timeout: number;
76
+ retry: number;
77
+ debug: boolean;
78
+ webhook?: {
79
+ secret?: string | undefined;
80
+ tagMap?: Record<string, string[]> | undefined;
81
+ onRevalidate?: ((args_0: WebhookEvent, ...args: unknown[]) => void | Promise<void>) | undefined;
82
+ } | undefined;
83
+ }, {
84
+ url: string;
85
+ token: string;
86
+ webhook?: {
87
+ secret?: string | undefined;
88
+ tagMap?: Record<string, string[]> | undefined;
89
+ onRevalidate?: ((args_0: WebhookEvent, ...args: unknown[]) => void | Promise<void>) | undefined;
90
+ } | undefined;
91
+ cache?: {
92
+ driver?: "file" | "memory" | "redis" | undefined;
93
+ ttl?: number | undefined;
94
+ dir?: string | undefined;
95
+ fallbackDir?: string | undefined;
96
+ redisUrl?: string | undefined;
97
+ keyPrefix?: string | undefined;
98
+ } | undefined;
99
+ transport?: "graphql" | "rest" | undefined;
100
+ timeout?: number | undefined;
101
+ retry?: number | undefined;
102
+ debug?: boolean | undefined;
103
+ }>;
104
+ /** User-supplied configuration (pre-validation). */
105
+ export type RevalidateConfigInput = z.input<typeof revalidateConfigSchema>;
106
+ /** Validated, defaults-applied configuration. */
107
+ export type RevalidateConfig = z.output<typeof revalidateConfigSchema>;
108
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,0CAA0C;AAC1C,eAAO,MAAM,qBAAqB,wCAAsC,CAAC;AACzE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,gCAA8B,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAyBhE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASjC,CAAC;AAEH,oDAAoD;AACpD,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE3E,iDAAiD;AACjD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Runtime configuration schema for strapi-revalidate.
3
+ *
4
+ * Validated with zod so misconfigurations surface at startup rather than
5
+ * at the first cache miss or webhook delivery.
6
+ */
7
+ import { z } from 'zod';
8
+ /** Supported cache driver identifiers. */
9
+ export const cacheDriverNameSchema = z.enum(['file', 'memory', 'redis']);
10
+ /** Supported transport identifiers for the Strapi client. */
11
+ export const transportNameSchema = z.enum(['graphql', 'rest']);
12
+ const cacheConfigSchema = z
13
+ .object({
14
+ driver: cacheDriverNameSchema.default('file'),
15
+ ttl: z.number().int().positive().default(3600),
16
+ dir: z.string().default('.cache/strapi-revalidate'),
17
+ fallbackDir: z.string().default('.cache/strapi-fallback'),
18
+ redisUrl: z.string().url().optional(),
19
+ keyPrefix: z.string().optional(),
20
+ })
21
+ .default({});
22
+ const webhookConfigSchema = z
23
+ .object({
24
+ secret: z.string().optional(),
25
+ tagMap: z.record(z.array(z.string())).optional(),
26
+ onRevalidate: z
27
+ .function()
28
+ .args(z.custom())
29
+ .returns(z.union([z.void(), z.promise(z.void())]))
30
+ .optional(),
31
+ })
32
+ .optional();
33
+ /**
34
+ * Full runtime configuration schema.
35
+ *
36
+ * Use `revalidateConfigSchema.parse(input)` to validate user input and
37
+ * apply defaults in one step.
38
+ */
39
+ export const revalidateConfigSchema = z.object({
40
+ url: z.string().url(),
41
+ token: z.string().min(1),
42
+ webhook: webhookConfigSchema,
43
+ cache: cacheConfigSchema,
44
+ transport: transportNameSchema.default('graphql'),
45
+ timeout: z.number().int().positive().default(3000),
46
+ retry: z.number().int().min(0).default(2),
47
+ debug: z.boolean().default(false),
48
+ });
49
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,0CAA0C;AAC1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAGzE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAG/D,MAAM,iBAAiB,GAAG,CAAC;KACxB,MAAM,CAAC;IACN,MAAM,EAAE,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC;IACnD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC;IACzD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC;KACD,OAAO,CAAC,EAAE,CAAC,CAAC;AAEf,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChD,YAAY,EAAE,CAAC;SACZ,QAAQ,EAAE;SACV,IAAI,CAAC,CAAC,CAAC,MAAM,EAAgB,CAAC;SAC9B,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;SACjD,QAAQ,EAAE;CACd,CAAC;KACD,QAAQ,EAAE,CAAC;AAEd;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,OAAO,EAAE,mBAAmB;IAC5B,KAAK,EAAE,iBAAiB;IACxB,SAAS,EAAE,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC;IACjD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CAClC,CAAC,CAAC"}