Skip to content

Commit 5bc4a49

Browse files
committed
Merge remote-tracking branch 'origin/develop' into 4504-p3-glide-bug-npx-poly-prepare-does-not-find-any-deployables-in-windows
2 parents dedee00 + d166c4b commit 5bc4a49

21 files changed

+843
-17
lines changed

index.d.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@ type Visibility = 'PUBLIC' | 'TENANT' | 'ENVIRONMENT';
66
type PolyDeployable<CustomConfig extends Record<string, any> = {}> = {
77
context: string;
88
name: string;
9+
description?: string;
910
disableAi?: boolean; // Disable use of AI for filling in missing descriptions
1011
} & CustomConfig;
1112

12-
type PolyFunction = PolyDeployable<{ logsEnabled?: boolean; visibility?: Visibility }>;
13+
type PolyFunction = PolyDeployable<{ visibility?: Visibility }>;
1314

14-
export type PolyServerFunction = PolyFunction & { alwaysOn?: boolean };
15+
export type PolyServerFunction = PolyFunction & {
16+
alwaysOn?: boolean;
17+
logsEnabled?: boolean;
18+
serverSideAsync?: boolean;
19+
cachePolyLibrary?: boolean;
20+
generateContexts?: string[];
21+
};
1522

1623
export type PolyClientFunction = PolyFunction;
1724

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "polyapi",
3-
"version": "0.23.26",
3+
"version": "0.24.3",
44
"description": "Poly is a CLI tool to help create and manage your Poly definitions.",
55
"license": "MIT",
66
"repository": {
@@ -28,6 +28,7 @@
2828
"prepublishOnly": "npm run lint && npm run build",
2929
"preversion": "npm run lint",
3030
"postversion": "git push && git push --tags",
31+
3132
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
3233
},
3334
"devDependencies": {

src/cli.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,47 @@ import { loadConfig } from './config';
88
import { type RenameT } from './commands/model';
99
import { DEFAULT_POLY_PATH } from './constants';
1010
import { isValidHttpUrl } from './utils';
11+
import fs from 'fs';
12+
import path from 'path';
1113

1214
if (process.env.NO_COLOR) {
1315
// Support NO_COLOR env variable https://no-color.org/
1416
chalk.level = 0;
1517
}
1618

19+
const showWelcomeIfFirstTime = () => {
20+
try {
21+
const polyDir = DEFAULT_POLY_PATH;
22+
const welcomeFile = path.join(polyDir, '.welcome-shown');
23+
24+
// If welcome has already been shown, return early
25+
if (fs.existsSync(welcomeFile)) {
26+
return;
27+
}
28+
29+
// Get version from package.json
30+
const packagePath = path.join(__dirname, '..', 'package.json');
31+
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
32+
const version = packageJson.version;
33+
34+
// Show welcome message
35+
console.log('');
36+
console.log(chalk.green('✓ PolyAPI SDK installed successfully!'));
37+
console.log(chalk.blue(`📦 Version: ${version}`));
38+
console.log('');
39+
console.log(chalk.yellow('Getting started:'));
40+
console.log(' • Run ' + chalk.cyan('poly --help') + ' to see all available commands');
41+
console.log(' • Run ' + chalk.cyan('poly setup') + ' to configure your Poly connection');
42+
console.log('');
43+
44+
// Ensure .poly directory exists and mark welcome as shown
45+
fs.mkdirSync(polyDir, { recursive: true });
46+
fs.writeFileSync(welcomeFile, new Date().toISOString());
47+
} catch (error) {
48+
// Silently fail if there's an issue - don't break the CLI
49+
}
50+
};
51+
1752
const checkPolyConfig = (polyPath: string) => {
1853
loadConfig(polyPath);
1954

@@ -24,6 +59,9 @@ const checkPolyConfig = (polyPath: string) => {
2459
return true;
2560
};
2661

62+
// Show welcome message on first usage
63+
showWelcomeIfFirstTime();
64+
2765
void yargs
2866
.usage('$0 <cmd> [args]')
2967
.command(
@@ -236,6 +274,10 @@ void yargs
236274
.option('execution-api-key', {
237275
describe: 'Optional API key for server functions',
238276
type: 'string',
277+
})
278+
.option('cache-poly-library', {
279+
describe: 'Server function only - cache the poly library to improve function performance',
280+
type: 'boolean',
239281
}),
240282
async ({
241283
name,
@@ -247,6 +289,7 @@ void yargs
247289
logs,
248290
generateContexts,
249291
executionApiKey,
292+
cachePolyLibrary,
250293
}) => {
251294
const logsEnabled =
252295
logs === 'enabled' ? true : logs === 'disabled' ? false : undefined;
@@ -266,6 +309,8 @@ void yargs
266309
? 'Invalid value for `logs` option.'
267310
: executionApiKey && !uuidValidate(executionApiKey)
268311
? 'Invalid value for `execution-api-key`. Must be a valid PolyAPI Key.'
312+
: cachePolyLibrary && !server
313+
? 'Option `cache-poly-library` is only for server functions (--server).'
269314
: '';
270315
if (err) {
271316
shell.echo(chalk.redBright('ERROR:'), err);
@@ -286,6 +331,7 @@ void yargs
286331
logsEnabled,
287332
generateContexts,
288333
executionApiKey,
334+
cachePolyLibrary,
289335
);
290336
},
291337
);

src/commands/function.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import fs from 'fs';
32
import chalk from 'chalk';
43
import shell from 'shelljs';
@@ -31,6 +30,7 @@ export const addOrUpdateCustomFunction = async (
3130
logsEnabled: boolean | undefined,
3231
generateContexts: string | undefined,
3332
executionApiKey: string | null | undefined,
33+
cachePolyLibrary: boolean | undefined,
3434
) => {
3535
loadConfig(polyPath);
3636

@@ -96,6 +96,7 @@ export const addOrUpdateCustomFunction = async (
9696
const other: Record<string, any> = {};
9797
if (generateContexts) { other.generateContexts = generateContexts.split(','); }
9898
if (logsEnabled !== undefined) other.logsEnabled = logsEnabled;
99+
if (cachePolyLibrary !== undefined) other.cachePolyLibrary = cachePolyLibrary;
99100

100101
customFunction = await createOrUpdateServerFunction(
101102
context,

src/commands/generate/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ServerFunctionSpecification,
1212
ServerVariableSpecification,
1313
Specification,
14+
TableSpecification,
1415
WebhookHandleSpecification,
1516
} from '../../types';
1617
import { getSpecs } from '../../api';
@@ -37,6 +38,7 @@ import {
3738
setGenerationErrors,
3839
} from './types';
3940
import { generateSchemaTSDeclarationFiles } from './schemaTypes';
41+
import { generateTableTSDeclarationFiles } from './table';
4042

4143
// Register the eq helper for equality comparison
4244
handlebars.registerHelper('eq', (a, b) => a === b);
@@ -62,6 +64,7 @@ const prepareDir = async (polyPath: string) => {
6264
fs.mkdirSync(`${libPath}/webhooks`);
6365
fs.mkdirSync(`${libPath}/server`);
6466
fs.mkdirSync(`${libPath}/vari`);
67+
fs.mkdirSync(`${libPath}/tabi`);
6568
fs.mkdirSync(`${libPath}/schemas`);
6669

6770
if (polyPath !== DEFAULT_POLY_PATH) {
@@ -138,6 +141,9 @@ const generateJSFiles = async (
138141
const serverVariables = specs.filter(
139142
(spec) => spec.type === 'serverVariable',
140143
) as ServerVariableSpecification[];
144+
const tables = specs.filter(
145+
(spec) => spec.type === 'table',
146+
) as TableSpecification[];
141147

142148
await generateIndexJSFile(libPath);
143149
await generatePolyCustomJSFile(libPath);
@@ -164,6 +170,10 @@ const generateJSFiles = async (
164170
generateServerVariableJSFiles(libPath, serverVariables),
165171
'variables',
166172
);
173+
await tryAsync(
174+
generateTableJSFiles(libPath, tables),
175+
'tables',
176+
);
167177

168178
return customFnCodeGenerationErrors;
169179
};
@@ -323,6 +333,18 @@ const generateServerVariableJSFiles = async (
323333
);
324334
};
325335

336+
const generateTableJSFiles = async (
337+
libPath: string,
338+
specifications: TableSpecification[],
339+
) => {
340+
const tablesJSTemplate = handlebars.compile(loadTemplate('tabi/tables.js.hbs'));
341+
fs.writeFileSync(
342+
`${libPath}/tabi/tables.js`,
343+
tablesJSTemplate({ specifications }),
344+
);
345+
fs.copyFileSync(templateUrl('tabi/index.js'), `${libPath}/tabi/index.js`);
346+
};
347+
326348
const generateAuthFunctionJSFiles = async (
327349
libPath: string,
328350
specifications: AuthFunctionSpecification[],
@@ -607,6 +629,13 @@ export const generateSpecs = async (
607629
),
608630
'schemas',
609631
);
632+
await tryAsync(
633+
generateTableTSDeclarationFiles(
634+
libPath,
635+
filteredSpecs.filter((s) => s.type === 'table') as TableSpecification[],
636+
),
637+
'table types',
638+
);
610639
}
611640

612641
generateContextDataFile(libPath, filteredSpecs);

src/commands/generate/schemaTypes.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,12 @@ export type JsonSchema = {
5656
$id?: string;
5757
$ref?: string;
5858
$schema?: string;
59-
// eslint-disable-next-line @typescript-eslint/naming-convention
60-
'x-poly-ref'?: SchemaRef;
6159
deprecated?: boolean;
6260
nullable?: boolean;
6361
enum?: ConstValueT[];
6462
const?: ConstValueT;
6563
definitions?: Record<string, JsonSchema>;
64+
'x-poly-ref'?: SchemaRef;
6665
[k: string]: unknown;
6766
};
6867

@@ -72,7 +71,7 @@ export type SchemaSpec = Omit<SchemaSpecification, 'definition'> & {
7271

7372
type SchemaTree = Record<string, SchemaSpec | Record<string, SchemaSpec>>;
7473

75-
const ws = memoize((depth = 1) =>
74+
export const ws = memoize((depth = 1) =>
7675
depth < 0 ? '' : new Array(depth).fill(' ').join(''),
7776
);
7877
const end = memoize((nested?: NestedT) =>
@@ -216,12 +215,13 @@ const printObjectSchema: PrintSchemaFn = (
216215
schema.description,
217216
depth,
218217
schema.deprecated,
219-
)}${ws(depth)}${printTypeName(schema.title, key, nested, optional)}{`;
218+
)}${ws(depth)}${printTypeName(schema.title, key, nested, optional)}`;
220219
if (
221220
schema.properties ||
222221
schema.patternProperties ||
223222
schema.additionalProperties
224223
) {
224+
result = `${result}{`;
225225
if (schema.properties) {
226226
Object.entries(schema.properties).forEach(([k, v]) => {
227227
result = `${result}${EOL}${printSchemaAsType(
@@ -265,8 +265,12 @@ const printObjectSchema: PrintSchemaFn = (
265265
}
266266
}
267267
result = `${result}${EOL}${ws(depth)}}${end(nested)}`;
268+
} else if (nested) {
269+
// Nested object type with no properties falls back to record type
270+
result = `${result}Record<string, unknown>${end(nested)}`;
268271
} else {
269-
result = `${result}}${end(nested)}`;
272+
// Non-nested object type uses empty interface {}
273+
result = `${result}{}${end(nested)}`;
270274
}
271275
return result;
272276
};
@@ -500,7 +504,7 @@ const printConstSchema: PrintSchemaFn = (
500504
}${end(nested)}`;
501505
};
502506

503-
const printSchemaAsType: PrintSchemaFn = (
507+
export const printSchemaAsType: PrintSchemaFn = (
504508
schema: JsonSchema,
505509
key,
506510
depth = 0,

0 commit comments

Comments
 (0)