cloudcommerce 0.0.71 → 0.0.74

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 (139) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/CHANGELOG.md +38 -0
  3. package/package.json +9 -9
  4. package/packages/api/package.json +1 -1
  5. package/packages/apps/correios/package.json +1 -1
  6. package/packages/apps/custom-shipping/package.json +1 -1
  7. package/packages/apps/discounts/package.json +1 -1
  8. package/packages/apps/frenet/CHANGELOG.md +1 -0
  9. package/packages/apps/frenet/README.md +1 -0
  10. package/packages/apps/frenet/lib/frenet.d.ts +2 -0
  11. package/packages/apps/frenet/lib/frenet.js +6 -0
  12. package/packages/apps/frenet/lib/frenet.js.map +1 -0
  13. package/packages/apps/frenet/lib/index.d.ts +1 -0
  14. package/packages/apps/{tiny-erp → frenet}/lib/index.js +1 -1
  15. package/packages/apps/{tiny-erp → frenet}/lib/index.js.map +1 -1
  16. package/packages/apps/frenet/lib-mjs/calculate-frenet.mjs +152 -0
  17. package/packages/apps/frenet/package.json +28 -0
  18. package/packages/apps/frenet/src/frenet.ts +7 -0
  19. package/packages/apps/frenet/src/index.ts +1 -0
  20. package/packages/apps/frenet/tsconfig.json +6 -0
  21. package/packages/apps/tiny-erp/package.json +1 -1
  22. package/packages/cli/config/firebase.json +47 -0
  23. package/packages/cli/package.json +1 -1
  24. package/packages/config/lib/config.js +9 -8
  25. package/packages/config/lib/config.js.map +1 -1
  26. package/packages/config/package.json +1 -1
  27. package/packages/config/src/config.ts +11 -10
  28. package/packages/events/package.json +1 -1
  29. package/packages/firebase/lib/config.d.ts +3 -0
  30. package/packages/firebase/lib/config.js +3 -0
  31. package/packages/firebase/lib/config.js.map +1 -1
  32. package/packages/firebase/package.json +1 -1
  33. package/packages/firebase/src/config.ts +3 -0
  34. package/packages/modules/package.json +3 -1
  35. package/packages/modules/schemas/@checkout.cjs +28 -28
  36. package/packages/modules/schemas/apply_discount.cjs +2 -2
  37. package/packages/modules/schemas/calculate_shipping.cjs +4 -4
  38. package/packages/modules/schemas/create_transaction.cjs +30 -30
  39. package/packages/modules/schemas/list_payments.cjs +6 -6
  40. package/packages/modules/src/firebase/ajv.ts +2 -1
  41. package/packages/modules/src/firebase/call-app-module.ts +5 -0
  42. package/packages/modules/src/firebase/handle-module.ts +5 -1
  43. package/packages/modules/src/firebase/serve-modules-api.ts +5 -3
  44. package/packages/passport/lib/firebase/handle-passport.js +96 -92
  45. package/packages/passport/lib/firebase/serve-passport-api.js +35 -34
  46. package/packages/passport/lib/firebase.js +5 -7
  47. package/packages/passport/lib/index.js +2 -1
  48. package/packages/passport/package.json +1 -1
  49. package/packages/ssr/lib/firebase/serve-storefront.js +37 -55
  50. package/packages/ssr/lib/firebase/serve-storefront.js.map +1 -1
  51. package/packages/ssr/lib/firebase.js +2 -4
  52. package/packages/ssr/lib/index.js +1 -2
  53. package/packages/ssr/package.json +1 -1
  54. package/packages/ssr/src/firebase/serve-storefront.ts +13 -36
  55. package/packages/storefront/astro.config.mjs +2 -0
  56. package/packages/storefront/dist/client/LoginModal.d6b935cf.js +1 -0
  57. package/packages/storefront/dist/client/assets/{_...98510c96.css → _...27b7eb4d.css} +1 -1
  58. package/packages/storefront/dist/client/assets/_...b3f65c5c.css +1 -0
  59. package/packages/storefront/dist/client/assets/fallback-index.90217cf0.css +1 -0
  60. package/packages/storefront/dist/client/assets/{404.530428e5.css → fallback.9cd2ed3f.css} +1 -1
  61. package/packages/storefront/dist/client/assets/{index.53a3a3e0.css → index.c5a9ea80.css} +1 -1
  62. package/packages/storefront/dist/client/chunks/index.esm.69f70489.js +1726 -0
  63. package/packages/storefront/dist/client/chunks/index.esm2017.1194d1a1.js +457 -0
  64. package/packages/storefront/dist/client/chunks/runtime-core.esm-bundler.a7337834.js +1 -0
  65. package/packages/storefront/dist/client/client.80b904f3.js +1 -0
  66. package/packages/storefront/dist/client/hoisted.24787260.js +376 -0
  67. package/packages/storefront/dist/server/entry.mjs +672 -144
  68. package/packages/storefront/package.json +13 -11
  69. package/packages/storefront/src/assets/firebaseui.css +648 -0
  70. package/packages/storefront/src/env.d.ts +1 -0
  71. package/packages/storefront/src/{components → lib/components}/Card.astro +0 -0
  72. package/packages/storefront/src/lib/components/LoginModal.vue +89 -0
  73. package/packages/storefront/src/lib/layouts/Layout.astro +84 -0
  74. package/packages/storefront/src/lib/layouts/meta/Head.astro +7 -0
  75. package/packages/storefront/src/lib/layouts/meta/Json.astro +34 -0
  76. package/packages/storefront/src/lib/ssr-context.ts +131 -0
  77. package/packages/storefront/src/lib/views/[...slug].astro +77 -0
  78. package/packages/storefront/src/lib/views/app/index.astro +0 -0
  79. package/packages/storefront/src/{pages/404.astro → lib/views/fallback.astro} +6 -1
  80. package/packages/storefront/src/lib/views/index.astro +87 -0
  81. package/packages/storefront/src/pages/[...slug].astro +12 -76
  82. package/packages/storefront/src/pages/fallback.astro +13 -0
  83. package/packages/storefront/src/pages/index.astro +15 -79
  84. package/packages/storefront/storefront.config.mjs +23 -6
  85. package/packages/storefront/tsconfig.json +4 -1
  86. package/packages/types/package.json +1 -1
  87. package/packages/apps/tiny-erp/lib/event-to-tiny.js +0 -115
  88. package/packages/apps/tiny-erp/lib/event-to-tiny.js.map +0 -1
  89. package/packages/apps/tiny-erp/lib/integration/after-tiny-queue.js +0 -79
  90. package/packages/apps/tiny-erp/lib/integration/after-tiny-queue.js.map +0 -1
  91. package/packages/apps/tiny-erp/lib/integration/export-order-to-tiny.js +0 -84
  92. package/packages/apps/tiny-erp/lib/integration/export-order-to-tiny.js.map +0 -1
  93. package/packages/apps/tiny-erp/lib/integration/export-product-to-tiny.js +0 -58
  94. package/packages/apps/tiny-erp/lib/integration/export-product-to-tiny.js.map +0 -1
  95. package/packages/apps/tiny-erp/lib/integration/helpers/format-tiny-date.js +0 -7
  96. package/packages/apps/tiny-erp/lib/integration/helpers/format-tiny-date.js.map +0 -1
  97. package/packages/apps/tiny-erp/lib/integration/import-order-from-tiny.js +0 -92
  98. package/packages/apps/tiny-erp/lib/integration/import-order-from-tiny.js.map +0 -1
  99. package/packages/apps/tiny-erp/lib/integration/import-product-from-tiny.js +0 -158
  100. package/packages/apps/tiny-erp/lib/integration/import-product-from-tiny.js.map +0 -1
  101. package/packages/apps/tiny-erp/lib/integration/parsers/order-from-tiny.js +0 -46
  102. package/packages/apps/tiny-erp/lib/integration/parsers/order-from-tiny.js.map +0 -1
  103. package/packages/apps/tiny-erp/lib/integration/parsers/order-to-tiny.js +0 -193
  104. package/packages/apps/tiny-erp/lib/integration/parsers/order-to-tiny.js.map +0 -1
  105. package/packages/apps/tiny-erp/lib/integration/parsers/product-from-tiny.js +0 -199
  106. package/packages/apps/tiny-erp/lib/integration/parsers/product-from-tiny.js.map +0 -1
  107. package/packages/apps/tiny-erp/lib/integration/parsers/product-to-tiny.js +0 -129
  108. package/packages/apps/tiny-erp/lib/integration/parsers/product-to-tiny.js.map +0 -1
  109. package/packages/apps/tiny-erp/lib/integration/parsers/status-from-tiny.js +0 -34
  110. package/packages/apps/tiny-erp/lib/integration/parsers/status-from-tiny.js.map +0 -1
  111. package/packages/apps/tiny-erp/lib/integration/parsers/status-to-tiny.js +0 -39
  112. package/packages/apps/tiny-erp/lib/integration/parsers/status-to-tiny.js.map +0 -1
  113. package/packages/apps/tiny-erp/lib/integration/post-tiny-erp.js +0 -47
  114. package/packages/apps/tiny-erp/lib/integration/post-tiny-erp.js.map +0 -1
  115. package/packages/apps/tiny-erp/lib/tiny-erp.js +0 -18
  116. package/packages/apps/tiny-erp/lib/tiny-erp.js.map +0 -1
  117. package/packages/apps/tiny-erp/lib/tiny-webhook.js +0 -92
  118. package/packages/apps/tiny-erp/lib/tiny-webhook.js.map +0 -1
  119. package/packages/modules/lib/firebase/ajv.js +0 -33
  120. package/packages/modules/lib/firebase/ajv.js.map +0 -1
  121. package/packages/modules/lib/firebase/call-app-module.js +0 -130
  122. package/packages/modules/lib/firebase/call-app-module.js.map +0 -1
  123. package/packages/modules/lib/firebase/checkout.js +0 -1
  124. package/packages/modules/lib/firebase/checkout.js.map +0 -1
  125. package/packages/modules/lib/firebase/handle-module.js +0 -165
  126. package/packages/modules/lib/firebase/handle-module.js.map +0 -1
  127. package/packages/modules/lib/firebase/proxy-apps.js +0 -1
  128. package/packages/modules/lib/firebase/proxy-apps.js.map +0 -1
  129. package/packages/modules/lib/firebase/serve-modules-api.js +0 -57
  130. package/packages/modules/lib/firebase/serve-modules-api.js.map +0 -1
  131. package/packages/modules/lib/firebase.js +0 -13
  132. package/packages/modules/lib/firebase.js.map +0 -1
  133. package/packages/modules/lib/index.js +0 -25
  134. package/packages/modules/lib/index.js.map +0 -1
  135. package/packages/storefront/dist/client/assets/404-_...d4aa8aff.css +0 -1
  136. package/packages/storefront/dist/client/assets/404-index.d9230d24.css +0 -1
  137. package/packages/storefront/dist/client/client.6d48c590.js +0 -1
  138. package/packages/storefront/src/layouts/Layout.astro +0 -63
  139. package/packages/storefront/src/types.ts +0 -18
@@ -0,0 +1,89 @@
1
+ <template>
2
+ <div class="counter">
3
+ <button @click="subtract()">-</button>
4
+ <pre>{{ count }}</pre>
5
+ <button @click="add()">+</button>
6
+ </div>
7
+ <div class="counter-message">
8
+ <slot />
9
+ </div>
10
+ <div id="firebaseui-auth-container"></div>
11
+ </template>
12
+
13
+ <script lang="ts">
14
+ import { ref } from 'vue';
15
+ import config from '@cloudcommerce/config';
16
+
17
+ const setupFirebaseUi = async () => {
18
+ const { lang } = config.get();
19
+ import('../../assets/firebaseui.css');
20
+
21
+ await Promise.all([
22
+ import('firebase/compat/auth'),
23
+ new Promise((resolve, reject) => {
24
+ const script = document.createElement('script');
25
+ script.src = `https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth__${lang}.js`;
26
+ script.onload = resolve;
27
+ script.onerror = reject;
28
+ script.async = true;
29
+ document.body.appendChild(script);
30
+ }),
31
+ ]);
32
+ const { firebase, firebaseui }: { firebase: any, firebaseui: any } = window;
33
+ const ui = new firebaseui.auth.AuthUI(firebase.auth());
34
+ console.log(firebase.auth);
35
+ const uiConfig = {
36
+ signInSuccessUrl: '<url-to-redirect-to-on-success>',
37
+ signInOptions: [
38
+ // Leave the lines as is for the providers you want to offer your users.
39
+ // firebase.auth.GoogleAuthProvider.PROVIDER_ID,
40
+ // firebase.auth.FacebookAuthProvider.PROVIDER_ID,
41
+ // firebase.auth.TwitterAuthProvider.PROVIDER_ID,
42
+ // firebase.auth.GithubAuthProvider.PROVIDER_ID,
43
+ firebase.auth.EmailAuthProvider.PROVIDER_ID,
44
+ // firebase.auth.PhoneAuthProvider.PROVIDER_ID,
45
+ // firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID,
46
+ ],
47
+ // tosUrl and privacyPolicyUrl accept either url string or a callback
48
+ // function.
49
+ // Terms of service url/callback.
50
+ tosUrl: '<your-tos-url>',
51
+ // Privacy policy url/callback.
52
+ privacyPolicyUrl: '<your-privacy-policy-url>',
53
+ };
54
+ ui.start('#firebaseui-auth-container', uiConfig);
55
+ };
56
+
57
+ export default {
58
+ setup() {
59
+ if (!import.meta.env.SSR) {
60
+ setupFirebaseUi();
61
+ }
62
+ const count = ref(0);
63
+ const add = () => {
64
+ count.value += 1;
65
+ };
66
+ const subtract = () => {
67
+ count.value -= 1;
68
+ };
69
+ return {
70
+ count,
71
+ add,
72
+ subtract,
73
+ };
74
+ },
75
+ };
76
+ </script>
77
+
78
+ <style>
79
+ .counter {
80
+ display: grid;
81
+ font-size: 2em;
82
+ grid-template-columns: repeat(3, minmax(0, 1fr));
83
+ margin-top: 2em;
84
+ place-items: center;
85
+ }
86
+ .counter-message {
87
+ text-align: center;
88
+ }
89
+ </style>
@@ -0,0 +1,84 @@
1
+ ---
2
+ import { getConfig } from '../ssr-context';
3
+ import MetaHead from './meta/Head.astro';
4
+ import MetaJson from './meta/Json.astro';
5
+ import LoginModal from '../components/LoginModal.vue';
6
+
7
+ export interface Props {
8
+ title: string;
9
+ }
10
+
11
+ const { lang } = getConfig();
12
+ const { title } = Astro.props as Props;
13
+ ---
14
+
15
+ <!DOCTYPE html>
16
+ <html lang={lang.replace('_', '-')}>
17
+ <head>
18
+ <MetaHead />
19
+ <title>{title}</title>
20
+ </head>
21
+ <body>
22
+ <LoginModal client:idle />
23
+ <slot />
24
+ <MetaJson />
25
+ <slot name="firebase-init">
26
+ <script>
27
+ // Import Firebase in compat version for Auth UI
28
+ // https://github.com/firebase/firebaseui-web#starting-the-sign-in-flow
29
+ import firebase from "firebase/compat/app";
30
+ import { getAnalytics } from "firebase/analytics";
31
+ // @ts-ignore
32
+ const firebaseConfig = window.firebaseConfig || {
33
+ apiKey: "AIzaSyCrVzemDgpyp9i6ni7Yc5ZuEVfXYwl-4J0",
34
+ authDomain: "ecom2-002.firebaseapp.com",
35
+ projectId: "ecom2-002",
36
+ storageBucket: "ecom2-002.appspot.com",
37
+ messagingSenderId: "402807248219",
38
+ appId: "1:402807248219:web:cf7d57759751e74776367e",
39
+ measurementId: "G-SC592CE0GB"
40
+ };
41
+ // @ts-ignore
42
+ window.firebase = firebase;
43
+ const app = firebase.initializeApp(firebaseConfig);
44
+ const analytics = getAnalytics(app);
45
+ </script>
46
+ </slot>
47
+ </body>
48
+ </html>
49
+
50
+ <style>
51
+ :root {
52
+ --font-size-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
53
+ --font-size-lg: clamp(1.2rem, 0.7vw + 1.2rem, 1.5rem);
54
+ --font-size-xl: clamp(2.44rem, 2.38vw + 1.85rem, 3.75rem);
55
+
56
+ --color-text: hsl(12, 5%, 4%);
57
+ --color-bg: hsl(10, 21%, 95%);
58
+ --color-border: hsl(17, 24%, 90%);
59
+ }
60
+
61
+ html {
62
+ font-family: system-ui, sans-serif;
63
+ font-size: var(--font-size-base);
64
+ color: var(--color-text);
65
+ background-color: var(--color-bg);
66
+ }
67
+
68
+ body {
69
+ margin: 0;
70
+ }
71
+
72
+ :global(h1) {
73
+ font-size: var(--font-size-xl);
74
+ }
75
+
76
+ :global(h2) {
77
+ font-size: var(--font-size-lg);
78
+ }
79
+
80
+ :global(code) {
81
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
82
+ Bitstream Vera Sans Mono, Courier New, monospace;
83
+ }
84
+ </style>
@@ -0,0 +1,7 @@
1
+ ---
2
+
3
+ ---
4
+
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width">
7
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
@@ -0,0 +1,34 @@
1
+ ---
2
+ import { getConfig } from '../../ssr-context';
3
+
4
+ const {
5
+ storeId,
6
+ lang,
7
+ countryCode,
8
+ currency,
9
+ currencySymbol,
10
+ domain,
11
+ settings,
12
+ } = getConfig();
13
+
14
+ const inlineClientJS = `
15
+ window._settings = ${JSON.stringify({
16
+ ...settings,
17
+ store_id: storeId,
18
+ lang,
19
+ country_code: countryCode,
20
+ currency,
21
+ currency_symbol: currencySymbol,
22
+ })};`;
23
+
24
+ const inlineJSONLd = JSON.stringify({
25
+ '@context': 'http://schema.org',
26
+ '@type': 'Organization',
27
+ name: settings.name,
28
+ url: `https://${domain}/`,
29
+ logo: `https://${domain}${settings.logo}`,
30
+ });
31
+ ---
32
+
33
+ <script is:inline set:html={inlineClientJS} />
34
+ <script type="application/ld+json" set:html={inlineJSONLd} />
@@ -0,0 +1,131 @@
1
+ import type { AstroGlobal } from 'astro';
2
+ import type { BaseConfig } from '@cloudcommerce/config';
3
+ import api, { ApiError, ApiEndpoint } from '@cloudcommerce/api';
4
+ import _getConfig from '../../storefront.config.mjs';
5
+ import settings from '../../content/settings.json';
6
+
7
+ type CmsSettings = typeof settings;
8
+
9
+ type StorefrontConfig = {
10
+ storeId: BaseConfig['storeId'],
11
+ lang: BaseConfig['lang'],
12
+ countryCode: BaseConfig['countryCode'],
13
+ currency: BaseConfig['currency'],
14
+ currencySymbol: BaseConfig['currencySymbol'],
15
+ domain: CmsSettings['domain'],
16
+ primaryColor: CmsSettings['primary_color'],
17
+ secondaryColor: CmsSettings['secondary_color'],
18
+ settings: CmsSettings,
19
+ dirContent: string,
20
+ // eslint-disable-next-line no-unused-vars
21
+ cms: (filename: string) => Record<string, any> | Array<string>,
22
+ };
23
+
24
+ const getConfig: () => StorefrontConfig = _getConfig;
25
+
26
+ if (!globalThis.api_prefetch_endpoints) {
27
+ globalThis.api_prefetch_endpoints = ['categories'];
28
+ }
29
+
30
+ type ApiPrefetchEndpoints = Array<ApiEndpoint>;
31
+
32
+ const setResponseCache = (Astro: AstroGlobal, maxAge: number, sMaxAge?: number) => {
33
+ const headerName = import.meta.env.PROD ? 'Cache-Control' : 'X-Cache-Control';
34
+ let cacheControl = `public, max-age=${maxAge}`;
35
+ if (sMaxAge) {
36
+ cacheControl += `, s-maxage=${sMaxAge}, stale-while-revalidate=86400`;
37
+ }
38
+ Astro.response.headers.set(headerName, cacheControl);
39
+ };
40
+
41
+ const loadPageContext = async (Astro: AstroGlobal, {
42
+ cmsCollection,
43
+ apiPrefetchEndpoints = globalThis.api_prefetch_endpoints,
44
+ }: {
45
+ cmsCollection?: string;
46
+ apiPrefetchEndpoints?: ApiPrefetchEndpoints;
47
+ } = {}) => {
48
+ const urlPath = Astro.url.pathname;
49
+ const { slug } = Astro.params;
50
+ const config = getConfig();
51
+ let cmsContent: Record<string, any> | undefined;
52
+ let apiResource: string | undefined;
53
+ let apiDoc: Record<string, any> | undefined;
54
+ const apiState: { [k: string]: Record<string, any> } = {};
55
+ const apiOptions = {
56
+ fetch,
57
+ isNoAuth: true,
58
+ };
59
+ const apiFetchings = [
60
+ null, // fetch by slug
61
+ ...apiPrefetchEndpoints.map((endpoint) => api.get(endpoint, apiOptions)),
62
+ ];
63
+ if (slug) {
64
+ if (cmsCollection) {
65
+ cmsContent = config.cms(`${cmsCollection}/${slug}`);
66
+ } else {
67
+ apiFetchings[0] = api.get(`slugs/${slug}`, apiOptions);
68
+ }
69
+ }
70
+ try {
71
+ const [slugResponse, ...prefetchResponses] = await Promise.all(apiFetchings);
72
+ if (slugResponse) {
73
+ apiResource = slugResponse.data.resource;
74
+ apiDoc = slugResponse.data.doc;
75
+ apiState[`${apiResource}/${apiDoc._id}`] = apiDoc;
76
+ }
77
+ prefetchResponses.forEach(({ config: { endpoint }, data }) => {
78
+ apiState[endpoint] = data;
79
+ });
80
+ } catch (err: any) {
81
+ const error: ApiError = err;
82
+ const status = error.statusCode || 500;
83
+ if (status === 404) {
84
+ if (urlPath.endsWith('/')) {
85
+ err.redirectUrl = urlPath.slice(0, -1);
86
+ err.astroResponse = Astro.redirect(err.redirectUrl);
87
+ throw err;
88
+ }
89
+ setResponseCache(Astro, 120, 300);
90
+ } else {
91
+ console.error(error);
92
+ setResponseCache(Astro, 30);
93
+ Astro.response.headers.set('X-SSR-Error', error.message);
94
+ }
95
+ Astro.response.status = status;
96
+ err.responseHTML = `<html><head>
97
+ <meta http-equiv="refresh" content="0;
98
+ url=/fallback?status=${status}&url=${encodeURIComponent(urlPath)}"/>
99
+ </head>
100
+ <body></body></html>`;
101
+ throw err;
102
+ }
103
+ if (urlPath === '/fallback') {
104
+ setResponseCache(Astro, 3600, 86400);
105
+ } else {
106
+ setResponseCache(Astro, 120, 600);
107
+ }
108
+ return {
109
+ ...config,
110
+ cmsContent,
111
+ apiResource,
112
+ apiDoc,
113
+ apiState,
114
+ };
115
+ };
116
+
117
+ export default loadPageContext;
118
+
119
+ export {
120
+ getConfig,
121
+ loadPageContext,
122
+ };
123
+
124
+ type PageContext = Awaited<ReturnType<typeof loadPageContext>>;
125
+
126
+ export type {
127
+ StorefrontConfig,
128
+ CmsSettings,
129
+ ApiPrefetchEndpoints,
130
+ PageContext,
131
+ };
@@ -0,0 +1,77 @@
1
+ ---
2
+ import type { PageContext } from '../ssr-context';
3
+ import Layout from '../layouts/Layout.astro';
4
+
5
+ export interface Props {
6
+ pageContext: PageContext;
7
+ }
8
+
9
+ const { pageContext } = Astro.props;
10
+ const { apiResource, apiDoc } = pageContext;
11
+ ---
12
+
13
+ <Layout title={apiDoc.name}>
14
+ <main>
15
+ <h1>Hello <span class="text-gradient">{apiDoc.name}</span></h1>
16
+ <hr>
17
+ <div class="mt-3">
18
+ <mark>{apiDoc._id}</mark> from <i>{apiResource}</i>
19
+ <p>{Math.random()}</p>
20
+ <em>Lorem ipsum dolor sit amet</em>
21
+ </div>
22
+ </main>
23
+ </Layout>
24
+
25
+ <style>
26
+ :root {
27
+ --astro-gradient: linear-gradient(0deg,#4F39FA, #DA62C4);
28
+ }
29
+
30
+ h1 {
31
+ margin: 2rem 0;
32
+ }
33
+
34
+ main {
35
+ margin: auto;
36
+ padding: 1em;
37
+ max-width: 60ch;
38
+ }
39
+
40
+ .text-gradient {
41
+ font-weight: 900;
42
+ background-image: var(--astro-gradient);
43
+ -webkit-background-clip: text;
44
+ -webkit-text-fill-color: transparent;
45
+ background-size: 100% 200%;
46
+ background-position-y: 100%;
47
+ border-radius: 0.4rem;
48
+ animation: pulse 4s ease-in-out infinite;
49
+ }
50
+
51
+ @keyframes pulse {
52
+ 0%, 100% { background-position-y: 0%; }
53
+ 50% { background-position-y: 80%; }
54
+ }
55
+
56
+ .instructions {
57
+ line-height: 1.6;
58
+ margin: 1rem 0;
59
+ background: #4F39FA;
60
+ padding: 1.0rem;
61
+ border-radius: 0.4rem;
62
+ color: var(--color-bg);
63
+ }
64
+
65
+ .instructions code {
66
+ font-size: 0.875em;
67
+ border: 0.1em solid var(--color-border);
68
+ border-radius: 4px;
69
+ padding: 0.15em 0.25em;
70
+ }
71
+ .link-card-grid {
72
+ display: grid;
73
+ grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
74
+ gap: 1rem;
75
+ padding: 0;
76
+ }
77
+ </style>
@@ -1,11 +1,16 @@
1
1
  ---
2
+ import type { PageContext } from '../ssr-context';
2
3
  import Layout from '../layouts/Layout.astro';
3
4
  import Card from '../components/Card.astro';
5
+
6
+ export interface Props {
7
+ pageContext: PageContext;
8
+ }
4
9
  ---
5
10
 
6
11
  <Layout title="Welcome to Astro.">
7
12
  <main>
8
- <h1>404</h1>
13
+ <h1>Error :/</h1>
9
14
  <p class="instructions">
10
15
  Check out the <code>src/pages</code> directory to get started.<br/>
11
16
  <strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
@@ -0,0 +1,87 @@
1
+ ---
2
+ import type { PageContext } from '../ssr-context';
3
+ import api from '@cloudcommerce/api';
4
+ import Layout from '../layouts/Layout.astro';
5
+ import Card from '../components/Card.astro';
6
+
7
+ export interface Props {
8
+ pageContext: PageContext;
9
+ }
10
+
11
+ const products = (await api.get('products')).data.result;
12
+ ---
13
+
14
+ <Layout title="Welcome to Astro.">
15
+ <main>
16
+ <h1>Welcome to <span class="text-gradient">Astro</span></h1>
17
+ <p class="instructions">
18
+ Check out the <code>src/pages</code> directory to get started.<br/>
19
+ <strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
20
+ </p>
21
+ <ul role="list" class="link-card-grid">
22
+ <Card href="https://docs.astro.build/" title="Documentation" body="Learn how Astro works and explore the official API docs." />
23
+ <Card href="https://astro.build/integrations/" title="Integrations" body="Supercharge your project with new frameworks and libraries." />
24
+ <Card href="https://astro.build/themes/" title="Themes" body="Explore a galaxy of community-built starter themes." />
25
+ <Card href="https://astro.build/chat/" title="Chat" body="Come say hi to our amazing Discord community. ❤️" />
26
+ </ul>
27
+ <ul role="list" class="mt-3 fs-20">
28
+ {products.map((product) => <li>
29
+ <a href={`/${product.slug}`}>{product.sku}</a>
30
+ </li>)}
31
+ </ul>
32
+ </main>
33
+ </Layout>
34
+
35
+ <style>
36
+ :root {
37
+ --astro-gradient: linear-gradient(0deg,#4F39FA, #DA62C4);
38
+ }
39
+
40
+ h1 {
41
+ margin: 2rem 0;
42
+ }
43
+
44
+ main {
45
+ margin: auto;
46
+ padding: 1em;
47
+ max-width: 60ch;
48
+ }
49
+
50
+ .text-gradient {
51
+ font-weight: 900;
52
+ background-image: var(--astro-gradient);
53
+ -webkit-background-clip: text;
54
+ -webkit-text-fill-color: transparent;
55
+ background-size: 100% 200%;
56
+ background-position-y: 100%;
57
+ border-radius: 0.4rem;
58
+ animation: pulse 4s ease-in-out infinite;
59
+ }
60
+
61
+ @keyframes pulse {
62
+ 0%, 100% { background-position-y: 0%; }
63
+ 50% { background-position-y: 80%; }
64
+ }
65
+
66
+ .instructions {
67
+ line-height: 1.6;
68
+ margin: 1rem 0;
69
+ background: #4F39FA;
70
+ padding: 1.0rem;
71
+ border-radius: 0.4rem;
72
+ color: var(--color-bg);
73
+ }
74
+
75
+ .instructions code {
76
+ font-size: 0.875em;
77
+ border: 0.1em solid var(--color-border);
78
+ border-radius: 4px;
79
+ padding: 0.15em 0.25em;
80
+ }
81
+ .link-card-grid {
82
+ display: grid;
83
+ grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
84
+ gap: 1rem;
85
+ padding: 0;
86
+ }
87
+ </style>
@@ -1,82 +1,18 @@
1
1
  ---
2
- import api from '@cloudcommerce/api';
3
- import '../../storefront.config.mjs';
4
- import Layout from '../layouts/Layout.astro';
2
+ import ViewWildcard from '../lib/views/[...slug].astro';
3
+ import loadPageContext, { PageContext } from '../lib/ssr-context';
5
4
 
6
- const { slug } = Astro.params as { slug: string };
7
- let resource: string;
8
- let doc: Record<string, any>;
5
+ let pageContext: PageContext;
6
+ let loadError: any;
9
7
  try {
10
- const { data } = await api.get(`slugs/${slug}`, { fetch });
11
- resource = data.resource;
12
- doc = data.doc;
13
- } catch {
14
- return Astro.redirect(`/404?url=${encodeURIComponent(`/${slug}`)}`);
8
+ pageContext = await loadPageContext(Astro);
9
+ } catch (err) {
10
+ if (err.astroResponse) {
11
+ return err.astroResponse;
12
+ }
13
+ loadError = err;
15
14
  }
16
15
  ---
17
16
 
18
- <Layout title={doc.name}>
19
- <main>
20
- <h1>Hello <span class="text-gradient">{doc.name}</span></h1>
21
- <hr>
22
- <div class="mt-3">
23
- <mark>{doc._id}</mark> from <i>{resource}</i>
24
- <p>{Math.random()}</p>
25
- <em>Lorem ipsum dolor sit amet</em>
26
- </div>
27
- </main>
28
- </Layout>
29
-
30
- <style>
31
- :root {
32
- --astro-gradient: linear-gradient(0deg,#4F39FA, #DA62C4);
33
- }
34
-
35
- h1 {
36
- margin: 2rem 0;
37
- }
38
-
39
- main {
40
- margin: auto;
41
- padding: 1em;
42
- max-width: 60ch;
43
- }
44
-
45
- .text-gradient {
46
- font-weight: 900;
47
- background-image: var(--astro-gradient);
48
- -webkit-background-clip: text;
49
- -webkit-text-fill-color: transparent;
50
- background-size: 100% 200%;
51
- background-position-y: 100%;
52
- border-radius: 0.4rem;
53
- animation: pulse 4s ease-in-out infinite;
54
- }
55
-
56
- @keyframes pulse {
57
- 0%, 100% { background-position-y: 0%; }
58
- 50% { background-position-y: 80%; }
59
- }
60
-
61
- .instructions {
62
- line-height: 1.6;
63
- margin: 1rem 0;
64
- background: #4F39FA;
65
- padding: 1.0rem;
66
- border-radius: 0.4rem;
67
- color: var(--color-bg);
68
- }
69
-
70
- .instructions code {
71
- font-size: 0.875em;
72
- border: 0.1em solid var(--color-border);
73
- border-radius: 4px;
74
- padding: 0.15em 0.25em;
75
- }
76
- .link-card-grid {
77
- display: grid;
78
- grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
79
- gap: 1rem;
80
- padding: 0;
81
- }
82
- </style>
17
+ {pageContext && <ViewWildcard pageContext={pageContext} />}
18
+ {loadError && <Fragment set:html={loadError.responseHTML} />}
@@ -0,0 +1,13 @@
1
+ ---
2
+ import ViewFallback from '../lib/views/fallback.astro';
3
+ import loadPageContext, { PageContext } from '../lib/ssr-context';
4
+
5
+ let pageContext: PageContext;
6
+ try {
7
+ pageContext = await loadPageContext(Astro);
8
+ } catch (err) {
9
+ return err.astroResponse;
10
+ }
11
+ ---
12
+
13
+ <ViewFallback pageContext={pageContext} />