@linktr.ee/create-link-app 0.3.0-next.4 → 0.3.0-next.41
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 +29 -0
- package/dist/commands/build.js +3 -2
- package/dist/commands/dev.js +2 -1
- package/dist/commands/generate-types.js +111 -0
- package/dist/commands/storybook.js +28 -0
- package/dist/lib/create/create-project.js +3 -0
- package/dist/lib/deploy/pack-project.js +12 -1
- package/dist/lib/schema/compile.js +30 -0
- package/dist/postcss/postcss.config.js +31 -0
- package/dist/storybook/global.css +53 -0
- package/dist/storybook/main.js +53 -0
- package/dist/storybook/preview.js +21 -0
- package/dist/webpack/webpack.config.js +40 -40
- package/html-template/development.html +2 -2
- package/html-template/production.html +2 -2
- package/oclif.manifest.json +32 -1
- package/package.json +28 -9
- package/templates/common/README.md +38 -17
- package/templates/common/fixtures/props-data.json +1 -2
- package/templates/common/gitignore +1 -0
- package/templates/common/schema/editablePrivate.jtd.json +6 -0
- package/templates/common/schema/editablePublic.jtd.json +10 -0
- package/templates/common/schema/readonlyPrivate.jtd.json +8 -0
- package/templates/common/schema/readonlyPublic.jtd.json +6 -0
- package/templates/common/schema/system.jtd.json +6 -0
- package/templates/common/settings.json +11 -23
- package/templates/react/package.json +5 -2
- package/templates/react/src/index.jsx +4 -13
- package/templates/react/src/tailwind.css +5 -0
- package/templates/react-ts/package.json +7 -4
- package/templates/react-ts/src/App.tsx +23 -0
- package/templates/react-ts/src/Editor.tsx +7 -0
- package/templates/react-ts/src/Sheet.tsx +7 -0
- package/templates/react-ts/src/components/Layouts.tsx +59 -0
- package/templates/react-ts/src/stories/LinkApp.stories.tsx +94 -0
- package/templates/react-ts/src/stories/tailwind.sb.css +5 -0
- package/templates/react-ts/src/tailwind.css +4 -0
- package/templates/react-ts/src/types/global.d.ts +11 -5
- package/templates/react-ts/src/types/index.ts +8 -7
- package/templates/react-ts/src/types/schema/index.ts +33 -0
- package/templates/react/src/images/logo.png +0 -0
- package/templates/react-ts/src/images/logo.png +0 -0
- package/templates/react-ts/src/index.tsx +0 -19
package/README.md
CHANGED
|
@@ -23,10 +23,12 @@ yarn create @linktr.ee/create-link-app my-link-app
|
|
|
23
23
|
* [`create-link-app create NAME`](#create-link-app-create-name)
|
|
24
24
|
* [`create-link-app deploy`](#create-link-app-deploy)
|
|
25
25
|
* [`create-link-app dev`](#create-link-app-dev)
|
|
26
|
+
* [`create-link-app generate-types`](#create-link-app-generate-types)
|
|
26
27
|
* [`create-link-app grant-access LINK_APP_ID USERNAME`](#create-link-app-grant-access-link_app_id-username)
|
|
27
28
|
* [`create-link-app help [COMMANDS]`](#create-link-app-help-commands)
|
|
28
29
|
* [`create-link-app login`](#create-link-app-login)
|
|
29
30
|
* [`create-link-app logout`](#create-link-app-logout)
|
|
31
|
+
* [`create-link-app storybook`](#create-link-app-storybook)
|
|
30
32
|
|
|
31
33
|
## `create-link-app build`
|
|
32
34
|
|
|
@@ -106,6 +108,18 @@ EXAMPLES
|
|
|
106
108
|
$ create-link-app dev --https
|
|
107
109
|
```
|
|
108
110
|
|
|
111
|
+
## `create-link-app generate-types`
|
|
112
|
+
|
|
113
|
+
Generate Typescript types from the schema definitions
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
USAGE
|
|
117
|
+
$ create-link-app generate-types
|
|
118
|
+
|
|
119
|
+
DESCRIPTION
|
|
120
|
+
Generate Typescript types from the schema definitions
|
|
121
|
+
```
|
|
122
|
+
|
|
109
123
|
## `create-link-app grant-access LINK_APP_ID USERNAME`
|
|
110
124
|
|
|
111
125
|
Grant access to other developers to push updates for your Link App
|
|
@@ -168,4 +182,19 @@ USAGE
|
|
|
168
182
|
DESCRIPTION
|
|
169
183
|
Logout and clear browser session
|
|
170
184
|
```
|
|
185
|
+
|
|
186
|
+
## `create-link-app storybook`
|
|
187
|
+
|
|
188
|
+
Start the Storybook development server
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
USAGE
|
|
192
|
+
$ create-link-app storybook [-p <value>]
|
|
193
|
+
|
|
194
|
+
FLAGS
|
|
195
|
+
-p, --port=<value> [default: 6006] Port to run the Storybook server on
|
|
196
|
+
|
|
197
|
+
DESCRIPTION
|
|
198
|
+
Start the Storybook development server
|
|
199
|
+
```
|
|
171
200
|
<!-- commandsstop -->
|
package/dist/commands/build.js
CHANGED
|
@@ -10,9 +10,10 @@ const webpack_config_1 = __importDefault(require("../webpack/webpack.config"));
|
|
|
10
10
|
class Build extends base_1.default {
|
|
11
11
|
async run() {
|
|
12
12
|
const { flags } = await this.parse(Build);
|
|
13
|
-
|
|
13
|
+
const config = await (0, webpack_config_1.default)('production', {
|
|
14
14
|
allowAnyOrigin: flags['allow-any-origin'],
|
|
15
|
-
})
|
|
15
|
+
});
|
|
16
|
+
(0, webpack_1.default)(config, (err, stats) => {
|
|
16
17
|
if (err) {
|
|
17
18
|
this.error(err);
|
|
18
19
|
}
|
package/dist/commands/dev.js
CHANGED
|
@@ -11,6 +11,7 @@ const webpack_config_1 = __importDefault(require("../webpack/webpack.config"));
|
|
|
11
11
|
class Dev extends base_1.default {
|
|
12
12
|
async run() {
|
|
13
13
|
const { flags } = await this.parse(Dev);
|
|
14
|
+
const config = await (0, webpack_config_1.default)('development');
|
|
14
15
|
const devServer = new webpack_dev_server_1.default({
|
|
15
16
|
client: {
|
|
16
17
|
overlay: false,
|
|
@@ -18,7 +19,7 @@ class Dev extends base_1.default {
|
|
|
18
19
|
hot: false,
|
|
19
20
|
https: flags.https,
|
|
20
21
|
port: flags.port,
|
|
21
|
-
}, (0, webpack_1.default)(
|
|
22
|
+
}, (0, webpack_1.default)(config));
|
|
22
23
|
await devServer.start();
|
|
23
24
|
}
|
|
24
25
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const base_1 = __importDefault(require("../base"));
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
class MissingDependencyException extends Error {
|
|
10
|
+
constructor(packageName) {
|
|
11
|
+
super(`'${packageName}' is required on your system. Please refer to the create-link-app README`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const ucfirst = (str) => {
|
|
15
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
16
|
+
};
|
|
17
|
+
class GenerateTypes extends base_1.default {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.schemaDirPath = path_1.default.join(process.cwd(), '/schema');
|
|
21
|
+
this.tmpPath = path_1.default.join(process.cwd(), '/__temp__');
|
|
22
|
+
this.typesPath = path_1.default.join(process.cwd(), '/src/types/schema');
|
|
23
|
+
}
|
|
24
|
+
async run() {
|
|
25
|
+
try {
|
|
26
|
+
// Check for necessary deps
|
|
27
|
+
await this.dependOn('npx');
|
|
28
|
+
await this.dependOn('jtd-codegen');
|
|
29
|
+
await this.log('✓ All dependencies present');
|
|
30
|
+
// Ensure necessary directories exist
|
|
31
|
+
await this.cmd(`mkdir -p ${this.tmpPath} && touch ${this.tmpPath}/index.ts`);
|
|
32
|
+
await this.cmd(`mkdir -p ${this.typesPath} && touch ${this.typesPath}/index.ts`);
|
|
33
|
+
await this.log('✓ Files prepped for generation');
|
|
34
|
+
// Wipe existing types & drop comments
|
|
35
|
+
await this.cmd(`> ${this.typesPath}/index.ts`);
|
|
36
|
+
await this.cmd(`echo "/**" >> ${this.typesPath}/index.ts`);
|
|
37
|
+
await this.cmd(`echo " * These types were autogenerated by @linktr.ee/create-link-app" >> ${this.typesPath}/index.ts`);
|
|
38
|
+
await this.cmd(`echo " * https://www.npmjs.com/package/@linktr.ee/create-link-app " >> ${this.typesPath}/index.ts`);
|
|
39
|
+
await this.cmd(`echo " */" >> ${this.typesPath}/index.ts`);
|
|
40
|
+
// Generate and append types
|
|
41
|
+
await this.generateAndAppendSchemaType('editablePublic');
|
|
42
|
+
await this.log('✓ Generated EditablePublicData type');
|
|
43
|
+
await this.generateAndAppendSchemaType('readonlyPublic');
|
|
44
|
+
await this.log('✓ Generated ReadonlyPublicData type');
|
|
45
|
+
await this.generateAndAppendSchemaType('editablePrivate');
|
|
46
|
+
await this.log('✓ Generated EditablePrivateData type');
|
|
47
|
+
await this.generateAndAppendSchemaType('readonlyPrivate');
|
|
48
|
+
await this.log('✓ Generated ReadonlyPrivateData type');
|
|
49
|
+
// Clean up file formatting
|
|
50
|
+
await this.cmd(`npx prettier ${this.typesPath}/index.ts --write`);
|
|
51
|
+
await this.log('✓ All types created successfully');
|
|
52
|
+
// Garbage collect temporary dir
|
|
53
|
+
await this.cmd(`rm -rf ${this.tmpPath}`);
|
|
54
|
+
await this.log('✓ Cleanup complete');
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
await this.log(`𐄂 ERROR: ${e}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generates a Typescript type for the schema defined in schema/<schemaName>.jtd.json
|
|
62
|
+
* and appends that type to src/types/schema/index.ts
|
|
63
|
+
*/
|
|
64
|
+
async generateAndAppendSchemaType(schemaName) {
|
|
65
|
+
// Generate schema
|
|
66
|
+
await this.cmd(`jtd-codegen ${this.schemaDirPath}/${schemaName}.jtd.json --typescript-out ${this.tmpPath} --root-name=${ucfirst(schemaName)}Data`);
|
|
67
|
+
// Strip jtd comment
|
|
68
|
+
await this.cmd(`sed '/^\\/\\//d' ${this.tmpPath}/index.ts > ${this.tmpPath}/parsed.ts`);
|
|
69
|
+
// Append to final file
|
|
70
|
+
await this.cmd(`cat ${this.tmpPath}/parsed.ts >> ${this.typesPath}/index.ts`);
|
|
71
|
+
}
|
|
72
|
+
async dependOn(dependencyName) {
|
|
73
|
+
try {
|
|
74
|
+
await this.cmd(`command -v ${dependencyName} || exit 1`);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
throw new MissingDependencyException('prettier');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Run a command with spawn effectively synchronously
|
|
82
|
+
*/
|
|
83
|
+
async cmd(command, opts = {
|
|
84
|
+
shell: true,
|
|
85
|
+
stdio: 'ignore',
|
|
86
|
+
}, onError) {
|
|
87
|
+
await new Promise((resolve, reject) => {
|
|
88
|
+
(0, child_process_1.spawn)(command, opts)
|
|
89
|
+
.on('error', (e) => {
|
|
90
|
+
reject(e);
|
|
91
|
+
})
|
|
92
|
+
.on('exit', (code) => {
|
|
93
|
+
if (code === 1)
|
|
94
|
+
reject({ exitCode: code });
|
|
95
|
+
})
|
|
96
|
+
.on('close', () => {
|
|
97
|
+
resolve();
|
|
98
|
+
});
|
|
99
|
+
}).catch((e) => {
|
|
100
|
+
if (onError) {
|
|
101
|
+
onError();
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
throw e;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.default = GenerateTypes;
|
|
111
|
+
GenerateTypes.description = 'Generate Typescript types from the schema definitions';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const core_1 = require("@oclif/core");
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const base_1 = __importDefault(require("../base"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
class Storybook extends base_1.default {
|
|
11
|
+
async run() {
|
|
12
|
+
const configPath = path_1.default.resolve(__dirname, '..', 'storybook');
|
|
13
|
+
const { flags } = await this.parse(Storybook);
|
|
14
|
+
const storybook = (0, child_process_1.spawn)(`start-storybook -p ${flags.port} -c ${configPath}`, { shell: true, stdio: 'inherit' });
|
|
15
|
+
storybook.on('error', (err) => {
|
|
16
|
+
throw err;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.default = Storybook;
|
|
21
|
+
Storybook.description = 'Start the Storybook development server';
|
|
22
|
+
Storybook.flags = {
|
|
23
|
+
port: core_1.Flags.integer({
|
|
24
|
+
char: 'p',
|
|
25
|
+
description: 'Port to run the Storybook server on',
|
|
26
|
+
default: 6006,
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
@@ -14,6 +14,9 @@ const createProject = async (template, targetDir) => {
|
|
|
14
14
|
await fs_extra_1.default.copy(templateDir, targetDir);
|
|
15
15
|
await fs_extra_1.default.copy(templateCommonDir, targetDir);
|
|
16
16
|
await fs_extra_1.default.move(`${targetDir}/gitignore`, `${targetDir}/.gitignore`);
|
|
17
|
+
if (await fs_extra_1.default.existsSync(`${targetDir}/src/types/global.d.ts`)) {
|
|
18
|
+
await fs_extra_1.default.unlink(`${targetDir}/src/types/global.d.ts`);
|
|
19
|
+
}
|
|
17
20
|
// update `name` field in project manifest
|
|
18
21
|
const manifest = await fs_extra_1.default.readJson(`${targetDir}/manifest.json`);
|
|
19
22
|
manifest.name = (0, project_name_to_title_1.default)(path_1.default.basename(targetDir));
|
|
@@ -8,7 +8,13 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
/**
|
|
10
10
|
* Pack the Link App source files into `package.tgz`. This includes the following:
|
|
11
|
+
* - `schema/editablePublic.jtd.json`
|
|
12
|
+
* - `schema/readonlyPublic.jtd.json`
|
|
13
|
+
* - `schema/editablePrivate.jtd.json`
|
|
14
|
+
* - `schema/readonlyPrivate.jtd.json`
|
|
15
|
+
* - `schema/system.jtd.json`
|
|
11
16
|
* - `src/`
|
|
17
|
+
* - `schema.json`
|
|
12
18
|
* - `package.json`
|
|
13
19
|
* - `package-lock.json` - *optional*
|
|
14
20
|
* - `yarn.lock` - *optional*
|
|
@@ -30,7 +36,7 @@ async function packProject() {
|
|
|
30
36
|
gzipOptions: { level: 9 },
|
|
31
37
|
});
|
|
32
38
|
archive.on('warning', (err) => {
|
|
33
|
-
if (err
|
|
39
|
+
if (err?.code === 'ENOENT') {
|
|
34
40
|
// lock files and tsconfig may or may not exist
|
|
35
41
|
const fileName = path_1.default.basename(err.path);
|
|
36
42
|
if (fileName === 'package-lock.json' || fileName === 'yarn.lock' || fileName === 'tsconfig.json') {
|
|
@@ -43,6 +49,11 @@ async function packProject() {
|
|
|
43
49
|
handleFailure(err);
|
|
44
50
|
});
|
|
45
51
|
archive.pipe(outputWriteStream);
|
|
52
|
+
archive.file(resolveProjPath('schema/editablePublic.jtd.json'), { name: 'schema/editablePublic.jtd.json' });
|
|
53
|
+
archive.file(resolveProjPath('schema/readonlyPublic.jtd.json'), { name: 'schema/readonlyPublic.jtd.json' });
|
|
54
|
+
archive.file(resolveProjPath('schema/editablePrivate.jtd.json'), { name: 'schema/editablePrivate.jtd.json' });
|
|
55
|
+
archive.file(resolveProjPath('schema/readonlyPrivate.jtd.json'), { name: 'schema/readonlyPrivate.jtd.json' });
|
|
56
|
+
archive.file(resolveProjPath('schema/system.jtd.json'), { name: 'schema/system.jtd.json' });
|
|
46
57
|
archive.file(resolveProjPath('package.json'), { name: 'package.json' });
|
|
47
58
|
archive.file(resolveProjPath('package-lock.json'), { name: 'package-lock.json' });
|
|
48
59
|
archive.file(resolveProjPath('yarn.lock'), { name: 'yarn.lock' });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const jtd_js_1 = __importDefault(require("ajv/dist/jtd.js"));
|
|
9
|
+
const index_js_1 = __importDefault(require("ajv/dist/standalone/index.js"));
|
|
10
|
+
const schemaNames = ['editablePublic', 'readonlyPublic', 'editablePrivate', 'readonlyPrivate', 'system'];
|
|
11
|
+
async function compileSchema() {
|
|
12
|
+
try {
|
|
13
|
+
const ajv = new jtd_js_1.default({
|
|
14
|
+
// @ts-expect-error: In JTD mode some options are not typed correctly.
|
|
15
|
+
strict: false,
|
|
16
|
+
code: { source: true, esm: true },
|
|
17
|
+
});
|
|
18
|
+
await Promise.all(schemaNames.map(async (schemaName) => {
|
|
19
|
+
const schemaPath = path_1.default.join(process.cwd(), `./schema/${schemaName}.jtd.json`);
|
|
20
|
+
const schema = await fs_extra_1.default.readJSON(schemaPath);
|
|
21
|
+
ajv.addSchema(schema, schemaName);
|
|
22
|
+
}));
|
|
23
|
+
const moduleCode = (0, index_js_1.default)(ajv);
|
|
24
|
+
return moduleCode;
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
console.error(e);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.default = compileSchema;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getPostcssConfig = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const tailwindcss_1 = __importDefault(require("tailwindcss"));
|
|
9
|
+
const autoprefixer_1 = __importDefault(require("autoprefixer"));
|
|
10
|
+
const componentLibraryContentPath = path_1.default.join(require.resolve('@linktr.ee/component-library/tailwind.config').split('/').slice(0, -1).join('/'), 'dist', '**', '*.js');
|
|
11
|
+
const uiLinkKitPath = path_1.default.join(require.resolve('@linktr.ee/ui-link-kit').split('/').slice(0, -2).join('/'), '**', '*.js');
|
|
12
|
+
function getPostcssConfig({ linkTypeSlug, env = 'production' }) {
|
|
13
|
+
const isStorybook = env === 'storybook';
|
|
14
|
+
const content = [`${process.cwd()}/src/**/*.{js,jsx,ts,tsx}`, uiLinkKitPath];
|
|
15
|
+
if (isStorybook) {
|
|
16
|
+
content.push(componentLibraryContentPath);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
...(isStorybook && { inject: { insertAtTop: true } }),
|
|
20
|
+
plugins: [
|
|
21
|
+
(0, tailwindcss_1.default)({
|
|
22
|
+
important: `[data-link-type-id=${linkTypeSlug}]`,
|
|
23
|
+
content,
|
|
24
|
+
presets: [require('@linktr.ee/component-library/tailwind.config')],
|
|
25
|
+
plugins: [],
|
|
26
|
+
}),
|
|
27
|
+
(0, autoprefixer_1.default)(),
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
exports.getPostcssConfig = getPostcssConfig;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--lt-color-primary: #849589;
|
|
3
|
+
--lt-color-on-primary: #ffffff;
|
|
4
|
+
--lt-color-on-primary-alpha: #ffffffb2;
|
|
5
|
+
|
|
6
|
+
--lt-color-secondary: #67776b;
|
|
7
|
+
--lt-color-on-secondary: #ffffffb3;
|
|
8
|
+
|
|
9
|
+
--lt-color-background: #3a463c;
|
|
10
|
+
--lt-color-on-background: #f7fdf9;
|
|
11
|
+
|
|
12
|
+
--lt-color0: #ffffff;
|
|
13
|
+
--lt-color1: #f7fdf9;
|
|
14
|
+
--lt-color2: #eef6ed;
|
|
15
|
+
--lt-color3: #e0ece2;
|
|
16
|
+
--lt-color4: #c9d5cb;
|
|
17
|
+
--lt-color5: #b6c5b7;
|
|
18
|
+
--lt-color6: #849589;
|
|
19
|
+
--lt-color7: #67776b;
|
|
20
|
+
--lt-color8: #4d5e52;
|
|
21
|
+
--lt-color9: #3a463c;
|
|
22
|
+
--lt-color10: #29382d;
|
|
23
|
+
--lt-color11: #151e16;
|
|
24
|
+
--lt-color12: #0b140c;
|
|
25
|
+
--lt-color13: #000501;
|
|
26
|
+
--lt-color14: #000000;
|
|
27
|
+
--lt-color15: #000000;
|
|
28
|
+
|
|
29
|
+
--lt-treetop-radius-mobile: 2.5rem;
|
|
30
|
+
|
|
31
|
+
--lt-cover-radius: 6rem;
|
|
32
|
+
--lt-cover-radius-mobile: 4rem;
|
|
33
|
+
|
|
34
|
+
--lt-feature-container-radius: 2rem;
|
|
35
|
+
--lt-feature-thumbnail-radius: 1.5rem;
|
|
36
|
+
|
|
37
|
+
--lt-carousel-container-radius: 1.5rem;
|
|
38
|
+
--lt-carousel-thumbnail-radius: 1rem;
|
|
39
|
+
|
|
40
|
+
--lt-grid-container-radius: 1.25rem;
|
|
41
|
+
--lt-grid-thumbnail-radius: 0.75rem;
|
|
42
|
+
|
|
43
|
+
--lt-stack-container-radius: 1rem;
|
|
44
|
+
--lt-stack-thumbnail-radius: 0.65rem;
|
|
45
|
+
|
|
46
|
+
--lt-font-family: INTER;
|
|
47
|
+
--lt-text-2xl: 1.5rem;
|
|
48
|
+
--lt-text-xl: 1.25rem;
|
|
49
|
+
--lt-text-lg: 1.125rem;
|
|
50
|
+
--lt-text-md: 1rem;
|
|
51
|
+
--lt-text-sm: 0.875rem;
|
|
52
|
+
--lt-text-xs: 0.75rem;
|
|
53
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const postcss_1 = __importDefault(require("postcss"));
|
|
7
|
+
const webpack_1 = __importDefault(require("webpack"));
|
|
8
|
+
const postcss_config_1 = require("../postcss/postcss.config");
|
|
9
|
+
// Do not need to be the real values, just need to be defined for storybook
|
|
10
|
+
const linkTypeSlug = 'test-id';
|
|
11
|
+
const linkTypeId = 'testId';
|
|
12
|
+
const config = {
|
|
13
|
+
stories: [`${process.cwd()}/src/**/*.stories.@(js|jsx|ts|tsx)`],
|
|
14
|
+
addons: [
|
|
15
|
+
'@storybook/addon-links',
|
|
16
|
+
'@storybook/addon-essentials',
|
|
17
|
+
{
|
|
18
|
+
name: 'storybook-addon-turbo-build',
|
|
19
|
+
options: {
|
|
20
|
+
optimizationLevel: 2,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
/**
|
|
25
|
+
* Fix Storybook issue with PostCSS@8
|
|
26
|
+
* @see https://github.com/storybookjs/storybook/issues/12668#issuecomment-773958085
|
|
27
|
+
*/
|
|
28
|
+
name: '@storybook/addon-postcss',
|
|
29
|
+
options: {
|
|
30
|
+
cssLoaderOptions: { importLoaders: 1 },
|
|
31
|
+
postcssLoaderOptions: {
|
|
32
|
+
implementation: postcss_1.default,
|
|
33
|
+
postcssOptions: (0, postcss_config_1.getPostcssConfig)({ linkTypeSlug, env: 'storybook' }),
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
framework: '@storybook/react',
|
|
39
|
+
core: {
|
|
40
|
+
builder: 'webpack5',
|
|
41
|
+
},
|
|
42
|
+
webpackFinal: async (config) => {
|
|
43
|
+
if (config.plugins?.length) {
|
|
44
|
+
// Add the DefinePlugin to the Webpack plugins array
|
|
45
|
+
config.plugins.push(new webpack_1.default.DefinePlugin({
|
|
46
|
+
__LINK_TYPE_ID__: JSON.stringify(linkTypeId),
|
|
47
|
+
__LINK_TYPE_SLUG__: JSON.stringify(linkTypeSlug),
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
return config;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
module.exports = config;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.decorators = exports.parameters = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
require("./global.css");
|
|
9
|
+
exports.parameters = {
|
|
10
|
+
actions: { argTypesRegex: '^on[A-Z].*' },
|
|
11
|
+
controls: {
|
|
12
|
+
matchers: {
|
|
13
|
+
color: /(background|color)$/i,
|
|
14
|
+
date: /Date$/,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
const WrapperDecorator = (storyFn) => (react_1.default.createElement("div", { style: {
|
|
19
|
+
display: 'contents',
|
|
20
|
+
}, "data-link-type-id": __LINK_TYPE_SLUG__ }, storyFn()));
|
|
21
|
+
exports.decorators = [WrapperDecorator];
|
|
@@ -13,19 +13,35 @@ const path_1 = __importDefault(require("path"));
|
|
|
13
13
|
const webpack_1 = require("webpack");
|
|
14
14
|
const camelcase_1 = __importDefault(require("camelcase"));
|
|
15
15
|
const slugify_1 = __importDefault(require("slugify"));
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const compile_1 = __importDefault(require("../lib/schema/compile"));
|
|
17
|
+
const postcss_config_1 = require("../postcss/postcss.config");
|
|
18
18
|
const { ModuleFederationPlugin } = webpack_1.container;
|
|
19
|
-
function
|
|
19
|
+
function toVirtualModule(code) {
|
|
20
|
+
const base64 = Buffer.from(code).toString('base64');
|
|
21
|
+
return `data:text/javascript;base64,${base64}`;
|
|
22
|
+
}
|
|
23
|
+
function hasEntrypoint(appDir, file) {
|
|
24
|
+
try {
|
|
25
|
+
fs_1.default.accessSync(path_1.default.resolve(appDir, 'src', file));
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function default_1(env, options) {
|
|
20
33
|
const appDir = process.cwd();
|
|
21
34
|
const entryFile = path_1.default.resolve(__dirname, `${env}.entry`);
|
|
22
35
|
const htmlTemplateFile = path_1.default.resolve(__dirname, '..', '..', 'html-template', `${env}.html`);
|
|
36
|
+
const useAppEntry = hasEntrypoint(appDir, 'App.tsx');
|
|
37
|
+
const useSheetEntry = hasEntrypoint(appDir, 'Sheet.tsx');
|
|
38
|
+
const useEditorEntry = hasEntrypoint(appDir, 'Editor.tsx');
|
|
39
|
+
const appEntry = useAppEntry ? path_1.default.resolve(appDir, 'src/App') : path_1.default.resolve(appDir, 'src');
|
|
23
40
|
const manifestJson = JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(appDir, 'manifest.json'), 'utf8'));
|
|
24
41
|
const linkTypeName = manifestJson.name.replace(/[^A-Za-z0-9 ]/g, '');
|
|
25
42
|
const linkTypeSlug = (0, slugify_1.default)(linkTypeName, { lower: true });
|
|
26
43
|
const linkTypeId = (0, camelcase_1.default)(linkTypeSlug, { pascalCase: true });
|
|
27
44
|
const hasTsconfig = fileExists(path_1.default.resolve(appDir, 'tsconfig.json'));
|
|
28
|
-
const componentLibraryContentPath = path_1.default.join(require.resolve('@linktr.ee/component-library/tailwind.config').split('/').slice(0, -1).join('/'), 'dist', '**', '*.js');
|
|
29
45
|
const config = {
|
|
30
46
|
target: 'web',
|
|
31
47
|
mode: env,
|
|
@@ -33,7 +49,9 @@ function default_1(env, options) {
|
|
|
33
49
|
output: {
|
|
34
50
|
publicPath: 'auto',
|
|
35
51
|
path: path_1.default.resolve(appDir, 'dist'),
|
|
36
|
-
assetModuleFilename: 'images/[hash][ext][query]',
|
|
52
|
+
assetModuleFilename: 'images/[hash].[contenthash][ext][query]',
|
|
53
|
+
chunkFilename: '[id].[contenthash].js',
|
|
54
|
+
filename: '[name].[contenthash].js',
|
|
37
55
|
},
|
|
38
56
|
module: {
|
|
39
57
|
rules: [
|
|
@@ -52,7 +70,7 @@ function default_1(env, options) {
|
|
|
52
70
|
},
|
|
53
71
|
{
|
|
54
72
|
test: /\.(png|jpe?g|gif|svg)$/i,
|
|
55
|
-
type: 'asset/inline',
|
|
73
|
+
type: 'asset/inline', // <-- this builds all images into data URLs, is that what you want?
|
|
56
74
|
},
|
|
57
75
|
{
|
|
58
76
|
test: /\.css$/,
|
|
@@ -62,33 +80,7 @@ function default_1(env, options) {
|
|
|
62
80
|
{
|
|
63
81
|
loader: 'postcss-loader',
|
|
64
82
|
options: {
|
|
65
|
-
postcssOptions: {
|
|
66
|
-
plugins: [
|
|
67
|
-
(0, tailwindcss_1.default)({
|
|
68
|
-
content: [`${appDir}/src/**/*.{js,jsx,ts,tsx}`, componentLibraryContentPath],
|
|
69
|
-
important: `.ui-link-app-${linkTypeSlug}`,
|
|
70
|
-
presets: [require('@linktr.ee/component-library/tailwind.config')],
|
|
71
|
-
plugins: [],
|
|
72
|
-
theme: {
|
|
73
|
-
extend: {
|
|
74
|
-
backgroundImage: {
|
|
75
|
-
loading: 'linear-gradient(90deg,#f3f3f1,#fff,#f3f3f1);',
|
|
76
|
-
},
|
|
77
|
-
keyframes: {
|
|
78
|
-
loading: {
|
|
79
|
-
'75%': { transform: 'translateX(100%)' },
|
|
80
|
-
'100%': { transform: 'translateX(100%)' },
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
animation: {
|
|
84
|
-
loading: 'loading 1.5s ease-in-out infinite',
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
}),
|
|
89
|
-
(0, autoprefixer_1.default)(),
|
|
90
|
-
],
|
|
91
|
-
},
|
|
83
|
+
postcssOptions: { ...(0, postcss_config_1.getPostcssConfig)({ linkTypeSlug }) },
|
|
92
84
|
},
|
|
93
85
|
},
|
|
94
86
|
],
|
|
@@ -101,15 +93,12 @@ function default_1(env, options) {
|
|
|
101
93
|
// TODO: The behaviour here with module resolution is confusing, can we make it more explicit?
|
|
102
94
|
modules: [path_1.default.resolve(appDir, 'node_modules'), 'node_modules'],
|
|
103
95
|
alias: {
|
|
104
|
-
'@linktr.ee/extension':
|
|
96
|
+
'@linktr.ee/extension': appEntry,
|
|
105
97
|
},
|
|
106
98
|
},
|
|
107
99
|
plugins: [
|
|
108
100
|
new html_webpack_plugin_1.default({
|
|
109
101
|
template: htmlTemplateFile,
|
|
110
|
-
templateParameters: {
|
|
111
|
-
tailwindBaseClass: `ui-link-app-${linkTypeSlug}`,
|
|
112
|
-
},
|
|
113
102
|
excludeChunks: [`LinkApp_${linkTypeId}`],
|
|
114
103
|
}),
|
|
115
104
|
],
|
|
@@ -127,6 +116,17 @@ function default_1(env, options) {
|
|
|
127
116
|
config.plugins.push(new mini_css_extract_plugin_1.default());
|
|
128
117
|
}
|
|
129
118
|
if (env === 'production') {
|
|
119
|
+
const exposedEntryPoints = {
|
|
120
|
+
// Default entry points
|
|
121
|
+
['./App']: appEntry,
|
|
122
|
+
['./validate']: toVirtualModule((await (0, compile_1.default)())),
|
|
123
|
+
};
|
|
124
|
+
if (useEditorEntry) {
|
|
125
|
+
exposedEntryPoints['./Editor'] = path_1.default.resolve(appDir, 'src/Editor');
|
|
126
|
+
}
|
|
127
|
+
if (useSheetEntry) {
|
|
128
|
+
exposedEntryPoints['./Sheet'] = path_1.default.resolve(appDir, 'src/Sheet');
|
|
129
|
+
}
|
|
130
130
|
// TODO: Figure out how to manage externals with Module Federation
|
|
131
131
|
// Possibly make the index.html a host app, via separate webpack config
|
|
132
132
|
// config.externals = {
|
|
@@ -141,6 +141,8 @@ function default_1(env, options) {
|
|
|
141
141
|
};
|
|
142
142
|
config.plugins.push(new webpack_1.DefinePlugin({
|
|
143
143
|
__ALLOW_ANY_ORIGIN__: options?.allowAnyOrigin,
|
|
144
|
+
__LINK_TYPE_SLUG__: JSON.stringify(linkTypeSlug),
|
|
145
|
+
__LINK_TYPE_ID__: JSON.stringify(linkTypeId),
|
|
144
146
|
}),
|
|
145
147
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
146
148
|
// @ts-ignore
|
|
@@ -150,9 +152,7 @@ function default_1(env, options) {
|
|
|
150
152
|
}), new ModuleFederationPlugin({
|
|
151
153
|
name: `LinkApp_${linkTypeId}`,
|
|
152
154
|
filename: 'remoteEntry.js',
|
|
153
|
-
exposes:
|
|
154
|
-
['./App']: path_1.default.resolve(appDir, 'src'),
|
|
155
|
-
},
|
|
155
|
+
exposes: exposedEntryPoints,
|
|
156
156
|
shared: {
|
|
157
157
|
react: {
|
|
158
158
|
singleton: true,
|