@cedarjs/cli 7.0.0-canary.3104 → 7.0.0-canary.3107

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.
@@ -14,7 +14,7 @@ function buildMembershipsSelectProperty() {
14
14
  `;
15
15
  const property = j.withParser("ts")(snippet).find(j.ObjectProperty, { key: { name: "memberships" } }).nodes()[0];
16
16
  if (!property) {
17
- throw new Error("RW_CODEMOD_ERR_AUTH_SHAPE_NOT_FOUND");
17
+ throw new Error("CEDAR_CODEMOD_ERR_AUTH_SHAPE_NOT_FOUND");
18
18
  }
19
19
  return property;
20
20
  }
@@ -51,7 +51,7 @@ function transform(fileInfo) {
51
51
  selectFound = true;
52
52
  });
53
53
  if (!selectFound) {
54
- throw new Error("RW_CODEMOD_ERR_AUTH_SHAPE_NOT_FOUND");
54
+ throw new Error("CEDAR_CODEMOD_ERR_AUTH_SHAPE_NOT_FOUND");
55
55
  }
56
56
  const tenancyExportSnippet = `export { hasOrgRole, requireMembership } from '@cedarjs/tenancy'
57
57
  `;
@@ -36,7 +36,7 @@ function transform(fileInfo, _api, options) {
36
36
  return;
37
37
  }
38
38
  if (j.NewExpression.check(dbDeclaration.init)) {
39
- throw new Error("RW_CODEMOD_ERR_OLD_FORMAT");
39
+ throw new Error("CEDAR_CODEMOD_ERR_OLD_FORMAT");
40
40
  }
41
41
  if (!j.Expression.check(dbDeclaration.init)) {
42
42
  return;
@@ -52,7 +52,7 @@ function transform(fileInfo, _api, options) {
52
52
  );
53
53
  });
54
54
  if (!found) {
55
- throw new Error("RW_CODEMOD_ERR_DB_SHAPE_NOT_FOUND");
55
+ throw new Error("CEDAR_CODEMOD_ERR_DB_SHAPE_NOT_FOUND");
56
56
  }
57
57
  return root.toSource().replace(
58
58
  "createTenancyExtension(",
@@ -42,7 +42,7 @@ function buildContextProperty() {
42
42
  `;
43
43
  const property = j.withParser("ts")(snippet).find(j.ObjectProperty, { key: { name: "context" } }).nodes()[0];
44
44
  if (!property) {
45
- throw new Error("RW_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
45
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
46
46
  }
47
47
  return property;
48
48
  }
@@ -61,18 +61,18 @@ function transform(fileInfo) {
61
61
  callee: { name: "createGraphQLHandler" }
62
62
  });
63
63
  if (handlerCalls.length === 0) {
64
- throw new Error("RW_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
64
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
65
65
  }
66
66
  handlerCalls.forEach((path) => {
67
67
  const [config] = path.node.arguments;
68
68
  if (!j.ObjectExpression.check(config)) {
69
- throw new Error("RW_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
69
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
70
70
  }
71
71
  const hasContext = config.properties.some(
72
72
  (prop) => j.ObjectProperty.check(prop) && j.Identifier.check(prop.key) && prop.key.name === "context"
73
73
  );
74
74
  if (hasContext) {
75
- throw new Error("RW_CODEMOD_ERR_GRAPHQL_CONTEXT_EXISTS");
75
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_CONTEXT_EXISTS");
76
76
  }
77
77
  config.properties.push(buildContextProperty());
78
78
  });
@@ -1,23 +1,26 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
3
4
  const WEB_AUTH_EXTENSIONS = ["ts", "tsx", "js", "jsx"];
4
5
  function hasWebAuthFile(webSrcPath) {
5
6
  return WEB_AUTH_EXTENSIONS.some(
6
7
  (extension) => fs.existsSync(path.join(webSrcPath, `auth.${extension}`))
7
8
  );
8
9
  }
9
- const AUTH_NOT_SET_UP_MESSAGE = [
10
- "Auth is not set up in this project.",
11
- "",
12
- "Tenancy builds on your app's auth: it adds memberships to",
13
- "`getCurrentUser`, and resolves the current organization from the",
14
- "signed-in user's memberships. Set up auth first, then run this command",
15
- "again:",
16
- "",
17
- " yarn cedar setup auth dbAuth",
18
- "",
19
- "Any provider works. See https://cedarjs.com/docs/authentication"
20
- ].join("\n");
10
+ function authNotSetUpMessage() {
11
+ return [
12
+ "Auth is not set up in this project.",
13
+ "",
14
+ "Tenancy builds on your app's auth: it adds memberships to",
15
+ "`getCurrentUser`, and resolves the current organization from the",
16
+ "signed-in user's memberships. Set up auth first, then run this command",
17
+ "again:",
18
+ "",
19
+ ` ${formatCedarCommand(["setup", "auth", "dbAuth"])}`,
20
+ "",
21
+ "Any provider works. See https://cedarjs.com/docs/authentication"
22
+ ].join("\n");
23
+ }
21
24
  function noUserModelMessage(schemaPath) {
22
25
  return [
23
26
  `No \`User\` model found in ${schemaPath}.`,
@@ -30,7 +33,7 @@ function noUserModelMessage(schemaPath) {
30
33
  "provider's id in a column beside it, so memberships keep working if you",
31
34
  "switch providers or add a second one.",
32
35
  "",
33
- "Add a model like this one, run `yarn cedar prisma migrate dev`, then",
36
+ `Add a model like this one, run \`${formatCedarCommand(["prisma", "migrate", "dev"])}\`, then`,
34
37
  "run this command again:",
35
38
  "",
36
39
  " model User {",
@@ -40,7 +43,7 @@ function noUserModelMessage(schemaPath) {
40
43
  ].join("\n");
41
44
  }
42
45
  export {
43
- AUTH_NOT_SET_UP_MESSAGE,
46
+ authNotSetUpMessage,
44
47
  hasWebAuthFile,
45
48
  noUserModelMessage
46
49
  };
@@ -56,12 +56,12 @@ ${RW_DATA_MIGRATION_MODEL}
56
56
  }
57
57
  function editSchema(schema, options) {
58
58
  if (!hasModel(schema, "User")) {
59
- throw new Error("RW_TENANCY_ERR_NO_USER_MODEL");
59
+ throw new Error("CEDAR_TENANCY_ERR_NO_USER_MODEL");
60
60
  }
61
61
  const modelsExist = hasModel(schema, "Organization") || hasModel(schema, "Membership");
62
62
  const modelsAreThisCommands = schema.includes(ORGANIZATION_MODEL) && schema.includes(MEMBERSHIP_MODEL);
63
63
  if (modelsExist && !modelsAreThisCommands && !options.force) {
64
- throw new Error("RW_TENANCY_ERR_MODELS_EXIST");
64
+ throw new Error("CEDAR_TENANCY_ERR_MODELS_EXIST");
65
65
  }
66
66
  const withTenancyModels = addTenancyModels(schema);
67
67
  return addDataMigrationModel(withTenancyModels);
@@ -2,13 +2,13 @@ import j from "jscodeshift";
2
2
  function useShorthandUserAttributes(fn) {
3
3
  const [firstParam] = fn.params;
4
4
  if (!j.ObjectPattern.check(firstParam)) {
5
- throw new Error("RW_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
5
+ throw new Error("CEDAR_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
6
6
  }
7
7
  const userAttributesProperty = firstParam.properties.find(
8
8
  (prop) => j.ObjectProperty.check(prop) && j.Identifier.check(prop.key) && prop.key.name === "userAttributes"
9
9
  );
10
10
  if (!userAttributesProperty || !j.ObjectProperty.check(userAttributesProperty)) {
11
- throw new Error("RW_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
11
+ throw new Error("CEDAR_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
12
12
  }
13
13
  userAttributesProperty.value = j.identifier("userAttributes");
14
14
  userAttributesProperty.shorthand = true;
@@ -68,7 +68,7 @@ function wrapCreateCall(fn) {
68
68
  );
69
69
  const returnStatement = fn.body.body[returnIndex];
70
70
  if (returnIndex === -1 || !j.ReturnStatement.check(returnStatement) || !returnStatement.argument) {
71
- throw new Error("RW_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
71
+ throw new Error("CEDAR_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
72
72
  }
73
73
  const createUserStatement = j.variableDeclaration("const", [
74
74
  j.variableDeclarator(
@@ -105,7 +105,7 @@ function wrapCreateCall(fn) {
105
105
  ]);
106
106
  return;
107
107
  }
108
- throw new Error("RW_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
108
+ throw new Error("CEDAR_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
109
109
  }
110
110
  function transform(fileInfo) {
111
111
  const root = j.withParser("tsx")(fileInfo.source);
@@ -113,7 +113,7 @@ function transform(fileInfo) {
113
113
  id: { name: "signupOptions" }
114
114
  });
115
115
  if (signupOptionsDeclarators.length === 0) {
116
- throw new Error("RW_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
116
+ throw new Error("CEDAR_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
117
117
  }
118
118
  let handlerFound = false;
119
119
  signupOptionsDeclarators.forEach((path) => {
@@ -136,7 +136,7 @@ function transform(fileInfo) {
136
136
  handlerFound = true;
137
137
  });
138
138
  if (!handlerFound) {
139
- throw new Error("RW_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
139
+ throw new Error("CEDAR_CODEMOD_ERR_SIGNUP_SHAPE_NOT_FOUND");
140
140
  }
141
141
  addInvitationTokenToUserAttributes(root);
142
142
  const imports = root.find(j.ImportDeclaration);
@@ -10,8 +10,9 @@ const BATCH_SIZE = 100
10
10
  * dbAuth, the signup handler). Every user without a membership gets one, in
11
11
  * batches, using the same `ensureDefaultOrganization` new signups use.
12
12
  *
13
- * Run with `yarn cedar data-migrate up`, after `yarn cedar prisma migrate
14
- * dev` has applied the `Organization`/`Membership` migration.
13
+ * Run with `__DATA_MIGRATE_UP_COMMAND__`, after
14
+ * `__PRISMA_MIGRATE_DEV_COMMAND__` has applied the
15
+ * `Organization`/`Membership` migration.
15
16
  */
16
17
  export default async ({ db }: { db: PrismaClient }) => {
17
18
  let cursor: string | undefined
@@ -18,7 +18,7 @@ import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
18
18
  import { isTypeScriptProject } from "../../../lib/project.js";
19
19
  import { runTransform } from "../../../lib/runTransform.js";
20
20
  import {
21
- AUTH_NOT_SET_UP_MESSAGE,
21
+ authNotSetUpMessage,
22
22
  hasWebAuthFile,
23
23
  noUserModelMessage
24
24
  } from "./preflight.js";
@@ -61,7 +61,7 @@ const SIGNUP_SNIPPET = `
61
61
  const handler = async ({ tenantField, force }) => {
62
62
  const paths = getPaths();
63
63
  if (!hasWebAuthFile(paths.web.src)) {
64
- console.error(c.error(AUTH_NOT_SET_UP_MESSAGE));
64
+ console.error(c.error(authNotSetUpMessage()));
65
65
  process.exit(1);
66
66
  }
67
67
  const preflightSchemaPath = await getSchemaPath(paths.api.prismaConfig);
@@ -82,16 +82,13 @@ const handler = async ({ tenantField, force }) => {
82
82
  const graphqlPath = path.join(paths.api.functions, `graphql.${ext}`);
83
83
  const functionsAuthPath = path.join(paths.api.functions, `auth.${ext}`);
84
84
  const isDbAuthProject = fs.existsSync(functionsAuthPath) && fs.readFileSync(functionsAuthPath, "utf-8").includes("DbAuthHandler");
85
- const writeTemplateFile = async (templateFile, outputPath) => {
86
- const templatePath = path.resolve(
87
- import.meta.dirname,
88
- "templates",
89
- templateFile
90
- );
91
- const templateContent = fs.readFileSync(templatePath, {
92
- encoding: "utf8",
93
- flag: "r"
94
- });
85
+ const writeTemplateFile = async (templateFile, outputPath, replacements = {}) => {
86
+ const dirname = import.meta.dirname;
87
+ const templatePath = path.resolve(dirname, "templates", templateFile);
88
+ let templateContent = fs.readFileSync(templatePath, "utf-8");
89
+ for (const [token, value] of Object.entries(replacements)) {
90
+ templateContent = templateContent.replaceAll(token, value);
91
+ }
95
92
  const content = projectIsTypescript ? templateContent : await transformTSToJS(outputPath, templateContent);
96
93
  return writeFile(outputPath, content, { overwriteExisting: force });
97
94
  };
@@ -115,12 +112,14 @@ const handler = async ({ tenantField, force }) => {
115
112
  updatedSchema = editSchema(schema, { force });
116
113
  } catch (e) {
117
114
  const message = e instanceof Error ? e.message : String(e);
118
- if (message === "RW_TENANCY_ERR_NO_USER_MODEL") {
115
+ if (message === "CEDAR_TENANCY_ERR_NO_USER_MODEL") {
116
+ const authSetup = formatCedarCommand(["setup", "auth", "dbAuth"]);
117
+ const tenancySetup = formatCedarCommand(["setup", "tenancy"]);
119
118
  throw new Error(
120
- "No `User` model found in schema.prisma. Set up authentication first (e.g. `yarn cedar setup auth dbAuth`) before running `yarn cedar setup tenancy`."
119
+ `No \`User\` model found in schema.prisma. Set up authentication first (e.g. \`${authSetup}\`) before running \`${tenancySetup}\`.`
121
120
  );
122
121
  }
123
- if (message === "RW_TENANCY_ERR_MODELS_EXIST") {
122
+ if (message === "CEDAR_TENANCY_ERR_MODELS_EXIST") {
124
123
  throw new Error(
125
124
  "`Organization` and/or `Membership` models already exist in schema.prisma. Re-run with --force to keep them as-is and continue with the rest of the setup."
126
125
  );
@@ -158,13 +157,14 @@ const handler = async ({ tenantField, force }) => {
158
157
  options: tenantField !== DEFAULT_TENANT_FIELD ? { tenantField } : {}
159
158
  });
160
159
  if (transformResult.error) {
161
- if (transformResult.error === "RW_CODEMOD_ERR_OLD_FORMAT") {
160
+ if (transformResult.error === "CEDAR_CODEMOD_ERR_OLD_FORMAT") {
161
+ const tenancySetup = formatCedarCommand(["setup", "tenancy"]);
162
162
  throw new Error(
163
- "It looks like your api/src/lib/db file is using the old format. Please update it as per the v8 upgrade guide, then run `yarn cedar setup tenancy` again."
163
+ `It looks like your api/src/lib/db file is using the old format. Please update it as per the v8 upgrade guide, then run \`${tenancySetup}\` again.`
164
164
  );
165
165
  }
166
166
  throw new Error(
167
- "Could not add the tenancy Prisma extension. Please modify api/src/lib/db by hand: wrap the `db` export in `.$extends(createTenancyExtension({ models: { allExcept: ['user', 'organization', 'membership'] } }))`."
167
+ "Could not add the tenancy Prisma extension. Please modify `api/src/lib/db` by hand: wrap the `db` export in `.$extends(createTenancyExtension({ models: { allExcept: ['user', 'organization', 'membership'] } }))`."
168
168
  );
169
169
  }
170
170
  }
@@ -194,7 +194,7 @@ ${AUTH_SNIPPET}`;
194
194
  targetPaths: [graphqlPath]
195
195
  });
196
196
  if (transformResult.error) {
197
- if (transformResult.error === "RW_CODEMOD_ERR_GRAPHQL_CONTEXT_EXISTS") {
197
+ if (transformResult.error === "CEDAR_CODEMOD_ERR_GRAPHQL_CONTEXT_EXISTS") {
198
198
  throw new Error(
199
199
  "api/src/functions/graphql already has a `context` option. Please wire it up for tenancy by hand; see the multi-tenancy how-to for the shape it needs."
200
200
  );
@@ -271,7 +271,18 @@ ${SIGNUP_SNIPPET}`;
271
271
  path.join(
272
272
  dataMigrationsPath,
273
273
  `${timestamp}-ensure-default-organizations.${ext}`
274
- )
274
+ ),
275
+ {
276
+ __DATA_MIGRATE_UP_COMMAND__: formatCedarCommand([
277
+ "data-migrate",
278
+ "up"
279
+ ]),
280
+ __PRISMA_MIGRATE_DEV_COMMAND__: formatCedarCommand([
281
+ "prisma",
282
+ "migrate",
283
+ "dev"
284
+ ])
285
+ }
275
286
  );
276
287
  }
277
288
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "7.0.0-canary.3104",
3
+ "version": "7.0.0-canary.3107",
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.8",
38
38
  "@babel/types": "7.29.8",
39
- "@cedarjs/api-server": "7.0.0-canary.3104",
40
- "@cedarjs/babel-config": "7.0.0-canary.3104",
41
- "@cedarjs/cli-helpers": "7.0.0-canary.3104",
42
- "@cedarjs/internal": "7.0.0-canary.3104",
43
- "@cedarjs/prerender": "7.0.0-canary.3104",
44
- "@cedarjs/project-config": "7.0.0-canary.3104",
45
- "@cedarjs/structure": "7.0.0-canary.3104",
46
- "@cedarjs/telemetry": "7.0.0-canary.3104",
47
- "@cedarjs/utils": "7.0.0-canary.3104",
48
- "@cedarjs/vite": "7.0.0-canary.3104",
49
- "@cedarjs/web-server": "7.0.0-canary.3104",
39
+ "@cedarjs/api-server": "7.0.0-canary.3107",
40
+ "@cedarjs/babel-config": "7.0.0-canary.3107",
41
+ "@cedarjs/cli-helpers": "7.0.0-canary.3107",
42
+ "@cedarjs/internal": "7.0.0-canary.3107",
43
+ "@cedarjs/prerender": "7.0.0-canary.3107",
44
+ "@cedarjs/project-config": "7.0.0-canary.3107",
45
+ "@cedarjs/structure": "7.0.0-canary.3107",
46
+ "@cedarjs/telemetry": "7.0.0-canary.3107",
47
+ "@cedarjs/utils": "7.0.0-canary.3107",
48
+ "@cedarjs/vite": "7.0.0-canary.3107",
49
+ "@cedarjs/web-server": "7.0.0-canary.3107",
50
50
  "@listr2/prompt-adapter-enquirer": "4.3.1",
51
51
  "@opentelemetry/api": "1.9.1",
52
52
  "@opentelemetry/core": "1.30.1",
@@ -94,7 +94,7 @@
94
94
  "yargs": "17.7.3"
95
95
  },
96
96
  "devDependencies": {
97
- "@cedarjs/framework-tools": "7.0.0-canary.3104",
97
+ "@cedarjs/framework-tools": "7.0.0-canary.3107",
98
98
  "@prisma/dmmf": "7.10.0",
99
99
  "@types/archiver": "^7.0.0",
100
100
  "memfs": "4.68.2",