@react-foundry/create 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (C) 2019-2025 Crown Copyright
4
+ Copyright (C) 2019-2026 Daniel A.C. Martin
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ this software and associated documentation files (the "Software"), to deal in
8
+ the Software without restriction, including without limitation the rights to
9
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10
+ of the Software, and to permit persons to whom the Software is furnished to do
11
+ so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ React Foundry - Create
2
+ ======================
3
+
4
+ A project and prototype initialiser.
5
+
6
+
7
+ Using this package
8
+ ------------------
9
+
10
+ Typically you would not install this package but rather call it with
11
+ `npx` or `npm init`. Similar to `npm init` this will not initialise Git
12
+ or even create a directory for you. We suggest that you set up your
13
+ directory with Git and its remote before you start. For example:
14
+
15
+ ```shell
16
+ mkdir MY-PROJECT
17
+ cd MY-PROJECT
18
+ git init
19
+ git remote add origin https://github.com/MY-USER/MY-PROJECT.git
20
+ ```
21
+
22
+ Once that is set up you can run:
23
+
24
+ ```shell
25
+ npm init @react-foundry
26
+ ```
27
+
28
+ Follow the prompts to set up your new project.
29
+
30
+
31
+ Working on this package
32
+ -----------------------
33
+
34
+ Before working on this package you must install its dependencies using
35
+ the following command:
36
+
37
+ ```shell
38
+ pnpm install
39
+ ```
40
+
41
+
42
+ ### Building
43
+
44
+ ```shell
45
+ npm run build
46
+ ```
47
+
48
+
49
+ ### Clean-up
50
+
51
+ ```shell
52
+ npm run clean
53
+ ```
package/bin/create.mjs ADDED
@@ -0,0 +1,10 @@
1
+ #! /usr/bin/env node
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { runPlop } from '@react-foundry/plop-pack-internal';
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+
8
+ const plopfile = resolve(__dirname, '..', 'plopfile.js');
9
+
10
+ runPlop(plopfile);
@@ -0,0 +1,51 @@
1
+ {
2
+ "scripts": {
3
+ "create": "plop",
4
+ "create:app": "plop app",
5
+ "create:component": "plop component",
6
+ "create:lib": "plop lib",
7
+ "pnpm": "pnpm",
8
+ "pnpm:all": "npm run pnpm -- -r",
9
+ "pnpm:apps": "npm run pnpm:all -- --filter './apps/**'",
10
+ "pnpm:libs": "npm run pnpm:all -- --filter './components/**' --filter './lib/**'",
11
+ "pnpm:storybook": "npm run pnpm:all -- --filter './apps/storybook'",
12
+ "all:build": "npm run pnpm:all -- run build",
13
+ "all:clean": "npm run pnpm:all -- run clean",
14
+ "all:publish": "npm run libs:publish",
15
+ "apps:build": "npm run pnpm:apps -- run build",
16
+ "apps:clean": "npm run pnpm:apps -- run clean",
17
+ "libs:build": "npm run pnpm:libs -- run build",
18
+ "libs:clean": "npm run pnpm:libs -- run clean",
19
+ "libs:publish": "npm run pnpm:libs -- publish --access public",
20
+ "build": "npm run build:storybook",
21
+ "clean": "npm run clean:storybook",
22
+ "pnpm:devPreinstall": "cp pnpm-lock-committed.yaml pnpm-lock.yaml",
23
+ "preversion": "echo 'Warning: This should only be done on a fresh branch from master.'",
24
+ "version": "bash .npm/version.sh",
25
+ "postversion": "echo 'Done. You should now publish (with `npm run all:publish`), push your branch, push your tags and merge to master.'",
26
+ "distclean": "pnpm recursive exec -- rm -rf node_modules && rm -rf node_modules",
27
+ "start": "echo 'Error: This is the root of the monorepo, you should run `cd apps/YOUR_APP && npm start` or run `npm run storybook` to start Storybook.' && false",
28
+ "storybook": "npm run pnpm:storybook -- run dev",
29
+ "build:storybook": "npm run pnpm:storybook -- run build",
30
+ "clean:storybook": "npm run pnpm:storybook -- run clean",
31
+ "chromatic": "npm run pnpm:storybook -- run chromatic",
32
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest --coverage --json --outputFile=.jest-results.json"
33
+ },
34
+ "devDependencies": {
35
+ "@babel/core": "7.28.6",
36
+ "@babel/plugin-transform-export-namespace-from": "7.27.1",
37
+ "@babel/preset-env": "7.28.6",
38
+ "@babel/preset-react": "7.28.5",
39
+ "@babel/preset-typescript": "7.28.5",
40
+ "@react-foundry/plop-pack": "workspace:*",
41
+ "@types/jest": "30.0.0",
42
+ "@types/react": "19.2.9",
43
+ "babel-jest": "30.2.0",
44
+ "jest": "30.2.0",
45
+ "jest-environment-jsdom": "30.2.0",
46
+ "plop": "4.0.5",
47
+ "react-is": "19.2.3",
48
+ "ts-jest": "29.4.6",
49
+ "typescript": "5.9.3"
50
+ }
51
+ }
Binary file
package/dist/skel.tar ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@react-foundry/create",
3
+ "version": "0.1.0",
4
+ "description": "A project and prototype initialiser.",
5
+ "type": "module",
6
+ "main": "plopfile.js",
7
+ "exports": {
8
+ ".": "./plopfile.js"
9
+ },
10
+ "bin": "bin/create.mjs",
11
+ "files": [
12
+ "/bin",
13
+ "/dist",
14
+ "/plopfile.js",
15
+ "/skel"
16
+ ],
17
+ "author": "Daniel A.C. Martin <npm@daniel-martin.co.uk> (http://daniel-martin.co.uk/)",
18
+ "license": "MIT",
19
+ "engines": {
20
+ "node": ">=12.0.0"
21
+ },
22
+ "dependencies": {
23
+ "shelljs": "^0.10.0",
24
+ "@react-foundry/plop-pack": "^0.1.0"
25
+ },
26
+ "devDependencies": {
27
+ "plop": "4.0.5"
28
+ },
29
+ "scripts": {
30
+ "build": "make",
31
+ "clean": "make clean"
32
+ }
33
+ }
package/plopfile.js ADDED
@@ -0,0 +1,241 @@
1
+ import { createRequire } from 'node:module';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import shell from 'shelljs';
5
+
6
+ const require = createRequire(import.meta.url);
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const skelPackage = require('./dist/package.base.json');
9
+ const plopPack = require.resolve('@react-foundry/plop-pack');
10
+
11
+ const cmd = (command, options) => {
12
+ const r = shell.exec(command, { ...options, async: false });
13
+
14
+ if (r.code !== 0) {
15
+ process.exit(r.code);
16
+ }
17
+
18
+ return r;
19
+ };
20
+
21
+ const shortToLong = (name) => (
22
+ name
23
+ .split(/[\-_]+/)
24
+ .map(str => str.charAt(0).toUpperCase() + str.slice(1))
25
+ .join(' ')
26
+ );
27
+
28
+ const defaultKeywords = [
29
+ ];
30
+
31
+ const tarball = resolve(__dirname, 'dist', 'skel.tar');
32
+ const tarballPrototype = resolve(__dirname, 'dist', 'skel-prototype.tar');
33
+
34
+ let defaults = undefined;
35
+
36
+ const init = () => {
37
+ console.log('Welcome.');
38
+ console.log('This generator / initialiser builds on top of the standard `npm init`, which writes to the current working directory; you should do the following before running this tool:');
39
+ console.log(' 1. create a new directory for your project');
40
+ console.log(' 2. set up version control, including hooking up to GitHub or similar service');
41
+ console.log('');
42
+
43
+ // Allow standard `npm init` to do its magic (so we can then build on top)
44
+ console.log('Creating temporary package.json with `npm init`...');
45
+ cmd('npm init -y', { silent: true });
46
+ shell.mv('package.json', 'default.package.json');
47
+ console.log('... Done.');
48
+
49
+ // Parse in the output
50
+ const npmDefaults = require(resolve(process.cwd(), './default.package.json'));
51
+ defaults = {
52
+ ...skelPackage,
53
+ ...npmDefaults,
54
+ scripts: { ...skelPackage.scripts, ...npmDefaults.scripts }
55
+ };
56
+
57
+ // Clean up
58
+ console.log('Cleaning up temporary package.json...');
59
+ shell.rm('default.package.json');
60
+ console.log('... Done.');
61
+
62
+ console.log('');
63
+ };
64
+
65
+ export const plopFile = async (plop) => {
66
+ plop.load(plopPack, undefined, { actionTypes: true, generators: false, helpers: true, partials: false });
67
+
68
+ if (!defaults) {
69
+ init();
70
+ }
71
+
72
+ const patchPackage = file => [
73
+ {
74
+ type: 'modify',
75
+ path: file,
76
+ pattern: /"name": "@.*\/(.+)"/,
77
+ template: '"name": "@{{{name}}}/$1"'
78
+ },
79
+ {
80
+ type: 'modify',
81
+ path: file,
82
+ pattern: /"version": ".*"/,
83
+ template: '"version": "{{{version}}}"'
84
+ },
85
+ {
86
+ type: 'modify',
87
+ path: file,
88
+ pattern: /"license": ".*"/,
89
+ template: '"license": "{{{license}}}"'
90
+ },
91
+ {
92
+ type: 'modify',
93
+ path: file,
94
+ pattern: /"author": ".*"/,
95
+ template: `"author": "${defaults.author}"`
96
+ }
97
+ ];
98
+
99
+ plop.setGenerator('project', {
100
+ description: 'Project',
101
+ prompts: [
102
+ {
103
+ type: 'input',
104
+ name: 'name',
105
+ message: 'Short name (e.g. "my-project"):',
106
+ default: defaults.name || undefined
107
+ },
108
+ {
109
+ type: 'input',
110
+ name: 'fullName',
111
+ message: 'Full name (e.g. "My project"):',
112
+ default: shortToLong(defaults.name) || undefined
113
+ },
114
+ {
115
+ type: 'input',
116
+ name: 'version',
117
+ message: 'Version:',
118
+ default: defaults.version || undefined
119
+ },
120
+ {
121
+ type: 'input',
122
+ name: 'description',
123
+ message: 'Description:',
124
+ default: defaults.description || undefined
125
+ },
126
+ {
127
+ type: 'input',
128
+ name: 'keywords',
129
+ message: 'Keywords:',
130
+ default: [ ...defaultKeywords, ...defaults.keywords ].join(', ') || undefined
131
+ },
132
+ {
133
+ type: 'input',
134
+ name: 'license',
135
+ message: 'License:',
136
+ default: defaults.license || undefined
137
+ }
138
+ ],
139
+ actions: [
140
+ {
141
+ type: 'shell',
142
+ command: `tar -xv --strip-components=1 -f '${tarball}'`
143
+ },
144
+ {
145
+ type: 'copy',
146
+ destination: '.jest-results.json',
147
+ source: 'skel/project/.jest-results.json'
148
+ },
149
+ ...patchPackage('apps/docs/package.json'),
150
+ {
151
+ type: 'write',
152
+ path: 'package.json',
153
+ content: answers => ({
154
+ ...defaults,
155
+ name: answers.name,
156
+ version: answers.version,
157
+ description: answers.description,
158
+ keywords: ( answers.keywords && answers.keywords.split(/,\s*/) ) || undefined,
159
+ license: answers.license
160
+ })
161
+ },
162
+ {
163
+ type: 'add',
164
+ path: 'README.md',
165
+ templateFile: 'skel/project/README.md.hbs'
166
+ },
167
+ {
168
+ type: 'message',
169
+ content: 'Done. (You can install dependencies with `pnpm i` and you may then want to commit with `git add . && git commit -m \'Initial commit\'`.)'
170
+ }
171
+ ]
172
+ });
173
+
174
+ plop.setGenerator('prototype', {
175
+ description: 'Prototype (stand-alone application)',
176
+ prompts: [
177
+ {
178
+ type: 'input',
179
+ name: 'name',
180
+ message: 'Short name (e.g. "my-prototype"):',
181
+ default: defaults.name || undefined
182
+ },
183
+ {
184
+ type: 'input',
185
+ name: 'fullName',
186
+ message: 'Full name (e.g. "My prototype"):',
187
+ default: shortToLong(defaults.name) || undefined
188
+ },
189
+ {
190
+ type: 'input',
191
+ name: 'version',
192
+ message: 'Version:',
193
+ default: defaults.version || undefined
194
+ },
195
+ {
196
+ type: 'input',
197
+ name: 'description',
198
+ message: 'Description:',
199
+ default: defaults.description || undefined
200
+ },
201
+ {
202
+ type: 'input',
203
+ name: 'license',
204
+ message: 'License:',
205
+ default: defaults.license || undefined
206
+ }
207
+ ],
208
+ actions: [
209
+ {
210
+ type: 'shell',
211
+ command: `tar -xv --strip-components=1 -f '${tarballPrototype}'`
212
+ },
213
+ {
214
+ type: 'copy',
215
+ destination: '.github/actions/setup/action.yml',
216
+ source: 'skel/prototype/.github/actions/setup/action.yml'
217
+ },
218
+ {
219
+ type: 'copy',
220
+ destination: '.github/workflows/change-assurance.yml',
221
+ source: 'skel/prototype/.github/workflows/change-assurance.yml'
222
+ },
223
+ {
224
+ type: 'copy',
225
+ destination: '.github/workflows/deploy.yml',
226
+ source: 'skel/prototype/.github/workflows/deploy.yml'
227
+ },
228
+ {
229
+ type: 'merge',
230
+ path: 'package.json',
231
+ templateFile: 'skel/prototype/package.json.hbs'
232
+ },
233
+ {
234
+ type: 'message',
235
+ content: 'Done. (You may want to commit this with `git add . && git commit -m \'Initial commit\'`.)'
236
+ }
237
+ ]
238
+ });
239
+ };
240
+
241
+ export default plopFile;
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1,101 @@
1
+ {{#mdTitle}}{{{fullName}}}{{/mdTitle}}
2
+
3
+ {{{description}}}
4
+
5
+
6
+ Welcome to your new project
7
+ ---------------------------
8
+
9
+ Your project is a monorepo managed via [pnpm]. You can build multiple
10
+ packages from this one repository. Packages come in the following
11
+ varieties:
12
+ - Applications (found in [apps/])
13
+ - Libraries (found in [lib/])
14
+ - Components (found in [components/])
15
+
16
+ **Note:** If you would like add more varieties you can do so by modifying
17
+ your [pnpm-workspace.yaml] and [plopfile.js].
18
+
19
+
20
+ Getting started
21
+ ---------------
22
+
23
+ In order to work on this repository you will need to [install pnpm].
24
+
25
+ Once you have it installed you can pull down NPM dependencies for the
26
+ entire project by running:
27
+
28
+ ```shell
29
+ pnpm install
30
+ ```
31
+
32
+
33
+ Creating a new package
34
+ ----------------------
35
+
36
+ To create a new package, simply run:
37
+ ```shell
38
+ npm run create
39
+ ```
40
+
41
+ This is all orchestrated from your [plopfile.js] so you can modify how
42
+ it works.
43
+
44
+ See: [PLOP]
45
+
46
+
47
+ Installing your packages
48
+ ------------------------
49
+
50
+ You will often need to install the libraries and components that you create into
51
+ each other or into your applications. This can be done as follows:
52
+
53
+ ```shell
54
+ pnpm add --workspace @{{{ dashCase name }}}/your-new-package
55
+ ```
56
+
57
+ Under the hood, this will create a symlink so you need not worry about
58
+ updates. This helps when working on mutliple packages at the same time.
59
+
60
+
61
+ Your documentation
62
+ ------------------
63
+
64
+ Your project comes with its own [documentation application] to allow you
65
+ to easily document your project, including any components that you create.
66
+
67
+ You can run it as you would any other application in your project:
68
+
69
+ ```shell
70
+ cd apps/docs
71
+ npm run dev
72
+ ```
73
+
74
+ We advise that you set up CI to publish your documentation site when
75
+ pushing to the `master` branch.
76
+
77
+
78
+ Continuous Integration
79
+ ----------------------
80
+
81
+ You project comes with configuration files for running Continuous
82
+ Integration (CI) via [GitHub Actions]. These files are found in the
83
+ [.github/workflows] directory.
84
+
85
+ If you add the required secrets to your GitHub repository, it is also
86
+ possible to quickly set up Continuous Deployment (CD) for your
87
+ documentation to [Netlify].
88
+
89
+
90
+ [pnpm]: https://pnpm.io
91
+ [apps/]: ./apps/
92
+ [lib/]: ./lib/
93
+ [components/]: ./components/
94
+ [pnpm-workspace.yaml]: ./pnpm-workspace.yaml
95
+ [plopfile.js]: ./plopfile.js
96
+ [install pnpm]: https://pnpm.io/installation
97
+ [PLOP]: https://plopjs.com/
98
+ [documentation application]: ./apps/docs
99
+ [GitHub Actions]: https://github.com/features/actions
100
+ [.github/workflows]: ./.github/workflows
101
+ [Netlify]: https://www.netlify.com/
@@ -0,0 +1,28 @@
1
+ name: Set-up
2
+ description: Set-up for building, testing and deployment of standalone Catalyse apps
3
+ inputs:
4
+ node:
5
+ description: The version of Node.js to use.
6
+ required: false
7
+ default: 22
8
+ runs:
9
+ using: composite
10
+ steps:
11
+
12
+ - name: Setup Node.js
13
+ uses: actions/setup-node@v6
14
+ with:
15
+ node-version: ${{ inputs.node }}
16
+ cache: 'npm'
17
+
18
+ - name: Cache Cypress.io
19
+ uses: actions/cache@v5
20
+ env:
21
+ cache-hash: ${{ hashFiles('pnpm-lock.yaml') }}
22
+ with:
23
+ path: '~/.cache/Cypress'
24
+ key: cypress-os_${{ runner.os }}-lock_${{ env.cache-hash }}
25
+
26
+ - name: Pull dependencies
27
+ shell: bash
28
+ run: 'if [[ -f "package-lock.json" ]]; then npm ci; else npm install; fi'
@@ -0,0 +1,80 @@
1
+ name: Change assurance
2
+ on:
3
+ pull_request:
4
+ jobs:
5
+ common:
6
+ name: Dependencies, Unit tests
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ node: [ '18', '20', '22' ]
11
+ steps:
12
+
13
+ - name: Check out repository
14
+ uses: actions/checkout@v6
15
+
16
+ - name: Setup
17
+ uses: ./.github/actions/setup
18
+ with:
19
+ node: ${{ matrix.node }}
20
+
21
+ - name: Run unit tests
22
+ uses: ./.github/actions/test-code
23
+
24
+ build-app:
25
+ name: Build application
26
+ needs:
27
+ - common
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+
31
+ - name: Check out repository
32
+ uses: actions/checkout@v6
33
+
34
+ - name: Setup
35
+ uses: ./.github/actions/setup
36
+ with:
37
+ node: 22
38
+
39
+ - name: Build
40
+ uses: ./.github/actions/build-app
41
+
42
+ - name: Save build directory
43
+ uses: actions/upload-artifact@v6
44
+ with:
45
+ name: 'build'
46
+ path: "dist"
47
+ if-no-files-found: error
48
+ retention-days: 2
49
+
50
+ test-app:
51
+ name: Test application
52
+ needs:
53
+ - build-app
54
+ runs-on: ubuntu-latest
55
+ strategy:
56
+ matrix:
57
+ browser: [ 'chromium', 'firefox', 'electron' ]
58
+ steps:
59
+
60
+ - name: Check out repository
61
+ uses: actions/checkout@v6
62
+
63
+ - name: Setup
64
+ uses: ./.github/actions/setup
65
+ with:
66
+ node: 22
67
+
68
+ - name: Download build directory
69
+ uses: actions/download-artifact@v7
70
+ with:
71
+ name: 'build'
72
+ path: "dist"
73
+
74
+ - name: Run functional tests
75
+ uses: './.github/actions/test-app'
76
+ with:
77
+ browser: ${{ matrix.browser }}
78
+ cypress-project-id: ${{ secrets.CYPRESS_PROJECT_ID }}
79
+ cypress-record-key: ${{ secrets.CYPRESS_RECORD_KEY }}
80
+ node: ${{ matrix.node }}
@@ -0,0 +1,4 @@
1
+ name: Deploy
2
+ on:
3
+ push:
4
+ jobs:
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "{{{name}}}",
3
+ "version": "{{{version}}}",
4
+ "description": "{{{description}}}",
5
+ "license": "{{{license}}}"
6
+ }