@norbix.ai/cli 1.1.0 → 1.2.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/README.md +9 -0
- package/dist/base.js +23 -3
- package/dist/commands/push/preview.js +30 -6
- package/oclif.manifest.json +863 -982
- package/package.json +1 -1
- package/dist/commands/push/integration/app-request.js +0 -34
package/README.md
CHANGED
|
@@ -149,6 +149,15 @@ came back negative (`norbix files integrations test`).
|
|
|
149
149
|
not before — `norbix files publish` / `unpublish` were the two commands that
|
|
150
150
|
used to treat it as a success.
|
|
151
151
|
|
|
152
|
+
## Versioning
|
|
153
|
+
|
|
154
|
+
The major version is frozen at **v1** until the public launch.
|
|
155
|
+
|
|
156
|
+
- A breaking change is released as a **minor** (for example v1.2.0 → v1.3.0), never as a new major.
|
|
157
|
+
- Write it as `feat(<scope>): <what>` and add a line `Breaking: <what changed and what callers must do>` in plain words, in the pull-request body and in the commit message.
|
|
158
|
+
- Never mark it the conventional-commits way: no `!` in the title (`feat!:`), no BREAKING CHANGE footer. The `PR title` check fails a pull request that does.
|
|
159
|
+
- As a safety net, the release config (`.releaserc.json` → `releaseRules`) maps breaking commits to a minor, so one that slips through still does not bump the major.
|
|
160
|
+
|
|
152
161
|
## Development
|
|
153
162
|
|
|
154
163
|
```sh
|
package/dist/base.js
CHANGED
|
@@ -2,6 +2,16 @@ import { Norbix, NorbixError } from '@norbix.ai/ts';
|
|
|
2
2
|
import { Command, Flags } from '@oclif/core';
|
|
3
3
|
import { DEFAULT_API_URL, DEFAULT_HUB_URL, isSessionValid, readProfiles, readSession, } from './lib/profiles.js';
|
|
4
4
|
import { readStore } from './lib/store.js';
|
|
5
|
+
/** Stands in for a projectId the SDK constructor insists on; never sent. */
|
|
6
|
+
const NO_PROJECT_PLACEHOLDER = 'no-project';
|
|
7
|
+
/** Removes the project headers the SDK adds for the placeholder projectId. */
|
|
8
|
+
export const dropProjectHeaders = async (ctx) => {
|
|
9
|
+
const headers = new Headers(ctx.init.headers);
|
|
10
|
+
headers.delete('norbix-project-id');
|
|
11
|
+
headers.delete('X-CM-ProjectId');
|
|
12
|
+
ctx.init.headers = headers;
|
|
13
|
+
return ctx.next();
|
|
14
|
+
};
|
|
5
15
|
/**
|
|
6
16
|
* Base class for every Norbix CLI command.
|
|
7
17
|
*
|
|
@@ -127,18 +137,28 @@ export class BaseCommand extends Command {
|
|
|
127
137
|
'or set custom api_url / hub_url in the profile for self-hosted installations.');
|
|
128
138
|
}
|
|
129
139
|
}
|
|
130
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Build an SDK client from the resolved context. Errors politely when auth is missing.
|
|
142
|
+
*
|
|
143
|
+
* `requireAuth: false` — the call may go out without a login (a signed link is the key);
|
|
144
|
+
* a login, when there is one, is still used.
|
|
145
|
+
* `requireProject: false` — the call does not need a project (a signed link carries it).
|
|
146
|
+
* The SDK constructor still demands a projectId, so a placeholder is passed and the
|
|
147
|
+
* project headers are taken off the wire again: the gateway never sees a fake project.
|
|
148
|
+
*/
|
|
131
149
|
client(flags, opts = {}) {
|
|
132
150
|
const ctx = this.resolveContext(flags);
|
|
133
151
|
this.assertEndpoints(ctx);
|
|
134
|
-
|
|
152
|
+
const noProject = !ctx.projectId && opts.requireProject === false;
|
|
153
|
+
if (!ctx.projectId && !noProject) {
|
|
135
154
|
this.error('No project ID configured.\nRun `norbix configure` (or `norbix login`), or pass --project.');
|
|
136
155
|
}
|
|
137
156
|
if (opts.requireAuth !== false && !ctx.apiKey && !ctx.bearerToken) {
|
|
138
157
|
this.error('Not authenticated.\nRun `norbix login` (browser/user session) or `norbix configure` (API key profile), or pass --api-key.');
|
|
139
158
|
}
|
|
140
159
|
return new Norbix({
|
|
141
|
-
projectId: ctx.projectId,
|
|
160
|
+
projectId: noProject ? NO_PROJECT_PLACEHOLDER : ctx.projectId,
|
|
161
|
+
middleware: noProject ? [dropProjectHeaders] : [],
|
|
142
162
|
accountId: ctx.accountId,
|
|
143
163
|
apiKey: ctx.apiKey,
|
|
144
164
|
bearerToken: ctx.bearerToken,
|
|
@@ -1,19 +1,43 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NorbixError } from '@norbix.ai/ts';
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
3
|
import { BaseCommand } from '../../base.js';
|
|
3
4
|
export default class PushPreview extends BaseCommand {
|
|
4
5
|
static description = `Render the title, body and subtitle behind a push preview link
|
|
5
6
|
|
|
6
7
|
The hash is the opaque value the backend puts in a preview link — you cannot
|
|
7
|
-
build it yourself, so copy it out of the link
|
|
8
|
-
|
|
8
|
+
build it yourself, so copy it out of the link.
|
|
9
|
+
|
|
10
|
+
The signed link is the key: no login and no project are needed. When you are
|
|
11
|
+
logged in, your session is still sent.`;
|
|
12
|
+
static examples = [
|
|
13
|
+
'<%= config.bin %> push preview 8f2a91c4...',
|
|
14
|
+
'<%= config.bin %> push preview --hash 8f2a91c4... --region nb-eu-germany',
|
|
15
|
+
];
|
|
9
16
|
static args = {
|
|
10
|
-
hash: Args.string({ required:
|
|
17
|
+
hash: Args.string({ required: false, description: 'Preview hash from the preview link' }),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
hash: Flags.string({ description: 'Preview hash from the preview link (same as the argument)' }),
|
|
11
21
|
};
|
|
12
22
|
async run() {
|
|
13
23
|
const { args, flags } = await this.parse(PushPreview);
|
|
14
|
-
const
|
|
15
|
-
|
|
24
|
+
const hash = flags.hash ?? args.hash;
|
|
25
|
+
if (!hash) {
|
|
26
|
+
this.error('Pass the preview hash: `norbix push preview <hash>` or `--hash <hash>`.');
|
|
27
|
+
}
|
|
28
|
+
// The signed link opens without sign-in, so neither a login nor a project
|
|
29
|
+
// is forced here. A login, when there is one, is still used.
|
|
30
|
+
const client = this.client(flags, { requireAuth: false, requireProject: false });
|
|
31
|
+
const res = await client.hub.notifications.previewPushNotification({ hash });
|
|
16
32
|
this.print(res);
|
|
17
33
|
return res;
|
|
18
34
|
}
|
|
35
|
+
async catch(error) {
|
|
36
|
+
// A 401 here means the link is bad or expired, not that a session ran out.
|
|
37
|
+
if (error instanceof NorbixError && error.status === 401) {
|
|
38
|
+
const { code } = error;
|
|
39
|
+
return this.error(`${code ? `${code}: ` : ''}${error.message}\nThe preview link is invalid or has expired. Ask for a new link.`);
|
|
40
|
+
}
|
|
41
|
+
return super.catch(error);
|
|
42
|
+
}
|
|
19
43
|
}
|