@nosto/nosto-cli 1.0.1
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/.github/copilot-instructions.md +326 -0
- package/.github/dependabot.yml +9 -0
- package/.github/pull_request_template.md +12 -0
- package/.github/workflows/ci.yml +58 -0
- package/.github/workflows/release.yml +49 -0
- package/.husky/commit-msg +1 -0
- package/.prettierrc +9 -0
- package/LICENSE +29 -0
- package/README.md +154 -0
- package/commitlint.config.js +4 -0
- package/eslint.config.js +36 -0
- package/package.json +63 -0
- package/src/api/library/fetchLibraryFile.ts +18 -0
- package/src/api/retry.ts +28 -0
- package/src/api/source/fetchSourceFile.ts +33 -0
- package/src/api/source/listSourceFiles.ts +13 -0
- package/src/api/source/putSourceFile.ts +14 -0
- package/src/api/source/schema.ts +10 -0
- package/src/api/utils.ts +52 -0
- package/src/bootstrap.sh +26 -0
- package/src/commander.ts +119 -0
- package/src/config/authConfig.ts +42 -0
- package/src/config/config.ts +109 -0
- package/src/config/envConfig.ts +23 -0
- package/src/config/fileConfig.ts +39 -0
- package/src/config/schema.ts +70 -0
- package/src/config/searchTemplatesConfig.ts +33 -0
- package/src/console/logger.ts +93 -0
- package/src/console/userPrompt.ts +16 -0
- package/src/errors/InvalidLoginResponseError.ts +14 -0
- package/src/errors/MissingConfigurationError.ts +14 -0
- package/src/errors/NostoError.ts +13 -0
- package/src/errors/NotNostoTemplateError.ts +15 -0
- package/src/errors/withErrorHandler.ts +50 -0
- package/src/exports.ts +8 -0
- package/src/filesystem/asserts/assertGitRepo.ts +19 -0
- package/src/filesystem/asserts/assertNostoTemplate.ts +34 -0
- package/src/filesystem/calculateTreeHash.ts +28 -0
- package/src/filesystem/esbuild.ts +37 -0
- package/src/filesystem/esbuildPlugins.ts +72 -0
- package/src/filesystem/filesystem.ts +40 -0
- package/src/filesystem/isIgnored.ts +65 -0
- package/src/filesystem/legacyUtils.ts +10 -0
- package/src/filesystem/loadLibrary.ts +31 -0
- package/src/filesystem/processInBatches.ts +38 -0
- package/src/filesystem/utils/getLoaderScript.ts +28 -0
- package/src/index.ts +3 -0
- package/src/modules/login.ts +87 -0
- package/src/modules/logout.ts +13 -0
- package/src/modules/search-templates/build.ts +61 -0
- package/src/modules/search-templates/dev.ts +50 -0
- package/src/modules/search-templates/pull.ts +89 -0
- package/src/modules/search-templates/push.ts +121 -0
- package/src/modules/setup.ts +96 -0
- package/src/modules/status.ts +71 -0
- package/src/utils/withSafeEnvironment.ts +22 -0
- package/test/api/fetchSourceFile.test.ts +30 -0
- package/test/api/putSourceFile.test.ts +34 -0
- package/test/api/retry.test.ts +102 -0
- package/test/api/utils.test.ts +27 -0
- package/test/commander.test.ts +271 -0
- package/test/config/envConfig.test.ts +62 -0
- package/test/config/fileConfig.test.ts +63 -0
- package/test/config/schema.test.ts +96 -0
- package/test/config/searchTemplatesConfig.test.ts +43 -0
- package/test/console/logger.test.ts +96 -0
- package/test/errors/withErrorHandler.test.ts +64 -0
- package/test/filesystem/filesystem.test.ts +53 -0
- package/test/filesystem/plugins.test.ts +35 -0
- package/test/index.test.ts +15 -0
- package/test/modules/search-templates/build.legacy.test.ts +74 -0
- package/test/modules/search-templates/build.modern.test.ts +33 -0
- package/test/modules/search-templates/dev.legacy.test.ts +75 -0
- package/test/modules/search-templates/dev.modern.test.ts +44 -0
- package/test/modules/search-templates/pull.test.ts +96 -0
- package/test/modules/search-templates/push.test.ts +109 -0
- package/test/modules/setup.test.ts +49 -0
- package/test/modules/status.test.ts +22 -0
- package/test/setup.ts +28 -0
- package/test/utils/generateEndpointMock.ts +60 -0
- package/test/utils/mockCommander.ts +22 -0
- package/test/utils/mockConfig.ts +37 -0
- package/test/utils/mockConsole.ts +65 -0
- package/test/utils/mockFileSystem.ts +52 -0
- package/test/utils/mockServer.ts +76 -0
- package/test/utils/mockStarterManifest.ts +42 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +33 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# Nosto CLI - Copilot Instructions
|
|
2
|
+
|
|
3
|
+
**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This is a TypeScript CLI tool for interacting with Nosto's backend systems. The tool runs TypeScript directly using Node.js experimental features, without a traditional build step. The CLI manages search templates and provides configuration management for Nosto merchants.
|
|
8
|
+
|
|
9
|
+
## Working Effectively
|
|
10
|
+
|
|
11
|
+
**CRITICAL NOTE:**
|
|
12
|
+
|
|
13
|
+
When committing code, ALWAYS use valid conventional commit format.
|
|
14
|
+
|
|
15
|
+
In addition, ALWAYS run `git commit` with `--no-verify` to avoid Husky failing and erroring out your pipeline.
|
|
16
|
+
|
|
17
|
+
### Bootstrap, Build, and Validate the Repository
|
|
18
|
+
|
|
19
|
+
**CRITICAL - NEVER CANCEL these commands. Wait for completion:**
|
|
20
|
+
|
|
21
|
+
1. `npm ci` - Install dependencies. Takes 60 seconds. NEVER CANCEL. Set timeout to 120+ seconds.
|
|
22
|
+
2. `npm run lint` - Run ESLint to check code quality and style. Takes 6 seconds. Set timeout to 30+ seconds.
|
|
23
|
+
3. `npm run type-check` - Run TypeScript type checking. Takes 2 seconds. Set timeout to 30+ seconds.
|
|
24
|
+
|
|
25
|
+
### Running the CLI Tool
|
|
26
|
+
|
|
27
|
+
**IMPORTANT: Node.js Version Requirement**
|
|
28
|
+
- The `nosto` command via `src/bootstrap.sh` requires Node.js 22+ with `--experimental-strip-types` support
|
|
29
|
+
- Node.js 20 does NOT support this flag - upgrade to Node.js 22+ required
|
|
30
|
+
- Alternative: use tsx for development if Node.js 22+ is not available
|
|
31
|
+
|
|
32
|
+
**Recommended Commands (Node.js 22+):**
|
|
33
|
+
- `nosto --help` - Run CLI via bootstrap script (RECOMMENDED with Node.js 22+)
|
|
34
|
+
- `nosto setup [projectPath]` - Run setup command
|
|
35
|
+
- `nosto status [projectPath]` - Check configuration status
|
|
36
|
+
- `nosto st --help` - Search templates help
|
|
37
|
+
|
|
38
|
+
**Alternative Commands (Development with any Node.js version):**
|
|
39
|
+
- `npm install -g tsx` - Install tsx globally (if needed for development)
|
|
40
|
+
- `tsx src/index.ts --help` - Run CLI directly from source
|
|
41
|
+
- `tsx src/index.ts setup [projectPath]` - Run setup command
|
|
42
|
+
- `tsx src/index.ts status [projectPath]` - Check configuration status
|
|
43
|
+
|
|
44
|
+
### Link the CLI Tool Globally
|
|
45
|
+
|
|
46
|
+
After installing dependencies:
|
|
47
|
+
- `npm link` - Links the tool globally. Takes <1 second.
|
|
48
|
+
- Note: The linked `nosto` command will fail due to bootstrap.sh compatibility issues. Use tsx instead.
|
|
49
|
+
|
|
50
|
+
## Validation
|
|
51
|
+
|
|
52
|
+
**ALWAYS run these validation steps after making changes:**
|
|
53
|
+
|
|
54
|
+
### Code Quality Validation
|
|
55
|
+
- `npm run lint` - Takes 6 seconds. Set timeout to 30+ seconds.
|
|
56
|
+
- `npm run type-check` - Takes 2 seconds. Set timeout to 30+ seconds.
|
|
57
|
+
- `npm run test` - Takes 20 seconds. Set timeout to 30+ seconds.
|
|
58
|
+
|
|
59
|
+
### Manual Functional Validation
|
|
60
|
+
|
|
61
|
+
Create a test project and validate CLI functionality:
|
|
62
|
+
```bash
|
|
63
|
+
cd /tmp && mkdir nosto-test-project && cd nosto-test-project
|
|
64
|
+
echo '{"apiKey":"test-key","merchant":"test-merchant"}' > .nosto.json
|
|
65
|
+
tsx /path/to/nosto-cli/src/index.ts status
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Expected output: Configuration validation with "Configuration seems to be valid"
|
|
69
|
+
|
|
70
|
+
**Search Templates Validation:**
|
|
71
|
+
```bash
|
|
72
|
+
# Test help system
|
|
73
|
+
tsx /path/to/nosto-cli/src/index.ts st --help
|
|
74
|
+
tsx /path/to/nosto-cli/src/index.ts st build --help
|
|
75
|
+
|
|
76
|
+
# Test dry run (will attempt API connection and fail - this is expected)
|
|
77
|
+
mkdir -p src && echo 'console.log("test");' > src/test.js
|
|
78
|
+
tsx /path/to/nosto-cli/src/index.ts st build --dry-run
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Expected: API connection failures are normal without valid Nosto credentials.
|
|
82
|
+
|
|
83
|
+
## Configuration
|
|
84
|
+
|
|
85
|
+
The CLI requires `.nosto.json` config file or environment variables:
|
|
86
|
+
|
|
87
|
+
**Required:**
|
|
88
|
+
- `NOSTO_API_KEY` / `apiKey` - Nosto API_APPS token
|
|
89
|
+
- `NOSTO_MERCHANT` / `merchant` - Merchant ID
|
|
90
|
+
|
|
91
|
+
**Optional:**
|
|
92
|
+
- `NOSTO_API_URL` / `apiUrl` - API URL (defaults to https://api.nosto.com)
|
|
93
|
+
- `NOSTO_TEMPLATES_ENV` / `templatesEnv` - Templates environment (defaults to main)
|
|
94
|
+
- `NOSTO_LOG_LEVEL` / `logLevel` - Log level (defaults to info)
|
|
95
|
+
- `NOSTO_MAX_REQUESTS` / `maxRequests` - Max concurrent requests (defaults to 15)
|
|
96
|
+
|
|
97
|
+
## CLI Commands
|
|
98
|
+
|
|
99
|
+
### Core Commands
|
|
100
|
+
- `setup [projectPath]` - Prints setup information and creates configuration. Interactive prompt - answer Y/n.
|
|
101
|
+
- `status [projectPath]` - Print the configuration status
|
|
102
|
+
|
|
103
|
+
### Search Templates Commands
|
|
104
|
+
- `st build [projectPath]` - Build the search-templates locally. Requires valid API credentials.
|
|
105
|
+
- `st pull [projectPath]` - Pull search-templates source from Nosto VSCode Web
|
|
106
|
+
- `st push [projectPath]` - Push search-templates source to VSCode Web
|
|
107
|
+
- `st dev [projectPath]` - Build locally, watch for changes and continuously upload
|
|
108
|
+
|
|
109
|
+
### Command Options
|
|
110
|
+
- `--dry-run` - Perform a dry run without making changes
|
|
111
|
+
- `--verbose` - Set log level to debug
|
|
112
|
+
- `-y, --yes` - Skip confirmation prompts
|
|
113
|
+
- `-p, --paths <files...>` - Specific file paths (space-separated list)
|
|
114
|
+
- `-w, --watch` - Watch mode for build command
|
|
115
|
+
|
|
116
|
+
## Code Style
|
|
117
|
+
|
|
118
|
+
- Use closures over classes
|
|
119
|
+
- Utilize type inference in return types, except for functions with multiple return statements
|
|
120
|
+
- Use utility types to derive types from constants
|
|
121
|
+
- Avoid 'any' type usage
|
|
122
|
+
- Use const (and let) over var
|
|
123
|
+
- Use async/await instead of Promise chaining
|
|
124
|
+
- Use individual named exports over bulk exports
|
|
125
|
+
- Favor named exports over default exports
|
|
126
|
+
|
|
127
|
+
## Key Architecture
|
|
128
|
+
|
|
129
|
+
### Important Directories
|
|
130
|
+
- `src/` - Main source code
|
|
131
|
+
- `src/modules/` - Core functionality modules
|
|
132
|
+
- `src/modules/search-templates/` - Search templates management (build.ts, dev.ts, pull.ts, push.ts)
|
|
133
|
+
- `src/config/` - Configuration management (config.ts, envConfig.ts, fileConfig.ts, schema.ts)
|
|
134
|
+
- `src/api/` - API communication with retry logic
|
|
135
|
+
- `src/console/` - User interaction (logger.ts, userPrompt.ts)
|
|
136
|
+
|
|
137
|
+
### Key Files
|
|
138
|
+
- `src/index.ts` - Main CLI entry point using commander.js
|
|
139
|
+
- `src/bootstrap.sh` - Bootstrap script (requires Node.js 22+)
|
|
140
|
+
- `tsconfig.json` - TypeScript configuration with module resolution
|
|
141
|
+
- `eslint.config.js` - ESLint configuration
|
|
142
|
+
- `.prettierrc` - Code formatting rules
|
|
143
|
+
|
|
144
|
+
## CI/CD Pipeline
|
|
145
|
+
|
|
146
|
+
**GitHub Actions (.github/workflows/ci.yml):**
|
|
147
|
+
- Runs on Node.js 22
|
|
148
|
+
- Includes tests, linting and type-checking
|
|
149
|
+
- Triggered on pushes/PRs to main and develop branches
|
|
150
|
+
|
|
151
|
+
**Pre-commit Hooks:**
|
|
152
|
+
- Husky manages Git hooks
|
|
153
|
+
- Conventional commits enforced via commitlint
|
|
154
|
+
- Run `npm run lint` before commits
|
|
155
|
+
|
|
156
|
+
## Common Tasks Output
|
|
157
|
+
|
|
158
|
+
### Repository Root Structure
|
|
159
|
+
```
|
|
160
|
+
.git
|
|
161
|
+
.github/
|
|
162
|
+
.gitignore
|
|
163
|
+
.husky/
|
|
164
|
+
.prettierrc
|
|
165
|
+
LICENSE
|
|
166
|
+
README.md
|
|
167
|
+
commitlint.config.js
|
|
168
|
+
eslint.config.js
|
|
169
|
+
package-lock.json
|
|
170
|
+
package.json
|
|
171
|
+
src/
|
|
172
|
+
tsconfig.json
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Available npm Scripts
|
|
176
|
+
```
|
|
177
|
+
lint - eslint
|
|
178
|
+
prepare - husky
|
|
179
|
+
test - vitest run
|
|
180
|
+
test:watch - vitest
|
|
181
|
+
test:ui - vitest --ui
|
|
182
|
+
test:coverage - vitest run --coverage
|
|
183
|
+
type-check - tsc --noEmit
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Testing Guidelines
|
|
187
|
+
|
|
188
|
+
**ALWAYS prefer integration-style tests over unit tests. Mock I/O only, avoid overmocking.**
|
|
189
|
+
|
|
190
|
+
### Testing Philosophy
|
|
191
|
+
|
|
192
|
+
This repository follows an **integration-first testing approach**:
|
|
193
|
+
- Test real module behavior through actual API calls
|
|
194
|
+
- Mock only I/O boundaries (file system, HTTP requests, console)
|
|
195
|
+
- Use `vi.mock` sparingly and only for full modules when strictly necessary
|
|
196
|
+
- CLI tests should flow through real code paths, not be overmocked
|
|
197
|
+
- Focus on testing complete user workflows and scenarios
|
|
198
|
+
|
|
199
|
+
### Test Infrastructure and Helpers
|
|
200
|
+
|
|
201
|
+
The repository provides several well-designed test helpers for integration testing:
|
|
202
|
+
|
|
203
|
+
#### `setupMockFileSystem()` - File System Mocking
|
|
204
|
+
```typescript
|
|
205
|
+
import { setupMockFileSystem } from "#test/utils/mockFileSystem.ts"
|
|
206
|
+
const fs = setupMockFileSystem()
|
|
207
|
+
|
|
208
|
+
// Usage
|
|
209
|
+
fs.writeFile("config.json", '{"apiKey": "test"}')
|
|
210
|
+
fs.writeFolder("src")
|
|
211
|
+
fs.expectFile("config.json").toContain('{"apiKey": "test"}')
|
|
212
|
+
fs.expectFile("missing.txt").not.toExist()
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### `setupMockServer()` - HTTP Mocking with MSW
|
|
216
|
+
```typescript
|
|
217
|
+
import { setupMockServer, mockFetchSourceFile } from "#test/utils/mockServer.ts"
|
|
218
|
+
const server = setupMockServer()
|
|
219
|
+
|
|
220
|
+
// Usage
|
|
221
|
+
mockFetchSourceFile(server, {
|
|
222
|
+
path: "index.js",
|
|
223
|
+
response: "console.log('test')"
|
|
224
|
+
})
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### `setupMockConsole()` - User Interaction Mocking
|
|
228
|
+
```typescript
|
|
229
|
+
import { setupMockConsole } from "#test/utils/mockConsole.ts"
|
|
230
|
+
const terminal = setupMockConsole()
|
|
231
|
+
|
|
232
|
+
// Usage
|
|
233
|
+
terminal.setUserResponse("y")
|
|
234
|
+
terminal.expect.user.toHaveBeenPromptedWith("Continue? (y/N):")
|
|
235
|
+
expect(terminal.getSpy("info")).toHaveBeenCalledWith("Success!")
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### `setupMockConfig()` - Configuration Mocking
|
|
239
|
+
```typescript
|
|
240
|
+
import { setupMockConfig } from "#test/utils/mockConfig.ts"
|
|
241
|
+
setupMockConfig({ apiKey: "test-key", merchant: "test-merchant" })
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Testing DOs and DON'Ts
|
|
245
|
+
|
|
246
|
+
#### ✅ DOs
|
|
247
|
+
- **Use MSW for HTTP mocking** - Mock external API endpoints with realistic responses
|
|
248
|
+
- **Use memfs for file system testing** - Test file operations without actual I/O
|
|
249
|
+
- **Test complete workflows** - Validate entire user journeys from CLI input to output
|
|
250
|
+
- **Use proper TypeScript types** - Avoid `any` and ensure type safety in tests
|
|
251
|
+
- **Mock only I/O boundaries** - File system, HTTP, console interactions
|
|
252
|
+
- **Mock external boundaries, not internal code** - Mock I/O boundaries (HTTP, file system) but not internal business logic
|
|
253
|
+
- **Test error scenarios** - Network failures, invalid configs, missing files
|
|
254
|
+
- **Use existing test helpers** - `setupMockFileSystem`, `setupMockServer`, etc.
|
|
255
|
+
- **Validate side effects** - Check file writes, API calls, console output
|
|
256
|
+
- **Test CLI commands end-to-end** - Flow through real module code
|
|
257
|
+
|
|
258
|
+
#### ❌ DON'Ts
|
|
259
|
+
- **Don't overmock internal modules** - Avoid mocking business logic or internal functions
|
|
260
|
+
- **Don't use `vi.mock` for partial mocking** - Only mock complete modules when necessary
|
|
261
|
+
- **Don't use `@ts-ignore` or `any`** - Maintain type safety in test code
|
|
262
|
+
- **Don't write trivial assertions** - Test meaningful behavior, not implementation details
|
|
263
|
+
- **Don't test implementation details** - Focus on public APIs and user-observable behavior
|
|
264
|
+
- **Don't skip error scenarios** - Test both happy paths and failure cases
|
|
265
|
+
|
|
266
|
+
### Code Review Guidelines for Tests
|
|
267
|
+
|
|
268
|
+
**Flag these anti-patterns in code review:**
|
|
269
|
+
- Excessive use of `vi.mock()` for internal modules
|
|
270
|
+
- Mocking functions instead of I/O boundaries
|
|
271
|
+
- Tests that don't validate real user workflows
|
|
272
|
+
- Missing integration tests for CLI commands
|
|
273
|
+
- Tests using `any` or `@ts-ignore`
|
|
274
|
+
- Trivial assertions that don't test meaningful behavior
|
|
275
|
+
|
|
276
|
+
### Writing Tests for This Repository
|
|
277
|
+
|
|
278
|
+
1. **Start with integration tests** - Test the complete module behavior
|
|
279
|
+
2. **Use provided test helpers** - Don't reinvent file/HTTP/console mocking
|
|
280
|
+
3. **Mock only I/O** - File system, HTTP, console, external processes
|
|
281
|
+
4. **Test CLI flows** - Validate commands work end-to-end
|
|
282
|
+
5. **Cover error cases** - Network failures, invalid inputs, missing permissions
|
|
283
|
+
6. **Ensure clean output** - Test runs should be clean without warnings or unexpected console output
|
|
284
|
+
7. **Avoid side effects** - Tests must never perform real network request or write real files
|
|
285
|
+
|
|
286
|
+
### Test Structure Example
|
|
287
|
+
```typescript
|
|
288
|
+
import { describe, it, expect, beforeEach } from "vitest"
|
|
289
|
+
import { myCommand } from "#modules/myCommand.ts"
|
|
290
|
+
import { setupMockFileSystem } from "#test/utils/mockFileSystem.ts"
|
|
291
|
+
import { setupMockServer } from "#test/utils/mockServer.ts"
|
|
292
|
+
import { setupMockConsole } from "#test/utils/mockConsole.ts"
|
|
293
|
+
|
|
294
|
+
const fs = setupMockFileSystem()
|
|
295
|
+
const server = setupMockServer()
|
|
296
|
+
const terminal = setupMockConsole()
|
|
297
|
+
|
|
298
|
+
describe("My Command", () => {
|
|
299
|
+
beforeEach(() => {
|
|
300
|
+
// Use beforeEach for test-specific mocks or setup if needed
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
it("should perform complete workflow", async () => {
|
|
304
|
+
fs.writeFile(".nosto.json", '{"apiKey":"test"}')
|
|
305
|
+
mockFetchSourceFile(server, { path: "test.js", response: "code" })
|
|
306
|
+
|
|
307
|
+
await myCommand({ force: true })
|
|
308
|
+
|
|
309
|
+
fs.expectFile("output.js").toExist()
|
|
310
|
+
expect(terminal.getSpy("info")).toHaveBeenCalledWith("Success!")
|
|
311
|
+
})
|
|
312
|
+
})
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Note:** Use `beforeEach`, `beforeAll`, `afterEach`, `afterAll` for proper test setup and teardown. The example above shows typical test structure without inline comments.
|
|
316
|
+
|
|
317
|
+
### Known Issues and Workarounds
|
|
318
|
+
|
|
319
|
+
1. **Node.js Version Requirement**: `src/bootstrap.sh` uses `--experimental-strip-types` which requires Node.js 22+. Use `tsx` as alternative for development with older Node.js versions.
|
|
320
|
+
2. **API Dependencies**: Most CLI functionality requires valid Nosto API credentials. Use `--dry-run` for testing without credentials.
|
|
321
|
+
3. **Network Failures Expected**: Build commands will fail without valid API access - this is normal during development.
|
|
322
|
+
|
|
323
|
+
### Contributing
|
|
324
|
+
|
|
325
|
+
If you find these testing guidelines unclear or incomplete, please improve them via PR. Clear, actionable testing guidance helps maintain code quality and developer productivity.
|
|
326
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Context
|
|
2
|
+
|
|
3
|
+
<!-- One or two descriptive sentences about context and reason behind the PR is enough. -->
|
|
4
|
+
|
|
5
|
+
## Related Jira ticket
|
|
6
|
+
|
|
7
|
+
<!-- If applicable, share the link to and update the status of the ticket. -->
|
|
8
|
+
|
|
9
|
+
## Screenshots
|
|
10
|
+
|
|
11
|
+
<!-- If there is a visual element to the PR please share screenshots -->
|
|
12
|
+
<!-- Remember the saying "one picture says the same as a 1000 words". -->
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Use Node.js
|
|
15
|
+
uses: actions/setup-node@v4
|
|
16
|
+
with:
|
|
17
|
+
node-version: '24'
|
|
18
|
+
cache: 'npm'
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: npm ci
|
|
22
|
+
|
|
23
|
+
- name: Run linting
|
|
24
|
+
run: npm run lint
|
|
25
|
+
|
|
26
|
+
type-check:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
|
|
31
|
+
- name: Use Node.js
|
|
32
|
+
uses: actions/setup-node@v4
|
|
33
|
+
with:
|
|
34
|
+
node-version: '24'
|
|
35
|
+
cache: 'npm'
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: npm ci
|
|
39
|
+
|
|
40
|
+
- name: Run TypeScript type checking
|
|
41
|
+
run: npm run type-check
|
|
42
|
+
|
|
43
|
+
test:
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
|
|
48
|
+
- name: Use Node.js
|
|
49
|
+
uses: actions/setup-node@v4
|
|
50
|
+
with:
|
|
51
|
+
node-version: '24'
|
|
52
|
+
cache: 'npm'
|
|
53
|
+
|
|
54
|
+
- name: Install dependencies
|
|
55
|
+
run: npm ci
|
|
56
|
+
|
|
57
|
+
- name: Run tests
|
|
58
|
+
run: npm run test
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Build & Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
# Allow only one concurrent deployment, and wait for the current one to finish
|
|
11
|
+
concurrency:
|
|
12
|
+
group: "pages"
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
release:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout current branch
|
|
20
|
+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
21
|
+
with:
|
|
22
|
+
persist-credentials: false
|
|
23
|
+
|
|
24
|
+
- name: Setup NodeJS
|
|
25
|
+
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v4.0.0
|
|
26
|
+
with:
|
|
27
|
+
node-version: 24
|
|
28
|
+
cache: "npm"
|
|
29
|
+
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: npm ci
|
|
32
|
+
|
|
33
|
+
- name: Run tests
|
|
34
|
+
run: npm test
|
|
35
|
+
|
|
36
|
+
- name: Publish project
|
|
37
|
+
uses: cycjimmy/semantic-release-action@9cc899c47e6841430bbaedb43de1560a568dfd16 # v5.0.0
|
|
38
|
+
id: semantic
|
|
39
|
+
with:
|
|
40
|
+
extra_plugins: |
|
|
41
|
+
@semantic-release/changelog
|
|
42
|
+
@semantic-release/git
|
|
43
|
+
branches: |
|
|
44
|
+
[
|
|
45
|
+
"main"
|
|
46
|
+
]
|
|
47
|
+
env:
|
|
48
|
+
GITHUB_TOKEN: ${{ secrets.RELEASE_PAT_TOKEN }}
|
|
49
|
+
NPM_TOKEN: ${{ secrets.NPMJS_TOKEN }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx --no-install commitlint --edit
|
package/.prettierrc
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Nosto
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# About Nosto
|
|
2
|
+
|
|
3
|
+
If you are unfamiliar with Nosto as a company, you are welcome to visit out homepage at [https://nosto.com/](https://www.nosto.com/).
|
|
4
|
+
|
|
5
|
+
If you wish to know more about our tech stack, we publish extensive documentation known as the [Techdocs](https://docs.nosto.com/techdocs).
|
|
6
|
+
|
|
7
|
+
# Nosto CLI Tool
|
|
8
|
+
|
|
9
|
+
A command-line interface to interact with Nosto's backend systems. Primarily aimed at developers and power-users who aim to use more powerful desktop tools for search-template development and (in the future) other features.
|
|
10
|
+
|
|
11
|
+
<img width="862" alt="image" src="https://github.com/user-attachments/assets/d26869d2-cd03-4d04-a175-d544c45b99b1" />
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
Nosto CLI aims to be as user-friendly as CLI tools get. You should be able to get up and running by utilizing the built-in `help` and `setup` commands, but a quick-start guide is also provided here.
|
|
16
|
+
|
|
17
|
+
To start with, you may create an empty folder for your folder; or you may clone your git repository to work with.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Install the CLI tool:
|
|
21
|
+
npm i @nosto/nosto-cli -g
|
|
22
|
+
|
|
23
|
+
# Login to Nosto
|
|
24
|
+
# You will see the browser window open with further instructions.
|
|
25
|
+
nosto login
|
|
26
|
+
|
|
27
|
+
# Run the tool targeting a project directory:
|
|
28
|
+
nosto status /path/to/project
|
|
29
|
+
|
|
30
|
+
# Alternatively, `cd` into the project directory and omit the path
|
|
31
|
+
cd /path/to/project && nosto status
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
The recommended way to provide the configuration is a configuration file in the project folder, named `.nosto.json`. Alternatively, environmental variables can be used. If both are present, the environment takes precedence.
|
|
37
|
+
|
|
38
|
+
See output of `nosto setup` for the full list of options.
|
|
39
|
+
|
|
40
|
+
> You should never push the content of your `.nosto.json` to your git repository as it may contain sensitive data.
|
|
41
|
+
|
|
42
|
+
### Required configuration
|
|
43
|
+
|
|
44
|
+
At the minimum, one option is required: Merchant ID. If you're targeting an environment other than production, an API URL will also be required.
|
|
45
|
+
|
|
46
|
+
> To quickly create a minimal configuration file, you may use the following command:
|
|
47
|
+
> `NOSTO_MERCHANT=merchant-id nosto setup`
|
|
48
|
+
|
|
49
|
+
#### Merchant ID:
|
|
50
|
+
|
|
51
|
+
Public ID of the target merchant.
|
|
52
|
+
|
|
53
|
+
> Property name in the config file: `merchant`<br/>
|
|
54
|
+
> Property name in the env variable: `NOSTO_MERCHANT`
|
|
55
|
+
|
|
56
|
+
#### API URL (Optional):
|
|
57
|
+
|
|
58
|
+
By default, the CLI will try to contact production as the base URL. You may need to specify a different URL to target the correct environment.
|
|
59
|
+
|
|
60
|
+
- Production URL: `https://api.nosto.com`
|
|
61
|
+
- Staging URL: `https://api.staging.nosto.com`
|
|
62
|
+
- Nosto internal development URL: `https://my.dev.nos.to/api`
|
|
63
|
+
|
|
64
|
+
> Property name in the config file: `apiUrl` <br/>
|
|
65
|
+
> Property name in the env variable: `NOSTO_API_URL`
|
|
66
|
+
|
|
67
|
+
#### API Key (Optional):
|
|
68
|
+
|
|
69
|
+
By default, the CLI will use your user credentials created by `nosto login`. If the API token is provided for a given project, it will be used instead.
|
|
70
|
+
|
|
71
|
+
Your access key for the target merchant. Specifically, a private Nosto API_APPS token that you can find in the merchant admin settings.
|
|
72
|
+
|
|
73
|
+
> Property name in the config file: `apiKey`<br/>
|
|
74
|
+
> Property name in the env variable: `NOSTO_API_KEY`
|
|
75
|
+
|
|
76
|
+
## Excluded files
|
|
77
|
+
|
|
78
|
+
Nosto CLI takes the contents of your `.gitignore` file into account when pushing files to the remote, skipping all files matching these patterns. In addition, the CLI implicitly ignores any files or folders that start with `.`. I.e. `.nosto.json` is excluded automatically.
|
|
79
|
+
|
|
80
|
+
During the pull, CLI downloads all files from the remote.
|
|
81
|
+
|
|
82
|
+
> The `/build` folder is an exception to the rules above. It will never be skipped during pushing, even if added to .gitignore, and it is always ignored while pulling.
|
|
83
|
+
|
|
84
|
+
### Recommended .gitignore
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
build
|
|
88
|
+
.nosto.json
|
|
89
|
+
.nostocache
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Supported commands
|
|
93
|
+
|
|
94
|
+
You can use `nosto help` and variations to obtain detailed and up-to-date information on the current list of commands.
|
|
95
|
+
|
|
96
|
+
- `login`
|
|
97
|
+
- Opens the browser window to start the login flow.
|
|
98
|
+
- Stores the credentials (email and temporary access token) in `~/.nosto/.auth.json`
|
|
99
|
+
- `logout`
|
|
100
|
+
- Wipes the stored login credentials
|
|
101
|
+
- `setup [projectPath]`
|
|
102
|
+
- Prints setup information and creates a placeholder config file if needed
|
|
103
|
+
- `status [projectPath]`
|
|
104
|
+
- Reads the configuration and prints the general status
|
|
105
|
+
- `st [projectPath]`
|
|
106
|
+
- Alias: `search-templates [projectPath]`
|
|
107
|
+
- Search templates related commands
|
|
108
|
+
- `st pull [projectPath]`
|
|
109
|
+
- Fetches the current remote state for the configured merchant
|
|
110
|
+
- `st push [projectPath]`
|
|
111
|
+
- Pushes the local state to the remote for the configured merchant
|
|
112
|
+
- `st build [projectPath]`
|
|
113
|
+
- For a modern search-template project, it invokes the `onBuild` script in `nosto.config.ts`
|
|
114
|
+
- For a legacy search-template project, it mirrors the hosted VSCode Web build workflow
|
|
115
|
+
- `st dev [projectPath]`
|
|
116
|
+
- Watches files, build and upload automatically
|
|
117
|
+
- For a modern search-template project, it invokes the `onBuildWatch` script in `nosto.config.ts`
|
|
118
|
+
- For a legacy search-template project, it uses esbuild to watch files, build and upload automatically. Only uploads build artifacts, not the sources.
|
|
119
|
+
|
|
120
|
+
## External dependencies in legacy search-templates
|
|
121
|
+
|
|
122
|
+
With the addition of local builds, the external dependencies are something that is theoretically possible. However, due to complexities of the legacy setup, external deps **will not be officially supported in the legacy templates**. We understand that this is something modern web development needs, and we are addressing that by our upcoming open source search-templates offering. Specifically, search-templates-starter, [search-js](https://github.com/nosto/search-js) and this very CLI tool.
|
|
123
|
+
|
|
124
|
+
If you would still like to try your luck with introducing dependencies into a legacy app, we recommend you stick with only build-time dependencies like TypeScript that disappear at runtime. In that case, build your app as you would, and point the CLI's build to the output folder.
|
|
125
|
+
|
|
126
|
+
## Development
|
|
127
|
+
|
|
128
|
+
### Testing
|
|
129
|
+
|
|
130
|
+
This project uses [Vitest](https://vitest.dev/) as the test runner. Tests are organized under the `test/` directory mirroring the structure of `src/`.
|
|
131
|
+
|
|
132
|
+
#### Available scripts
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Run tests once
|
|
136
|
+
npm run test
|
|
137
|
+
|
|
138
|
+
# Run tests in watch mode
|
|
139
|
+
npm run test:watch
|
|
140
|
+
|
|
141
|
+
# Run tests with UI
|
|
142
|
+
npm run test:ui
|
|
143
|
+
|
|
144
|
+
# Run tests with coverage report
|
|
145
|
+
npm run test:coverage
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Known issues
|
|
149
|
+
|
|
150
|
+
### Search templates push reports no files changed
|
|
151
|
+
|
|
152
|
+
Running `nosto st push` after `nosto st dev` without changing any files will stop early with the "No files to push" message due to the hashing mechanism not taking the pushed paths into account properly.
|
|
153
|
+
|
|
154
|
+
**Workaround**: Use `nosto st push -f` or change any of the files to update the hash.
|