@positronic/template-new-project 0.0.2 → 0.0.4

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/index.js CHANGED
@@ -53,9 +53,9 @@ module.exports = {
53
53
  ],
54
54
  setup: async ctx => {
55
55
  const devRootPath = process.env.POSITRONIC_LOCAL_PATH;
56
- let coreVersion = 'latest';
57
- let cloudflareVersion = 'latest';
58
- let clientVercelVersion = 'latest';
56
+ let coreVersion = '^0.0.3';
57
+ let cloudflareVersion = '^0.0.3';
58
+ let clientVercelVersion = '^0.0.3';
59
59
 
60
60
  // Map backend selection to package names
61
61
  const backendPackageMap = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@positronic/template-new-project",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -12,6 +12,11 @@
12
12
  },
13
13
  "author": "",
14
14
  "license": "MIT",
15
+ "files": [
16
+ "index.js",
17
+ "package.json",
18
+ "template"
19
+ ],
15
20
  "devDependencies": {
16
21
  "caz": "^2.0.0"
17
22
  }
@@ -1,8 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npm test)"
5
- ],
6
- "deny": []
7
- }
8
- }
package/CLAUDE.md DELETED
@@ -1,215 +0,0 @@
1
- # Maintainer's Guide to the Positronic Project Template & Caz
2
-
3
- This document serves as the complete guide for maintainers of the `@positronic/template-new-project`. It provides a deep dive into the structure of this template, its configuration, and the underlying scaffolding engine, `caz`, that powers it.
4
-
5
- This guide assumes no prior knowledge of the `caz` codebase.
6
-
7
- ## Part 1: The `@positronic/template-new-project`
8
-
9
- This project is a `caz` template. Its sole purpose is to generate new Positronic projects by running a command like `npx @positronic/template-new-project <new-project-name>`.
10
-
11
- ### The Anatomy of the Template
12
-
13
- The template is controlled by its `index.js` file, which defines how `caz` should behave. The actual files to be generated live inside the `template/` directory.
14
-
15
- #### Key Files
16
-
17
- * **`index.js`**: The brain of the template. This is a configuration file that tells `caz` what questions to ask, what logic to run before generating files, and how to prepare the files.
18
- * **`package.json`**: This defines the template itself, including its dependencies like `caz`. Note that the dependencies here are for the *template*, not the *generated project*.
19
- * **`template/`**: This directory contains the skeleton of the project that will be created. Files and filenames here can contain template variables.
20
-
21
- #### The Generation Process at a Glance
22
-
23
- When a user runs this template, `caz` performs the following high-level steps:
24
-
25
- 1. **Prompts**: Asks the user a series of questions defined in `index.js`.
26
- 2. **Setup**: Runs custom logic to process the user's answers and prepare dynamic variables.
27
- 3. **Prepare**: Prepares the list of files to be generated, renaming special files like `_gitignore`.
28
- 4. **Render & Emit**: Copies files from the `template/` directory, injecting variables and processing logic.
29
- 5. **Install & Initialize**: (Optionally) installs dependencies and initializes a Git repository in the new project.
30
-
31
- ### In-Depth Configuration (`index.js`)
32
-
33
- The `index.js` file exports a configuration object that `caz` uses to drive the entire process. Let's break down its key sections.
34
-
35
- #### **1. Prompts (`prompts` array)**
36
-
37
- This array defines the interactive questions `caz` will ask the user.
38
-
39
- * **`name`**: The name of the new project. Defaults to `my-positronic-project`.
40
- * **`backend`**: A selection list for the deployment backend. This is critical as it drives which dependencies and configurations are included. Currently, only 'Cloudflare' is enabled.
41
- * **`install`**: A confirmation to ask whether dependencies should be installed automatically.
42
- * **`pm`**: A selection list for the package manager (npm, pnpm, yarn), which only appears if the user opts to install dependencies.
43
-
44
- #### **2. Pre-Generation Logic (`setup` hook)**
45
-
46
- This asynchronous function runs after the user has answered the prompts but before any files are generated. It's used for complex, dynamic configuration.
47
-
48
- * **Local Development with `POSITRONIC_LOCAL_PATH`**: This is a crucial feature for maintainers. If the `POSITRONIC_LOCAL_PATH` environment variable is set (pointing to the root of a local monorepo), the template will map the `@positronic/*` dependencies to local `file:` paths instead of fetching them from `npm`. This allows for simultaneous development and testing of the core libraries and the template.
49
- * **Backend Package Mapping**: It maps the user's `backend` choice (e.g., 'cloudflare') to a specific npm package name (e.g., `@positronic/cloudflare`).
50
- * **Dynamic Versioning**: It sets the versions for `@positronic/core`, `@positronic/cloudflare`, and `@positronic/client-vercel` to either `'latest'` or a local `file:` path.
51
- * **Installation Control**: It sets `ctx.config.install` to the chosen package manager or `false`, telling `caz` whether to run an installation step later.
52
- * **Context Augmentation**: It adds new properties to `ctx.answers` (like `projectName`, `positronicCoreVersion`, etc.) which can then be used as variables in the template files.
53
-
54
- #### **3. File Preparation (`prepare` hook)**
55
-
56
- This function runs after `caz` has gathered all the template files but before they are rendered and written to disk. It allows for final manipulation of the file list.
57
-
58
- * **Renaming System Files**: It renames `_gitignore` to `.gitignore` and `_env` to `.env`. This is a common pattern to prevent the template's own `.gitignore` or `.env` from affecting the template repository itself.
59
- * **Marking Files as Binary**: It iterates through the files and marks any markdown files in the `docs/` directory as binary. This tells `caz`'s rendering engine to skip them, preventing it from trying to inject template variables into the documentation.
60
-
61
- ### The Template Files (`template/` directory)
62
-
63
- Files within this directory are the blueprint for the generated project. They utilize Lodash template syntax.
64
-
65
- * **Variable Injection**: Simple variables are injected using `<%=...%>`.
66
- * Example from `template/positronic.config.json`: `"projectName": "<%= name %>"`
67
- * **Conditional Logic**: JavaScript logic can be embedded with `<%...%>`. This is used powerfully in `template/package.json` to conditionally include dependencies based on the backend choice.
68
- ```json
69
- "dependencies": {
70
- ...
71
- "@positronic/core": "<%= positronicCoreVersion %>"<% if (backend === 'cloudflare') { %>,
72
- "@positronic/cloudflare": "<%= positronicCloudflareVersion %>"<% } %>
73
- }
74
- ```
75
- * **File Renaming**: `caz` also supports renaming files that contain `{variable}` syntax in their names, though this template does not currently use that feature.
76
-
77
- ***
78
-
79
- ## Part 2: `caz` - The Scaffolding Engine
80
-
81
- `caz` is the engine that interprets and executes our template. Understanding its workflow is key to understanding why the template is built the way it is.
82
-
83
- ### The Core `caz` Workflow (Middleware Chain)
84
-
85
- `caz` processes a project in a strict, sequential order of middleware.
86
-
87
- 1. **`confirm`**: Checks if the target project directory exists. If it's not empty, it prompts the user to either merge, overwrite, or cancel. The `--force` flag bypasses this.
88
- 2. **`resolve`**: Locates the template. It can be a local path (`./my-template`) or a remote repository (`zce/nm`). Remote templates are downloaded and cached in `~/.cache/caz` for offline use and speed.
89
- 3. **`load`**: Loads the template's configuration (`index.js`). **Crucially, it also runs `npm install --production` inside the template's directory**, installing any `dependencies` listed in the template's `package.json`.
90
- 4. **`inquire`**: Presents the interactive prompts from the `prompts` array to the user. `caz` automatically provides smart defaults and validation for common fields like `name`, `version`, `author`, `email`, and `url` by reading system `.npmrc` and `.gitconfig` files.
91
- 5. **`setup`**: Executes the `setup` hook from the template config, as described above.
92
- 6. **`prepare`**: Reads all files from the `source` directory (`template/` by default). It applies any `filters` defined in the config to conditionally exclude files. After this, it runs the `prepare` hook.
93
- 7. **`rename`**: Scans filenames for `{variable}` patterns and renames them based on user answers.
94
- 8. **`render`**: Scans the content of all non-binary files for template syntax (`<%=...%>` or `${...}`) and renders them using the user's answers and any configured `helpers`.
95
- 9. **`emit`**: Writes the final, rendered files to the destination project directory. It runs an `emit` hook if one is defined.
96
- 10. **`install`**: If `config.install` is set to `'npm'`, `'yarn'`, or `'pnpm'`, it runs the corresponding installation command in the new project directory.
97
- 11. **`init`**: If `config.init` is `true` (or if a `.gitignore` file is present), it runs `git init`, `git add`, and `git commit`.
98
- 12. **`complete`**: Executes the `complete` hook, which is typically used to print a "getting started" message to the user. If not defined, it prints a default message listing the created files.
99
-
100
- ***
101
-
102
- ## Part 3: Practical Maintainer Tasks
103
-
104
- With this knowledge, here is how to approach common maintenance tasks.
105
-
106
- ### How to Add a New Backend (e.g., "Fly.io")
107
-
108
- 1. **Modify Prompts (`index.js`)**: Add a new choice to the `backend` prompt. You can disable it initially if it's a work in progress.
109
- ```javascript
110
- {
111
- name: 'backend',
112
- type: 'select',
113
- message: 'Select your deployment backend',
114
- choices: [
115
- { title: 'Cloudflare', value: 'cloudflare' },
116
- // ...
117
- { title: 'Fly.io', value: 'fly', disabled: false }, // Add new choice
118
- { title: 'None (Core only)', value: 'none' }
119
- ]
120
- }
121
- ```
122
- 2. **Update Setup Logic (`index.js`)**:
123
- * Add the new backend to `backendPackageMap`.
124
- * Add logic to handle the `file:` path for the new backend when `POSITRONIC_LOCAL_PATH` is set.
125
- * Add the new dependency version to `ctx.answers`.
126
- 3. **Update Template Files (`template/package.json`)**: Add a conditional block to include the new dependency.
127
- ```json
128
- "dependencies": {
129
- ...
130
- <% if (backend === 'fly') { %>
131
- "@positronic/fly": "<%= positronicFlyVersion %>"
132
- <% } %>
133
- }
134
- ```
135
- 4. **Add New Files**: If the new backend requires specific files (e.g., `fly.toml`), add them to the `template/` directory. You can use `filters` in `index.js` to ensure they are only included when that backend is selected.
136
-
137
- ### How to Test Changes Locally
138
-
139
- This is the most important workflow for a maintainer.
140
-
141
- 1. Make your changes to the `template-new-project` repository.
142
- 2. In your terminal, navigate to a directory *outside* of the project.
143
- 3. To simulate a normal user's experience, run:
144
- ```bash
145
- # Use 'npx caz' to run caz without a global install
146
- # Point it to the local directory of your template
147
- # 'my-test-app' is the output directory
148
- npx caz ./path/to/template-new-project my-test-app --force
149
- ```
150
- 4. To test with local monorepo packages, set the environment variable first:
151
- ```bash
152
- # Point to the root of your positronic monorepo
153
- export POSITRONIC_LOCAL_PATH=~/dev/positronic
154
-
155
- npx caz ./path/to/template-new-project my-local-test-app --force
156
- ```
157
- 5. Inspect the generated `my-test-app` or `my-local-test-app` directory to ensure the files and `package.json` are correct. The `--force` flag is useful for quickly re-running the command.
158
-
159
- ### Gotcha: Accidental Template Processing
160
-
161
- The `caz` rendering engine is greedy. It scans every non-binary file for its template syntax. If it finds a match, it will attempt to process the *entire file*, which can cause unexpected behavior or break the scaffolding process.
162
-
163
- **Important**: Any file containing text that matches the `<%= ... %>` or `${...}` patterns will be treated as a template and processed by the engine, which can cause errors if the content is not a valid template variable or expression.
164
-
165
- For example, imagine you add a new shell script to the template called `configure.sh`:
166
-
167
- ```sh
168
- #!/bin/bash
169
-
170
- # This script configures the local environment
171
- echo "Setting up for user: ${USER}"
172
- ```
173
-
174
- When `caz` processes this file, it will see `${USER}` and interpret it as a template variable. It will search for a `USER` key in the answers provided by the user during the prompts. If it's not found, the output will likely be `Setting up for user: undefined`, or it could even throw an error, breaking the project generation.
175
-
176
- ### How to Prevent Accidental Processing
177
-
178
- The codebase reveals two ways to handle this, depending on your goal.
179
-
180
- 1. **Escaping the Syntax (The Preferred Method)**
181
-
182
- If you need the literal syntax (like `${USER}`) to appear in the final generated file, you must escape it using the template engine itself. The `caz` documentation (`docs/create-template.md`) explicitly describes this:
183
-
184
- * To output a literal `<%= name %>`, you must write `<%= '\<%= name %\>' %>` in your template file.
185
- * To output a literal `${name}`, you must write `<%= '${name}' %>` in your template file.
186
-
187
- 2. **Marking the File as Binary**
188
-
189
- If a file should be copied verbatim with no processing whatsoever, the solution is to instruct `caz` to treat it as a binary file. The renderer explicitly skips binary files.
190
-
191
- The `@positronic/template-new-project` template already does this for its documentation files as a preventative measure. You can add a similar rule in the `prepare` hook within `index.js`:
192
-
193
- ```javascript
194
- // in index.js
195
- prepare: async ctx => {
196
- // ... existing prepare logic ...
197
-
198
- // Add a rule to treat all .sh files as binary
199
- ctx.files.forEach(file => {
200
- if (file.path.endsWith('.sh')) {
201
- // This is a made-up property for the example, but it would
202
- // need to be supported by caz's `isBinary` check.
203
- // A more robust way is to check the file contents.
204
- // The key insight is that the prepare hook is where you would
205
- // manipulate files before rendering.
206
- // The current template shows a real example for .md files:
207
- if (file.path.startsWith('docs/') && file.path.endsWith('.md')) {
208
- file.binary = true; // This is a conceptual flag.
209
- // The actual implementation is in caz's `isBinary` check.
210
- }
211
- }
212
- });
213
- }
214
- ```
215
- This tells the `render` step to ignore the file completely, ensuring it is copied as-is.