@cedarjs/cli 8.0.0-canary.3386 → 8.0.0-canary.3387

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.
@@ -10,21 +10,18 @@ const memJsFormattedLogger = {
10
10
  log: (msg: string) => logger.error(msg),
11
11
  }
12
12
 
13
- export let client: InMemoryClient | MemcachedClient
13
+ // The client connects to Memcached the first time it's used. If it can't
14
+ // connect, the error is logged and `cache()` runs the uncached function
15
+ // instead
16
+ export const client =
17
+ process.env.NODE_ENV === 'test'
18
+ ? new InMemoryClient()
19
+ : new MemcachedClient(process.env.CACHE_HOST, {
20
+ logger: memJsFormattedLogger,
21
+ })
14
22
 
15
- if (process.env.NODE_ENV === 'test') {
16
- client = new InMemoryClient()
17
- } else {
18
- try {
19
- client = new MemcachedClient(process.env.CACHE_HOST, {
20
- logger: memJsFormattedLogger,
21
- })
22
- } catch (e) {
23
- logger.error(`Could not connect to cache: ${e.message}`)
24
- }
25
- }
26
-
27
- export const { cache, cacheFindMany, cacheClient, deleteCacheKey } = createCache(client, {
28
- logger,
29
- timeout: 500,
30
- })
23
+ export const { cache, cacheFindMany, cacheClient, deleteCacheKey } =
24
+ createCache(client, {
25
+ logger,
26
+ timeout: 500,
27
+ })
@@ -1,24 +1,16 @@
1
- import {
2
- createCache,
3
- InMemoryClient,
4
- RedisClient,
5
- } from '@cedarjs/api/cache'
1
+ import { createCache, InMemoryClient, RedisClient } from '@cedarjs/api/cache'
6
2
 
7
3
  import { logger } from './logger'
8
4
 
9
- export let client: InMemoryClient | RedisClient
5
+ // The client connects to Redis the first time it's used. If it can't connect,
6
+ // the error is logged and `cache()` runs the uncached function instead
7
+ export const client =
8
+ process.env.NODE_ENV === 'test'
9
+ ? new InMemoryClient()
10
+ : new RedisClient({ url: process.env.CACHE_HOST, logger })
10
11
 
11
- if (process.env.NODE_ENV === 'test') {
12
- client = new InMemoryClient()
13
- } else {
14
- try {
15
- client = new RedisClient({ url: process.env.CACHE_HOST, logger })
16
- } catch (e) {
17
- logger.error(`Could not connect to cache: ${e.message}`)
18
- }
19
- }
20
-
21
- export const { cache, cacheFindMany, cacheClient, deleteCacheKey } = createCache(client, {
22
- logger,
23
- timeout: 500,
24
- })
12
+ export const { cache, cacheFindMany, cacheClient, deleteCacheKey } =
13
+ createCache(client, {
14
+ logger,
15
+ timeout: 500,
16
+ })
@@ -76,7 +76,6 @@ const handler = async ({ force }) => {
76
76
  "export const handler = createGraphQLHandler({",
77
77
  "extraPlugins: [useSentry({",
78
78
  " includeRawResult: true,",
79
- " includeResolverArgs: true,",
80
79
  " includeExecuteVariables: true,",
81
80
  "})],"
82
81
  );
@@ -112,7 +111,11 @@ const handler = async ({ force }) => {
112
111
  contentLines.splice(
113
112
  boundaryOpenIndex,
114
113
  1,
115
- "<Sentry.ErrorBoundary fallback={FatalErrorPage}>"
114
+ "<Sentry.ErrorBoundary",
115
+ " fallback={({ error }) => (",
116
+ " <FatalErrorPage error={error instanceof Error ? error : undefined} />",
117
+ " )}",
118
+ ">"
116
119
  );
117
120
  const boundaryCloseIndex = contentLines.findLastIndex(
118
121
  (line) => line.includes("</FatalErrorBoundary>")
@@ -3,10 +3,7 @@ import * as Sentry from '@sentry/node'
3
3
  Sentry.init({
4
4
  dsn: process.env.SENTRY_DSN,
5
5
  environment: process.env.NODE_ENV,
6
- integrations: [
7
- Sentry.prismaIntegration(),
8
- Sentry.httpIntegration(),
9
- ],
6
+ integrations: [Sentry.prismaIntegration(), Sentry.httpIntegration()],
10
7
  tracesSampleRate: 1.0,
11
8
  })
12
9
 
@@ -1,9 +1,12 @@
1
1
  import * as Sentry from '@sentry/react'
2
2
 
3
+ const sentryDsn =
4
+ typeof process === 'undefined' ? undefined : process.env?.SENTRY_DSN
5
+
3
6
  let dsn = ''
4
7
  let environment = 'development'
5
8
 
6
- if (typeof process === 'undefined' || !process.env?.SENTRY_DSN) {
9
+ if (!sentryDsn) {
7
10
  console.error(
8
11
  'Missing SENTRY_DSN environment variable. Did you forget to add it to ' +
9
12
  'your cedar.toml (or redwood.toml) in `includeEnvironmentVariables`?'
@@ -17,14 +20,14 @@ if (typeof process === 'undefined' || !process.env?.SENTRY_DSN) {
17
20
  `)
18
21
  console.error('Sentry is disabled for now')
19
22
  } else {
20
- dsn = process.env.SENTRY_DSN
21
- environment = process.env.NODE_ENV
23
+ dsn = sentryDsn
24
+ environment = process.env.NODE_ENV ?? 'development'
22
25
  }
23
26
 
24
27
  Sentry.init({
25
28
  dsn,
26
29
  environment,
27
- integrations: [ Sentry.browserTracingIntegration() ],
30
+ integrations: [Sentry.browserTracingIntegration()],
28
31
  tracesSampleRate: 1.0,
29
32
  })
30
33
 
@@ -7,7 +7,10 @@ export const fastField = async () => {
7
7
  return 'I am fast'
8
8
  }
9
9
 
10
- export const slowField = async (_, { waitFor = 5000 }) => {
10
+ export const slowField = async (
11
+ _: unknown,
12
+ { waitFor = 5000 }: { waitFor?: number }
13
+ ) => {
11
14
  logger.debug('waiting on slowField')
12
15
  await wait(waitFor)
13
16
  return 'I am slow'
@@ -1,8 +1,16 @@
1
+ import type { BidInput } from 'types/graphql'
2
+
1
3
  import type { LiveQueryStorageMechanism } from '@cedarjs/realtime'
2
4
 
3
5
  import { logger } from 'src/lib/logger'
4
6
 
5
- const auctions = [
7
+ interface AuctionData {
8
+ id: string
9
+ title: string
10
+ bids: { amount: number }[]
11
+ }
12
+
13
+ const auctions: AuctionData[] = [
6
14
  { id: '1', title: 'RedwoodJS Logo Shirt', bids: [{ amount: 20 }] },
7
15
  { id: '2', title: 'RedwoodJS Lapel Pin', bids: [{ amount: 5 }] },
8
16
  { id: '3', title: 'RedwoodJS Beanie', bids: [{ amount: 15 }] },
@@ -34,14 +42,14 @@ const auctions = [
34
42
  * }
35
43
  * }
36
44
  */
37
- export const auction = async ({ id }) => {
45
+ export const auction = async ({ id }: { id: string }) => {
38
46
  const foundAuction = auctions.find((a) => a.id === id)
39
47
  logger.debug({ id, auction: foundAuction }, 'auction')
40
48
  return foundAuction
41
49
  }
42
50
 
43
51
  export const bid = async (
44
- { input },
52
+ { input }: { input: BidInput },
45
53
  { context }: { context: { liveQueryStore: LiveQueryStorageMechanism } }
46
54
  ) => {
47
55
  const { auctionId, amount } = input
@@ -62,7 +70,7 @@ export const bid = async (
62
70
  }
63
71
 
64
72
  export const Auction = {
65
- highestBid: (obj, { root }) => {
73
+ highestBid: (obj: unknown, { root }: { root: AuctionData }) => {
66
74
  const [max] = root.bids.sort((a, b) => b.amount - a.amount)
67
75
 
68
76
  logger.debug({ obj, root }, 'highestBid')
@@ -48,7 +48,7 @@ const newMessage = {
48
48
 
49
49
  return pubSub.subscribe('newMessage', roomId)
50
50
  },
51
- resolve: (payload) => {
51
+ resolve: (payload: NewMessageChannel['newMessage'][1]) => {
52
52
  logger.debug({ payload }, 'newMessage subscription resolve')
53
53
 
54
54
  return payload
@@ -52,7 +52,8 @@ function wrapCreateCall(fn) {
52
52
  ),
53
53
  j.objectProperty(
54
54
  j.identifier("invitationToken"),
55
- j.memberExpression(
55
+ // `userAttributes` is optional in dbAuth's signup handler options
56
+ j.optionalMemberExpression(
56
57
  j.identifier("userAttributes"),
57
58
  j.identifier("invitationToken")
58
59
  )
@@ -1,11 +1,20 @@
1
1
  import { useEffect, useState } from 'react'
2
2
 
3
+ import type {
4
+ AcceptInvitationMutation,
5
+ AcceptInvitationMutationVariables,
6
+ } from 'types/graphql'
7
+
3
8
  import { navigate, routes, useParams } from '@cedarjs/router'
4
9
  import { Metadata, useMutation } from '@cedarjs/web'
10
+ import type { TypedDocumentNode } from '@cedarjs/web'
5
11
 
6
12
  import { useAuth } from 'src/auth'
7
13
 
8
- const ACCEPT_INVITATION_MUTATION = gql`
14
+ const ACCEPT_INVITATION_MUTATION: TypedDocumentNode<
15
+ AcceptInvitationMutation,
16
+ AcceptInvitationMutationVariables
17
+ > = gql`
9
18
  mutation AcceptInvitationMutation($token: String!) {
10
19
  acceptInvitation(token: $token) {
11
20
  id
@@ -321,7 +321,7 @@ export const removeMember: MutationResolvers['removeMember'] = async ({
321
321
 
322
322
  export const Membership: MembershipRelationResolvers = {
323
323
  organization: (_obj, { root }) =>
324
- db.membership.findUnique({ where: { id: root?.id } }).organization(),
324
+ db.membership.findUniqueOrThrow({ where: { id: root.id } }).organization(),
325
325
  }
326
326
 
327
327
  interface EnsureDefaultOrganizationArgs {
@@ -7,7 +7,7 @@ import requireMembership from './requireMembership.js'
7
7
  * selects more fields than these tests need.
8
8
  */
9
9
  const asCurrentUser = (user: { id: string; memberships?: unknown[] }) =>
10
- user as unknown as typeof context.currentUser
10
+ user as unknown as NonNullable<typeof context.currentUser>
11
11
 
12
12
  describe('requireMembership directive', () => {
13
13
  it('declares the directive sdl as schema, with the correct name', () => {
@@ -57,7 +57,7 @@ const SIGNUP_SNIPPET = `
57
57
 
58
58
  await ensureDefaultOrganization({
59
59
  currentUser: user,
60
- invitationToken: userAttributes.invitationToken,
60
+ invitationToken: userAttributes?.invitationToken,
61
61
  })
62
62
 
63
63
  return user
@@ -40,6 +40,12 @@ const S3_CLIENT = `
40
40
  export const s3Client = new S3Client({
41
41
  region: process.env.AWS_REGION,
42
42
  })
43
+
44
+ const s3Bucket = process.env.S3_BUCKET_UPLOADS
45
+
46
+ if (!s3Bucket) {
47
+ throw new Error('Set S3_BUCKET_UPLOADS in .env to use the S3 storage target')
48
+ }
43
49
  `;
44
50
  const TARGET_BLOCKS = {
45
51
  fs: ` // Files uploaded through the api server and stored on local disk. Good for
@@ -56,7 +62,7 @@ const TARGET_BLOCKS = {
56
62
  s3: ` // Files uploaded straight from the browser to S3 with presigned URLs.
57
63
  files: createS3Provider({
58
64
  client: s3Client,
59
- bucket: process.env.S3_BUCKET_UPLOADS,
65
+ bucket: s3Bucket,
60
66
  region: process.env.AWS_REGION,
61
67
  keyPrefix: 'uploads/',
62
68
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "8.0.0-canary.3386",
3
+ "version": "8.0.0-canary.3387",
4
4
  "description": "The CedarJS Command Line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,17 +36,17 @@
36
36
  "@babel/preset-typescript": "7.29.7",
37
37
  "@babel/traverse": "7.29.10",
38
38
  "@babel/types": "7.29.8",
39
- "@cedarjs/api-server": "8.0.0-canary.3386",
40
- "@cedarjs/babel-config": "8.0.0-canary.3386",
41
- "@cedarjs/cli-helpers": "8.0.0-canary.3386",
42
- "@cedarjs/internal": "8.0.0-canary.3386",
43
- "@cedarjs/prerender": "8.0.0-canary.3386",
44
- "@cedarjs/project-config": "8.0.0-canary.3386",
45
- "@cedarjs/structure": "8.0.0-canary.3386",
46
- "@cedarjs/telemetry": "8.0.0-canary.3386",
47
- "@cedarjs/utils": "8.0.0-canary.3386",
48
- "@cedarjs/vite": "8.0.0-canary.3386",
49
- "@cedarjs/web-server": "8.0.0-canary.3386",
39
+ "@cedarjs/api-server": "8.0.0-canary.3387",
40
+ "@cedarjs/babel-config": "8.0.0-canary.3387",
41
+ "@cedarjs/cli-helpers": "8.0.0-canary.3387",
42
+ "@cedarjs/internal": "8.0.0-canary.3387",
43
+ "@cedarjs/prerender": "8.0.0-canary.3387",
44
+ "@cedarjs/project-config": "8.0.0-canary.3387",
45
+ "@cedarjs/structure": "8.0.0-canary.3387",
46
+ "@cedarjs/telemetry": "8.0.0-canary.3387",
47
+ "@cedarjs/utils": "8.0.0-canary.3387",
48
+ "@cedarjs/vite": "8.0.0-canary.3387",
49
+ "@cedarjs/web-server": "8.0.0-canary.3387",
50
50
  "@listr2/prompt-adapter-enquirer": "4.3.3",
51
51
  "@opentelemetry/api": "1.9.1",
52
52
  "@opentelemetry/core": "2.12.0",
@@ -94,7 +94,7 @@
94
94
  "yargs": "17.7.3"
95
95
  },
96
96
  "devDependencies": {
97
- "@cedarjs/framework-tools": "8.0.0-canary.3386",
97
+ "@cedarjs/framework-tools": "8.0.0-canary.3387",
98
98
  "@prisma/dmmf": "7.10.0",
99
99
  "@types/archiver": "^7.0.0",
100
100
  "memfs": "4.80.0",