create-harper 0.11.0 → 0.12.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/index.js +1 -7
- package/lib/fs/crawlTemplateDir.js +2 -9
- package/lib/steps/scaffoldProject.js +2 -3
- package/package.json +1 -1
- package/template-react/AGENTS.md +1 -1
- package/template-react/resources/README.md +11 -0
- package/template-react/schemas/README.md +11 -0
- package/template-react-ts/AGENTS.md +1 -1
- package/template-react-ts/resources/README.md +11 -0
- package/template-react-ts/schemas/README.md +11 -0
- package/template-vanilla/AGENTS.md +1 -1
- package/template-vanilla/resources/README.md +11 -0
- package/template-vanilla/schemas/README.md +11 -0
- package/template-vanilla-ts/AGENTS.md +1 -1
- package/template-vanilla-ts/resources/README.md +11 -0
- package/template-vanilla-ts/schemas/README.md +11 -0
- package/lib/constants/exampleFiles.js +0 -33
- package/lib/steps/getExamples.js +0 -49
- package/template-react/resources/examplePeople.js +0 -14
- package/template-react/resources/exampleSocket.js +0 -34
- package/template-react/resources/greeting.js +0 -10
- package/template-react/schemas/exampleCat.graphql +0 -6
- package/template-react/schemas/examplePeople.graphql +0 -7
- package/template-react-ts/resources/examplePeople.ts +0 -20
- package/template-react-ts/resources/exampleSocket.ts +0 -41
- package/template-react-ts/resources/greeting.ts +0 -29
- package/template-react-ts/schemas/examplePeople.graphql +0 -7
- package/template-vanilla/resources/examplePeople.js +0 -14
- package/template-vanilla/resources/exampleSocket.js +0 -34
- package/template-vanilla/resources/greeting.js +0 -10
- package/template-vanilla/schemas/examplePeople.graphql +0 -7
- package/template-vanilla-ts/resources/examplePeople.ts +0 -20
- package/template-vanilla-ts/resources/exampleSocket.ts +0 -41
- package/template-vanilla-ts/resources/greeting.ts +0 -29
- package/template-vanilla-ts/schemas/examplePeople.graphql +0 -7
- /package/template-react/skills/{adding-tables.md → adding-tables-with-schemas.md} +0 -0
- /package/template-react-ts/skills/{adding-tables.md → adding-tables-with-schemas.md} +0 -0
- /package/template-vanilla/skills/{adding-tables.md → adding-tables-with-schemas.md} +0 -0
- /package/template-vanilla-ts/skills/{adding-tables.md → adding-tables-with-schemas.md} +0 -0
package/index.js
CHANGED
|
@@ -5,7 +5,6 @@ import { helpMessage } from './lib/constants/helpMessage.js';
|
|
|
5
5
|
import { pkgFromUserAgent } from './lib/pkg/pkgFromUserAgent.js';
|
|
6
6
|
import { checkForUpdate } from './lib/steps/checkForUpdate.js';
|
|
7
7
|
import { getEnvVars } from './lib/steps/getEnvVars.js';
|
|
8
|
-
import { getExamples } from './lib/steps/getExamples.js';
|
|
9
8
|
import { getPackageName } from './lib/steps/getPackageName.js';
|
|
10
9
|
import { getProjectName } from './lib/steps/getProjectName.js';
|
|
11
10
|
import { getRunAppImmediately } from './lib/steps/getRunAppImmediately.js';
|
|
@@ -60,11 +59,6 @@ async function init() {
|
|
|
60
59
|
if (templateResult.cancelled) { return cancel(); }
|
|
61
60
|
const { template } = templateResult;
|
|
62
61
|
|
|
63
|
-
// Choose which examples to include
|
|
64
|
-
const examplesResult = await getExamples(template, interactive);
|
|
65
|
-
if (examplesResult.cancelled) { return cancel(); }
|
|
66
|
-
const { excludedFiles } = examplesResult;
|
|
67
|
-
|
|
68
62
|
// Get environment variables for .env file
|
|
69
63
|
const envVarsResult = await getEnvVars(interactive, template, args.deploymentUsername, args.deploymentURL);
|
|
70
64
|
if (envVarsResult.cancelled) { return cancel(); }
|
|
@@ -80,7 +74,7 @@ async function init() {
|
|
|
80
74
|
// Write out the contents based on all prior steps.
|
|
81
75
|
const cwd = process.cwd();
|
|
82
76
|
const root = path.join(cwd, targetDir);
|
|
83
|
-
scaffoldProject(root, projectName, packageName, template, envVars
|
|
77
|
+
scaffoldProject(root, projectName, packageName, template, envVars);
|
|
84
78
|
|
|
85
79
|
// Log out the next steps.
|
|
86
80
|
installAndOptionallyStart(root, pkgManager, immediate, args.skipInstall);
|
|
@@ -9,23 +9,16 @@ import { copyFile } from './copyFile.js';
|
|
|
9
9
|
* @param {string} root - The current target directory.
|
|
10
10
|
* @param {string} dir - The current source directory in the template.
|
|
11
11
|
* @param {Record<string, string> | ((content: string) => string)} substitutions - A mapping of strings to replace or a function that returns the updated content.
|
|
12
|
-
* @param {string[]} [excludedFiles] - A list of relative paths to exclude from copying.
|
|
13
|
-
* @param {string} [templateRootDir] - The absolute path to the root of the template directory (internal).
|
|
14
12
|
*/
|
|
15
|
-
export function crawlTemplateDir(root, dir, substitutions
|
|
13
|
+
export function crawlTemplateDir(root, dir, substitutions) {
|
|
16
14
|
const files = fs.readdirSync(dir);
|
|
17
15
|
for (const file of files) {
|
|
18
16
|
const templatePath = path.join(dir, file);
|
|
19
|
-
const relativePath = path.relative(templateRootDir, templatePath).split(path.sep).join('/');
|
|
20
|
-
|
|
21
|
-
if (excludedFiles.includes(relativePath)) {
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
17
|
|
|
25
18
|
const targetPath = path.join(root, renameFiles[file] ?? file);
|
|
26
19
|
if (fs.lstatSync(templatePath).isDirectory()) {
|
|
27
20
|
fs.mkdirSync(targetPath, { recursive: true });
|
|
28
|
-
crawlTemplateDir(targetPath, templatePath, substitutions
|
|
21
|
+
crawlTemplateDir(targetPath, templatePath, substitutions);
|
|
29
22
|
} else {
|
|
30
23
|
copyFile(templatePath, targetPath, substitutions);
|
|
31
24
|
}
|
|
@@ -12,9 +12,8 @@ import { crawlTemplateDir } from '../fs/crawlTemplateDir.js';
|
|
|
12
12
|
* @param {string} packageName - The name for the package.json.
|
|
13
13
|
* @param {string} template - The template name to use.
|
|
14
14
|
* @param {import('./getEnvVars.js').EnvVars} [envVars] - Environment variables to substitute.
|
|
15
|
-
* @param {string[]} [excludedFiles] - A list of files to exclude from the template.
|
|
16
15
|
*/
|
|
17
|
-
export function scaffoldProject(root, projectName, packageName, template, envVars
|
|
16
|
+
export function scaffoldProject(root, projectName, packageName, template, envVars) {
|
|
18
17
|
fs.mkdirSync(root, { recursive: true });
|
|
19
18
|
prompts.log.step(`Scaffolding project in ${root}...`);
|
|
20
19
|
|
|
@@ -34,5 +33,5 @@ export function scaffoldProject(root, projectName, packageName, template, envVar
|
|
|
34
33
|
'..',
|
|
35
34
|
`template-${template}`,
|
|
36
35
|
);
|
|
37
|
-
crawlTemplateDir(root, templateDir, substitutions
|
|
36
|
+
crawlTemplateDir(root, templateDir, substitutions);
|
|
38
37
|
}
|
package/package.json
CHANGED
package/template-react/AGENTS.md
CHANGED
|
@@ -4,7 +4,7 @@ This repository contains "skills" that guide AI agents in developing Harper appl
|
|
|
4
4
|
|
|
5
5
|
## Available Skills
|
|
6
6
|
|
|
7
|
-
- [Adding Tables](skills/adding-tables.md): Learn how to define schemas and enable automatic REST APIs for your database tables.
|
|
7
|
+
- [Adding Tables with Schemas](skills/adding-tables-with-schemas.md): Learn how to define schemas and enable automatic REST APIs for your database tables with schema .graphql files in Harper.
|
|
8
8
|
- [Automatic REST APIs](skills/automatic-rest-apis.md): Details on the CRUD endpoints automatically generated for exported tables.
|
|
9
9
|
- [Querying REST APIs](skills/querying-rest-apis.md): How to use filters, operators, sorting, and pagination in REST requests.
|
|
10
10
|
- [Programmatic Table Requests](skills/programmatic-table-requests.md): How to use filters, operators, sorting, and pagination in programmatic table requests.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Resources
|
|
2
|
+
|
|
3
|
+
The [schemas you define in .GraphQL files](../skills/adding-tables-with-schemas.md) will [automatically stand-up REST APIs](../skills/automatic-rest-apis.md).
|
|
4
|
+
|
|
5
|
+
But you can [extend your tables with custom logic](../skills/extending-tables.md) and [create your own resources](../skills/custom-resources.md) in this directory.
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Schemas
|
|
2
|
+
|
|
3
|
+
Your schemas are defined in `.graphql` files within this `schemas` directory. These files contain the structure and types for your database tables, allowing Harper to automatically generate REST APIs for CRUD operations.
|
|
4
|
+
|
|
5
|
+
Take a look at the [Adding Tables with Schemas](../skills/adding-tables-with-schemas.md) to learn more!
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -4,7 +4,7 @@ This repository contains "skills" that guide AI agents in developing Harper appl
|
|
|
4
4
|
|
|
5
5
|
## Available Skills
|
|
6
6
|
|
|
7
|
-
- [Adding Tables](skills/adding-tables.md): Learn how to define schemas and enable automatic REST APIs for your database tables.
|
|
7
|
+
- [Adding Tables with Schemas](skills/adding-tables-with-schemas.md): Learn how to define schemas and enable automatic REST APIs for your database tables with schema .graphql files in Harper.
|
|
8
8
|
- [Automatic REST APIs](skills/automatic-rest-apis.md): Details on the CRUD endpoints automatically generated for exported tables.
|
|
9
9
|
- [Querying REST APIs](skills/querying-rest-apis.md): How to use filters, operators, sorting, and pagination in REST requests.
|
|
10
10
|
- [Programmatic Table Requests](skills/programmatic-table-requests.md): How to use filters, operators, sorting, and pagination in programmatic table requests.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Resources
|
|
2
|
+
|
|
3
|
+
The [schemas you define in .GraphQL files](../skills/adding-tables-with-schemas.md) will [automatically stand-up REST APIs](../skills/automatic-rest-apis.md).
|
|
4
|
+
|
|
5
|
+
But you can [extend your tables with custom logic](../skills/extending-tables.md) and [create your own resources](../skills/custom-resources.md) in this directory.
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Schemas
|
|
2
|
+
|
|
3
|
+
Your schemas are defined in `.graphql` files within this `schemas` directory. These files contain the structure and types for your database tables, allowing Harper to automatically generate REST APIs for CRUD operations.
|
|
4
|
+
|
|
5
|
+
Take a look at the [Adding Tables with Schemas](../skills/adding-tables-with-schemas.md) to learn more!
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -4,7 +4,7 @@ This repository contains "skills" that guide AI agents in developing Harper appl
|
|
|
4
4
|
|
|
5
5
|
## Available Skills
|
|
6
6
|
|
|
7
|
-
- [Adding Tables](skills/adding-tables.md): Learn how to define schemas and enable automatic REST APIs for your database tables.
|
|
7
|
+
- [Adding Tables with Schemas](skills/adding-tables-with-schemas.md): Learn how to define schemas and enable automatic REST APIs for your database tables with schema .graphql files in Harper.
|
|
8
8
|
- [Automatic REST APIs](skills/automatic-rest-apis.md): Details on the CRUD endpoints automatically generated for exported tables.
|
|
9
9
|
- [Querying REST APIs](skills/querying-rest-apis.md): How to use filters, operators, sorting, and pagination in REST requests.
|
|
10
10
|
- [Programmatic Table Requests](skills/programmatic-table-requests.md): How to use filters, operators, sorting, and pagination in programmatic table requests.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Resources
|
|
2
|
+
|
|
3
|
+
The [schemas you define in .GraphQL files](../skills/adding-tables-with-schemas.md) will [automatically stand-up REST APIs](../skills/automatic-rest-apis.md).
|
|
4
|
+
|
|
5
|
+
But you can [extend your tables with custom logic](../skills/extending-tables.md) and [create your own resources](../skills/custom-resources.md) in this directory.
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Schemas
|
|
2
|
+
|
|
3
|
+
Your schemas are defined in `.graphql` files within this `schemas` directory. These files contain the structure and types for your database tables, allowing Harper to automatically generate REST APIs for CRUD operations.
|
|
4
|
+
|
|
5
|
+
Take a look at the [Adding Tables with Schemas](../skills/adding-tables-with-schemas.md) to learn more!
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -4,7 +4,7 @@ This repository contains "skills" that guide AI agents in developing Harper appl
|
|
|
4
4
|
|
|
5
5
|
## Available Skills
|
|
6
6
|
|
|
7
|
-
- [Adding Tables](skills/adding-tables.md): Learn how to define schemas and enable automatic REST APIs for your database tables.
|
|
7
|
+
- [Adding Tables with Schemas](skills/adding-tables-with-schemas.md): Learn how to define schemas and enable automatic REST APIs for your database tables with schema .graphql files in Harper.
|
|
8
8
|
- [Automatic REST APIs](skills/automatic-rest-apis.md): Details on the CRUD endpoints automatically generated for exported tables.
|
|
9
9
|
- [Querying REST APIs](skills/querying-rest-apis.md): How to use filters, operators, sorting, and pagination in REST requests.
|
|
10
10
|
- [Programmatic Table Requests](skills/programmatic-table-requests.md): How to use filters, operators, sorting, and pagination in programmatic table requests.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Resources
|
|
2
|
+
|
|
3
|
+
The [schemas you define in .GraphQL files](../skills/adding-tables-with-schemas.md) will [automatically stand-up REST APIs](../skills/automatic-rest-apis.md).
|
|
4
|
+
|
|
5
|
+
But you can [extend your tables with custom logic](../skills/extending-tables.md) and [create your own resources](../skills/custom-resources.md) in this directory.
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Schemas
|
|
2
|
+
|
|
3
|
+
Your schemas are defined in `.graphql` files within this `schemas` directory. These files contain the structure and types for your database tables, allowing Harper to automatically generate REST APIs for CRUD operations.
|
|
4
|
+
|
|
5
|
+
Take a look at the [Adding Tables with Schemas](../skills/adding-tables-with-schemas.md) to learn more!
|
|
6
|
+
|
|
7
|
+
## Want to read more?
|
|
8
|
+
|
|
9
|
+
Check out the rest of the "skills" documentation!
|
|
10
|
+
|
|
11
|
+
[AGENTS.md](../AGENTS.md)
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {Object} ExampleFile
|
|
3
|
-
* @property {string} label - The display label for the example.
|
|
4
|
-
* @property {string} value - The internal value for the example.
|
|
5
|
-
* @property {string[]} files - The files associated with this example.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The list of available example files that can be optionally included in the project.
|
|
10
|
-
* @type {ExampleFile[]}
|
|
11
|
-
*/
|
|
12
|
-
export const exampleFiles = [
|
|
13
|
-
{
|
|
14
|
-
label: 'Table schema',
|
|
15
|
-
value: 'tableSchema',
|
|
16
|
-
files: ['schemas/examplePeople.graphql'],
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
label: 'Table handling',
|
|
20
|
-
value: 'table',
|
|
21
|
-
files: ['resources/examplePeople.ts', 'resources/examplePeople.js'],
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
label: 'Resource',
|
|
25
|
-
value: 'resource',
|
|
26
|
-
files: ['resources/greeting.ts', 'resources/greeting.js'],
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
label: 'Sockets',
|
|
30
|
-
value: 'socket',
|
|
31
|
-
files: ['resources/exampleSocket.ts', 'resources/exampleSocket.js'],
|
|
32
|
-
},
|
|
33
|
-
];
|
package/lib/steps/getExamples.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import * as prompts from '@clack/prompts';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { exampleFiles } from '../constants/exampleFiles.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Step 5 (Optional): Choose which example files to include in the project.
|
|
9
|
-
*
|
|
10
|
-
* @param {string} template - The selected template name.
|
|
11
|
-
* @param {boolean} interactive - Whether the CLI is running in interactive mode.
|
|
12
|
-
* @returns {Promise<{excludedFiles: string[], cancelled: boolean}>} - A list of files to exclude based on selection, and cancellation status.
|
|
13
|
-
*/
|
|
14
|
-
export async function getExamples(template, interactive) {
|
|
15
|
-
const templateDir = path.resolve(
|
|
16
|
-
fileURLToPath(import.meta.url),
|
|
17
|
-
'..',
|
|
18
|
-
'..',
|
|
19
|
-
'..',
|
|
20
|
-
`template-${template}`,
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
const availableExamples = exampleFiles.filter((example) =>
|
|
24
|
-
example.files.some((file) => fs.existsSync(path.join(templateDir, file)))
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
if (availableExamples.length === 0 || !interactive) {
|
|
28
|
-
return { excludedFiles: [], cancelled: false };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const selectedExamples = await prompts.multiselect({
|
|
32
|
-
message: 'Select examples to include:',
|
|
33
|
-
options: availableExamples.map((example) => ({
|
|
34
|
-
label: example.label,
|
|
35
|
-
value: example.value,
|
|
36
|
-
})),
|
|
37
|
-
initialValues: availableExamples.map((example) => example.value),
|
|
38
|
-
required: false,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
if (prompts.isCancel(selectedExamples)) {
|
|
42
|
-
return { excludedFiles: [], cancelled: true };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const unselectedExamples = availableExamples.filter((example) => !selectedExamples.includes(example.value));
|
|
46
|
-
const excludedFiles = unselectedExamples.flatMap((example) => example.files);
|
|
47
|
-
|
|
48
|
-
return { excludedFiles, cancelled: false };
|
|
49
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
export class ExamplePeople extends tables.ExamplePeople {
|
|
4
|
-
// we can define our own custom POST handler
|
|
5
|
-
post(content) {
|
|
6
|
-
// do something with the incoming content;
|
|
7
|
-
return super.post(content);
|
|
8
|
-
}
|
|
9
|
-
// or custom GET handler
|
|
10
|
-
get() {
|
|
11
|
-
// we can modify this resource before returning
|
|
12
|
-
return super.get();
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Resource, tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
export class ExampleSocket extends Resource {
|
|
4
|
-
static loadAsInstance = false;
|
|
5
|
-
|
|
6
|
-
// This customizes handling the socket connections; tables can have this method too!
|
|
7
|
-
async *connect(
|
|
8
|
-
target,
|
|
9
|
-
incomingMessages,
|
|
10
|
-
) {
|
|
11
|
-
const subscription = await tables.ExamplePeople.subscribe(target);
|
|
12
|
-
if (!incomingMessages) {
|
|
13
|
-
// Server sent events, no incoming messages!
|
|
14
|
-
// Subscribe to changes to the table.
|
|
15
|
-
return subscription;
|
|
16
|
-
}
|
|
17
|
-
for await (let message of incomingMessages) {
|
|
18
|
-
const { type, id, name, tag } = message;
|
|
19
|
-
switch (type) {
|
|
20
|
-
case 'get':
|
|
21
|
-
const loaded = await tables.ExamplePeople.get(id);
|
|
22
|
-
yield {
|
|
23
|
-
type: 'get',
|
|
24
|
-
id,
|
|
25
|
-
...(loaded ? loaded : {}),
|
|
26
|
-
};
|
|
27
|
-
break;
|
|
28
|
-
case 'put':
|
|
29
|
-
await tables.ExamplePeople.put(id, { name, tag });
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
## This table is @export'ed, which means API endpoints are stood up for it automatically.
|
|
2
|
-
type ExampleCat @table @export {
|
|
3
|
-
id: ID @primaryKey # Here we define primary key (must be one)
|
|
4
|
-
name: String # we can define any other attributes here
|
|
5
|
-
tag: String @indexed # we can specify any attributes that should be indexed
|
|
6
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
## Here we can define any tables in our database. This example shows how we define a type as a table using
|
|
2
|
-
## the type name as the table name and specifying it is an "export" available in the REST and other external protocols.
|
|
3
|
-
type ExamplePeople @table @export {
|
|
4
|
-
id: ID @primaryKey # Here we define primary key (must be one)
|
|
5
|
-
name: String # we can define any other attributes here
|
|
6
|
-
tag: String @indexed # we can specify any attributes that should be indexed
|
|
7
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type RequestTargetOrId, tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
export interface ExamplePerson {
|
|
4
|
-
id: string;
|
|
5
|
-
name: string;
|
|
6
|
-
tag: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class ExamplePeople extends tables.ExamplePeople<ExamplePerson> {
|
|
10
|
-
// we can define our own custom POST handler
|
|
11
|
-
async post(target: RequestTargetOrId, newRecord: Omit<ExamplePerson, 'id'>) {
|
|
12
|
-
// do something with the incoming content;
|
|
13
|
-
return super.post(target, newRecord);
|
|
14
|
-
}
|
|
15
|
-
// or custom GET handler
|
|
16
|
-
async get(target: RequestTargetOrId): Promise<ExamplePerson> {
|
|
17
|
-
// we can modify this resource before returning
|
|
18
|
-
return super.get(target);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { type IterableEventQueue, RequestTarget, Resource, tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
interface ExampleSocketRecord {
|
|
4
|
-
id: string;
|
|
5
|
-
type?: 'get' | 'put';
|
|
6
|
-
name: string;
|
|
7
|
-
tag: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class ExampleSocket extends Resource<ExampleSocketRecord> {
|
|
11
|
-
static loadAsInstance = false;
|
|
12
|
-
|
|
13
|
-
// This customizes handling the socket connections; tables can have this method too!
|
|
14
|
-
async *connect(
|
|
15
|
-
target: RequestTarget,
|
|
16
|
-
incomingMessages: IterableEventQueue<ExampleSocketRecord>,
|
|
17
|
-
): AsyncIterable<ExampleSocketRecord> {
|
|
18
|
-
const subscription = await tables.ExamplePeople.subscribe(target);
|
|
19
|
-
if (!incomingMessages) {
|
|
20
|
-
// Server sent events, no incoming messages!
|
|
21
|
-
// Subscribe to changes to the table.
|
|
22
|
-
return subscription;
|
|
23
|
-
}
|
|
24
|
-
for await (let message of incomingMessages) {
|
|
25
|
-
const { type, id, name, tag } = message;
|
|
26
|
-
switch (type) {
|
|
27
|
-
case 'get':
|
|
28
|
-
const loaded = await tables.ExamplePeople.get(id);
|
|
29
|
-
yield {
|
|
30
|
-
type: 'get',
|
|
31
|
-
id,
|
|
32
|
-
...(loaded ? loaded : {}),
|
|
33
|
-
};
|
|
34
|
-
break;
|
|
35
|
-
case 'put':
|
|
36
|
-
await tables.ExamplePeople.put(id, { name, tag });
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { type RecordObject, type RequestTargetOrId, Resource } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
interface GreetingRecord {
|
|
4
|
-
greeting: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export class Greeting extends Resource<GreetingRecord> {
|
|
8
|
-
static loadAsInstance = false;
|
|
9
|
-
|
|
10
|
-
async post(target: RequestTargetOrId, newRecord: Partial<GreetingRecord & RecordObject>): Promise<GreetingRecord> {
|
|
11
|
-
return { greeting: 'Greetings, post!' };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async get(target?: RequestTargetOrId): Promise<GreetingRecord> {
|
|
15
|
-
return { greeting: 'Greetings, get!' };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async put(target: RequestTargetOrId, record: GreetingRecord & RecordObject): Promise<GreetingRecord> {
|
|
19
|
-
return { greeting: 'Greetings, put!' };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async patch(target: RequestTargetOrId, record: Partial<GreetingRecord & RecordObject>): Promise<GreetingRecord> {
|
|
23
|
-
return { greeting: 'Greetings, patch!' };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async delete(target: RequestTargetOrId): Promise<boolean> {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
## Here we can define any tables in our database. This example shows how we define a type as a table using
|
|
2
|
-
## the type name as the table name and specifying it is an "export" available in the REST and other external protocols.
|
|
3
|
-
type ExamplePeople @table @export {
|
|
4
|
-
id: ID @primaryKey # Here we define primary key (must be one)
|
|
5
|
-
name: String # we can define any other attributes here
|
|
6
|
-
tag: String @indexed # we can specify any attributes that should be indexed
|
|
7
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
export class ExamplePeople extends tables.ExamplePeople {
|
|
4
|
-
// we can define our own custom POST handler
|
|
5
|
-
post(content) {
|
|
6
|
-
// do something with the incoming content;
|
|
7
|
-
return super.post(content);
|
|
8
|
-
}
|
|
9
|
-
// or custom GET handler
|
|
10
|
-
get() {
|
|
11
|
-
// we can modify this resource before returning
|
|
12
|
-
return super.get();
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Resource, tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
export class ExampleSocket extends Resource {
|
|
4
|
-
static loadAsInstance = false;
|
|
5
|
-
|
|
6
|
-
// This customizes handling the socket connections; tables can have this method too!
|
|
7
|
-
async *connect(
|
|
8
|
-
target,
|
|
9
|
-
incomingMessages,
|
|
10
|
-
) {
|
|
11
|
-
const subscription = await tables.ExamplePeople.subscribe(target);
|
|
12
|
-
if (!incomingMessages) {
|
|
13
|
-
// Server sent events, no incoming messages!
|
|
14
|
-
// Subscribe to changes to the table.
|
|
15
|
-
return subscription;
|
|
16
|
-
}
|
|
17
|
-
for await (let message of incomingMessages) {
|
|
18
|
-
const { type, id, name, tag } = message;
|
|
19
|
-
switch (type) {
|
|
20
|
-
case 'get':
|
|
21
|
-
const loaded = await tables.ExamplePeople.get(id);
|
|
22
|
-
yield {
|
|
23
|
-
type: 'get',
|
|
24
|
-
id,
|
|
25
|
-
...(loaded ? loaded : {}),
|
|
26
|
-
};
|
|
27
|
-
break;
|
|
28
|
-
case 'put':
|
|
29
|
-
await tables.ExamplePeople.put(id, { name, tag });
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
## Here we can define any tables in our database. This example shows how we define a type as a table using
|
|
2
|
-
## the type name as the table name and specifying it is an "export" available in the REST and other external protocols.
|
|
3
|
-
type ExamplePeople @table @export {
|
|
4
|
-
id: ID @primaryKey # Here we define primary key (must be one)
|
|
5
|
-
name: String # we can define any other attributes here
|
|
6
|
-
tag: String @indexed # we can specify any attributes that should be indexed
|
|
7
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type RequestTargetOrId, tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
export interface ExamplePerson {
|
|
4
|
-
id: string;
|
|
5
|
-
name: string;
|
|
6
|
-
tag: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class ExamplePeople extends tables.ExamplePeople<ExamplePerson> {
|
|
10
|
-
// we can define our own custom POST handler
|
|
11
|
-
async post(target: RequestTargetOrId, newRecord: Omit<ExamplePerson, 'id'>) {
|
|
12
|
-
// do something with the incoming content;
|
|
13
|
-
return super.post(target, newRecord);
|
|
14
|
-
}
|
|
15
|
-
// or custom GET handler
|
|
16
|
-
async get(target: RequestTargetOrId): Promise<ExamplePerson> {
|
|
17
|
-
// we can modify this resource before returning
|
|
18
|
-
return super.get(target);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { type IterableEventQueue, RequestTarget, Resource, tables } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
interface ExampleSocketRecord {
|
|
4
|
-
id: string;
|
|
5
|
-
type?: 'get' | 'put';
|
|
6
|
-
name: string;
|
|
7
|
-
tag: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class ExampleSocket extends Resource<ExampleSocketRecord> {
|
|
11
|
-
static loadAsInstance = false;
|
|
12
|
-
|
|
13
|
-
// This customizes handling the socket connections; tables can have this method too!
|
|
14
|
-
async *connect(
|
|
15
|
-
target: RequestTarget,
|
|
16
|
-
incomingMessages: IterableEventQueue<ExampleSocketRecord>,
|
|
17
|
-
): AsyncIterable<ExampleSocketRecord> {
|
|
18
|
-
const subscription = await tables.ExamplePeople.subscribe(target);
|
|
19
|
-
if (!incomingMessages) {
|
|
20
|
-
// Server sent events, no incoming messages!
|
|
21
|
-
// Subscribe to changes to the table.
|
|
22
|
-
return subscription;
|
|
23
|
-
}
|
|
24
|
-
for await (let message of incomingMessages) {
|
|
25
|
-
const { type, id, name, tag } = message;
|
|
26
|
-
switch (type) {
|
|
27
|
-
case 'get':
|
|
28
|
-
const loaded = await tables.ExamplePeople.get(id);
|
|
29
|
-
yield {
|
|
30
|
-
type: 'get',
|
|
31
|
-
id,
|
|
32
|
-
...(loaded ? loaded : {}),
|
|
33
|
-
};
|
|
34
|
-
break;
|
|
35
|
-
case 'put':
|
|
36
|
-
await tables.ExamplePeople.put(id, { name, tag });
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { type RecordObject, type RequestTargetOrId, Resource } from 'harperdb';
|
|
2
|
-
|
|
3
|
-
interface GreetingRecord {
|
|
4
|
-
greeting: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export class Greeting extends Resource<GreetingRecord> {
|
|
8
|
-
static loadAsInstance = false;
|
|
9
|
-
|
|
10
|
-
async post(target: RequestTargetOrId, newRecord: Partial<GreetingRecord & RecordObject>): Promise<GreetingRecord> {
|
|
11
|
-
return { greeting: 'Greetings, post!' };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async get(target?: RequestTargetOrId): Promise<GreetingRecord> {
|
|
15
|
-
return { greeting: 'Greetings, get!' };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async put(target: RequestTargetOrId, record: GreetingRecord & RecordObject): Promise<GreetingRecord> {
|
|
19
|
-
return { greeting: 'Greetings, put!' };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async patch(target: RequestTargetOrId, record: Partial<GreetingRecord & RecordObject>): Promise<GreetingRecord> {
|
|
23
|
-
return { greeting: 'Greetings, patch!' };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async delete(target: RequestTargetOrId): Promise<boolean> {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
## Here we can define any tables in our database. This example shows how we define a type as a table using
|
|
2
|
-
## the type name as the table name and specifying it is an "export" available in the REST and other external protocols.
|
|
3
|
-
type ExamplePeople @table @export {
|
|
4
|
-
id: ID @primaryKey # Here we define primary key (must be one)
|
|
5
|
-
name: String # we can define any other attributes here
|
|
6
|
-
tag: String @indexed # we can specify any attributes that should be indexed
|
|
7
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|