@reactionary/source 0.0.27

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 (197) hide show
  1. package/.editorconfig +13 -0
  2. package/.github/workflows/pull-request.yml +37 -0
  3. package/.github/workflows/release.yml +49 -0
  4. package/.nvmrc +1 -0
  5. package/.prettierignore +6 -0
  6. package/.prettierrc +3 -0
  7. package/.verdaccio/config.yml +28 -0
  8. package/.vscode/extensions.json +9 -0
  9. package/README.md +39 -0
  10. package/core/README.md +11 -0
  11. package/core/eslint.config.mjs +23 -0
  12. package/core/package.json +8 -0
  13. package/core/project.json +33 -0
  14. package/core/src/cache/caching-strategy.ts +25 -0
  15. package/core/src/cache/redis-cache.ts +41 -0
  16. package/core/src/client/client.ts +39 -0
  17. package/core/src/index.ts +42 -0
  18. package/core/src/providers/analytics.provider.ts +10 -0
  19. package/core/src/providers/base.provider.ts +75 -0
  20. package/core/src/providers/cart.provider.ts +10 -0
  21. package/core/src/providers/identity.provider.ts +10 -0
  22. package/core/src/providers/inventory.provider.ts +11 -0
  23. package/core/src/providers/price.provider.ts +10 -0
  24. package/core/src/providers/product.provider.ts +11 -0
  25. package/core/src/providers/search.provider.ts +12 -0
  26. package/core/src/schemas/capabilities.schema.ts +13 -0
  27. package/core/src/schemas/models/analytics.model.ts +7 -0
  28. package/core/src/schemas/models/base.model.ts +19 -0
  29. package/core/src/schemas/models/cart.model.ts +17 -0
  30. package/core/src/schemas/models/currency.model.ts +187 -0
  31. package/core/src/schemas/models/identifiers.model.ts +45 -0
  32. package/core/src/schemas/models/identity.model.ts +15 -0
  33. package/core/src/schemas/models/inventory.model.ts +8 -0
  34. package/core/src/schemas/models/price.model.ts +17 -0
  35. package/core/src/schemas/models/product.model.ts +28 -0
  36. package/core/src/schemas/models/search.model.ts +35 -0
  37. package/core/src/schemas/mutations/analytics.mutation.ts +22 -0
  38. package/core/src/schemas/mutations/base.mutation.ts +7 -0
  39. package/core/src/schemas/mutations/cart.mutation.ts +30 -0
  40. package/core/src/schemas/mutations/identity.mutation.ts +18 -0
  41. package/core/src/schemas/mutations/inventory.mutation.ts +5 -0
  42. package/core/src/schemas/mutations/price.mutation.ts +5 -0
  43. package/core/src/schemas/mutations/product.mutation.ts +6 -0
  44. package/core/src/schemas/mutations/search.mutation.ts +5 -0
  45. package/core/src/schemas/queries/analytics.query.ts +5 -0
  46. package/core/src/schemas/queries/base.query.ts +7 -0
  47. package/core/src/schemas/queries/cart.query.ts +12 -0
  48. package/core/src/schemas/queries/identity.query.ts +10 -0
  49. package/core/src/schemas/queries/inventory.query.ts +9 -0
  50. package/core/src/schemas/queries/price.query.ts +12 -0
  51. package/core/src/schemas/queries/product.query.ts +18 -0
  52. package/core/src/schemas/queries/search.query.ts +12 -0
  53. package/core/src/schemas/session.schema.ts +9 -0
  54. package/core/tsconfig.json +23 -0
  55. package/core/tsconfig.lib.json +23 -0
  56. package/core/tsconfig.spec.json +28 -0
  57. package/eslint.config.mjs +46 -0
  58. package/examples/angular/e2e/example.spec.ts +9 -0
  59. package/examples/angular/eslint.config.mjs +41 -0
  60. package/examples/angular/playwright.config.ts +38 -0
  61. package/examples/angular/project.json +86 -0
  62. package/examples/angular/public/favicon.ico +0 -0
  63. package/examples/angular/src/app/app.component.html +6 -0
  64. package/examples/angular/src/app/app.component.scss +22 -0
  65. package/examples/angular/src/app/app.component.ts +14 -0
  66. package/examples/angular/src/app/app.config.ts +16 -0
  67. package/examples/angular/src/app/app.routes.ts +25 -0
  68. package/examples/angular/src/app/cart/cart.component.html +4 -0
  69. package/examples/angular/src/app/cart/cart.component.scss +14 -0
  70. package/examples/angular/src/app/cart/cart.component.ts +73 -0
  71. package/examples/angular/src/app/identity/identity.component.html +6 -0
  72. package/examples/angular/src/app/identity/identity.component.scss +18 -0
  73. package/examples/angular/src/app/identity/identity.component.ts +49 -0
  74. package/examples/angular/src/app/product/product.component.html +14 -0
  75. package/examples/angular/src/app/product/product.component.scss +11 -0
  76. package/examples/angular/src/app/product/product.component.ts +42 -0
  77. package/examples/angular/src/app/search/search.component.html +35 -0
  78. package/examples/angular/src/app/search/search.component.scss +129 -0
  79. package/examples/angular/src/app/search/search.component.ts +50 -0
  80. package/examples/angular/src/app/services/product.service.ts +35 -0
  81. package/examples/angular/src/app/services/search.service.ts +48 -0
  82. package/examples/angular/src/app/services/trpc.client.ts +27 -0
  83. package/examples/angular/src/index.html +13 -0
  84. package/examples/angular/src/main.ts +7 -0
  85. package/examples/angular/src/styles.scss +17 -0
  86. package/examples/angular/src/test-setup.ts +6 -0
  87. package/examples/angular/tsconfig.app.json +10 -0
  88. package/examples/angular/tsconfig.editor.json +6 -0
  89. package/examples/angular/tsconfig.json +32 -0
  90. package/examples/node/README.md +11 -0
  91. package/examples/node/eslint.config.mjs +22 -0
  92. package/examples/node/jest.config.ts +10 -0
  93. package/examples/node/package.json +10 -0
  94. package/examples/node/project.json +20 -0
  95. package/examples/node/src/index.ts +2 -0
  96. package/examples/node/src/initialize-algolia.spec.ts +29 -0
  97. package/examples/node/src/initialize-commercetools.spec.ts +31 -0
  98. package/examples/node/src/initialize-extended-providers.spec.ts +38 -0
  99. package/examples/node/src/initialize-mixed-providers.spec.ts +36 -0
  100. package/examples/node/src/providers/custom-algolia-product.provider.ts +18 -0
  101. package/examples/node/src/schemas/custom-product.schema.ts +8 -0
  102. package/examples/node/tsconfig.json +23 -0
  103. package/examples/node/tsconfig.lib.json +10 -0
  104. package/examples/node/tsconfig.spec.json +15 -0
  105. package/examples/trpc-node/eslint.config.mjs +3 -0
  106. package/examples/trpc-node/project.json +61 -0
  107. package/examples/trpc-node/src/assets/.gitkeep +0 -0
  108. package/examples/trpc-node/src/main.ts +55 -0
  109. package/examples/trpc-node/src/router-instance.ts +52 -0
  110. package/examples/trpc-node/tsconfig.app.json +9 -0
  111. package/examples/trpc-node/tsconfig.json +13 -0
  112. package/examples/vue/eslint.config.mjs +24 -0
  113. package/examples/vue/index.html +13 -0
  114. package/examples/vue/project.json +8 -0
  115. package/examples/vue/src/app/App.vue +275 -0
  116. package/examples/vue/src/main.ts +6 -0
  117. package/examples/vue/src/styles.scss +9 -0
  118. package/examples/vue/src/vue-shims.d.ts +5 -0
  119. package/examples/vue/tsconfig.app.json +14 -0
  120. package/examples/vue/tsconfig.json +20 -0
  121. package/examples/vue/vite.config.ts +31 -0
  122. package/jest.config.ts +6 -0
  123. package/jest.preset.js +3 -0
  124. package/migrations.json +11 -0
  125. package/nx.json +130 -0
  126. package/package.json +118 -0
  127. package/project.json +14 -0
  128. package/providers/algolia/README.md +11 -0
  129. package/providers/algolia/eslint.config.mjs +22 -0
  130. package/providers/algolia/jest.config.ts +10 -0
  131. package/providers/algolia/package.json +9 -0
  132. package/providers/algolia/project.json +33 -0
  133. package/providers/algolia/src/core/initialize.ts +20 -0
  134. package/providers/algolia/src/index.ts +7 -0
  135. package/providers/algolia/src/providers/product.provider.ts +25 -0
  136. package/providers/algolia/src/providers/search.provider.ts +125 -0
  137. package/providers/algolia/src/schema/capabilities.schema.ts +10 -0
  138. package/providers/algolia/src/schema/configuration.schema.ts +9 -0
  139. package/providers/algolia/src/schema/search.schema.ts +14 -0
  140. package/providers/algolia/src/test/product.provider.spec.ts +18 -0
  141. package/providers/algolia/src/test/search.provider.spec.ts +82 -0
  142. package/providers/algolia/tsconfig.json +23 -0
  143. package/providers/algolia/tsconfig.lib.json +10 -0
  144. package/providers/algolia/tsconfig.spec.json +15 -0
  145. package/providers/commercetools/README.md +11 -0
  146. package/providers/commercetools/eslint.config.mjs +22 -0
  147. package/providers/commercetools/jest.config.ts +10 -0
  148. package/providers/commercetools/package.json +10 -0
  149. package/providers/commercetools/project.json +33 -0
  150. package/providers/commercetools/src/core/client.ts +152 -0
  151. package/providers/commercetools/src/core/initialize.ts +40 -0
  152. package/providers/commercetools/src/index.ts +12 -0
  153. package/providers/commercetools/src/providers/cart.provider.ts +223 -0
  154. package/providers/commercetools/src/providers/identity.provider.ts +130 -0
  155. package/providers/commercetools/src/providers/inventory.provider.ts +82 -0
  156. package/providers/commercetools/src/providers/price.provider.ts +66 -0
  157. package/providers/commercetools/src/providers/product.provider.ts +90 -0
  158. package/providers/commercetools/src/providers/search.provider.ts +86 -0
  159. package/providers/commercetools/src/schema/capabilities.schema.ts +13 -0
  160. package/providers/commercetools/src/schema/configuration.schema.ts +11 -0
  161. package/providers/commercetools/src/test/product.provider.spec.ts +20 -0
  162. package/providers/commercetools/src/test/search.provider.spec.ts +18 -0
  163. package/providers/commercetools/tsconfig.json +23 -0
  164. package/providers/commercetools/tsconfig.lib.json +10 -0
  165. package/providers/commercetools/tsconfig.spec.json +15 -0
  166. package/providers/fake/README.md +7 -0
  167. package/providers/fake/eslint.config.mjs +22 -0
  168. package/providers/fake/package.json +9 -0
  169. package/providers/fake/project.json +33 -0
  170. package/providers/fake/src/core/initialize.ts +24 -0
  171. package/providers/fake/src/index.ts +8 -0
  172. package/providers/fake/src/providers/identity.provider.ts +91 -0
  173. package/providers/fake/src/providers/product.provider.ts +73 -0
  174. package/providers/fake/src/providers/search.provider.ts +142 -0
  175. package/providers/fake/src/schema/capabilities.schema.ts +10 -0
  176. package/providers/fake/src/schema/configuration.schema.ts +15 -0
  177. package/providers/fake/src/utilities/jitter.ts +14 -0
  178. package/providers/fake/tsconfig.json +20 -0
  179. package/providers/fake/tsconfig.lib.json +9 -0
  180. package/providers/posthog/README.md +7 -0
  181. package/providers/posthog/eslint.config.mjs +22 -0
  182. package/providers/posthog/package.json +11 -0
  183. package/providers/posthog/project.json +33 -0
  184. package/providers/posthog/src/core/initialize.ts +9 -0
  185. package/providers/posthog/src/index.ts +4 -0
  186. package/providers/posthog/src/schema/capabilities.schema.ts +8 -0
  187. package/providers/posthog/src/schema/configuration.schema.ts +8 -0
  188. package/providers/posthog/tsconfig.json +20 -0
  189. package/providers/posthog/tsconfig.lib.json +9 -0
  190. package/trpc/README.md +7 -0
  191. package/trpc/eslint.config.mjs +19 -0
  192. package/trpc/package.json +13 -0
  193. package/trpc/project.json +31 -0
  194. package/trpc/src/index.ts +64 -0
  195. package/trpc/tsconfig.json +13 -0
  196. package/trpc/tsconfig.lib.json +9 -0
  197. package/tsconfig.base.json +30 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "module": "commonjs",
6
+ "moduleResolution": "node10",
7
+ "types": ["jest", "node"]
8
+ },
9
+ "include": [
10
+ "jest.config.ts",
11
+ "src/**/*.test.ts",
12
+ "src/**/*.spec.ts",
13
+ "src/**/*.d.ts"
14
+ , "src/initialize-algolia.ts" ]
15
+ }
@@ -0,0 +1,3 @@
1
+ import baseConfig from '../../eslint.config.mjs';
2
+
3
+ export default [...baseConfig];
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "trpc-node",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "examples/trpc-node/src",
5
+ "projectType": "application",
6
+ "tags": [],
7
+ "targets": {
8
+ "build": {
9
+ "executor": "@nx/esbuild:esbuild",
10
+ "outputs": ["{options.outputPath}"],
11
+ "defaultConfiguration": "production",
12
+ "options": {
13
+ "platform": "node",
14
+ "outputPath": "dist/examples/trpc-node",
15
+ "format": ["esm"],
16
+ "bundle": true,
17
+ "main": "examples/trpc-node/src/main.ts",
18
+ "tsConfig": "examples/trpc-node/tsconfig.app.json",
19
+ "assets": ["examples/trpc-node/src/assets"],
20
+ "generatePackageJson": true,
21
+ "esbuildOptions": {
22
+ "sourcemap": true,
23
+ "outExtension": {
24
+ ".js": ".js"
25
+ }
26
+ }
27
+ },
28
+ "configurations": {
29
+ "development": {},
30
+ "production": {
31
+ "esbuildOptions": {
32
+ "sourcemap": false,
33
+ "outExtension": {
34
+ ".js": ".js"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ },
40
+ "serve": {
41
+ "executor": "@nx/js:node",
42
+ "defaultConfiguration": "development",
43
+ "dependsOn": [
44
+ "build"
45
+ ],
46
+ "options": {
47
+ "buildTarget": "trpc-node:build",
48
+ "runBuildTargetDependencies": false
49
+ },
50
+ "configurations": {
51
+ "development": {
52
+ "buildTarget": "trpc-node:build:development"
53
+ },
54
+ "production": {
55
+ "buildTarget": "trpc-node:build:production"
56
+ }
57
+ },
58
+ "continuous": true
59
+ }
60
+ }
61
+ }
File without changes
@@ -0,0 +1,55 @@
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import * as trpcExpress from '@trpc/server/adapters/express';
4
+ import { Client } from '@reactionary/core';
5
+ import session from 'express-session';
6
+ import { CreateExpressContextOptions } from '@trpc/server/adapters/express';
7
+ import { Redis } from 'ioredis';
8
+ import { RedisStore } from 'connect-redis';
9
+ import { client, mergedRouter } from './router-instance';
10
+
11
+ const app = express();
12
+
13
+ export function createContext(client: Client) {
14
+ return async ({ req, res, info }: CreateExpressContextOptions) => {
15
+ const session = (req as any).session || {};
16
+
17
+ return {
18
+ session,
19
+ client,
20
+ };
21
+ };
22
+ }
23
+
24
+ app.use(
25
+ cors({
26
+ origin: 'http://localhost:4200',
27
+ credentials: true,
28
+ })
29
+ );
30
+
31
+ const redis = new Redis(process.env['SESSION_STORE_REDIS_CONNECTION']);
32
+
33
+ const store = new RedisStore({
34
+ client: redis,
35
+ });
36
+
37
+ app.use(
38
+ session({
39
+ store: store,
40
+ secret: process.env['SESSION_STORE_SECRET'],
41
+ cookie: {},
42
+ resave: true,
43
+ saveUninitialized: true,
44
+ })
45
+ );
46
+
47
+ app.use(
48
+ '/trpc',
49
+ trpcExpress.createExpressMiddleware({
50
+ router: mergedRouter,
51
+ createContext: createContext(client),
52
+ })
53
+ );
54
+
55
+ app.listen(3000);
@@ -0,0 +1,52 @@
1
+ import { buildClient } from "@reactionary/core";
2
+ import { withAlgoliaCapabilities } from "@reactionary/provider-algolia";
3
+ import { withCommercetoolsCapabilities } from "@reactionary/provider-commercetools";
4
+ import { withFakeCapabilities } from "@reactionary/provider-fake";
5
+ import { withPosthogCapabilities } from "@reactionary/provider-posthog";
6
+ import { createTRPCRouter } from "@reactionary/trpc";
7
+
8
+ /**
9
+ * TODO: This would likely be cleaner with:
10
+ * - implicit processing of parameters from the environment
11
+ * - as a builder-pattern
12
+ */
13
+ export const client = buildClient([
14
+ withAlgoliaCapabilities(
15
+ {
16
+ apiKey: process.env['ALGOLIA_API_KEY'] || '',
17
+ appId: process.env['ALGOLIA_APP_ID'] || '',
18
+ indexName: process.env['ALGOLIA_INDEX'] || '',
19
+ },
20
+ { search: true, analytics: true }
21
+ ),
22
+ withCommercetoolsCapabilities(
23
+ {
24
+ apiUrl: process.env['COMMERCETOOLS_API_URL'] || '',
25
+ authUrl: process.env['COMMERCETOOLS_AUTH_URL'] || '',
26
+ clientId: process.env['COMMERCETOOLS_CLIENT_ID'] || '',
27
+ clientSecret: process.env['COMMERCETOOLS_CLIENT_SECRET'] || '',
28
+ projectKey: process.env['COMMERCETOOLS_PROJECT_KEY'] || '',
29
+ },
30
+ { product: true, identity: true, cart: true, inventory: true, price: true }
31
+ ),
32
+ withFakeCapabilities(
33
+ {
34
+ jitter: {
35
+ mean: 300,
36
+ deviation: 100,
37
+ },
38
+ },
39
+ { search: false, product: false }
40
+ ),
41
+ withPosthogCapabilities(
42
+ {
43
+ apiKey: process.env['POSTHOG_API_KEY'] || '',
44
+ host: process.env['POSTHOG_HOST'] || '',
45
+ },
46
+ { analytics: true }
47
+ ),
48
+ ]);
49
+
50
+ export const mergedRouter = createTRPCRouter(client);
51
+
52
+ export type RouterType = typeof mergedRouter;
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "module": "commonjs",
6
+ "types": ["node"]
7
+ },
8
+ "include": ["src/**/*.ts"]
9
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "files": [],
4
+ "include": [],
5
+ "references": [
6
+ {
7
+ "path": "./tsconfig.app.json"
8
+ }
9
+ ],
10
+ "compilerOptions": {
11
+ "esModuleInterop": true
12
+ }
13
+ }
@@ -0,0 +1,24 @@
1
+ import vue from 'eslint-plugin-vue';
2
+ import baseConfig from '../../eslint.config.mjs';
3
+
4
+ export default [
5
+ ...baseConfig,
6
+ ...vue.configs['flat/recommended'],
7
+ {
8
+ files: ['**/*.vue'],
9
+ languageOptions: {
10
+ parserOptions: {
11
+ parser: await import('@typescript-eslint/parser'),
12
+ },
13
+ },
14
+ },
15
+ {
16
+ files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx', '**/*.vue'],
17
+ rules: {
18
+ 'vue/multi-word-component-names': 'off',
19
+ 'vue/html-self-closing': 'off',
20
+ 'vue/max-attributes-per-line': 'off',
21
+ 'vue/singleline-html-element-content-newline': 'off',
22
+ },
23
+ },
24
+ ];
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>examples-vue</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "examples-vue",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "projectType": "application",
5
+ "sourceRoot": "examples/vue/src",
6
+ "// targets": "to see all targets run: nx show project examples-vue --web",
7
+ "targets": {}
8
+ }
@@ -0,0 +1,275 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ buildClient,
4
+ FacetValueIdentifier,
5
+ SearchResult,
6
+ } from '@reactionary/core';
7
+ import { withAlgoliaCapabilities } from '@reactionary/provider-algolia';
8
+ import { ref, watch, reactive, computed } from 'vue';
9
+
10
+ const client = buildClient([
11
+ withAlgoliaCapabilities(
12
+ {
13
+ apiKey: 'd67221c03e6e4b3bd47e1a35bfa46f36',
14
+ appId: 'BPS0QU5YHD',
15
+ indexName: 'products',
16
+ },
17
+ { search: true, product: true }
18
+ ),
19
+ ]);
20
+
21
+ const result = ref<SearchResult | undefined>(undefined);
22
+
23
+ const query = reactive({
24
+ term: '',
25
+ facets: new Array<FacetValueIdentifier>(),
26
+ page: 0,
27
+ pageSize: 20,
28
+ });
29
+
30
+ watch(
31
+ query,
32
+ async (q) => {
33
+ result.value = await client.search.get({
34
+ term: q.term,
35
+ facets: q.facets,
36
+ page: q.page,
37
+ pageSize: q.pageSize,
38
+ });
39
+ },
40
+ { immediate: true }
41
+ );
42
+
43
+ const hasNextPage = computed(() => {
44
+ return query.page < (result.value?.pages || 0) - 1;
45
+ });
46
+
47
+ const hasPreviousPage = computed(() => {
48
+ return query.page > 0;
49
+ });
50
+
51
+ function toggleFacet(value: FacetValueIdentifier) {
52
+ const old = query.facets;
53
+ const existingIndex = old.findIndex(
54
+ (x) => JSON.stringify(x) === JSON.stringify(value)
55
+ );
56
+
57
+ if (existingIndex > -1) {
58
+ query.facets.splice(existingIndex, 1);
59
+ } else {
60
+ query.facets.push(value);
61
+ }
62
+ }
63
+
64
+ function updateTerm(e: Event) {
65
+ if (e.target && e.target instanceof HTMLInputElement) {
66
+ query.term = e.target.value;
67
+ }
68
+ }
69
+ </script>
70
+
71
+ <template>
72
+ <div class="host">
73
+ <header>
74
+ <input @change="(event) => updateTerm(event)" />
75
+ </header>
76
+ <main>
77
+ <aside>
78
+ <details v-for="facet in result?.facets" :key="facet.identifier.key">
79
+ <summary>
80
+ {{ facet.name }}
81
+ </summary>
82
+ <div>
83
+ <label
84
+ v-for="value of facet.values"
85
+ :key="value.identifier.key"
86
+ >
87
+ <span>{{ value.name }}</span>
88
+ <span>{{ value.count }}</span>
89
+ <input
90
+ type="checkbox"
91
+ :checked="value.active"
92
+ @click="() => toggleFacet(value.identifier)"
93
+ />
94
+ </label>
95
+ </div>
96
+ </details>
97
+ </aside>
98
+ <section>
99
+ <article
100
+ v-for="product in result?.products"
101
+ :key="product.identifier.key"
102
+ >
103
+ <img :src="product.image.replace('w_200', 'w_200,h_200')" />
104
+ <h3>{{ product.name }}</h3>
105
+ </article>
106
+ </section>
107
+ </main>
108
+ <footer>
109
+ <button :disabled="!hasPreviousPage" @click="() => query.page--">
110
+ &lt;
111
+ </button>
112
+ <button :disabled="!hasNextPage" @click="() => query.page++">&gt;</button>
113
+ </footer>
114
+ </div>
115
+ </template>
116
+
117
+ <style lang="scss" scoped>
118
+ .host {
119
+ input,
120
+ h3,
121
+ button,
122
+ a {
123
+ all: unset;
124
+ box-sizing: border-box;
125
+ }
126
+
127
+ header {
128
+ width: 100%;
129
+ padding: 0.5rem;
130
+
131
+ input {
132
+ padding-inline: 1rem;
133
+ color: rgb(205, 214, 244);
134
+ background: rgb(88, 91, 112);
135
+ width: 100%;
136
+ height: 3rem;
137
+ border-radius: 0.5rem;
138
+ }
139
+ }
140
+
141
+ main {
142
+ padding-inline: 0.5rem;
143
+ display: grid;
144
+ gap: 0.5rem;
145
+ grid-template-columns: 300px 1fr;
146
+ color: rgb(205, 214, 244);
147
+ }
148
+
149
+ details[open] {
150
+ summary:after {
151
+ content: '-';
152
+ }
153
+ }
154
+
155
+ details {
156
+ position: relative;
157
+ background: rgb(49, 50, 68);
158
+ border-radius: 0.5rem;
159
+ }
160
+
161
+ summary {
162
+ font-weight: bold;
163
+ text-transform: capitalize;
164
+ list-style: none;
165
+ padding: 0.5rem;
166
+
167
+ &::-webkit-details-marker {
168
+ display: none;
169
+ }
170
+
171
+ &::after {
172
+ position: absolute;
173
+ top: 0.5rem;
174
+ right: 0.5rem;
175
+ content: '+';
176
+ line-height: 1;
177
+ }
178
+ }
179
+
180
+ aside {
181
+ display: grid;
182
+ grid-template-columns: 1fr;
183
+ grid-auto-rows: min-content;
184
+ gap: 0.25rem;
185
+
186
+ div {
187
+ display: grid;
188
+ grid-template-columns: 1fr min-content min-content;
189
+ grid-auto-rows: min-content;
190
+ padding: 0.5rem;
191
+ gap: 0.5rem;
192
+
193
+ a {
194
+ display: contents;
195
+ }
196
+
197
+ label {
198
+ grid-column: span 3;
199
+ display: grid;
200
+ grid-template-columns: subgrid;
201
+ align-items: center;
202
+ gap: 0.5rem;
203
+
204
+ input {
205
+ width: 1.5rem;
206
+ height: 1.5rem;
207
+ background: rgb(147, 153, 178);
208
+ border-radius: 0.125rem;
209
+
210
+ &:checked {
211
+ background: rgb(137, 220, 235);
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+
218
+ section {
219
+ justify-content: center;
220
+ display: grid;
221
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
222
+ grid-auto-rows: min-content;
223
+ gap: 0.5rem;
224
+ }
225
+
226
+ article {
227
+ background: rgb(49, 50, 68);
228
+ border-radius: 0.25rem;
229
+ display: grid;
230
+ grid-template-columns: 1fr;
231
+ grid-template-rows: 1fr min-content;
232
+ gap: 1rem;
233
+
234
+ h3 {
235
+ line-height: 1.2;
236
+ font-size: 1rem;
237
+ text-align: center;
238
+ margin-bottom: 1rem;
239
+ }
240
+
241
+ img {
242
+ object-fit: contain;
243
+ border-top-left-radius: inherit;
244
+ border-top-right-radius: inherit;
245
+ max-width: 100%;
246
+ width: 100%;
247
+ }
248
+ }
249
+
250
+ footer {
251
+ margin: 0.5rem;
252
+ gap: 0.25rem;
253
+ display: grid;
254
+ grid-template-columns: min-content min-content;
255
+ align-items: center;
256
+ justify-content: center;
257
+ }
258
+
259
+ button {
260
+ display: grid;
261
+ justify-content: center;
262
+ align-items: center;
263
+
264
+ height: 3rem;
265
+ background: rgb(49, 50, 68);
266
+ color: rgb(205, 214, 244);
267
+ aspect-ratio: 1 / 1;
268
+ border-radius: 0.25rem;
269
+
270
+ &:disabled {
271
+ opacity: 0.5;
272
+ }
273
+ }
274
+ }
275
+ </style>
@@ -0,0 +1,6 @@
1
+ import './styles.scss';
2
+ import { createApp } from 'vue';
3
+ import App from './app/App.vue';
4
+
5
+ const app = createApp(App);
6
+ app.mount('#root');
@@ -0,0 +1,9 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ body {
6
+ margin: 0;
7
+ padding: 0;
8
+ background: rgb(17, 17, 27);
9
+ }
@@ -0,0 +1,5 @@
1
+ declare module '*.vue' {
2
+ import { defineComponent } from 'vue';
3
+ const component: ReturnType<typeof defineComponent>;
4
+ export default component;
5
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "types": ["vite/client"]
6
+ },
7
+ "exclude": [
8
+ "src/**/*.spec.ts",
9
+ "src/**/*.test.ts",
10
+ "src/**/*.spec.vue",
11
+ "src/**/*.test.vue"
12
+ ],
13
+ "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.vue"]
14
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "esModuleInterop": false,
5
+ "allowSyntheticDefaultImports": true,
6
+ "strict": true,
7
+ "jsx": "preserve",
8
+ "jsxImportSource": "vue",
9
+ "moduleResolution": "node",
10
+ "resolveJsonModule": true
11
+ },
12
+ "files": [],
13
+ "include": [],
14
+ "references": [
15
+ {
16
+ "path": "./tsconfig.app.json"
17
+ }
18
+ ],
19
+ "extends": "../../tsconfig.base.json"
20
+ }
@@ -0,0 +1,31 @@
1
+ /// <reference types='vitest' />
2
+ import { defineConfig } from 'vite';
3
+ import vue from '@vitejs/plugin-vue';
4
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
5
+ import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
6
+
7
+ export default defineConfig(() => ({
8
+ root: __dirname,
9
+ cacheDir: '../../node_modules/.vite/examples/vue',
10
+ server: {
11
+ port: 4200,
12
+ host: 'localhost',
13
+ },
14
+ preview: {
15
+ port: 4300,
16
+ host: 'localhost',
17
+ },
18
+ plugins: [vue(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
19
+ // Uncomment this if you are using workers.
20
+ // worker: {
21
+ // plugins: [ nxViteTsPaths() ],
22
+ // },
23
+ build: {
24
+ outDir: '../../dist/examples/vue',
25
+ emptyOutDir: true,
26
+ reportCompressedSize: true,
27
+ commonjsOptions: {
28
+ transformMixedEsModules: true,
29
+ },
30
+ },
31
+ }));
package/jest.config.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { Config } from 'jest';
2
+ import { getJestProjectsAsync } from '@nx/jest';
3
+
4
+ export default async (): Promise<Config> => ({
5
+ projects: await getJestProjectsAsync(),
6
+ });
package/jest.preset.js ADDED
@@ -0,0 +1,3 @@
1
+ const nxPreset = require('@nx/jest/preset').default;
2
+
3
+ module.exports = { ...nxPreset };
@@ -0,0 +1,11 @@
1
+ {
2
+ "migrations": [
3
+ {
4
+ "version": "21.1.0-beta.2",
5
+ "description": "Adds **/nx-rules.mdc and **/nx.instructions.md to .gitignore if not present",
6
+ "implementation": "./src/migrations/update-21-1-0/add-gitignore-entry",
7
+ "package": "nx",
8
+ "name": "21-1-0-add-ignore-entries-for-nx-rule-files"
9
+ }
10
+ ]
11
+ }