@friggframework/devtools 2.0.0--canary.663.9683f8b.0 → 2.0.0--canary.639.4058469.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.
Files changed (41) hide show
  1. package/frigg-cli/README.md +77 -30
  2. package/frigg-cli/__tests__/unit/commands/generate-iam.test.js +18 -0
  3. package/frigg-cli/__tests__/unit/commands/init.test.js +688 -0
  4. package/frigg-cli/__tests__/unit/commands/install.test.js +594 -341
  5. package/frigg-cli/generate-command/index.js +1 -0
  6. package/frigg-cli/generate-iam-command.js +1 -0
  7. package/frigg-cli/index.js +9 -4
  8. package/frigg-cli/init-command/backend-first-handler.js +397 -554
  9. package/frigg-cli/init-command/deployment-modes.js +7 -0
  10. package/frigg-cli/init-command/index.js +82 -35
  11. package/frigg-cli/init-command/safe-path.js +58 -0
  12. package/frigg-cli/init-command/scaffold-dependencies.js +202 -0
  13. package/frigg-cli/install-command/app-definition.js +174 -0
  14. package/frigg-cli/install-command/commit-changes.js +40 -8
  15. package/frigg-cli/install-command/environment-variables.js +15 -0
  16. package/frigg-cli/install-command/index.js +96 -21
  17. package/frigg-cli/install-command/install-package.js +77 -4
  18. package/frigg-cli/install-command/integration-file.js +20 -11
  19. package/frigg-cli/install-command/resolve-module.js +69 -0
  20. package/frigg-cli/install-command/template.js +102 -75
  21. package/frigg-cli/install-command/validate-package.js +36 -4
  22. package/frigg-cli/package.json +1 -1
  23. package/frigg-cli/templates/backend/README.md +267 -0
  24. package/frigg-cli/templates/backend/env.example +20 -0
  25. package/frigg-cli/templates/backend/gitignore +10 -0
  26. package/frigg-cli/templates/backend/index.js +114 -0
  27. package/frigg-cli/templates/backend/infrastructure.js +20 -0
  28. package/frigg-cli/test/init-command.test.js +9 -2
  29. package/infrastructure/README.md +2 -4
  30. package/infrastructure/__tests__/scaffold-default-infrastructure.test.js +148 -0
  31. package/infrastructure/docs/POSTGRES-CONFIGURATION.md +21 -1
  32. package/infrastructure/domains/database/aurora-builder.js +13 -2
  33. package/infrastructure/domains/database/aurora-builder.test.js +22 -0
  34. package/infrastructure/domains/parameters/offload-utils.js +0 -1
  35. package/infrastructure/domains/security/iam-generator.js +112 -5
  36. package/infrastructure/domains/security/iam-generator.test.js +94 -0
  37. package/infrastructure/domains/shared/environment-builder.js +1 -12
  38. package/infrastructure/domains/shared/environment-builder.test.js +0 -20
  39. package/infrastructure/domains/shared/utilities/base-definition-factory.js +7 -2
  40. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +21 -0
  41. package/package.json +10 -8
@@ -10,29 +10,68 @@ The Frigg CLI provides tools for building, deploying, and managing serverless in
10
10
 
11
11
  ### Core Commands
12
12
 
13
- #### `frigg init [options]`
13
+ #### `frigg init [projectName] [options]`
14
14
 
15
- **Status:** To be documented (command may not be merged yet)
16
-
17
- Initialize a new Frigg application with scaffolding and configuration.
15
+ Scaffold a new Frigg backend application that installs and runs out of the box.
18
16
 
19
17
  **Usage:**
18
+
20
19
  ```bash
21
- frigg init
22
- frigg init my-app
23
- frigg init --template typescript
20
+ frigg init my-app # interactive (when stdin is a TTY)
21
+ frigg init my-app --yes # accept every default, no prompts
22
+ frigg init my-app --yes --mode standalone --no-install --no-git
23
+ frigg init my-app --mode embedded # add to an existing project (./frigg-integration)
24
+ npx @friggframework/devtools init my-app --yes # without a global install
24
25
  ```
25
26
 
26
27
  **What it does:**
27
- - TBD - Full documentation pending implementation merge
28
+
29
+ 1. Validates the project name and `--mode`, and checks that the target directory is
30
+ empty (only `.git`, `.gitignore`, `README.md` and `.DS_Store` may exist) before asking anything else
31
+ 2. Copies the backend template: `index.js` (app definition, named after the project),
32
+ `infrastructure.js`, `README.md`, `.gitignore`, `.env.example` (also seeded into `.env`)
33
+ 3. Writes `package.json` with:
34
+ - scripts: `start` (`frigg start`), `build` (`frigg build`), `deploy` (`frigg deploy`),
35
+ `db:setup` (`frigg db:setup`), `test` (`jest --passWithNoTests`)
36
+ - dependencies: `@friggframework/core`, `@prisma/client`, `prisma`
37
+ - devDependencies: `@friggframework/devtools`, `@friggframework/serverless-plugin`,
38
+ `osls`, and the serverless plugins the composed definition loads
39
+ - Frigg package versions match the devtools that ran `init` (a prerelease is pinned exactly)
40
+ 4. Validates the generated app definition against the app-definition schema (problems
41
+ are printed as warnings; `frigg start`, `build` and `deploy` do not validate)
42
+ 5. Optionally initializes git and runs `npm install`
43
+ 6. Prints next steps. API modules picked in the interactive prompt are not wired in
44
+ automatically; the next steps list a `frigg install <module>` command for each
45
+
46
+ In `embedded` mode the backend is written to `./frigg-integration` inside the target
47
+ directory, which may already contain your application. Git is not initialized.
28
48
 
29
49
  **Options:**
30
- - TBD
31
50
 
32
- **Example Output:**
33
- - TBD
51
+ - `-n, --name <name>` - Project name (alternative to the positional argument)
52
+ - `-m, --mode <mode>` - `standalone` (default) or `embedded`
53
+ - `-y, --yes` - Accept the default for every prompt. Implied when stdin is not a TTY
54
+ - `--no-install` - Skip `npm install`
55
+ - `--no-git` - Skip `git init` and the initial commit
56
+ - `-f, --force` - Scaffold into a non-empty directory and overwrite an existing `README.md`/`.gitignore`
57
+ - `-v, --verbose` - Verbose output
58
+
59
+ **Next steps after `init`:**
60
+
61
+ ```bash
62
+ cd my-app
63
+ docker run --name frigg-postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:16
64
+ npm run db:setup
65
+ npm start
66
+ ```
34
67
 
35
- > **Note**: This command may be part of an upcoming release. Documentation will be updated once the implementation is merged to the main branch.
68
+ The scaffolded app deploys nothing that bills by the hour, so it costs near $0 while
69
+ idle: no VPC, NAT gateway or database cluster (`vpc: { enable: false }`,
70
+ `database.postgres.management: 'external'`), field-level encryption with a per-stage
71
+ KMS key ($1/month, about $3/month after its first two yearly rotations), 14-day log
72
+ retention, and the app connecting to a PostgreSQL you host through `DATABASE_URL`.
73
+ `frigg deploy` reads `DATABASE_URL` from the shell that runs it, not from `.env`. The
74
+ generated `README.md` lists every resource, the security model and the other options.
36
75
 
37
76
  ---
38
77
 
@@ -47,28 +86,36 @@ frigg install salesforce
47
86
  frigg install stripe
48
87
  ```
49
88
 
89
+ Run it in the app directory (the one with `package.json` and `index.js`).
90
+
50
91
  **What it does:**
51
- - Searches the api-module-library for the specified integration
52
- - Installs the npm package (@friggframework/api-module-{name})
53
- - Adds integration to your app definition
54
- - Configures OAuth flows and webhooks if applicable
55
- - Creates integration-specific environment variable placeholders
92
+ - Searches npm for `@friggframework/api-module-<name>` and lets you pick the
93
+ packages to install (with no terminal to prompt on, it takes the exact match)
94
+ - Runs `npm install` in the app directory. An app on a Frigg 2.x prerelease
95
+ (what `frigg init` scaffolds today) gets the module's `@next` release, because
96
+ most modules' `latest` is still a 1.x release built for Frigg 1.x
97
+ - Resolves the installed module from the app directory and writes
98
+ `src/integrations/<Label>Integration.js`: an `IntegrationBase` subclass whose
99
+ `Definition.modules` wraps the module (an existing file is kept)
100
+ - Registers the class in your app definition: in `index.js` it adds the
101
+ `require` and the first entry of the `integrations` array. When it cannot do
102
+ that safely (no single `integrations: [...]` array literal, or the file does not
103
+ parse) it changes nothing and prints the two lines to add by hand. Older apps
104
+ with a `backend.js` are updated there instead
105
+ - Commits the files it changed (`git commit -- <files>`, so nothing else you have
106
+ staged is included) when the app is in a git repository; otherwise leaves them
107
+ in the working tree
108
+ - Lists the environment variables the module reads (from its `definition.js`)
109
+ that are not in `.env`, and offers to add them when run in a terminal
56
110
 
57
111
  **Options:**
58
- - None currently (could add `--version`, `--registry` in future)
112
+ - None
59
113
 
60
- **Example Output:**
61
- ```
62
- 🔍 Finding integration module: hubspot
63
- ✓ Found @friggframework/api-module-hubspot@2.0.5
64
- 📦 Installing package...
65
- ✓ Package installed successfully
66
- 🔧 Configuring integration in app definition...
67
- ✓ Integration configured
68
- ⚙️ Next steps:
69
- 1. Set HUBSPOT_CLIENT_ID in your environment
70
- 2. Set HUBSPOT_CLIENT_SECRET in your environment
71
- 3. Run 'frigg start' to test locally
114
+ **Example:**
115
+ ```bash
116
+ cd my-app
117
+ npx frigg install hubspot
118
+ # -> src/integrations/HubSpotIntegration.js, listed in index.js's integrations
72
119
  ```
73
120
 
74
121
  ---
@@ -94,4 +94,22 @@ describe('CLI Command: generate-iam', () => {
94
94
  'arn:aws:kms:*:${AWS::AccountId}:key/*'
95
95
  );
96
96
  });
97
+
98
+ it("grants the app's own resources, named after Definition.name", async () => {
99
+ jest.doMock(
100
+ mockAppDefinitionPath,
101
+ () => ({ Definition: { name: 'my-app' } }),
102
+ { virtual: true }
103
+ );
104
+
105
+ await generateIamCommand({});
106
+
107
+ const [, generatedYaml] = fs.writeFile.mock.calls[0];
108
+ expect(generatedYaml).toContain(
109
+ 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/*my-app*/*'
110
+ );
111
+ expect(generatedYaml).toContain(
112
+ 'arn:aws:lambda:*:${AWS::AccountId}:function:*my-app*'
113
+ );
114
+ });
97
115
  });