@cedarjs/cli 1.0.0-canary.13101 → 1.0.0-canary.13103
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.
- package/dist/commands/generate/package/filesTask.js +73 -0
- package/dist/commands/generate/package/package.js +14 -0
- package/dist/commands/generate/package/packageHandler.js +158 -0
- package/dist/commands/generate/package/templates/README.md.template +15 -0
- package/dist/commands/generate/package/templates/index.ts.template +3 -0
- package/dist/commands/generate/package/templates/package.json.template +15 -0
- package/dist/commands/generate/package/templates/scenarios.ts.template +8 -0
- package/dist/commands/generate/package/templates/test.ts.template +7 -0
- package/dist/commands/generate/package/templates/tsconfig.json.template +16 -0
- package/dist/commands/generate/yargsHandlerHelpers.js +4 -3
- package/dist/commands/generate.js +2 -1
- package/dist/commands/setup/generator/generatorHandler.js +2 -1
- package/dist/lib/test.js +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { transformTSToJS } from "../../../lib/index.js";
|
|
3
|
+
import { templateForFile } from "../yargsHandlerHelpers.js";
|
|
4
|
+
const files = async ({
|
|
5
|
+
name,
|
|
6
|
+
folderName,
|
|
7
|
+
packageName,
|
|
8
|
+
fileName,
|
|
9
|
+
typescript,
|
|
10
|
+
tests: generateTests = true,
|
|
11
|
+
...rest
|
|
12
|
+
}) => {
|
|
13
|
+
const extension = typescript ? ".ts" : ".js";
|
|
14
|
+
const outputFiles = [];
|
|
15
|
+
const indexFile = await templateForFile({
|
|
16
|
+
name,
|
|
17
|
+
side: "packages",
|
|
18
|
+
generator: "package",
|
|
19
|
+
templatePath: "index.ts.template",
|
|
20
|
+
templateVars: rest,
|
|
21
|
+
outputPath: path.join(folderName, "src", `index${extension}`)
|
|
22
|
+
});
|
|
23
|
+
const readmeFile = await templateForFile({
|
|
24
|
+
name,
|
|
25
|
+
side: "packages",
|
|
26
|
+
generator: "package",
|
|
27
|
+
templatePath: "README.md.template",
|
|
28
|
+
templateVars: { packageName, ...rest },
|
|
29
|
+
outputPath: path.join(folderName, "README.md")
|
|
30
|
+
});
|
|
31
|
+
const packageJsonFile = await templateForFile({
|
|
32
|
+
name,
|
|
33
|
+
side: "packages",
|
|
34
|
+
generator: "package",
|
|
35
|
+
templatePath: "package.json.template",
|
|
36
|
+
templateVars: { packageName, ...rest },
|
|
37
|
+
outputPath: path.join(folderName, "package.json")
|
|
38
|
+
});
|
|
39
|
+
const tsconfigFile = await templateForFile({
|
|
40
|
+
name,
|
|
41
|
+
side: "packages",
|
|
42
|
+
generator: "package",
|
|
43
|
+
templatePath: "tsconfig.json.template",
|
|
44
|
+
templateVars: { packageName, ...rest },
|
|
45
|
+
outputPath: path.join(folderName, "tsconfig.json")
|
|
46
|
+
});
|
|
47
|
+
outputFiles.push(indexFile);
|
|
48
|
+
outputFiles.push(readmeFile);
|
|
49
|
+
outputFiles.push(packageJsonFile);
|
|
50
|
+
outputFiles.push(tsconfigFile);
|
|
51
|
+
if (generateTests) {
|
|
52
|
+
const testFile = await templateForFile({
|
|
53
|
+
name,
|
|
54
|
+
side: "packages",
|
|
55
|
+
generator: "package",
|
|
56
|
+
templatePath: "test.ts.template",
|
|
57
|
+
templateVars: rest,
|
|
58
|
+
outputPath: path.join(folderName, "src", `${fileName}.test${extension}`)
|
|
59
|
+
});
|
|
60
|
+
outputFiles.push(testFile);
|
|
61
|
+
}
|
|
62
|
+
return outputFiles.reduce(async (accP, [outputPath, content]) => {
|
|
63
|
+
const acc = await accP;
|
|
64
|
+
const template = typescript || outputPath.endsWith(".md") || outputPath.endsWith(".json") ? content : await transformTSToJS(outputPath, content);
|
|
65
|
+
return {
|
|
66
|
+
[outputPath]: template,
|
|
67
|
+
...acc
|
|
68
|
+
};
|
|
69
|
+
}, Promise.resolve({}));
|
|
70
|
+
};
|
|
71
|
+
export {
|
|
72
|
+
files
|
|
73
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createHandler, createBuilder } from "../yargsCommandHelpers.js";
|
|
2
|
+
const command = "package <name>";
|
|
3
|
+
const description = "Generate a workspace Package";
|
|
4
|
+
const builder = createBuilder({
|
|
5
|
+
componentName: "package",
|
|
6
|
+
addStories: false
|
|
7
|
+
});
|
|
8
|
+
const handler = createHandler("package");
|
|
9
|
+
export {
|
|
10
|
+
builder,
|
|
11
|
+
command,
|
|
12
|
+
description,
|
|
13
|
+
handler
|
|
14
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { paramCase, camelCase } from "change-case";
|
|
4
|
+
import execa from "execa";
|
|
5
|
+
import { Listr } from "listr2";
|
|
6
|
+
import { terminalLink } from "termi-link";
|
|
7
|
+
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
8
|
+
import { getConfig } from "@cedarjs/project-config";
|
|
9
|
+
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
10
|
+
import c from "../../../lib/colors.js";
|
|
11
|
+
import { getPaths, writeFilesTask } from "../../../lib/index.js";
|
|
12
|
+
import { prepareForRollback } from "../../../lib/rollback.js";
|
|
13
|
+
import { files } from "./filesTask.js";
|
|
14
|
+
function nameVariants(nameArg) {
|
|
15
|
+
const base = path.basename(getPaths().base);
|
|
16
|
+
const [orgName, name] = nameArg.startsWith("@") ? nameArg.slice(1).split("/", 2) : [paramCase(base), nameArg];
|
|
17
|
+
const folderName = paramCase(name);
|
|
18
|
+
const packageName = "@" + paramCase(orgName) + "/" + folderName;
|
|
19
|
+
const fileName = camelCase(name);
|
|
20
|
+
return { name, folderName, packageName, fileName };
|
|
21
|
+
}
|
|
22
|
+
async function updateTsconfig(task) {
|
|
23
|
+
const tsconfigPath = path.join(getPaths().api.base, "tsconfig.json");
|
|
24
|
+
const tsconfig = await fs.promises.readFile(tsconfigPath, "utf8");
|
|
25
|
+
const tsconfigLines = tsconfig.split("\n");
|
|
26
|
+
const moduleLineIndex = tsconfigLines.findIndex(
|
|
27
|
+
(line) => /^\s*"module":\s*"/.test(line)
|
|
28
|
+
);
|
|
29
|
+
const moduleLine = tsconfigLines[moduleLineIndex];
|
|
30
|
+
if (moduleLine.toLowerCase().includes("node20") || // While Cedar doesn't officially endorse the usage of NodeNext, it
|
|
31
|
+
// will still work here, so I won't overwrite it
|
|
32
|
+
moduleLine.toLowerCase().includes("nodenext")) {
|
|
33
|
+
task.skip("tsconfig already up to date");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
tsconfigLines[moduleLineIndex] = moduleLine.replace(
|
|
37
|
+
/":\s*"[\w\d]+"/,
|
|
38
|
+
'": "Node20"'
|
|
39
|
+
);
|
|
40
|
+
await fs.promises.writeFile(tsconfigPath, tsconfigLines.join("\n"));
|
|
41
|
+
}
|
|
42
|
+
async function installAndBuild(folderName) {
|
|
43
|
+
const packagePath = path.join("packages", folderName);
|
|
44
|
+
await execa("yarn", ["install"], { stdio: "inherit", cwd: getPaths().base });
|
|
45
|
+
await execa("yarn", ["build"], { stdio: "inherit", cwd: packagePath });
|
|
46
|
+
}
|
|
47
|
+
const handler = async ({ name, force, ...rest }) => {
|
|
48
|
+
recordTelemetryAttributes({
|
|
49
|
+
command: "generate package",
|
|
50
|
+
force,
|
|
51
|
+
rollback: rest.rollback
|
|
52
|
+
});
|
|
53
|
+
if (name.replaceAll("/", "").length < name.length - 1) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Invalid package name "${name}". Package names can have at most one slash.`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (!getConfig().experimental.packagesWorkspace.enabled) {
|
|
59
|
+
const releaseNotes = terminalLink(
|
|
60
|
+
"release notes",
|
|
61
|
+
"https://github.com/cedarjs/cedar/releases"
|
|
62
|
+
);
|
|
63
|
+
console.error(
|
|
64
|
+
"This is an experimental feature. Please enable it in your redwood.toml file and then run this command again."
|
|
65
|
+
);
|
|
66
|
+
console.error();
|
|
67
|
+
console.error(`See the ${releaseNotes} for instructions on how to enable.`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
let packageFiles = {};
|
|
71
|
+
const tasks = new Listr(
|
|
72
|
+
/** @type {import('listr2').ListrTask<ListrContext>[]} */
|
|
73
|
+
[
|
|
74
|
+
{
|
|
75
|
+
title: "Parsing package name...",
|
|
76
|
+
task: (ctx) => {
|
|
77
|
+
ctx.nameVariants = nameVariants(name);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
title: "Updating workspace config...",
|
|
82
|
+
task: async (ctx, task) => {
|
|
83
|
+
const rootPackageJsonPath = path.join(getPaths().base, "package.json");
|
|
84
|
+
const packageJson = JSON.parse(
|
|
85
|
+
await fs.promises.readFile(rootPackageJsonPath, "utf8")
|
|
86
|
+
);
|
|
87
|
+
if (!Array.isArray(packageJson.workspaces)) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
"Invalid workspace config in " + rootPackageJsonPath
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
const packagePath = `packages/${ctx.nameVariants.folderName}`;
|
|
93
|
+
const hasWildcardPackagesWorkspace = packageJson.workspaces.includes("packages/*");
|
|
94
|
+
const hasNamedPackagesWorkspace = packageJson.workspaces.includes(packagePath);
|
|
95
|
+
const hasOtherNamedPackages = packageJson.workspaces.some(
|
|
96
|
+
(workspace) => workspace.startsWith("packages/") && workspace !== packagePath
|
|
97
|
+
);
|
|
98
|
+
if (hasWildcardPackagesWorkspace || hasNamedPackagesWorkspace) {
|
|
99
|
+
task.skip("Workspaces already configured");
|
|
100
|
+
} else {
|
|
101
|
+
if (hasOtherNamedPackages) {
|
|
102
|
+
packageJson.workspaces.push(packagePath);
|
|
103
|
+
} else {
|
|
104
|
+
packageJson.workspaces.push("packages/*");
|
|
105
|
+
}
|
|
106
|
+
await fs.promises.writeFile(
|
|
107
|
+
rootPackageJsonPath,
|
|
108
|
+
JSON.stringify(packageJson, null, 2)
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
title: "Updating api side tsconfig file...",
|
|
115
|
+
task: (_ctx, task) => updateTsconfig(task)
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
title: "Generating package files...",
|
|
119
|
+
task: async (ctx) => {
|
|
120
|
+
packageFiles = await files({ ...ctx.nameVariants, ...rest });
|
|
121
|
+
return writeFilesTask(packageFiles, { overwriteExisting: force });
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
title: "Installing and building...",
|
|
126
|
+
task: (ctx) => installAndBuild(ctx.nameVariants.folderName)
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
title: "Cleaning up...",
|
|
130
|
+
task: () => {
|
|
131
|
+
execa.sync("yarn", [
|
|
132
|
+
"eslint",
|
|
133
|
+
"--fix",
|
|
134
|
+
"--config",
|
|
135
|
+
`${getPaths().base}/node_modules/@cedarjs/eslint-config/index.js`,
|
|
136
|
+
...Object.keys(packageFiles)
|
|
137
|
+
]);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
{ rendererOptions: { collapseSubtasks: false }, exitOnError: true }
|
|
142
|
+
);
|
|
143
|
+
try {
|
|
144
|
+
if (rest.rollback && !force) {
|
|
145
|
+
prepareForRollback(tasks);
|
|
146
|
+
}
|
|
147
|
+
await tasks.run();
|
|
148
|
+
} catch (e) {
|
|
149
|
+
errorTelemetry(process.argv, e.message);
|
|
150
|
+
console.error(c.error(e.message));
|
|
151
|
+
process.exit(e?.exitCode || 1);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
export {
|
|
155
|
+
handler,
|
|
156
|
+
nameVariants,
|
|
157
|
+
updateTsconfig
|
|
158
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Shared Package '${packageName}'
|
|
2
|
+
|
|
3
|
+
Use code in this package by adding it to the dependencies on the side you want
|
|
4
|
+
to use it, with the special `workspace:*` version. After that you can import it
|
|
5
|
+
into your code:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"${packageName}": "workspace:*"
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import { ${camelName} } from '${packageName}';
|
|
15
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "${packageName}",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"watch": "tsc --watch"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@cedarjs/testing": "2.2.1",
|
|
13
|
+
"typescript": "5.9.3"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ScenarioData } from '@cedarjs/testing/api'
|
|
2
|
+
|
|
3
|
+
export const standard = defineScenario({
|
|
4
|
+
// Define the "fixture" to write into your test database here
|
|
5
|
+
// See guide: https://cedarjs.com/docs/testing#scenarios
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
export type StandardScenario = ScenarioData<unknown>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"composite": true,
|
|
4
|
+
"target": "ES2023",
|
|
5
|
+
"module": "Node20",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"baseUrl": ".",
|
|
9
|
+
"rootDir": "src",
|
|
10
|
+
"outDir": "dist",
|
|
11
|
+
"sourceMap": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
},
|
|
15
|
+
"include": ["src"],
|
|
16
|
+
}
|
|
@@ -52,20 +52,21 @@ const templateForFile = async ({
|
|
|
52
52
|
templatePath,
|
|
53
53
|
templateVars
|
|
54
54
|
}) => {
|
|
55
|
-
const basePath = getPaths()[side][sidePathSection];
|
|
55
|
+
const basePath = sidePathSection ? getPaths()[side][sidePathSection] : getPaths()[side];
|
|
56
56
|
const fullOutputPath = path.join(basePath, outputPath);
|
|
57
57
|
const fullTemplatePath = customOrDefaultTemplatePath({
|
|
58
58
|
generator,
|
|
59
59
|
templatePath,
|
|
60
60
|
side
|
|
61
61
|
});
|
|
62
|
-
const
|
|
62
|
+
const mergedTemplateVars = {
|
|
63
63
|
name,
|
|
64
64
|
outputPath: ensurePosixPath(
|
|
65
65
|
`./${path.relative(getPaths().base, fullOutputPath)}`
|
|
66
66
|
),
|
|
67
67
|
...templateVars
|
|
68
|
-
}
|
|
68
|
+
};
|
|
69
|
+
const content = await generateTemplate(fullTemplatePath, mergedTemplateVars);
|
|
69
70
|
return [fullOutputPath, content];
|
|
70
71
|
};
|
|
71
72
|
const templateForComponentFile = async ({
|
|
@@ -11,6 +11,7 @@ import * as generateJob from "./generate/job/job.js";
|
|
|
11
11
|
import * as generateLayout from "./generate/layout/layout.js";
|
|
12
12
|
import * as generateModel from "./generate/model/model.js";
|
|
13
13
|
import * as generateOgImage from "./generate/ogImage/ogImage.js";
|
|
14
|
+
import * as generatePackage from "./generate/package/package.js";
|
|
14
15
|
import * as generatePage from "./generate/page/page.js";
|
|
15
16
|
import * as generateRealtime from "./generate/realtime/realtime.js";
|
|
16
17
|
import * as generateScaffold from "./generate/scaffold/scaffold.js";
|
|
@@ -28,7 +29,7 @@ const builder = (yargs) => yargs.command("types", "Generate supplementary code",
|
|
|
28
29
|
} catch (error) {
|
|
29
30
|
process.exitCode = error.exitCode ?? 1;
|
|
30
31
|
}
|
|
31
|
-
}).command(generateCell).command(generateComponent).command(generateDataMigration).command(generateDbAuth).command(generateDirective).command(generateFunction).command(generateJob).command(generateLayout).command(generateModel).command(generateOgImage).command(generatePage).command(generateRealtime).command(generateScaffold).command(generateScript).command(generateSdl).command(generateSecret).command(generateService).demandCommand().epilogue(
|
|
32
|
+
}).command(generateCell).command(generateComponent).command(generateDataMigration).command(generateDbAuth).command(generateDirective).command(generateFunction).command(generateJob).command(generateLayout).command(generateModel).command(generateOgImage).command(generatePackage).command(generatePage).command(generateRealtime).command(generateScaffold).command(generateScript).command(generateSdl).command(generateSecret).command(generateService).demandCommand().epilogue(
|
|
32
33
|
`Also see the ${terminalLink(
|
|
33
34
|
"CedarJS CLI Reference",
|
|
34
35
|
"https://cedarjs.com/docs/cli-commands#generate-alias-g"
|
|
@@ -6,7 +6,8 @@ import { getPaths } from "../../../lib/index.js";
|
|
|
6
6
|
const SIDE_MAP = {
|
|
7
7
|
web: ["cell", "component", "layout", "page", "scaffold"],
|
|
8
8
|
api: ["function", "sdl", "service"],
|
|
9
|
-
scripts: ["script"]
|
|
9
|
+
scripts: ["script"],
|
|
10
|
+
packages: ["package"]
|
|
10
11
|
};
|
|
11
12
|
const copyGenerator = (name, { force }) => {
|
|
12
13
|
const side = Object.keys(SIDE_MAP).find((key) => SIDE_MAP[key].includes(name));
|
package/dist/lib/test.js
CHANGED
|
@@ -45,6 +45,7 @@ vi.mock("@cedarjs/project-config", async (importOriginal) => {
|
|
|
45
45
|
generators: path.join(BASE_PATH, "./web/generators")
|
|
46
46
|
},
|
|
47
47
|
scripts: path.join(BASE_PATH, "scripts"),
|
|
48
|
+
packages: path.join(BASE_PATH, "packages"),
|
|
48
49
|
generatorTemplates: path.join(BASE_PATH, "generatorTemplates"),
|
|
49
50
|
generated: {
|
|
50
51
|
base: path.join(BASE_PATH, ".redwood"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/cli",
|
|
3
|
-
"version": "1.0.0-canary.
|
|
3
|
+
"version": "1.0.0-canary.13103+4239492c8",
|
|
4
4
|
"description": "The CedarJS Command Line",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@babel/preset-typescript": "7.28.5",
|
|
34
34
|
"@babel/runtime-corejs3": "7.28.4",
|
|
35
|
-
"@cedarjs/api-server": "1.0.0-canary.
|
|
36
|
-
"@cedarjs/cli-helpers": "1.0.0-canary.
|
|
37
|
-
"@cedarjs/fastify-web": "1.0.0-canary.
|
|
38
|
-
"@cedarjs/internal": "1.0.0-canary.
|
|
39
|
-
"@cedarjs/prerender": "1.0.0-canary.
|
|
40
|
-
"@cedarjs/project-config": "1.0.0-canary.
|
|
41
|
-
"@cedarjs/structure": "1.0.0-canary.
|
|
42
|
-
"@cedarjs/telemetry": "1.0.0-canary.
|
|
43
|
-
"@cedarjs/web-server": "1.0.0-canary.
|
|
35
|
+
"@cedarjs/api-server": "1.0.0-canary.13103",
|
|
36
|
+
"@cedarjs/cli-helpers": "1.0.0-canary.13103",
|
|
37
|
+
"@cedarjs/fastify-web": "1.0.0-canary.13103",
|
|
38
|
+
"@cedarjs/internal": "1.0.0-canary.13103",
|
|
39
|
+
"@cedarjs/prerender": "1.0.0-canary.13103",
|
|
40
|
+
"@cedarjs/project-config": "1.0.0-canary.13103",
|
|
41
|
+
"@cedarjs/structure": "1.0.0-canary.13103",
|
|
42
|
+
"@cedarjs/telemetry": "1.0.0-canary.13103",
|
|
43
|
+
"@cedarjs/web-server": "1.0.0-canary.13103",
|
|
44
44
|
"@listr2/prompt-adapter-enquirer": "2.0.16",
|
|
45
45
|
"@opentelemetry/api": "1.8.0",
|
|
46
46
|
"@opentelemetry/core": "1.22.0",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"publishConfig": {
|
|
103
103
|
"access": "public"
|
|
104
104
|
},
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "4239492c87fd30f05cf9e57a5ab4c95f117cbdfa"
|
|
106
106
|
}
|