@doubledigit/cli 0.3.1 → 0.4.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 CHANGED
@@ -118,15 +118,25 @@ dd actions remotion-hub
118
118
  dd actions remotion-hub search-components --query "animated chart" --limit 5
119
119
  ```
120
120
 
121
- The command resolves the app URL from `DD_APP_URL`, `APP_URL`, `BETTER_AUTH_URL`, or `http://localhost:3111` and prints JSON responses to stdout. It also reads `.env`, `.env.local`, `apps/main-app/.env`, and `apps/main-app/.env.local`; exported shell values take precedence.
121
+ The command resolves the app URL from exported `DD_APP_URL`, `APP_URL`, or `BETTER_AUTH_URL`; then local env-file `DD_APP_URL`; then the release-configured hosted app URL. It prints JSON responses to stdout. It also reads `.env`, `.env.local`, `apps/main-app/.env`, and `apps/main-app/.env.local`; exported shell values take precedence.
122
122
 
123
- Local development should use the local app URL. Use `DD_APP_URL` only when the action should intentionally hit a deployed app:
123
+ The hosted Double Digit app is the default for npm users:
124
124
 
125
125
  ```bash
126
- DD_APP_URL=https://your-project.vercel.app dd actions remotion-hub
126
+ dd actions remotion-hub
127
127
  ```
128
128
 
129
- In GitHub Actions or another CI/CD runner, provide `DD_APP_URL` through the runner environment, variables, or secrets. Do not rely on a local env file being present in CI, and do not point local `.env` files at Vercel by default.
129
+ This hosted default does not require a local checkout or running app.
130
+
131
+ Local development or self-hosted environments should override the target explicitly:
132
+
133
+ ```bash
134
+ DD_APP_URL=http://localhost:3111 dd actions remotion-hub
135
+ ```
136
+
137
+ In GitHub Actions or another CI/CD runner, provide `DD_ACTIONS_DEFAULT_APP_URL` or `DD_APP_URL` through the runner environment, variables, or secrets when the action target should differ from the hosted default. Do not rely on a local env file being present in CI.
138
+
139
+ GitHub or Infisical secrets are CI/CD inputs only. A local `npx @doubledigit/cli ...` command sees your shell environment and local env files, not repository secrets.
130
140
 
131
141
  ## Links
132
142
 
@@ -1,2 +1,3 @@
1
+ export declare function getDefaultActionsAppUrl(): string;
1
2
  export declare function actions(args: string[]): Promise<void>;
2
3
  //# sourceMappingURL=actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/commands/actions.ts"],"names":[],"mappings":"AAiEA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB3D"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/commands/actions.ts"],"names":[],"mappings":"AAiBA,wBAAgB,uBAAuB,WAKtC;AA+DD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB3D"}
@@ -1,10 +1,18 @@
1
1
  import path from 'node:path';
2
2
  import { readConfig, isEntryEnabled } from '../config.js';
3
+ import { GENERATED_DEFAULT_ACTIONS_APP_URL } from '../generated/defaults.js';
4
+ import { buildActionRequest, fetchActionRequest, isLocalAppUrl, parseActionsArgs, resolveActionAppUrl, resolveDefaultActionAppUrl, } from '../lib/actions-client.js';
3
5
  import { DEFAULT_APP_URL, readEnvFile } from '../lib/onboarding.js';
4
- import { buildActionRequest, fetchActionRequest, parseActionsArgs, resolveActionAppUrl, } from '../lib/actions-client.js';
5
6
  import { resolveWorkspacePaths } from '../paths.js';
6
7
  import { scanWorkspace } from '../scanner.js';
7
- const HELP = `
8
+ export function getDefaultActionsAppUrl() {
9
+ return resolveDefaultActionAppUrl({
10
+ generatedUrl: GENERATED_DEFAULT_ACTIONS_APP_URL,
11
+ localDefaultUrl: DEFAULT_APP_URL,
12
+ });
13
+ }
14
+ function buildHelp() {
15
+ return `
8
16
  dd actions — Discover and invoke micro-app actions
9
17
 
10
18
  Usage:
@@ -12,7 +20,7 @@ Usage:
12
20
  dd actions <micro-app> <action> [options]
13
21
 
14
22
  Options:
15
- --url, --app-url <url> App URL (default: DD_APP_URL, APP_URL, BETTER_AUTH_URL, or ${DEFAULT_APP_URL})
23
+ --url, --app-url <url> App URL (default: DD_APP_URL, APP_URL, BETTER_AUTH_URL, or ${getDefaultActionsAppUrl()})
16
24
  --json <json> JSON request body to send to the action
17
25
  --query <text> Set input.query
18
26
  --limit <number> Set input.limit
@@ -29,6 +37,7 @@ Examples:
29
37
  dd actions remotion-hub get-component --namespace doubledigit --slug motion-strip
30
38
  dd actions remotion-hub get-registry-payload --json '{"namespace":"doubledigit","slug":"motion-strip"}'
31
39
  `;
40
+ }
32
41
  function readActionEnvFiles(paths) {
33
42
  const env = {};
34
43
  for (const envPath of [
@@ -51,19 +60,30 @@ function validateMicroApp(paths, microApp) {
51
60
  throw new Error(`Micro-app is disabled: ${microApp}`);
52
61
  }
53
62
  }
63
+ function tryResolveWorkspacePaths() {
64
+ try {
65
+ return resolveWorkspacePaths();
66
+ }
67
+ catch {
68
+ return undefined;
69
+ }
70
+ }
54
71
  export async function actions(args) {
55
72
  const parsed = parseActionsArgs(args);
56
73
  if (parsed.help || !parsed.microApp) {
57
- console.log(HELP);
74
+ console.log(buildHelp());
58
75
  return;
59
76
  }
60
- const paths = resolveWorkspacePaths();
61
- validateMicroApp(paths, parsed.microApp);
62
- const request = buildActionRequest(parsed, resolveActionAppUrl({
77
+ const paths = tryResolveWorkspacePaths();
78
+ const appUrl = resolveActionAppUrl({
63
79
  explicitUrl: parsed.appUrl,
64
- fileEnv: readActionEnvFiles(paths),
65
- defaultUrl: DEFAULT_APP_URL,
66
- }));
80
+ fileEnv: paths ? readActionEnvFiles(paths) : {},
81
+ defaultUrl: getDefaultActionsAppUrl(),
82
+ });
83
+ if (paths && isLocalAppUrl(appUrl)) {
84
+ validateMicroApp(paths, parsed.microApp);
85
+ }
86
+ const request = buildActionRequest(parsed, appUrl);
67
87
  const result = await fetchActionRequest(request);
68
88
  console.log(JSON.stringify(result, null, 2));
69
89
  }
@@ -0,0 +1,2 @@
1
+ export declare const GENERATED_DEFAULT_ACTIONS_APP_URL = "https://doubledigit.vercel.app";
2
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/generated/defaults.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,mCAAmC,CAAC"}
@@ -0,0 +1 @@
1
+ export const GENERATED_DEFAULT_ACTIONS_APP_URL = "https://doubledigit.vercel.app";
@@ -15,9 +15,16 @@ export interface ResolveActionAppUrlOptions {
15
15
  fileEnv?: Record<string, string | undefined>;
16
16
  defaultUrl: string;
17
17
  }
18
+ export interface ResolveDefaultActionAppUrlOptions {
19
+ env?: Record<string, string | undefined>;
20
+ generatedUrl?: string;
21
+ localDefaultUrl: string;
22
+ }
23
+ export declare function resolveDefaultActionAppUrl({ env, generatedUrl, localDefaultUrl, }: ResolveDefaultActionAppUrlOptions): string;
18
24
  export declare function resolveActionAppUrl({ explicitUrl, env, fileEnv, defaultUrl, }: ResolveActionAppUrlOptions): string;
19
25
  export declare function parseActionsArgs(args: string[]): ParsedActionsArgs;
20
26
  export declare function normalizeAppUrl(appUrl: string): string;
27
+ export declare function isLocalAppUrl(appUrl: string): boolean;
21
28
  export declare function buildActionRequest(parsed: Pick<ParsedActionsArgs, 'microApp' | 'actionName' | 'input'>, appUrl: string): ActionRequest;
22
29
  export declare function fetchActionRequest(request: ActionRequest): Promise<unknown>;
23
30
  //# sourceMappingURL=actions-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions-client.d.ts","sourceRoot":"","sources":["../../src/lib/actions-client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;CACpB;AAOD,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,GAAiB,EACjB,OAAY,EACZ,UAAU,GACX,EAAE,0BAA0B,UAS5B;AA2DD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAsDlE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,UAE7C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAoBtI;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBjF"}
1
+ {"version":3,"file":"actions-client.d.ts","sourceRoot":"","sources":["../../src/lib/actions-client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;CACpB;AAOD,MAAM,WAAW,iCAAiC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,0BAA0B,CAAC,EACzC,GAAiB,EACjB,YAAY,EACZ,eAAe,GAChB,EAAE,iCAAiC,UAInC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,GAAiB,EACjB,OAAY,EACZ,UAAU,GACX,EAAE,0BAA0B,UAS5B;AA2DD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAsDlE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,UAS7C;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,WAK3C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAoBtI;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBjF"}
@@ -2,15 +2,20 @@ function readUrlValue(value) {
2
2
  const trimmed = value?.trim();
3
3
  return trimmed || undefined;
4
4
  }
5
+ export function resolveDefaultActionAppUrl({ env = process.env, generatedUrl, localDefaultUrl, }) {
6
+ return readUrlValue(env.DD_ACTIONS_DEFAULT_APP_URL)
7
+ ?? readUrlValue(generatedUrl)
8
+ ?? localDefaultUrl;
9
+ }
5
10
  export function resolveActionAppUrl({ explicitUrl, env = process.env, fileEnv = {}, defaultUrl, }) {
6
11
  return readUrlValue(explicitUrl)
7
12
  ?? readUrlValue(env.DD_APP_URL)
8
13
  ?? readUrlValue(env.APP_URL)
9
14
  ?? readUrlValue(env.BETTER_AUTH_URL)
10
15
  ?? readUrlValue(fileEnv.DD_APP_URL)
16
+ ?? defaultUrl
11
17
  ?? readUrlValue(fileEnv.APP_URL)
12
- ?? readUrlValue(fileEnv.BETTER_AUTH_URL)
13
- ?? defaultUrl;
18
+ ?? readUrlValue(fileEnv.BETTER_AUTH_URL);
14
19
  }
15
20
  function requireValue(args, index, flag) {
16
21
  const value = args[index + 1];
@@ -129,7 +134,20 @@ export function parseActionsArgs(args) {
129
134
  };
130
135
  }
131
136
  export function normalizeAppUrl(appUrl) {
132
- return appUrl.trim().replace(/\/+$/, '');
137
+ const trimmed = appUrl.trim().replace(/\/+$/, '');
138
+ if (/^https?:\/\//i.test(trimmed)) {
139
+ return trimmed;
140
+ }
141
+ if (/^(localhost|127(?:\.\d{1,3}){3}|\[::1\])(?::|\/|$)/i.test(trimmed)) {
142
+ return `http://${trimmed}`;
143
+ }
144
+ return `https://${trimmed}`;
145
+ }
146
+ export function isLocalAppUrl(appUrl) {
147
+ const parsed = new URL(normalizeAppUrl(appUrl));
148
+ return parsed.hostname === 'localhost'
149
+ || parsed.hostname === '127.0.0.1'
150
+ || parsed.hostname === '::1';
133
151
  }
134
152
  export function buildActionRequest(parsed, appUrl) {
135
153
  if (!parsed.microApp) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doubledigit/cli",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "description": "CLI for Double Digit local setup and extension management.",
6
6
  "license": "MIT",
@@ -50,7 +50,8 @@
50
50
  },
51
51
  "scripts": {
52
52
  "test": "tsx --test test/*.test.ts",
53
- "build": "tsc -p tsconfig.json",
54
- "typecheck": "tsc -p tsconfig.json --noEmit"
53
+ "build": "pnpm generate:defaults && tsc -p tsconfig.json",
54
+ "generate:defaults": "node scripts/generate-defaults.mjs",
55
+ "typecheck": "pnpm generate:defaults && tsc -p tsconfig.json --noEmit"
55
56
  }
56
57
  }