Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0727f47
add pos-cli exec liquid command
Slashek Jan 14, 2026
7bc5088
add pos-cli exec graphql command
Slashek Jan 14, 2026
672cd00
extra confirmation for production
Slashek Jan 14, 2026
f9defba
add pos-cli test run command
Slashek Jan 15, 2026
1b919bb
add support for -f command
Slashek Jan 15, 2026
f5d1cd6
modernize stack - commonjs -> esm, jest -> vitest, upgrade dependencies
Slashek Jan 17, 2026
7c9e6aa
bump minimum version to node 20
Slashek Jan 19, 2026
6804c0d
eslint
Slashek Jan 19, 2026
208f9f6
stash unit tests and integration tests
Slashek Jan 19, 2026
63f80b2
update package-lock.json
Slashek Jan 21, 2026
6d6325f
fix yeoman tests
Slashek Jan 21, 2026
1b3a94d
fix manifest tests
Slashek Jan 21, 2026
74b3109
add tests deubg generator
Slashek Jan 21, 2026
f80ddfa
fix yeoman
Slashek Jan 21, 2026
ae179f7
update playwright
Slashek Jan 21, 2026
5f1a37a
rebuild
Slashek Jan 21, 2026
16b33d4
fix cell to columnhaeder
Slashek Jan 21, 2026
60d645e
run on windows
Slashek Jan 21, 2026
a599f89
fixes on windows
Slashek Jan 21, 2026
bbd7655
next round
Slashek Jan 21, 2026
3ff098d
node 22 min
Slashek Jan 21, 2026
4747775
next round
Slashek Jan 21, 2026
12ab83f
try test-run fix
Slashek Jan 22, 2026
b77d9ec
update linting config and fix errors
Slashek Jan 22, 2026
b7356cf
add ability to measure test coverage
Slashek Jan 22, 2026
0bf3a9c
make sure that variables with _ are not used
Slashek Jan 23, 2026
64139a3
improve refresh token error handling
Slashek Jan 23, 2026
4195c9e
improve error handling
Slashek Jan 26, 2026
f9f7672
remove AI assertions ;)
Slashek Jan 26, 2026
ebeb23b
Claude fixes exiting test program (#684)
z-x Jan 27, 2026
124a1e6
remove unnecessary initializeEsmModules
Slashek Jan 27, 2026
32f35a2
add gracefull shutdown
Slashek Jan 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
40 changes: 0 additions & 40 deletions .eslintrc

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/pull_requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
container:
image: mcr.microsoft.com/playwright:v1.53.1-jammy
image: mcr.microsoft.com/playwright:v1.57.0-jammy
env:
MPKIT_EMAIL: ${{ secrets.MPKIT_EMAIL }}
MPKIT_TOKEN: ${{ secrets.MPKIT_TOKEN }}
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ on:

jobs:
test:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
timeout-minutes: 15

strategy:
max-parallel: 1
matrix:
version: ['18', '20', '20.11']
os: [windows-latest, ubuntu-latest]
version: ['22', '24']

steps:
- name: Checkout repository
Expand All @@ -31,7 +32,7 @@ jobs:
MPKIT_URL: ${{ secrets.TEST_MPKIT_URL }}
POS_PORTAL_PASSWORD: ${{secrets.POS_PORTAL_PASSWORD}}
CI: true
shell: sh
shell: bash
run: |
npm ci
npm test
Expand Down
1 change: 0 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
scope=@platformos
save=false
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
# Changelog

## Unreleased


## 6.0.0

* Feature: `pos-cli exec liquid` command to execute Liquid code directly on an instance (supports `-f` flag to load from file, requires confirmation on production)
* Feature: `pos-cli exec graphql` command to execute GraphQL queries directly on an instance (supports `-f` flag to load from file, requires confirmation on production)
* Feature: `pos-cli test run` command to run tests using the tests module

### Major Dependency Upgrades

We've completed a comprehensive modernization of the CLI including:

**Node.js Version Requirement**: Now requires Node.js 20 or higher (up from Node.js 18)

**Breaking Changes** that may require action from users:

1. **Yeoman generators**: If you have custom generators using `yeoman-generator`, they need to be rewritten for the v7.x update:
- No kebab-case in option names (e.g., `skip-install` → `skipInstall`)
- `composeWith()` is now async (use `await`)
- The `install()` action has been removed; use `addDependencies()` instead
- See [yeoman-generator v5 to v7 migration guide](https://yeoman.github.io/generator/v5-to-v7-migration/)

2. **Express v5 route syntax**: Routes using wildcards have changed from `/*` to `/*splat` format. This is handled automatically, but if you have custom Express middleware in your project, you may need to update route patterns.

**Package Upgrades**: All major dependencies have been updated to their latest stable versions including:
- chalk v5.6, chokidar v5.0, express v5.2, ora v9.0, open v11.0
- inquirer v13.2, mime v4.1, multer v2.0, yeoman-environment v5.1, yeoman-generator v7.5
- And many other dependency updates for security and stability

**Test Framework Migration**: Migrated from Jest to Vitest to better support ESM

## 5.5.0

* Feature: (GUI) Ability to add, edit and remove users
Expand Down
24 changes: 16 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ pos-cli/
Example:
```javascript
// bin/pos-cli-deploy.js
const fetchAuthData = require('../lib/settings').fetchSettings;
const deployStrategy = require('../lib/deploy/strategy');
import { fetchSettings } from '../lib/settings';
import deployStrategy from '../lib/deploy/strategy.js';

program
.argument('[environment]', 'name of environment')
.option('-p --partial-deploy', 'Partial deployment')
.action(async (environment, params) => {
const authData = fetchAuthData(environment);
const authData = fetchSettings(environment);
deployStrategy.run({ strategy: 'directAssetsUpload', opts: { ... } });
});
```
Expand Down Expand Up @@ -139,11 +139,17 @@ Two deployment strategies:

Strategy selection:
```javascript
import defaultStrategy from './defaultStrategy.js';
import directAssetsUploadStrategy from './directAssetsUploadStrategy.js';

const strategies = {
default: require('./defaultStrategy'),
directAssetsUpload: require('./directAssetsUploadStrategy'),
default: defaultStrategy,
directAssetsUpload: directAssetsUploadStrategy,
};
module.exports = { run: ({ strategy, opts }) => strategies[strategy](opts) };

const run = ({ strategy, opts }) => strategies[strategy](opts);

export { run };
```

#### 3. File Watching Pattern - Sync Mode
Expand Down Expand Up @@ -354,6 +360,8 @@ GUI apps are pre-built (in dist/ or build/ directories). To modify:
- **CDN** - Asset delivery and verification

## Node.js Version
- **Minimum**: Node.js 18
- **Tested on**: 18, 20, 20.11

- **Minimum**: Node.js 22
- **Recommended**: Node.js 22+
- **Tested on**: 22, 24
- Check enforced by `scripts/check-node-version.js` postinstall hook
56 changes: 55 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Run all commands from the project root directory, one level above the `app` or `

### Requirements

`pos-cli` requires Node.js version 18 or higher to function correctly. [See instructions for installing Node.js on your platform](https://nodejs.org/en/download/).
`pos-cli` requires Node.js version 22 or higher to function correctly. [See instructions for installing Node.js on your platform](https://nodejs.org/en/download/).

## Installation and Update

Expand Down Expand Up @@ -444,6 +444,60 @@ If you need guidance or additional information about how to use a specific gener

pos-cli generate modules/core/generators/command --generator-help

### Executing Code

#### Execute Liquid

Execute Liquid code directly on your instance:

pos-cli exec liquid [environment] [code]

Example:

pos-cli exec liquid staging "{{ 'hello' | upcase }}"

You can also execute Liquid code from a file using the `-f` flag:

pos-cli exec liquid staging -f path/to/script.liquid

#### Execute GraphQL

Execute GraphQL queries directly on your instance:

pos-cli exec graphql [environment] [query]

Example:

pos-cli exec graphql staging "{ users(per_page: 5) { results { id email } } }"

You can also execute GraphQL from a file using the `-f` flag:

pos-cli exec graphql staging -f path/to/query.graphql

**Note:** When executing on production environments (environment name contains "prod" or "production"), you will be prompted for confirmation before execution.

### Running Tests

To run tests on your instance, you need to have the [tests module](https://github.com/Platform-OS/pos-module-tests) installed.

#### Run All Tests

pos-cli test run [environment]

Example:

pos-cli test run staging

This command runs all tests and streams the results in real-time, showing individual test outcomes and a summary at the end.

#### Run a Single Test

pos-cli test run [environment] [test-name]

Example:

pos-cli test run staging my_test

## Development

The `pos-cli gui serve` command uses a distinct build process for the GraphiQL interface located in the `gui/editor/graphql` directory.
Expand Down
10 changes: 5 additions & 5 deletions bin/pos-cli-archive.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env node
const { program } = require('commander');
import { program } from 'commander';

const audit = require('../lib/audit');
const archive = require('../lib/archive');
import { run as auditRun } from '../lib/audit.js';
import archive from '../lib/archive.js';

const createArchive = async (env) => {
const numberOfFiles = await archive.makeArchive(env, { withoutAssets: false });
Expand All @@ -14,7 +14,7 @@ const runAudit = async () => {
return;
}

await audit.run();
await auditRun();
};

program
Expand All @@ -29,7 +29,7 @@ program
TARGET: params.output
});

await createArchive(env)
await createArchive(env);
});

program.parse(process.argv);
4 changes: 2 additions & 2 deletions bin/pos-cli-audit.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env node

const audit = require('../lib/audit');
import { run } from '../lib/audit.js';

audit.run();
run();
55 changes: 20 additions & 35 deletions bin/pos-cli-clone-init.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,40 @@
#!/usr/bin/env node

const { program } = require('commander'),
fs = require('fs'),
shell = require('shelljs'),
Gateway = require('../lib/proxy'),
fetchAuthData = require('../lib/settings').fetchSettings,
fetchFiles = require('../lib/data/fetchFiles'),
waitForStatus = require('../lib/data/waitForStatus'),
downloadFile = require('../lib/downloadFile');

const logger = require('../lib/logger'),
report = require('../lib/logger/report');

// importing ESM modules in CommonJS project
let ora;
const initializeEsmModules = async () => {
if(!ora) {
await import('ora').then(imported => ora = imported.default);
}

return true;
}

let gateway;
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
import { program } from 'commander';
import Gateway from '../lib/proxy.js';
import { fetchSettings } from '../lib/settings.js';
import waitForStatus from '../lib/data/waitForStatus.js';
import logger from '../lib/logger.js';
import ora from 'ora';

program.showHelpAfterError();
program
.name('pos-cli clone init')
.arguments('[sourceEnv]', 'source environment. Example: staging')
.arguments('[targetEnv]', 'target environment. Example: staging2')
.action(async (sourceEnv, targetEnv, params) => {
.action(async (sourceEnv, targetEnv, _params) => {

await initializeEsmModules();
const spinner = ora({ text: 'InstanceClone initilized', stream: process.stdout, interval: 500 });

try {
const sourceAuthData = fetchAuthData(sourceEnv, program);
const targetAuthData = fetchAuthData(targetEnv, program);
const sourceAuthData = fetchSettings(sourceEnv, program);
const targetAuthData = fetchSettings(targetEnv, program);

sourceGateway = new Gateway(sourceAuthData);
targetGateway = new Gateway(targetAuthData);
const sourceGateway = new Gateway(sourceAuthData);
const targetGateway = new Gateway(targetAuthData);

spinner.start();

const payload = await targetGateway.cloneInstanceInit();
const response = await sourceGateway.cloneInstanceExport(payload);

const checkInstanceCloneStatus = () => { return targetGateway.cloneInstanceStatus(payload.id) }
const formatResponse = r => `${r.status.name} \n${r.statuses.map((item) => [item.created_at, item.name].join(" ")).join("\n")}`
await waitForStatus(checkInstanceCloneStatus, [], 'done', 2000, (msg) => { spinner.text = formatResponse(msg) })
await sourceGateway.cloneInstanceExport(payload);

const checkInstanceCloneStatus = () => {
return targetGateway.cloneInstanceStatus(payload.id);
};
const formatResponse = r => `${r.status.name} \n${r.statuses.map((item) => [item.created_at, item.name].join(' ')).join('\n')}`;
await waitForStatus(checkInstanceCloneStatus, [], 'done', 2000, (msg) => {
spinner.text = formatResponse(msg);
});

spinner.stopAndPersist().succeed(`${sourceEnv} instance clone to ${targetEnv} succeeded.`);
} catch(e) {
Expand Down
2 changes: 1 addition & 1 deletion bin/pos-cli-clone.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env node

const { program } = require('commander');
import { program } from 'commander';

program
.name('pos-cli clone')
Expand Down
Loading
Loading