Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/stale-showers-write.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@wbce/projen-directus-extension": patch
"@wbce/projen-directus": patch
---

add readmes
15 changes: 9 additions & 6 deletions .projenrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ const directus = new cdk.JsiiProject({
...commonJsiiOptions,
parent: root,
outdir: './packages/directus',
name: '@wbce/projen-directus',
peerDeps: ['constructs', 'projen', '@wbce/projen-shared', '@wbce/projen-directus-extension'],
devDeps: ['@wbce/projen-shared@workspace:*', '@wbce/projen-directus-extension@workspace:*'],
name: '@wbce/projen-d9',
peerDeps: ['constructs', 'projen', '@wbce/projen-shared', '@wbce/projen-d9-extension'],
devDeps: ['@wbce/projen-shared@workspace:*', '@wbce/projen-d9-extension@workspace:*'],
});
directus.package.addVersion(readPackageVersion('./packages/directus'));
directus.npmrc.addConfig('node-linker', 'hoisted');
Expand All @@ -134,15 +134,18 @@ directus.addBundledDeps("pg");
directus.addBundledDeps("pg-copy-streams");
directus.addBundledDeps("@types/pg");
directus.addBundledDeps("@types/pg-copy-streams");
directus.addBins({"wbce-directus": "lib/cli/index.js"})
directus.addBins({
"wbce-d9": "lib/cli/index.js",
"wbce-directus": "lib/cli/index.js", // deprecated alias, kept for backward compatibility
});


// --- directus extension ---
const directusExtension = new cdk.JsiiProject({
...commonJsiiOptions,
parent: root,
outdir: './packages/directus-extension',
name: '@wbce/projen-directus-extension',
name: '@wbce/projen-d9-extension',
peerDeps: ['constructs', 'projen', '@wbce/projen-shared'],
devDeps: ['@wbce/projen-shared@workspace:*'],
});
Expand Down Expand Up @@ -188,7 +191,7 @@ const sample = new typescript.TypeScriptProject({
github: false,
devDeps: [
'@wbce/projen-blank@workspace:*',
'@wbce/projen-directus@workspace:*',
'@wbce/projen-d9@workspace:*',
],
deps: ['tsx'],
});
Expand Down
6,307 changes: 5,358 additions & 949 deletions packages/directus-extension/API.md

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions packages/directus-extension/README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
# @wbce/projen-directus-extension
# @wbce/projen-d9-extension

Projen constructs for authoring [d9](https://github.com/LaWebcapsule/d9) (Directus 9) extensions. Provides:

- `ExtensionFolder` — a pnpm workspace that holds extension packages
- `DirectusExtensionProject` — a TypeScript project for a single extension or a bundle of related extensions
- `DirectusExtensionType` — enum of supported extension kinds
- `D9ExtensionProject` — a TypeScript project for a single extension or a bundle of related extensions
- `D9ExtensionType` — enum of supported extension kinds

This package is typically consumed via [`@wbce/projen-directus`](../directus), which wires up an `ExtensionFolder` automatically and exposes `project.addExtension(...)`.
This package is typically consumed via [`@wbce/projen-d9`](../directus), which wires up an `ExtensionFolder` automatically and exposes `project.addExtension(...)`.

## Usage

In a `DirectusProject`:
In a `D9Project`:

```js
import { DirectusProject } from '@wbce/projen-directus';
import { DirectusExtensionType } from '@wbce/projen-directus-extension';
import { D9Project } from '@wbce/projen-d9';
import { D9ExtensionType } from '@wbce/projen-d9-extension';

const project = new DirectusProject({
const project = new D9Project({
name: 'my-d9',
defaultReleaseBranch: 'main',
});

// Single-type extension
project.addExtension('my-hook', [DirectusExtensionType.HOOK]);
project.addExtension('my-hook', [D9ExtensionType.HOOK]);

// Bundle: multiple types in one package
project.addExtension('my-bundle', [
DirectusExtensionType.INTERFACE,
DirectusExtensionType.DISPLAY,
D9ExtensionType.INTERFACE,
D9ExtensionType.DISPLAY,
]);

// Shared library (no extension type) — can be depended on by other extensions
project.addExtension('shared', []);

// Cross-extension dependency
const myHook = project.addExtension('feature', [DirectusExtensionType.HOOK]);
const myHook = project.addExtension('feature', [D9ExtensionType.HOOK]);
myHook.addDeps('shared@workspace:');

project.synth();
```

## Extension types

`DirectusExtensionType` values:
`D9ExtensionType` values:

| Type | Kind |
| --- | --- |
Expand All @@ -67,17 +67,17 @@ Per extension:
- Build step that runs `directus-extension build` and copies `dist/` into the parent project's `extensions/` tree at the right subfolder (`hooks/<name>`, `endpoints/<name>`, …)
- Vue is added as a devDep automatically when a UI type is included

The `ExtensionFolder` itself is a pnpm workspace; running `pnpm install` + `pnpm run --recursive build` inside it builds every extension. This is what the parent `DirectusProject`'s `build-extensions` task does.
The `ExtensionFolder` itself is a pnpm workspace; running `pnpm install` + `pnpm run --recursive build` inside it builds every extension. This is what the parent `D9Project`'s `build-extensions` task does.

## Direct usage

The constructs can be used outside `DirectusProject` if needed:
The constructs can be used outside `D9Project` if needed:

```js
import { ExtensionFolder, DirectusExtensionType } from '@wbce/projen-directus-extension';
import { ExtensionFolder, D9ExtensionType } from '@wbce/projen-d9-extension';

const folder = new ExtensionFolder({ parent: someProject, name: 'plugins' });
folder.add('my-endpoint', [DirectusExtensionType.ENDPOINT]);
folder.add('my-endpoint', [D9ExtensionType.ENDPOINT]);
```

## License
Expand Down
2 changes: 1 addition & 1 deletion packages/directus-extension/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 46 additions & 25 deletions packages/directus-extension/src/directus-extension-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function readTemplate(type: string): string {
/**
* Supported Directus v9 extension types.
*/
export enum DirectusExtensionType {
export enum D9ExtensionType {
INTERFACE = 'interface',
DISPLAY = 'display',
LAYOUT = 'layout',
Expand All @@ -25,27 +25,27 @@ export enum DirectusExtensionType {
OPERATION = 'operation',
}

export interface DirectusExtensionProjectOptions extends typescript.TypeScriptProjectOptions {
export interface D9ExtensionProjectOptions extends typescript.TypeScriptProjectOptions {
/**
* The type of Directus extension.
*/
readonly extensionTypes: DirectusExtensionType[];
readonly extensionTypes: D9ExtensionType[];
}

/**
* Whether the extension type is a UI (frontend) extension.
*/
function isUiExtension(type: DirectusExtensionType): boolean {
function isUiExtension(type: D9ExtensionType): boolean {
return [
DirectusExtensionType.INTERFACE,
DirectusExtensionType.DISPLAY,
DirectusExtensionType.LAYOUT,
DirectusExtensionType.MODULE,
DirectusExtensionType.PANEL,
D9ExtensionType.INTERFACE,
D9ExtensionType.DISPLAY,
D9ExtensionType.LAYOUT,
D9ExtensionType.MODULE,
D9ExtensionType.PANEL,
].includes(type);
}

function includeUiExtension(types: DirectusExtensionType[]) {
function includeUiExtension(types: D9ExtensionType[]) {
for (const type of types) {
if (isUiExtension(type)) {
return true;
Expand All @@ -57,33 +57,33 @@ function includeUiExtension(types: DirectusExtensionType[]) {
/**
* Returns the target directory where the built extension should be copied.
*/
function extensionTargetDir(type: DirectusExtensionType, name: string): string {
function extensionTargetDir(type: D9ExtensionType, name: string): string {
switch (type) {
case DirectusExtensionType.ENDPOINT:
case D9ExtensionType.ENDPOINT:
return `endpoints/${name}`;
case DirectusExtensionType.HOOK:
case D9ExtensionType.HOOK:
return `hooks/${name}`;
case DirectusExtensionType.OPERATION:
case D9ExtensionType.OPERATION:
return `operations/${name}`;
case DirectusExtensionType.INTERFACE:
case D9ExtensionType.INTERFACE:
return `interfaces/${name}`;
case DirectusExtensionType.DISPLAY:
case D9ExtensionType.DISPLAY:
return `displays/${name}`;
case DirectusExtensionType.LAYOUT:
case D9ExtensionType.LAYOUT:
return `layouts/${name}`;
case DirectusExtensionType.MODULE:
case D9ExtensionType.MODULE:
return `modules/${name}`;
case DirectusExtensionType.PANEL:
case D9ExtensionType.PANEL:
return `panels/${name}`;
}
}

export class DirectusExtensionProject extends typescript.TypeScriptProject {
export class D9ExtensionProject extends typescript.TypeScriptProject {

public readonly extensionTypes: DirectusExtensionType[];
public readonly extensionTypes: D9ExtensionType[];
public readonly extensionName: string;

constructor(options: DirectusExtensionProjectOptions) {
constructor(options: D9ExtensionProjectOptions) {
const extensionTypes = options.extensionTypes;
const ui = includeUiExtension(extensionTypes);

Expand All @@ -101,7 +101,7 @@ export class DirectusExtensionProject extends typescript.TypeScriptProject {
? [
`# ${options.name}`,
'',
`Shared library used by sibling [d9](https://github.com/LaWebcapsule/d9) extensions in this workspace.`,
'Shared library used by sibling [d9](https://github.com/LaWebcapsule/d9) extensions in this workspace.',
'',
'Built via `tsc`; consumers depend on it with `<name>@workspace:`.',
].join('\n')
Expand All @@ -122,7 +122,7 @@ export class DirectusExtensionProject extends typescript.TypeScriptProject {
].join('\n'),
},
devDeps: [
'@wbce/projen-directus-extension',
'@wbce/projen-d9-extension',
'@wbce-d9/extensions-sdk',
'@wbce-d9/types',
'@types/node',
Expand Down Expand Up @@ -202,7 +202,7 @@ export class DirectusExtensionProject extends typescript.TypeScriptProject {
if (extensionTypes.length) {

const extensionSubDir = extensionTypes.length === 1 ? extensionTargetDir(extensionTypes[0], this.extensionName):this.extensionName;
// Compute relative path from this extension project to the DirectusProject root (grandparent)
// Compute relative path from this extension project to the D9Project root (grandparent)
const grandParentOutdir = options.parent?.parent?.outdir ?? '../..';
const relativeToRoot = path.relative(this.outdir, grandParentOutdir);
let targetDir = path.join(relativeToRoot, 'extensions', extensionSubDir);
Expand All @@ -221,3 +221,24 @@ export class DirectusExtensionProject extends typescript.TypeScriptProject {

}
}

/**
* @deprecated Use {@link D9ExtensionType} instead. The package was renamed to `@wbce/projen-d9-extension` to reflect that it targets the d9 fork, not upstream Directus.
*/
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const DirectusExtensionType = D9ExtensionType;
/**
* @deprecated Use {@link D9ExtensionType} instead.
*/
export type DirectusExtensionType = D9ExtensionType;

/**
* @deprecated Use {@link D9ExtensionProjectOptions} instead. The package was renamed to `@wbce/projen-d9-extension`.
*/
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface DirectusExtensionProjectOptions extends D9ExtensionProjectOptions {}

/**
* @deprecated Use {@link D9ExtensionProject} instead. The package was renamed to `@wbce/projen-d9-extension`.
*/
export class DirectusExtensionProject extends D9ExtensionProject {}
10 changes: 5 additions & 5 deletions packages/directus-extension/src/extension-folder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PnpmWorkspace } from '@wbce/projen-shared';
import { Project, ProjectOptions } from 'projen';
import { DirectusExtensionProject, DirectusExtensionType } from './directus-extension-project';
import { D9ExtensionProject, D9ExtensionType } from './directus-extension-project';

/**
* Options passed to addExtension.
Expand Down Expand Up @@ -30,8 +30,8 @@ export interface ExtensionFolderOptions extends ProjectOptions {
* declared in extensions.json and loaded automatically.
*
* @example
* const project = new DirectusProject({ name: 'my-app', defaultReleaseBranch: 'main' });
* project.extensions.addExtension('my-hook', DirectusExtensionType.HOOK);
* const project = new D9Project({ name: 'my-app', defaultReleaseBranch: 'main' });
* project.extensions.addExtension('my-hook', D9ExtensionType.HOOK);
*/
export class ExtensionFolder extends Project {

Expand All @@ -53,8 +53,8 @@ export class ExtensionFolder extends Project {
/**
* Add a Directus extension to this folder.
*/
public add(name: string, extensionTypes: DirectusExtensionType[], options?: AddExtensionOptions): DirectusExtensionProject {
return new DirectusExtensionProject({
public add(name: string, extensionTypes: D9ExtensionType[], options?: AddExtensionOptions): D9ExtensionProject {
return new D9ExtensionProject({
name,
extensionTypes,
parent: this,
Expand Down
8 changes: 4 additions & 4 deletions packages/directus-extension/test/hello.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Testing } from 'projen/lib/testing';
import { DirectusExtensionProject, DirectusExtensionType } from '../src';
import { D9ExtensionProject, D9ExtensionType } from '../src';

test('DirectusExtensionProject can be instantiated', () => {
const project = new DirectusExtensionProject({
test('D9ExtensionProject can be instantiated', () => {
const project = new D9ExtensionProject({
name: 'test-extension',
extensionTypes: [DirectusExtensionType.HOOK],
extensionTypes: [D9ExtensionType.HOOK],
defaultReleaseBranch: 'main',
});
const snapshot = Testing.synth(project);
Expand Down
4 changes: 2 additions & 2 deletions packages/directus/.projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading