@hyperscale0/create 1.0.0-alpha.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/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @hyperscale0/create
2
+
3
+ The Hyperscale project launcher: `npm create @hyperscale0` scaffolds a
4
+ minimal project wired to your Product's hosted TypeScript SDK. It pins the
5
+ SDK version the registry serves today, writes the project `.npmrc` for the
6
+ authenticated registry, puts your key in a gitignored `.env`, and generates
7
+ a `hello.mjs` that makes the product's first read call.
8
+
9
+ ## Use
10
+
11
+ ```bash
12
+ export HYPERSCALE_API_KEY=<your Product API key>
13
+
14
+ npm create @hyperscale0
15
+ # or
16
+ bunx @hyperscale0/create my-product
17
+ ```
18
+
19
+ There are no prompts: every input is a flag or an environment variable.
20
+ Point it at another host with `--base-url`, and at the live plane with
21
+ `--environment live`. Run `bunx @hyperscale0/create --help` for the full
22
+ option list.
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import{spawn as R}from"node:child_process";import{existsSync as x,mkdirSync as U,readdirSync as b,writeFileSync as P}from"node:fs";import{basename as L,join as K,resolve as $}from"node:path";const f="https://hyperscale0.ai",v="sandbox",E="hyperscale-app",T=`create-hyperscale [directory] [options]
3
+
4
+ Scaffolds a minimal project wired to your Product's hosted TypeScript SDK:
5
+ a package.json pinned to the SDK version the registry serves today, a
6
+ project .npmrc for the authenticated registry, a .env carrying the key from
7
+ your environment, and hello.mjs making the product's first read call.
8
+
9
+ Options:
10
+ --api-key <key> Product API key (default: $HYPERSCALE_API_KEY)
11
+ --base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${f})
12
+ --environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${v})
13
+ --no-install Write the project without running npm install
14
+ --json Print a machine-readable summary
15
+ --version Print the launcher version
16
+ --help Print this help
17
+
18
+ The key rides in the environment, never on the command line, unless you are
19
+ pasting a one-off into a throwaway shell. There are no prompts: every input
20
+ is a flag or an environment variable, so the launcher runs the same way in a
21
+ terminal, a script, and an agent.
22
+
23
+ Examples:
24
+ npm create @hyperscale0
25
+ bunx @hyperscale0/create my-product
26
+ create-hyperscale my-product --no-install
27
+ `;class i extends Error{}const I=new Set(["--api-key","--base-url","--environment"]),O=new Set(["--help","--json","--no-install","--version"]);function j(e){const t=[],n={};for(let r=0;r<e.length;r+=1){const o=e[r];if(!o.startsWith("--")){t.push(o);continue}if(I.has(o)){const s=e[r+1];if(s===void 0)throw new i(`${o} needs a value`);n[o]=s,r+=1;continue}if(O.has(o)){n[o]=!0;continue}throw new i(`Unknown option: ${o}`)}return{flags:n,positional:t}}function C(e,t){const n=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!n)throw new i("No API key. Set HYPERSCALE_API_KEY, or pass --api-key. Mint a Product API key on the Developers desk.");const r=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??v;if(r!=="sandbox"&&r!=="live")throw new i(`Unknown environment: ${r}. Use sandbox or live.`);const o=(e["--base-url"]??t.HYPERSCALE_BASE_URL??f).replace(/\/+$/,"");return{apiKey:n,baseUrl:o,environment:r}}async function S(e,t){let n;try{n=await fetch(t,{headers:{accept:"application/json",authorization:`Bearer ${e.apiKey}`,"x-hyperscale-environment":e.environment}})}catch(o){throw new i(`Could not reach ${t}: ${o.message}`)}const r=await n.text();return{response:n,text:r}}async function D(e){const{response:t,text:n}=await S(e,`${e.baseUrl}/v1/llms.txt`);if(!t.ok)throw k(t,n);const r=/^# (.+)$/m.exec(n),o=/^## Operations \((\d+)\)$/m.exec(n),s=/^- Auth: \S+ \(secret via (\S+)\)$/m.exec(n);if(!r||!o||!s)throw new Error("The product document is not in the expected format; upgrade the launcher.");const a=s[1];if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(a))throw new Error(`The product document names an invalid auth environment variable (${a}); refusing to scaffold.`);const c=[],m=/^- ([A-Z]+) (\S+) · (\S+) \((\S+); idempotency (\S+)\)$/gm;for(const u of n.matchAll(m))c.push({method:u[1],operationId:u[4],path:u[2]});const h=Number(o[1]);if(c.length!==h)throw new Error(`The product document declares ${h} operations but ${c.length} parsed; upgrade the launcher.`);const l=new Map,N=/^ {2}\d+\. (\S+) \(([^)]+)\)$/gm;for(const u of n.matchAll(N)){const d=u[1];if(!/^[A-Za-z_$][\w$]*$/.test(d))throw new Error(`The product document names an invalid SDK function (${d}); refusing to scaffold.`);const[w,_]=u[2].split("; ");_!=="gap"&&!l.has(w)&&l.set(w,d)}const y=/^- Package: (.+)$/m.exec(n),g=/^- Registry: (\S+)$/m.exec(n);if(!y||!g)throw new i("This Product has no hosted SDK yet. Build it in the composer, then rerun.");return{apiKeyEnvVar:a,operations:c,packageName:y[1].trim(),registryUrl:g[1].replace(/\/+$/,""),sdkFunctionByOperationId:l,title:r[1].trim()}}async function H(e,t){const n=encodeURIComponent(t.packageName).replace("%40","@"),{response:r,text:o}=await S(e,`${t.registryUrl}/${n}`);if(!r.ok)throw k(r,o);let s;try{s=JSON.parse(o)["dist-tags"]?.latest}catch{s=void 0}if(typeof s!="string")throw new Error(`The registry packument for ${t.packageName} names no latest version; upgrade the launcher.`);return s}function k(e,t){let n=t.trim();try{const r=JSON.parse(t);r&&r.error&&typeof r.error.message=="string"&&(n=`${r.error.code}: ${r.error.message}`)}catch{}return new i(`HTTP ${e.status}${n?` \xB7 ${n}`:""}`)}function A(e){const t=e.operations.find(n=>n.method==="GET"&&!n.path.includes("{")&&e.sdkFunctionByOperationId.has(n.operationId));if(t)return e.sdkFunctionByOperationId.get(t.operationId)}function F(e,t){const n=`// Generated by create-hyperscale for ${e.title}.
28
+ // Run with: npm run hello (reads ${e.apiKeyEnvVar} from .env)
29
+ import { createHyperscaleSdk } from ${JSON.stringify(e.packageName)};
30
+
31
+ const apiKey = process.env.${e.apiKeyEnvVar};
32
+ if (!apiKey) {
33
+ throw new Error("Set ${e.apiKeyEnvVar} in .env before running.");
34
+ }
35
+ const client = createHyperscaleSdk({
36
+ environment: ${JSON.stringify(t)},
37
+ auth: () => apiKey,
38
+ ...(process.env.HYPERSCALE_BASE_URL
39
+ ? { baseUrl: process.env.HYPERSCALE_BASE_URL }
40
+ : {}),
41
+ });`,r=A(e);return r?`${n}
42
+
43
+ const result = await client[${JSON.stringify(r)}]();
44
+ if (result.error) {
45
+ console.error(result.error.code, result.error.message);
46
+ process.exit(1);
47
+ }
48
+ console.log(JSON.stringify(result.data, null, 2));
49
+ `:`${n}
50
+
51
+ console.log("SDK client ready for ${e.title}.");
52
+ console.log(
53
+ "This product has no parameterless read; see the first-call example in",
54
+ "node_modules/${e.packageName}/README.md",
55
+ );
56
+ `}function V(e){const t=new URL(e.registryUrl),n=t.pathname.endsWith("/")?t.pathname:`${t.pathname}/`;return`@hyperscale:registry=${e.registryUrl}
57
+ //${t.host}${n}:_authToken=\${${e.apiKeyEnvVar}}
58
+ `}function Y(e,t){const n=t.baseUrl===f?"":`HYPERSCALE_BASE_URL=${t.baseUrl}
59
+ `;return`${e.apiKeyEnvVar}=${t.apiKey}
60
+ ${n}`}function B(e){return L($(e)).toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^[-._]+/,"")||E}function J(e,t,n){return`${JSON.stringify({name:B(e),version:"0.0.0",private:!0,type:"module",scripts:{hello:"node --env-file=.env hello.mjs"},engines:{node:">=20.6"},dependencies:{[t.packageName]:n}},null,2)}
61
+ `}function M(e,t){return`# ${e.title}
62
+
63
+ A minimal project wired to the hosted Hyperscale SDK for this product.
64
+
65
+ - \`package.json\` pins \`${e.packageName}@${t}\`, the version the
66
+ registry served when this project was created.
67
+ - \`.npmrc\` points the \`@hyperscale\` scope at the product's registry and
68
+ reads the key from \`${e.apiKeyEnvVar}\`.
69
+ - \`.env\` carries the key this project was created with. It is gitignored;
70
+ rotate it from the Developers desk whenever you need to.
71
+ - \`hello.mjs\` makes the product's first read call through the SDK.
72
+
73
+ ## Run
74
+
75
+ \`\`\`bash
76
+ npm install
77
+ npm run hello
78
+ \`\`\`
79
+
80
+ The SDK's own README (\`node_modules/${e.packageName}/README.md\`)
81
+ carries the full first-call, retries, pagination, and webhook guidance. The
82
+ Hyperscale CLI drives the same surface from the shell:
83
+
84
+ \`\`\`bash
85
+ bunx @hyperscale/cli ops list
86
+ \`\`\`
87
+
88
+ Needs Node 20.6 or newer (\`--env-file\`).
89
+ `}function z(e,t,n,r){return[{path:".env",contents:Y(t,n)},{path:".gitignore",contents:`node_modules/
90
+ .env
91
+ `},{path:".npmrc",contents:V(t)},{path:"README.md",contents:M(t,r)},{path:"hello.mjs",contents:F(t,n.environment)},{path:"package.json",contents:J(e,t,r)}]}function G(e,t){const n=$(e);if(x(n)&&b(n).length>0)throw new i(`${e} already exists and is not empty. Pick a new directory.`);U(n,{recursive:!0});for(const r of t)P(K(n,r.path),r.contents);return n}function W(e,t,n){return new Promise((r,o)=>{const s=R("npm",["install","--no-audit","--no-fund"],{cwd:e,env:{...process.env,[t.apiKeyEnvVar]:n.apiKey},stdio:["ignore",2,2]});s.on("error",a=>{o(new i(`npm install could not start: ${a.message}. The project is written; fix the cause and run npm install in it.`))}),s.on("exit",a=>{if(a===0){r();return}o(new i(`npm install failed with exit code ${a}. The project is written; fix the cause and run npm install in it.`))})})}function p(e){process.stdout.write(`${e}
92
+ `)}async function Z(){const{readFileSync:e}=await import("node:fs");return JSON.parse(e(new URL("./package.json",import.meta.url),"utf8")).version}async function q(e,t){const{flags:n,positional:r}=j(e);if(n["--version"])return p(await Z()),0;if(n["--help"])return process.stdout.write(T),0;if(r.length>1)throw new i("At most one directory argument is allowed.");const o=r[0]??E,s=C(n,t),a=await D(s),c=await H(s,a),m=G(o,z(o,a,s,c)),h=!n["--no-install"];h&&await W(m,a,s);const l=A(a);return n["--json"]?(p(JSON.stringify({baseUrl:s.baseUrl,directory:m,environment:s.environment,helloOperation:l??null,installed:h,packageName:a.packageName,product:a.title,version:c},null,2)),0):(p(`Created ${o} for ${a.title}.`),p(""),p(` ${a.packageName}@${c} (${s.environment})`),h||p(" npm install"),p(l?` npm run hello calls ${l}`:" npm run hello constructs the client; see README.md for the first call"),0)}q(process.argv.slice(2),process.env).then(e=>{process.exitCode=e},e=>{e instanceof i?process.stderr.write(`${e.message}
93
+ `):console.error(e),process.exitCode=1});
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@hyperscale0/create",
3
+ "version": "1.0.0-alpha.1",
4
+ "description": "The Hyperscale project launcher: scaffold a minimal project wired to one Product's hosted SDK.",
5
+ "license": "LicenseRef-Hyperscale-Proprietary",
6
+ "author": "Hyperscale LLC",
7
+ "contributors": [
8
+ "Meshael AlBakaawi",
9
+ "Amir Ayub",
10
+ "Sara AlBakaawi"
11
+ ],
12
+ "type": "module",
13
+ "bin": {
14
+ "create-hyperscale": "create-hyperscale.js"
15
+ },
16
+ "engines": {
17
+ "node": ">=20"
18
+ },
19
+ "homepage": "https://hyperscale0.ai",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ }
23
+ }