@ptkl/toolkit 0.7.2 → 0.8.8

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.
@@ -0,0 +1,242 @@
1
+ /**
2
+ * IDL → TypeScript module-augmentation generator.
3
+ *
4
+ * Mirror of the runtime idlToDts.js used by the Monaco editor, but output
5
+ * targets a `declare module "@ptkl/sdk"` block so the generated `.d.ts` file
6
+ * extends the SDK's open interfaces at build time.
7
+ */
8
+ // ── Primitive type conversion ─────────────────────────────────────────────────
9
+ function idlTypeNodeToTs(node, indent = 0) {
10
+ if (!node)
11
+ return 'any';
12
+ switch (node.type) {
13
+ case 'string': return 'string';
14
+ case 'number': return 'number';
15
+ case 'boolean': return 'boolean';
16
+ case 'any': return 'any';
17
+ case 'array':
18
+ return node.items ? `Array<${idlTypeNodeToTs(node.items, indent)}>` : 'any[]';
19
+ case 'object':
20
+ if (node.fields && Object.keys(node.fields).length > 0) {
21
+ return objectShape(node.fields, indent);
22
+ }
23
+ return 'Record<string, any>';
24
+ case 'relation':
25
+ // When used as a standalone type (not as a field entry),
26
+ // a relation is a UUID string.
27
+ return 'string';
28
+ default:
29
+ // NamedRef or unknown — treat as any
30
+ return 'any';
31
+ }
32
+ }
33
+ const I = ' '; // indent unit
34
+ function objectShape(fields, indent = 0) {
35
+ const entries = Object.entries(fields);
36
+ // Keep short objects (≤3 simple fields) inline
37
+ if (entries.length <= 3 && entries.every(([, n]) => !n.fields && n.type !== 'object')) {
38
+ const props = entries.map(([key, node]) => {
39
+ const opt = node.required === false || node.required === undefined;
40
+ return `${key}${opt ? '?' : ''}: ${idlTypeNodeToTs(node, indent)}`;
41
+ });
42
+ return `{ ${props.join('; ')} }`;
43
+ }
44
+ const pad = I.repeat(indent + 1);
45
+ const closePad = I.repeat(indent);
46
+ const lines = entries.map(([key, node]) => {
47
+ const opt = node.required === false || node.required === undefined;
48
+ return `${pad}${key}${opt ? '?' : ''}: ${idlTypeNodeToTs(node, indent + 1)};`;
49
+ });
50
+ return `{\n${lines.join('\n')}\n${closePad}}`;
51
+ }
52
+ // ── Relation expansion ────────────────────────────────────────────────────────
53
+ /**
54
+ * Expands a field map into TypeScript property lines. Relation fields produce
55
+ * two entries: the UUID field (`field: string`) and the hydrated reference
56
+ * (`field_RefObj: T` or `field_RefObj: Array<T>`).
57
+ */
58
+ function expandFieldLines(fields, pad, indent) {
59
+ const lines = [];
60
+ for (const [k, node] of Object.entries(fields)) {
61
+ const opt = node.required === false || node.required === undefined;
62
+ if (node.type === 'relation') {
63
+ // UUID string field
64
+ lines.push(`${pad}${k}${opt ? '?' : ''}: string;`);
65
+ // Hydrated _RefObj field
66
+ const itemTs = node.items ? idlTypeNodeToTs(node.items, indent) : 'any';
67
+ const refType = node.cardinality === 'many' ? `Array<${itemTs}>` : itemTs;
68
+ lines.push(`${pad}${k}_RefObj?: ${refType};`);
69
+ }
70
+ else {
71
+ lines.push(`${pad}${k}${opt ? '?' : ''}: ${idlTypeNodeToTs(node, indent)};`);
72
+ }
73
+ }
74
+ return lines;
75
+ }
76
+ /**
77
+ * Like objectShape but expands relation fields into two properties.
78
+ */
79
+ function objectShapeWithRelations(fields, indent = 0) {
80
+ const entries = Object.entries(fields);
81
+ const hasRelation = entries.some(([, n]) => n.type === 'relation');
82
+ if (!hasRelation)
83
+ return objectShape(fields, indent); // fast path
84
+ const pad = I.repeat(indent + 1);
85
+ const closePad = I.repeat(indent);
86
+ const lines = expandFieldLines(fields, pad, indent + 1);
87
+ return `{\n${lines.join('\n')}\n${closePad}}`;
88
+ }
89
+ // ── Top-level generators ──────────────────────────────────────────────────────
90
+ function buildComponentModels(components, baseIndent) {
91
+ const entries = [];
92
+ const d = baseIndent;
93
+ const pad = I.repeat(d);
94
+ for (const [ref, comp] of Object.entries(components)) {
95
+ if (!comp)
96
+ continue;
97
+ // Collect all schema names from base + extensions.
98
+ const schemaNames = new Set();
99
+ for (const s of Object.keys(comp.schemas ?? {}))
100
+ schemaNames.add(s);
101
+ for (const ext of Object.values(comp.extensions ?? {})) {
102
+ if (!ext)
103
+ continue;
104
+ for (const s of Object.keys(ext.schemas ?? {}))
105
+ schemaNames.add(s);
106
+ }
107
+ for (const schema of schemaNames) {
108
+ const key = schema === 'default' ? ref : `${ref}.${schema}`;
109
+ const baseFields = comp.schemas?.[schema]?.fields;
110
+ // Collect extension entries for this schema.
111
+ const extEntries = [];
112
+ for (const [extName, ext] of Object.entries(comp.extensions ?? {})) {
113
+ if (!ext)
114
+ continue;
115
+ const extSchemaFields = ext.schemas?.[schema]?.fields;
116
+ if (extSchemaFields && Object.keys(extSchemaFields).length > 0) {
117
+ extEntries.push([extName, extSchemaFields]);
118
+ }
119
+ }
120
+ const hasBase = baseFields && Object.keys(baseFields).length > 0;
121
+ const hasExt = extEntries.length > 0;
122
+ if (!hasBase && !hasExt) {
123
+ entries.push(`${pad}${JSON.stringify(key)}: Record<string, any>;`);
124
+ continue;
125
+ }
126
+ const propLines = [];
127
+ if (hasBase) {
128
+ propLines.push(...expandFieldLines(baseFields, `${pad}${I}`, d + 1));
129
+ }
130
+ if (hasExt) {
131
+ const extInner = [];
132
+ for (const [extName, extFields] of extEntries) {
133
+ extInner.push(`${pad}${I}${I}${extName}: ${objectShapeWithRelations(extFields, d + 2)};`);
134
+ }
135
+ propLines.push(`${pad}${I}extensions: {\n${extInner.join('\n')}\n${pad}${I}};`);
136
+ }
137
+ entries.push(`${pad}${JSON.stringify(key)}: {\n${propLines.join('\n')}\n${pad}};`);
138
+ }
139
+ }
140
+ if (entries.length === 0)
141
+ return '';
142
+ return entries.join('\n');
143
+ }
144
+ function buildComponentFunctions(components, baseIndent) {
145
+ const entries = [];
146
+ const d = baseIndent;
147
+ const pad = I.repeat(d);
148
+ for (const [ref, comp] of Object.entries(components)) {
149
+ if (!comp)
150
+ continue;
151
+ const allFunctions = [
152
+ ...(comp.functions ?? []),
153
+ ...Object.values(comp.extensions ?? {}).flatMap(ext => ext?.functions ?? []),
154
+ ];
155
+ if (allFunctions.length === 0)
156
+ continue;
157
+ const fnLines = [];
158
+ for (const fn of allFunctions) {
159
+ const parts = [];
160
+ if (fn.input && Object.keys(fn.input).length > 0)
161
+ parts.push(`input: ${objectShape(fn.input, d + 2)}`);
162
+ if (fn.output)
163
+ parts.push(`output: ${idlTypeNodeToTs(fn.output, d + 2)}`);
164
+ if (parts.length === 0)
165
+ continue;
166
+ fnLines.push(`${pad}${I}${JSON.stringify(fn.name)}: { ${parts.join('; ')} };`);
167
+ }
168
+ if (fnLines.length > 0)
169
+ entries.push(`${pad}${JSON.stringify(ref)}: {\n${fnLines.join('\n')}\n${pad}};`);
170
+ }
171
+ if (entries.length === 0)
172
+ return '';
173
+ return entries.join('\n');
174
+ }
175
+ function buildPlatformFunctions(functions, baseIndent) {
176
+ const entries = [];
177
+ const d = baseIndent;
178
+ const pad = I.repeat(d);
179
+ for (const [name, sig] of Object.entries(functions)) {
180
+ if (!sig)
181
+ continue;
182
+ const parts = [];
183
+ if (sig.input && Object.keys(sig.input).length > 0)
184
+ parts.push(`input: ${objectShape(sig.input, d + 1)}`);
185
+ if (sig.output)
186
+ parts.push(`output: ${idlTypeNodeToTs(sig.output, d + 1)}`);
187
+ if (parts.length === 0)
188
+ continue;
189
+ entries.push(`${pad}${JSON.stringify(name)}: { ${parts.join('; ')} };`);
190
+ }
191
+ if (entries.length === 0)
192
+ return '';
193
+ return entries.join('\n');
194
+ }
195
+ // ── Main export ───────────────────────────────────────────────────────────────
196
+ /**
197
+ * Converts an IDL response into a `declare module "@ptkl/sdk"` augmentation
198
+ * block. Write the output to a `.d.ts` file and include it in your project
199
+ * (e.g., via `tsconfig.json` `"include"` or a triple-slash reference).
200
+ */
201
+ export function idlToModuleAugmentation(idl) {
202
+ const hasComponents = idl.components && Object.keys(idl.components).length > 0;
203
+ const hasFunctions = idl.functions && Object.keys(idl.functions).length > 0;
204
+ if (!hasComponents && !hasFunctions) {
205
+ return `// No IDL definitions found — nothing to generate.\n`;
206
+ }
207
+ const date = new Date().toISOString().slice(0, 10);
208
+ const lines = [
209
+ `// Generated by ptkl generate-types on ${date}`,
210
+ `// Do not edit manually — re-run \`ptkl generate-types\` to refresh.`,
211
+ ``,
212
+ `import "@ptkl/sdk";`,
213
+ `import "@ptkl/sdk/beta";`,
214
+ ];
215
+ // Declare interfaces once globally, then extend into both modules.
216
+ const ifaceNames = [];
217
+ if (hasComponents) {
218
+ const models = buildComponentModels(idl.components, 1);
219
+ if (models) {
220
+ lines.push(``, `interface _CM {\n${models}\n}`);
221
+ ifaceNames.push('ComponentModels extends _CM');
222
+ }
223
+ const fns = buildComponentFunctions(idl.components, 1);
224
+ if (fns) {
225
+ lines.push(``, `interface _CF {\n${fns}\n}`);
226
+ ifaceNames.push('ComponentFunctions extends _CF');
227
+ }
228
+ }
229
+ if (hasFunctions) {
230
+ const platFns = buildPlatformFunctions(idl.functions, 1);
231
+ if (platFns) {
232
+ lines.push(``, `interface _PF {\n${platFns}\n}`);
233
+ ifaceNames.push('PlatformFunctions extends _PF');
234
+ }
235
+ }
236
+ if (ifaceNames.length > 0) {
237
+ const augBody = ifaceNames.map(n => ` interface ${n} {}`).join('\n');
238
+ lines.push(``, `declare module "@ptkl/sdk" {\n${augBody}\n}`, ``, `declare module "@ptkl/sdk/beta" {\n${augBody}\n}`);
239
+ }
240
+ lines.push(``);
241
+ return lines.join('\n');
242
+ }
package/dist/lib/util.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
2
- import Api from '@ptkl/sdk';
2
+ import { Platform } from '@ptkl/sdk';
3
3
  export default class Util {
4
4
  static profilePath = `${process.env.HOME}/.ptkl`;
5
5
  static fileName = "profiles.json";
@@ -69,6 +69,6 @@ export default class Util {
69
69
  }
70
70
  static getClientForProfile() {
71
71
  const profile = Util.getCurrentProfile();
72
- return new Api({ project: profile.project, token: profile.token, host: profile.host });
72
+ return new Platform({ project: profile.project, token: profile.token, host: profile.host });
73
73
  }
74
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ptkl/toolkit",
3
- "version": "0.7.2",
3
+ "version": "0.8.8",
4
4
  "description": "A command-line toolkit for managing Protokol platform applications, profiles, functions, and components",
5
5
  "keywords": [
6
6
  "protokol",
@@ -28,9 +28,17 @@
28
28
  "prepublishOnly": "npm run build"
29
29
  },
30
30
  "dependencies": {
31
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
32
+ "@babel/plugin-proposal-decorators": "^7.28.0",
33
+ "@babel/plugin-transform-class-static-block": "^7.28.3",
34
+ "@babel/preset-react": "^7.28.5",
35
+ "@babel/preset-typescript": "^7.28.5",
31
36
  "@babel/standalone": "^7.26.10",
32
37
  "@inquirer/password": "^4.0.21",
33
- "@ptkl/sdk": "^0.9.12",
38
+ "@ptkl/sdk": "^1.5.1",
39
+ "@rollup/plugin-babel": "^6.1.0",
40
+ "@rollup/plugin-commonjs": "^29.0.0",
41
+ "@rollup/plugin-node-resolve": "^16.0.3",
34
42
  "@types/axios": "^0.14.0",
35
43
  "@types/commander": "^2.12.2",
36
44
  "@types/js-yaml": "^4.0.9",
@@ -45,6 +53,7 @@
45
53
  "lodash": "^4.17.21",
46
54
  "open": "^10.1.2",
47
55
  "rollup": "^4.34.6",
56
+ "sass": "^1.95.1",
48
57
  "tar": "^7.4.3",
49
58
  "vite": "^6.0.6",
50
59
  "vue-template-compiler": "^2.7.16",